From 2ae7009b0e7f638a070d2f669b10e924796ec779 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 1 May 2022 06:57:49 +0100 Subject: [PATCH] Add in tree aubio Signed-off-by: falkTX --- deps/aubio/COPYING | 674 +++++++++++++++++++++++ deps/aubio/Makefile | 62 +++ deps/aubio/config.h | 20 + deps/aubio/src/aubio.h | 208 ++++++++ deps/aubio/src/aubio_priv.h | 359 +++++++++++++ deps/aubio/src/cvec.c | 169 ++++++ deps/aubio/src/cvec.h | 247 +++++++++ deps/aubio/src/fvec.c | 149 ++++++ deps/aubio/src/fvec.h | 178 +++++++ deps/aubio/src/lvec.c | 80 +++ deps/aubio/src/lvec.h | 118 ++++ deps/aubio/src/mathutils.c | 681 ++++++++++++++++++++++++ deps/aubio/src/mathutils.h | 338 ++++++++++++ deps/aubio/src/musicutils.h | 270 ++++++++++ deps/aubio/src/pitch/pitch.c | 530 ++++++++++++++++++ deps/aubio/src/pitch/pitch.h | 197 +++++++ deps/aubio/src/pitch/pitchfcomb.c | 144 +++++ deps/aubio/src/pitch/pitchfcomb.h | 76 +++ deps/aubio/src/pitch/pitchmcomb.c | 435 +++++++++++++++ deps/aubio/src/pitch/pitchmcomb.h | 77 +++ deps/aubio/src/pitch/pitchschmitt.c | 119 +++++ deps/aubio/src/pitch/pitchschmitt.h | 75 +++ deps/aubio/src/pitch/pitchspecacf.c | 116 ++++ deps/aubio/src/pitch/pitchspecacf.h | 103 ++++ deps/aubio/src/pitch/pitchyin.c | 189 +++++++ deps/aubio/src/pitch/pitchyin.h | 100 ++++ deps/aubio/src/pitch/pitchyinfast.c | 201 +++++++ deps/aubio/src/pitch/pitchyinfast.h | 102 ++++ deps/aubio/src/pitch/pitchyinfft.c | 208 ++++++++ deps/aubio/src/pitch/pitchyinfft.h | 99 ++++ deps/aubio/src/spectral/fft.c | 582 ++++++++++++++++++++ deps/aubio/src/spectral/fft.h | 144 +++++ deps/aubio/src/spectral/phasevoc.c | 224 ++++++++ deps/aubio/src/spectral/phasevoc.h | 113 ++++ deps/aubio/src/temporal/a_weighting.c | 262 +++++++++ deps/aubio/src/temporal/a_weighting.h | 88 +++ deps/aubio/src/temporal/biquad.c | 54 ++ deps/aubio/src/temporal/biquad.h | 75 +++ deps/aubio/src/temporal/c_weighting.c | 217 ++++++++ deps/aubio/src/temporal/c_weighting.h | 88 +++ deps/aubio/src/temporal/filter.c | 163 ++++++ deps/aubio/src/temporal/filter.h | 176 ++++++ deps/aubio/src/temporal/resampler.c | 100 ++++ deps/aubio/src/temporal/resampler.h | 65 +++ deps/aubio/src/types.h | 70 +++ deps/aubio/src/utils/log.c | 92 ++++ deps/aubio/src/utils/log.h | 99 ++++ plugins/Cardinal/src/AudioToCVPitch.cpp | 2 +- 48 files changed, 8937 insertions(+), 1 deletion(-) create mode 100644 deps/aubio/COPYING create mode 100644 deps/aubio/Makefile create mode 100644 deps/aubio/config.h create mode 100644 deps/aubio/src/aubio.h create mode 100644 deps/aubio/src/aubio_priv.h create mode 100644 deps/aubio/src/cvec.c create mode 100644 deps/aubio/src/cvec.h create mode 100644 deps/aubio/src/fvec.c create mode 100644 deps/aubio/src/fvec.h create mode 100644 deps/aubio/src/lvec.c create mode 100644 deps/aubio/src/lvec.h create mode 100644 deps/aubio/src/mathutils.c create mode 100644 deps/aubio/src/mathutils.h create mode 100644 deps/aubio/src/musicutils.h create mode 100644 deps/aubio/src/pitch/pitch.c create mode 100644 deps/aubio/src/pitch/pitch.h create mode 100644 deps/aubio/src/pitch/pitchfcomb.c create mode 100644 deps/aubio/src/pitch/pitchfcomb.h create mode 100644 deps/aubio/src/pitch/pitchmcomb.c create mode 100644 deps/aubio/src/pitch/pitchmcomb.h create mode 100644 deps/aubio/src/pitch/pitchschmitt.c create mode 100644 deps/aubio/src/pitch/pitchschmitt.h create mode 100644 deps/aubio/src/pitch/pitchspecacf.c create mode 100644 deps/aubio/src/pitch/pitchspecacf.h create mode 100644 deps/aubio/src/pitch/pitchyin.c create mode 100644 deps/aubio/src/pitch/pitchyin.h create mode 100644 deps/aubio/src/pitch/pitchyinfast.c create mode 100644 deps/aubio/src/pitch/pitchyinfast.h create mode 100644 deps/aubio/src/pitch/pitchyinfft.c create mode 100644 deps/aubio/src/pitch/pitchyinfft.h create mode 100644 deps/aubio/src/spectral/fft.c create mode 100644 deps/aubio/src/spectral/fft.h create mode 100644 deps/aubio/src/spectral/phasevoc.c create mode 100644 deps/aubio/src/spectral/phasevoc.h create mode 100644 deps/aubio/src/temporal/a_weighting.c create mode 100644 deps/aubio/src/temporal/a_weighting.h create mode 100644 deps/aubio/src/temporal/biquad.c create mode 100644 deps/aubio/src/temporal/biquad.h create mode 100644 deps/aubio/src/temporal/c_weighting.c create mode 100644 deps/aubio/src/temporal/c_weighting.h create mode 100644 deps/aubio/src/temporal/filter.c create mode 100644 deps/aubio/src/temporal/filter.h create mode 100644 deps/aubio/src/temporal/resampler.c create mode 100644 deps/aubio/src/temporal/resampler.h create mode 100644 deps/aubio/src/types.h create mode 100644 deps/aubio/src/utils/log.c create mode 100644 deps/aubio/src/utils/log.h diff --git a/deps/aubio/COPYING b/deps/aubio/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/deps/aubio/COPYING @@ -0,0 +1,674 @@ + 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 +. diff --git a/deps/aubio/Makefile b/deps/aubio/Makefile new file mode 100644 index 0000000..8d6e45a --- /dev/null +++ b/deps/aubio/Makefile @@ -0,0 +1,62 @@ +#!/usr/bin/make -f +# Makefile for static aubio # +# ------------------------- # +# Created by falkTX +# + +# -------------------------------------------------------------- +# Import base definitions + +USE_NANOVG_FBO = true +include ../../dpf/Makefile.base.mk + +# -------------------------------------------------------------- + +BUILD_C_FLAGS += -DHAVE_CONFIG_H +BUILD_C_FLAGS += -I. +BUILD_C_FLAGS += -Isrc +BUILD_C_FLAGS += $(shell pkg-config --cflags fftw3f) + +OBJS = \ + src/cvec.c.o \ + src/fvec.c.o \ + src/lvec.c.o \ + src/mathutils.c.o \ + src/pitch/pitch.c.o \ + src/pitch/pitchfcomb.c.o \ + src/pitch/pitchmcomb.c.o \ + src/pitch/pitchschmitt.c.o \ + src/pitch/pitchspecacf.c.o \ + src/pitch/pitchyin.c.o \ + src/pitch/pitchyinfast.c.o \ + src/pitch/pitchyinfft.c.o \ + src/spectral/fft.c.o \ + src/spectral/phasevoc.c.o \ + src/temporal/a_weighting.c.o \ + src/temporal/biquad.c.o \ + src/temporal/c_weighting.c.o \ + src/temporal/filter.c.o \ + src/temporal/resampler.c.o \ + src/utils/log.c.o \ + +# -------------------------------------------------------------- + +all: libaubio.a + +clean: + rm -f *.a src/*.d src/*.o src/*/*.d src/*/*.o + +libaubio.a: $(OBJS) + rm -f $@ + $(AR) crs $@ $^ + +# -------------------------------------------------------------- + +%.c.o: %.c + $(CC) $< $(BUILD_C_FLAGS) -c -o $@ + +# -------------------------------------------------------------- + +-include $(OBJS:%.o=%.d) + +# -------------------------------------------------------------- diff --git a/deps/aubio/config.h b/deps/aubio/config.h new file mode 100644 index 0000000..7985662 --- /dev/null +++ b/deps/aubio/config.h @@ -0,0 +1,20 @@ +#ifndef AUBIO_CONFIG_H +#define AUBIO_CONFIG_H + +#define HAVE_STDLIB_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_MATH_H 1 +#define HAVE_STRING_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_GETOPT_H 1 +#define HAVE_UNISTD_H 1 + +#define HAVE_C99_VARARGS_MACROS 1 +#define HAVE_MEMCPY_HACKS 1 + +#define HAVE_FFTW3 +#define HAVE_FFTW3F +#define HAVE_COMPLEX_H + +#endif /* AUBIO_CONFIG_H */ diff --git a/deps/aubio/src/aubio.h b/deps/aubio/src/aubio.h new file mode 100644 index 0000000..4d26ea8 --- /dev/null +++ b/deps/aubio/src/aubio.h @@ -0,0 +1,208 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \mainpage + + \section introduction Introduction + + aubio is a library to extract annotations from audio signals: it provides a + set of functions that take an input audio signal, and output pitch estimates, + attack times (onset), beat location estimates, and other annotation tasks. + + \section basics Basics + + All object structures in aubio share the same function prefixes and suffixes: + + - \p new_aubio_foo creates the object \p foo + - \p aubio_foo_do executes the object \p foo + - \p del_aubio_foo destroys the object \p foo + + All memory allocation and deallocation take place in the \p new_ and \p del_ + functions. Optionally, more than one \p _do methods are available. + Additional parameters can be adjusted and observed using: + + - \p aubio_foo_get_param, getter function, gets the value of a parameter + - \p aubio_foo_set_param, setter function, changes the value of a parameter + + Unless specified in its documentation, no memory operations take place in the + getter functions. However, memory resizing can take place in setter + functions. + + \subsection vectors Vectors + + Two basic structures are being used in aubio: ::fvec_t and ::cvec_t. The + ::fvec_t structures are used to store vectors of floating pointer number. + ::cvec_t are used to store complex number, as two vectors of norm and phase + elements. + + Additionally, the ::lvec_t structure can be used to store floating point + numbers in double precision. They are mostly used to store filter + coefficients, to avoid instability. + + \subsection objects Available objects + + Here is a list of some of the most common objects for aubio: + + \code + + // fast Fourier transform (FFT) + aubio_fft_t *fft = new_aubio_fft (winsize); + // phase vocoder + aubio_pvoc_t *pv = new_aubio_pvoc (winsize, stepsize); + // onset detection + aubio_onset_t *onset = new_aubio_onset (method, winsize, stepsize, samplerate); + // pitch detection + aubio_pitch_t *pitch = new_aubio_pitch (method, winsize, stepsize, samplerate); + // beat tracking + aubio_tempo_t *tempo = new_aubio_tempo (method, winsize, stepsize, samplerate); + + \endcode + + See the list of typedefs for a complete list. + + \subsection example Example + + Here is a simple example that creates an A-Weighting filter and applies it to a + vector. + + \code + + // set window size, and sampling rate + uint_t winsize = 1024, sr = 44100; + // create a vector + fvec_t *this_buffer = new_fvec (winsize); + // create the a-weighting filter + aubio_filter_t *this_filter = new_aubio_filter_a_weighting (sr); + + while (running) { + // here some code to put some data in this_buffer + // ... + + // apply the filter, in place + aubio_filter_do (this_filter, this_buffer); + + // here some code to get some data from this_buffer + // ... + } + + // and free the structures + del_aubio_filter (this_filter); + del_fvec (this_buffer); + + \endcode + + Several examples of C programs are available in the \p examples/ and \p tests/src + directories of the source tree. + + Some examples: + - @ref spectral/test-fft.c + - @ref spectral/test-phasevoc.c + - @ref onset/test-onset.c + - @ref pitch/test-pitch.c + - @ref tempo/test-tempo.c + - @ref test-fvec.c + - @ref test-cvec.c + + \subsection unstable_api Unstable API + + Several more functions are available and used within aubio, but not + documented here, either because they are not considered useful to the user, + or because they may need to be changed in the future. However, they can still + be used by defining AUBIO_UNSTABLE to 1 before including the aubio header: + + \code + #define AUBIO_UNSTABLE 1 + #include + \endcode + + Future versions of aubio could break API compatibility with these functions + without warning. If you choose to use functions in AUBIO_UNSTABLE, you are on + your own. + + \section download Download + + Latest versions, further documentation, examples, wiki, and mailing lists can + be found at https://aubio.org . + + */ + +#ifndef AUBIO_H +#define AUBIO_H + +/** @file aubio.h Global aubio include file. + + You will want to include this file as: + + @code + #include + @endcode + + To access headers with unstable prototypes, use: + + @code + #define AUBIO_UNSTABLE 1 + #include + @endcode + + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* in this order */ +#include "types.h" +#include "fvec.h" +// #include "cvec.h" +// #include "lvec.h" +// // #include "fmat.h" +// #include "musicutils.h" +// // #include "vecutils.h" +// #include "temporal/resampler.h" +// #include "temporal/filter.h" +// #include "temporal/biquad.h" +// #include "temporal/a_weighting.h" +// #include "temporal/c_weighting.h" +// #include "spectral/fft.h" +// // #include "spectral/dct.h" +// #include "spectral/phasevoc.h" +// // #include "spectral/filterbank.h" +// // #include "spectral/filterbank_mel.h" +// // #include "spectral/mfcc.h" +// // #include "spectral/specdesc.h" +// // #include "spectral/awhitening.h" +// // #include "spectral/tss.h" +#include "pitch/pitch.h" +// // #include "onset/onset.h" +// // #include "tempo/tempo.h" +// // #include "notes/notes.h" +// // #include "io/source.h" +// // #include "io/sink.h" +// // #include "synth/sampler.h" +// // #include "synth/wavetable.h" +// // #include "utils/parameter.h" +// #include "utils/log.h" + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/deps/aubio/src/aubio_priv.h b/deps/aubio/src/aubio_priv.h new file mode 100644 index 0000000..8cd3225 --- /dev/null +++ b/deps/aubio/src/aubio_priv.h @@ -0,0 +1,359 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** @file + * Private include file + * + * This file is for inclusion from _within_ the library only. + */ + +#ifndef AUBIO_PRIV_H +#define AUBIO_PRIV_H + +/********************* + * + * External includes + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STDIO_H +#include +#endif + +/* must be included before fftw3.h */ +#ifdef HAVE_COMPLEX_H +#include +#endif + +#if defined(HAVE_FFTW3) || defined(HAVE_FFTW3F) +#include +#endif + +#ifdef HAVE_MATH_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_LIMITS_H +#include // for CHAR_BIT, in C99 standard +#endif + +#ifdef HAVE_STDARG_H +#include +#endif + +#ifdef HAVE_ACCELERATE +#define HAVE_ATLAS 1 +#include +#elif defined(HAVE_ATLAS_CBLAS_H) +#define HAVE_ATLAS 1 +#include +#else +#undef HAVE_ATLAS +#endif + +#ifdef HAVE_ACCELERATE +#include +#ifndef HAVE_AUBIO_DOUBLE +#define aubio_vDSP_mmov vDSP_mmov +#define aubio_vDSP_vmul vDSP_vmul +#define aubio_vDSP_vfill vDSP_vfill +#define aubio_vDSP_meanv vDSP_meanv +#define aubio_vDSP_sve vDSP_sve +#define aubio_vDSP_maxv vDSP_maxv +#define aubio_vDSP_maxvi vDSP_maxvi +#define aubio_vDSP_minv vDSP_minv +#define aubio_vDSP_minvi vDSP_minvi +#define aubio_vDSP_dotpr vDSP_dotpr +#define aubio_vDSP_vclr vDSP_vclr +#else /* HAVE_AUBIO_DOUBLE */ +#define aubio_vDSP_mmov vDSP_mmovD +#define aubio_vDSP_vmul vDSP_vmulD +#define aubio_vDSP_vfill vDSP_vfillD +#define aubio_vDSP_meanv vDSP_meanvD +#define aubio_vDSP_sve vDSP_sveD +#define aubio_vDSP_maxv vDSP_maxvD +#define aubio_vDSP_maxvi vDSP_maxviD +#define aubio_vDSP_minv vDSP_minvD +#define aubio_vDSP_minvi vDSP_minviD +#define aubio_vDSP_dotpr vDSP_dotprD +#define aubio_vDSP_vclr vDSP_vclrD +#endif /* HAVE_AUBIO_DOUBLE */ +#endif /* HAVE_ACCELERATE */ + +#ifdef HAVE_ATLAS +#ifndef HAVE_AUBIO_DOUBLE +#define aubio_catlas_set catlas_sset +#define aubio_cblas_copy cblas_scopy +#define aubio_cblas_swap cblas_sswap +#define aubio_cblas_dot cblas_sdot +#else /* HAVE_AUBIO_DOUBLE */ +#define aubio_catlas_set catlas_dset +#define aubio_cblas_copy cblas_dcopy +#define aubio_cblas_swap cblas_dswap +#define aubio_cblas_dot cblas_ddot +#endif /* HAVE_AUBIO_DOUBLE */ +#endif /* HAVE_ATLAS */ + +#if defined HAVE_INTEL_IPP +#include +#include +#include +#ifndef HAVE_AUBIO_DOUBLE +#define aubio_ippsSet ippsSet_32f +#define aubio_ippsZero ippsZero_32f +#define aubio_ippsCopy ippsCopy_32f +#define aubio_ippsMul ippsMul_32f +#define aubio_ippsMulC ippsMulC_32f +#define aubio_ippsAddC ippsAddC_32f +#define aubio_ippsLn ippsLn_32f_A21 +#define aubio_ippsMean(a,b,c) ippsMean_32f(a, b, c, ippAlgHintFast) +#define aubio_ippsSum(a,b,c) ippsSum_32f(a, b, c, ippAlgHintFast) +#define aubio_ippsMax ippsMax_32f +#define aubio_ippsMin ippsMin_32f +#else /* HAVE_AUBIO_DOUBLE */ +#define aubio_ippsSet ippsSet_64f +#define aubio_ippsZero ippsZero_64f +#define aubio_ippsCopy ippsCopy_64f +#define aubio_ippsMul ippsMul_64f +#define aubio_ippsMulC ippsMulC_64f +#define aubio_ippsAddC ippsAddC_64f +#define aubio_ippsLn ippsLn_64f_A26 +#define aubio_ippsMean ippsMean_64f +#define aubio_ippsSum ippsSum_64f +#define aubio_ippsMax ippsMax_64f +#define aubio_ippsMin ippsMin_64f +#endif /* HAVE_AUBIO_DOUBLE */ +#endif + +#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE) && !defined(HAVE_ATLAS) && !defined(HAVE_INTEL_IPP) +#define HAVE_NOOPT 1 +#else +#undef HAVE_NOOPT +#endif + +#include "types.h" + +#define AUBIO_UNSTABLE 1 + +#include "mathutils.h" + +/**** + * + * SYSTEM INTERFACE + * + */ + +/* Memory management */ +#define AUBIO_MALLOC(_n) malloc(_n) +#define AUBIO_REALLOC(_p,_n) realloc(_p,_n) +#define AUBIO_NEW(_t) (_t*)calloc(sizeof(_t), 1) +#define AUBIO_ARRAY(_t,_n) (_t*)calloc((_n)*sizeof(_t), 1) +#define AUBIO_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n) +#define AUBIO_MEMSET(_dst,_src,_t) memset(_dst,_src,_t) +#define AUBIO_FREE(_p) free(_p) + + +/* file interface */ +#define AUBIO_FOPEN(_f,_m) fopen(_f,_m) +#define AUBIO_FCLOSE(_f) fclose(_f) +#define AUBIO_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f) +#define AUBIO_FSEEK(_f,_n,_set) fseek(_f,_n,_set) + +/* strings */ +#define AUBIO_STRLEN(_s) strlen(_s) +#define AUBIO_STRCMP(_s,_t) strcmp(_s,_t) +#define AUBIO_STRNCMP(_s,_t,_n) strncmp(_s,_t,_n) +#define AUBIO_STRCPY(_dst,_src) strcpy(_dst,_src) +#define AUBIO_STRCHR(_s,_c) strchr(_s,_c) +#ifdef strdup +#define AUBIO_STRDUP(s) strdup(s) +#else +#define AUBIO_STRDUP(s) AUBIO_STRCPY(AUBIO_MALLOC(AUBIO_STRLEN(s) + 1), s) +#endif + + +/* Error reporting */ +typedef enum { + AUBIO_OK = 0, + AUBIO_FAIL = 1 +} aubio_status; + +/* Logging */ + +#include "utils/log.h" + +/** internal logging function, defined in utils/log.c */ +uint_t aubio_log(sint_t level, const char_t *fmt, ...); + +#ifdef HAVE_C99_VARARGS_MACROS +#define AUBIO_ERR(...) aubio_log(AUBIO_LOG_ERR, "AUBIO ERROR: " __VA_ARGS__) +#define AUBIO_INF(...) aubio_log(AUBIO_LOG_INF, "AUBIO INFO: " __VA_ARGS__) +#define AUBIO_MSG(...) aubio_log(AUBIO_LOG_MSG, __VA_ARGS__) +#define AUBIO_DBG(...) aubio_log(AUBIO_LOG_DBG, __VA_ARGS__) +#define AUBIO_WRN(...) aubio_log(AUBIO_LOG_WRN, "AUBIO WARNING: " __VA_ARGS__) +#else +#define AUBIO_ERR(format, args...) aubio_log(AUBIO_LOG_ERR, "AUBIO ERROR: " format , ##args) +#define AUBIO_INF(format, args...) aubio_log(AUBIO_LOG_INF, "AUBIO INFO: " format , ##args) +#define AUBIO_MSG(format, args...) aubio_log(AUBIO_LOG_MSG, format , ##args) +#define AUBIO_DBG(format, args...) aubio_log(AUBIO_LOG_DBG, format , ##args) +#define AUBIO_WRN(format, args...) aubio_log(AUBIO_LOG_WRN, "AUBIO WARNING: " format, ##args) +#endif + +#define AUBIO_ERROR AUBIO_ERR + +#define AUBIO_QUIT(_s) exit(_s) +#define AUBIO_SPRINTF sprintf + +#define AUBIO_MAX_SAMPLERATE (192000*8) +#define AUBIO_MAX_CHANNELS 1024 + +/* pi and 2*pi */ +#ifndef M_PI +#define PI (3.14159265358979323846) +#else +#define PI (M_PI) +#endif +#define TWO_PI (PI*2.) + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +/* aliases to math.h functions */ +#if !HAVE_AUBIO_DOUBLE +#define EXP expf +#define COS cosf +#define SIN sinf +#define ABS fabsf +#define POW powf +#define SQRT sqrtf +#define LOG10 log10f +#define LOG logf +#define FLOOR floorf +#define CEIL ceilf +#define ATAN atanf +#define ATAN2 atan2f +#else +#error using double +#define EXP exp +#define COS cos +#define SIN sin +#define ABS fabs +#define POW pow +#define SQRT sqrt +#define LOG10 log10 +#define LOG log +#define FLOOR floor +#define CEIL ceil +#define ATAN atan +#define ATAN2 atan2 +#endif +#define ROUND(x) FLOOR(x+.5) + +/* aliases to complex.h functions */ +#if HAVE_AUBIO_DOUBLE || !defined(HAVE_COMPLEX_H) || defined(WIN32) +/* mingw32 does not know about c*f functions */ +#define EXPC cexp +/** complex = CEXPC(complex) */ +#define CEXPC cexp +/** sample = ARGC(complex) */ +#define ARGC carg +/** sample = ABSC(complex) norm */ +#define ABSC cabs +/** sample = REAL(complex) */ +#define REAL creal +/** sample = IMAG(complex) */ +#define IMAG cimag +#else +/** sample = EXPC(complex) */ +#define EXPC cexpf +/** complex = CEXPC(complex) */ +#define CEXPC cexp +/** sample = ARGC(complex) */ +#define ARGC cargf +/** sample = ABSC(complex) norm */ +#define ABSC cabsf +/** sample = REAL(complex) */ +#define REAL crealf +/** sample = IMAG(complex) */ +#define IMAG cimagf +#endif + +/* avoid unresolved symbol with msvc 9 */ +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define isnan _isnan +#endif + +/* handy shortcuts */ +#define DB2LIN(g) (POW(10.0,(g)*0.05f)) +#define LIN2DB(v) (20.0*LOG10(v)) +#define SQR(_a) ((_a)*(_a)) + +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif /* MAX */ +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif /* MIN */ + +#define ELEM_SWAP(a,b) { register smpl_t t=(a);(a)=(b);(b)=t; } + +#define VERY_SMALL_NUMBER 2.e-42 //1.e-37 + +/** if ABS(f) < VERY_SMALL_NUMBER, returns 1, else 0 */ +#define IS_DENORMAL(f) ABS(f) < VERY_SMALL_NUMBER + +/** if ABS(f) < VERY_SMALL_NUMBER, returns 0., else f */ +#define KILL_DENORMAL(f) IS_DENORMAL(f) ? 0. : f + +/** if f > VERY_SMALL_NUMBER, returns f, else returns VERY_SMALL_NUMBER */ +#define CEIL_DENORMAL(f) f < VERY_SMALL_NUMBER ? VERY_SMALL_NUMBER : f + +#define SAFE_LOG10(f) LOG10(CEIL_DENORMAL(f)) +#define SAFE_LOG(f) LOG(CEIL_DENORMAL(f)) + +/** silence unused parameter warning by adding an attribute */ +#if defined(__GNUC__) +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + +/* are we using gcc -std=c99 ? */ +#if defined(__STRICT_ANSI__) +#define strnlen(a,b) MIN(strlen(a),b) +#if !HAVE_AUBIO_DOUBLE +#define floorf floor +#endif +#endif /* __STRICT_ANSI__ */ + +#endif /* AUBIO_PRIV_H */ diff --git a/deps/aubio/src/cvec.c b/deps/aubio/src/cvec.c new file mode 100644 index 0000000..00c43be --- /dev/null +++ b/deps/aubio/src/cvec.c @@ -0,0 +1,169 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "cvec.h" + +cvec_t * new_cvec(uint_t length) { + cvec_t * s; + if ((sint_t)length <= 0) { + return NULL; + } + s = AUBIO_NEW(cvec_t); + s->length = length/2 + 1; + s->norm = AUBIO_ARRAY(smpl_t,s->length); + s->phas = AUBIO_ARRAY(smpl_t,s->length); + return s; +} + +void del_cvec(cvec_t *s) { + AUBIO_FREE(s->norm); + AUBIO_FREE(s->phas); + AUBIO_FREE(s); +} + +void cvec_norm_set_sample (cvec_t *s, smpl_t data, uint_t position) { + s->norm[position] = data; +} + +void cvec_phas_set_sample (cvec_t *s, smpl_t data, uint_t position) { + s->phas[position] = data; +} + +smpl_t cvec_norm_get_sample (cvec_t *s, uint_t position) { + return s->norm[position]; +} + +smpl_t cvec_phas_get_sample (cvec_t *s, uint_t position) { + return s->phas[position]; +} + +smpl_t * cvec_norm_get_data (const cvec_t *s) { + return s->norm; +} + +smpl_t * cvec_phas_get_data (const cvec_t *s) { + return s->phas; +} + +/* helper functions */ + +void cvec_print(const cvec_t *s) { + uint_t j; + AUBIO_MSG("norm: "); + for (j=0; j< s->length; j++) { + AUBIO_MSG(AUBIO_SMPL_FMT " ", s->norm[j]); + } + AUBIO_MSG("\n"); + AUBIO_MSG("phas: "); + for (j=0; j< s->length; j++) { + AUBIO_MSG(AUBIO_SMPL_FMT " ", s->phas[j]); + } + AUBIO_MSG("\n"); +} + +void cvec_copy(const cvec_t *s, cvec_t *t) { + if (s->length != t->length) { + AUBIO_ERR("trying to copy %d elements to %d elements \n", + s->length, t->length); + return; + } +#if defined(HAVE_INTEL_IPP) + aubio_ippsCopy(s->phas, t->phas, (int)s->length); + aubio_ippsCopy(s->norm, t->norm, (int)s->length); +#elif defined(HAVE_MEMCPY_HACKS) + memcpy(t->norm, s->norm, t->length * sizeof(smpl_t)); + memcpy(t->phas, s->phas, t->length * sizeof(smpl_t)); +#else + uint_t j; + for (j=0; j< t->length; j++) { + t->norm[j] = s->norm[j]; + t->phas[j] = s->phas[j]; + } +#endif +} + +void cvec_norm_set_all(cvec_t *s, smpl_t val) { +#if defined(HAVE_INTEL_IPP) + aubio_ippsSet(val, s->norm, (int)s->length); +#else + uint_t j; + for (j=0; j< s->length; j++) { + s->norm[j] = val; + } +#endif +} + +void cvec_norm_zeros(cvec_t *s) { +#if defined(HAVE_INTEL_IPP) + aubio_ippsZero(s->norm, (int)s->length); +#elif defined(HAVE_MEMCPY_HACKS) + memset(s->norm, 0, s->length * sizeof(smpl_t)); +#else + cvec_norm_set_all (s, 0.); +#endif +} + +void cvec_norm_ones(cvec_t *s) { + cvec_norm_set_all (s, 1.); +} + +void cvec_phas_set_all (cvec_t *s, smpl_t val) { +#if defined(HAVE_INTEL_IPP) + aubio_ippsSet(val, s->phas, (int)s->length); +#else + uint_t j; + for (j=0; j< s->length; j++) { + s->phas[j] = val; + } +#endif +} + +void cvec_phas_zeros(cvec_t *s) { +#if defined(HAVE_INTEL_IPP) + aubio_ippsZero(s->phas, (int)s->length); +#elif defined(HAVE_MEMCPY_HACKS) + memset(s->phas, 0, s->length * sizeof(smpl_t)); +#else + cvec_phas_set_all (s, 0.); +#endif +} + +void cvec_phas_ones(cvec_t *s) { + cvec_phas_set_all (s, 1.); +} + +void cvec_zeros(cvec_t *s) { + cvec_norm_zeros(s); + cvec_phas_zeros(s); +} + +void cvec_logmag(cvec_t *s, smpl_t lambda) { +#if defined(HAVE_INTEL_IPP) + aubio_ippsMulC(s->norm, lambda, s->norm, (int)s->length); + aubio_ippsAddC(s->norm, 1.0, s->norm, (int)s->length); + aubio_ippsLn(s->norm, s->norm, (int)s->length); +#else + uint_t j; + for (j=0; j< s->length; j++) { + s->norm[j] = LOG(lambda * s->norm[j] + 1); + } +#endif +} diff --git a/deps/aubio/src/cvec.h b/deps/aubio/src/cvec.h new file mode 100644 index 0000000..7c826b6 --- /dev/null +++ b/deps/aubio/src/cvec.h @@ -0,0 +1,247 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_CVEC_H +#define AUBIO_CVEC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + + Vector of complex-valued data, stored in polar coordinates + + This file specifies the ::cvec_t buffer type, which is used throughout aubio + to store complex data. Complex values are stored in terms of ::cvec_t.phas + and norm, within 2 vectors of ::smpl_t of size (size/2+1) each. + + \example test-cvec.c + +*/ + +/** Vector of real-valued phase and spectrum data + + \code + + uint_t buffer_size = 1024; + + // create a complex vector of 512 values + cvec_t * input = new_cvec (buffer_size); + + // set some values of the vector + input->norm[23] = 2.; + input->phas[23] = M_PI; + // .. + + // compute the mean of the vector + mean = cvec_mean(input); + + // destroy the vector + del_cvec (input); + + \endcode + + */ +typedef struct { + uint_t length; /**< length of buffer = (requested length)/2 + 1 */ + smpl_t *norm; /**< norm array of size ::cvec_t.length */ + smpl_t *phas; /**< phase array of size ::cvec_t.length */ +} cvec_t; + +/** cvec_t buffer creation function + + This function creates a cvec_t structure holding two arrays of size + [length/2+1], corresponding to the norm and phase values of the + spectral frame. The length stored in the structure is the actual size of both + arrays, not the length of the complex and symmetrical vector, specified as + creation argument. + + \param length the length of the buffer to create + +*/ +cvec_t * new_cvec(uint_t length); + +/** cvec_t buffer deletion function + + \param s buffer to delete as returned by new_cvec() + +*/ +void del_cvec(cvec_t *s); + +/** write norm value in a complex buffer + + This is equivalent to: + \code + s->norm[position] = val; + \endcode + + \param s vector to write to + \param val norm value to write in s->norm[position] + \param position sample position to write to + +*/ +void cvec_norm_set_sample (cvec_t *s, smpl_t val, uint_t position); + +/** write phase value in a complex buffer + + This is equivalent to: + \code + s->phas[position] = val; + \endcode + + \param s vector to write to + \param val phase value to write in s->phas[position] + \param position sample position to write to + +*/ +void cvec_phas_set_sample (cvec_t *s, smpl_t val, uint_t position); + +/** read norm value from a complex buffer + + This is equivalent to: + \code + smpl_t foo = s->norm[position]; + \endcode + + \param s vector to read from + \param position sample position to read from + +*/ +smpl_t cvec_norm_get_sample (cvec_t *s, uint_t position); + +/** read phase value from a complex buffer + + This is equivalent to: + \code + smpl_t foo = s->phas[position]; + \endcode + + \param s vector to read from + \param position sample position to read from + \returns the value of the sample at position + +*/ +smpl_t cvec_phas_get_sample (cvec_t *s, uint_t position); + +/** read norm data from a complex buffer + + \code + smpl_t *data = s->norm; + \endcode + + \param s vector to read from + +*/ +smpl_t * cvec_norm_get_data (const cvec_t *s); + +/** read phase data from a complex buffer + + This is equivalent to: + \code + smpl_t *data = s->phas; + \endcode + + \param s vector to read from + +*/ +smpl_t * cvec_phas_get_data (const cvec_t *s); + +/** print out cvec data + + \param s vector to print out + +*/ +void cvec_print(const cvec_t *s); + +/** make a copy of a vector + + \param s source vector + \param t vector to copy to + +*/ +void cvec_copy(const cvec_t *s, cvec_t *t); + +/** set all norm elements to a given value + + \param s vector to modify + \param val value to set elements to + +*/ +void cvec_norm_set_all (cvec_t *s, smpl_t val); + +/** set all norm elements to zero + + \param s vector to modify + +*/ +void cvec_norm_zeros(cvec_t *s); + +/** set all norm elements to one + + \param s vector to modify + +*/ +void cvec_norm_ones(cvec_t *s); + +/** set all phase elements to a given value + + \param s vector to modify + \param val value to set elements to + +*/ +void cvec_phas_set_all (cvec_t *s, smpl_t val); + +/** set all phase elements to zero + + \param s vector to modify + +*/ +void cvec_phas_zeros(cvec_t *s); + +/** set all phase elements to one + + \param s vector to modify + +*/ +void cvec_phas_ones(cvec_t *s); + +/** set all norm and phas elements to zero + + \param s vector to modify + +*/ +void cvec_zeros(cvec_t *s); + +/** take logarithmic magnitude + + \param s input cvec to compress + \param lambda value to use for normalisation + + \f$ S_k = log( \lambda * S_k + 1 ) \f$ + +*/ +void cvec_logmag(cvec_t *s, smpl_t lambda); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_CVEC_H */ diff --git a/deps/aubio/src/fvec.c b/deps/aubio/src/fvec.c new file mode 100644 index 0000000..3bb0b17 --- /dev/null +++ b/deps/aubio/src/fvec.c @@ -0,0 +1,149 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" + +fvec_t * new_fvec(uint_t length) { + fvec_t * s; + if ((sint_t)length <= 0) { + return NULL; + } + s = AUBIO_NEW(fvec_t); + s->length = length; + s->data = AUBIO_ARRAY(smpl_t, s->length); + return s; +} + +void del_fvec(fvec_t *s) { + AUBIO_FREE(s->data); + AUBIO_FREE(s); +} + +void fvec_set_sample(fvec_t *s, smpl_t data, uint_t position) { + s->data[position] = data; +} + +smpl_t fvec_get_sample(const fvec_t *s, uint_t position) { + return s->data[position]; +} + +smpl_t * fvec_get_data(const fvec_t *s) { + return s->data; +} + +/* helper functions */ + +void fvec_print(const fvec_t *s) { + uint_t j; + for (j=0; j< s->length; j++) { + AUBIO_MSG(AUBIO_SMPL_FMT " ", s->data[j]); + } + AUBIO_MSG("\n"); +} + +void fvec_set_all (fvec_t *s, smpl_t val) { +#if defined(HAVE_INTEL_IPP) + aubio_ippsSet(val, s->data, (int)s->length); +#elif defined(HAVE_ATLAS) + aubio_catlas_set(s->length, val, s->data, 1); +#elif defined(HAVE_ACCELERATE) + aubio_vDSP_vfill(&val, s->data, 1, s->length); +#else + uint_t j; + for ( j = 0; j< s->length; j++ ) + { + s->data[j] = val; + } +#endif +} + +void fvec_zeros(fvec_t *s) { +#if defined(HAVE_INTEL_IPP) + aubio_ippsZero(s->data, (int)s->length); +#elif defined(HAVE_ACCELERATE) + aubio_vDSP_vclr(s->data, 1, s->length); +#elif defined(HAVE_MEMCPY_HACKS) + memset(s->data, 0, s->length * sizeof(smpl_t)); +#else + fvec_set_all(s, 0.); +#endif +} + +void fvec_ones(fvec_t *s) { + fvec_set_all (s, 1.); +} + +void fvec_rev(fvec_t *s) { + uint_t j; + for (j=0; j< FLOOR((smpl_t)s->length/2); j++) { + ELEM_SWAP(s->data[j], s->data[s->length-1-j]); + } +} + +void fvec_weight(fvec_t *s, const fvec_t *weight) { + uint_t length = MIN(s->length, weight->length); +#if defined(HAVE_INTEL_IPP) + aubio_ippsMul(s->data, weight->data, s->data, (int)length); +#elif defined(HAVE_ACCELERATE) + aubio_vDSP_vmul( s->data, 1, weight->data, 1, s->data, 1, length ); +#else + uint_t j; + for (j = 0; j < length; j++) { + s->data[j] *= weight->data[j]; + } +#endif /* HAVE_ACCELERATE */ +} + +void fvec_weighted_copy(const fvec_t *in, const fvec_t *weight, fvec_t *out) { + uint_t length = MIN(in->length, MIN(out->length, weight->length)); +#if defined(HAVE_INTEL_IPP) + aubio_ippsMul(in->data, weight->data, out->data, (int)length); +#elif defined(HAVE_ACCELERATE) + aubio_vDSP_vmul(in->data, 1, weight->data, 1, out->data, 1, length); +#else + uint_t j; + for (j = 0; j < length; j++) { + out->data[j] = in->data[j] * weight->data[j]; + } +#endif +} + +void fvec_copy(const fvec_t *s, fvec_t *t) { + if (s->length != t->length) { + AUBIO_ERR("trying to copy %d elements to %d elements \n", + s->length, t->length); + return; + } +#if defined(HAVE_INTEL_IPP) + aubio_ippsCopy(s->data, t->data, (int)s->length); +#elif defined(HAVE_BLAS) + aubio_cblas_copy(s->length, s->data, 1, t->data, 1); +#elif defined(HAVE_ACCELERATE) + aubio_vDSP_mmov(s->data, t->data, 1, s->length, 1, 1); +#elif defined(HAVE_MEMCPY_HACKS) + memcpy(t->data, s->data, t->length * sizeof(smpl_t)); +#else + uint_t j; + for (j = 0; j < t->length; j++) { + t->data[j] = s->data[j]; + } +#endif +} diff --git a/deps/aubio/src/fvec.h b/deps/aubio/src/fvec.h new file mode 100644 index 0000000..bd8c5a6 --- /dev/null +++ b/deps/aubio/src/fvec.h @@ -0,0 +1,178 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_FVEC_H +#define AUBIO_FVEC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + + Vector of real-valued data + + This file specifies the ::fvec_t buffer type, which is used throughout aubio + to store vector of real-valued ::smpl_t. + + \example test-fvec.c + +*/ + +/** Buffer for real data + + Vector of real-valued data + + ::fvec_t is is the structure used to store vector of real-valued data, ::smpl_t . + + \code + + uint_t buffer_size = 1024; + + // create a vector of 512 values + fvec_t * input = new_fvec (buffer_size); + + // set some values of the vector + input->data[23] = 2.; + // .. + + // compute the mean of the vector + mean = fvec_mean(a_vector); + + // destroy the vector + del_fvec(a_vector); + + \endcode + + See `examples/` and `tests/src` directories for more examples. + + */ +typedef struct { + uint_t length; /**< length of buffer */ + smpl_t *data; /**< data vector of length ::fvec_t.length */ +} fvec_t; + +/** fvec_t buffer creation function + + \param length the length of the buffer to create + +*/ +fvec_t * new_fvec(uint_t length); + +/** fvec_t buffer deletion function + + \param s buffer to delete as returned by new_fvec() + +*/ +void del_fvec(fvec_t *s); + +/** read sample value in a buffer + + \param s vector to read from + \param position sample position to read from + +*/ +smpl_t fvec_get_sample(const fvec_t *s, uint_t position); + +/** write sample value in a buffer + + \param s vector to write to + \param data value to write in s->data[position] + \param position sample position to write to + +*/ +void fvec_set_sample(fvec_t *s, smpl_t data, uint_t position); + +/** read data from a buffer + + \param s vector to read from + +*/ +smpl_t * fvec_get_data(const fvec_t *s); + +/** print out fvec data + + \param s vector to print out + +*/ +void fvec_print(const fvec_t *s); + +/** set all elements to a given value + + \param s vector to modify + \param val value to set elements to + +*/ +void fvec_set_all (fvec_t *s, smpl_t val); + +/** set all elements to zero + + \param s vector to modify + +*/ +void fvec_zeros(fvec_t *s); + +/** set all elements to ones + + \param s vector to modify + +*/ +void fvec_ones(fvec_t *s); + +/** revert order of vector elements + + \param s vector to revert + +*/ +void fvec_rev(fvec_t *s); + +/** apply weight to vector + + If the weight vector is longer than s, only the first elements are used. If + the weight vector is shorter than s, the last elements of s are not weighted. + + \param s vector to weight + \param weight weighting coefficients + +*/ +void fvec_weight(fvec_t *s, const fvec_t *weight); + +/** make a copy of a vector + + \param s source vector + \param t vector to copy to + +*/ +void fvec_copy(const fvec_t *s, fvec_t *t); + +/** make a copy of a vector, applying weights to each element + + \param in input vector + \param weight weights vector + \param out output vector + +*/ +void fvec_weighted_copy(const fvec_t *in, const fvec_t *weight, fvec_t *out); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_FVEC_H */ diff --git a/deps/aubio/src/lvec.c b/deps/aubio/src/lvec.c new file mode 100644 index 0000000..dd63bf4 --- /dev/null +++ b/deps/aubio/src/lvec.c @@ -0,0 +1,80 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "lvec.h" + +lvec_t * new_lvec(uint_t length) { + lvec_t * s; + if ((sint_t)length <= 0) { + return NULL; + } + s = AUBIO_NEW(lvec_t); + s->length = length; + s->data = AUBIO_ARRAY(lsmp_t, s->length); + return s; +} + +void del_lvec(lvec_t *s) { + AUBIO_FREE(s->data); + AUBIO_FREE(s); +} + +void lvec_set_sample(lvec_t *s, lsmp_t data, uint_t position) { + s->data[position] = data; +} + +lsmp_t lvec_get_sample(lvec_t *s, uint_t position) { + return s->data[position]; +} + +lsmp_t * lvec_get_data(const lvec_t *s) { + return s->data; +} + +/* helper functions */ + +void lvec_print(const lvec_t *s) { + uint_t j; + for (j=0; j< s->length; j++) { + AUBIO_MSG(AUBIO_LSMP_FMT " ", s->data[j]); + } + AUBIO_MSG("\n"); +} + +void lvec_set_all (lvec_t *s, smpl_t val) { + uint_t j; + for (j=0; j< s->length; j++) { + s->data[j] = val; + } +} + +void lvec_zeros(lvec_t *s) { +#if HAVE_MEMCPY_HACKS + memset(s->data, 0, s->length * sizeof(lsmp_t)); +#else + lvec_set_all (s, 0.); +#endif +} + +void lvec_ones(lvec_t *s) { + lvec_set_all (s, 1.); +} + diff --git a/deps/aubio/src/lvec.h b/deps/aubio/src/lvec.h new file mode 100644 index 0000000..402ba0f --- /dev/null +++ b/deps/aubio/src/lvec.h @@ -0,0 +1,118 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_LVEC_H +#define AUBIO_LVEC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + + Vector of real-valued data in double precision + + This file specifies the ::lvec_t buffer type, which is used in some places in + aubio to store a vector of ::lsmp_t. + + Note: the lvec_t data type is required in some algorithms such as IIR filters + (see temporal/filter.h). + + \example test-lvec.c + +*/ + +/** Buffer for real data in double precision */ +typedef struct { + uint_t length; /**< length of buffer */ + lsmp_t *data; /**< data array of size [length] */ +} lvec_t; + +/** lvec_t buffer creation function + + \param length the length of the buffer to create + +*/ +lvec_t * new_lvec(uint_t length); +/** lvec_t buffer deletion function + + \param s buffer to delete as returned by new_lvec() + +*/ +void del_lvec(lvec_t *s); + +/** read sample value in a buffer + + \param s vector to read from + \param position sample position to read from + +*/ +lsmp_t lvec_get_sample(lvec_t *s, uint_t position); + +/** write sample value in a buffer + + \param s vector to write to + \param data value to write in s->data[position] + \param position sample position to write to + +*/ +void lvec_set_sample(lvec_t *s, lsmp_t data, uint_t position); + +/** read data from a buffer + + \param s vector to read from + +*/ +lsmp_t * lvec_get_data(const lvec_t *s); + +/** print out lvec data + + \param s vector to print out + +*/ +void lvec_print(const lvec_t *s); + +/** set all elements to a given value + + \param s vector to modify + \param val value to set elements to + +*/ +void lvec_set_all(lvec_t *s, smpl_t val); + +/** set all elements to zero + + \param s vector to modify + +*/ +void lvec_zeros(lvec_t *s); + +/** set all elements to ones + + \param s vector to modify + +*/ +void lvec_ones(lvec_t *s); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_LVEC_H */ diff --git a/deps/aubio/src/mathutils.c b/deps/aubio/src/mathutils.c new file mode 100644 index 0000000..35755fe --- /dev/null +++ b/deps/aubio/src/mathutils.c @@ -0,0 +1,681 @@ +/* + Copyright (C) 2003-2014 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/* see in mathutils.h for doc */ + +#include "aubio_priv.h" +#include "fvec.h" +#include "mathutils.h" +#include "musicutils.h" + +/** Window types */ +typedef enum +{ + aubio_win_ones, + aubio_win_rectangle, + aubio_win_hamming, + aubio_win_hanning, + aubio_win_hanningz, + aubio_win_blackman, + aubio_win_blackman_harris, + aubio_win_gaussian, + aubio_win_welch, + aubio_win_parzen, + aubio_win_default = aubio_win_hanningz, +} aubio_window_type; + +fvec_t * +new_aubio_window (char_t * window_type, uint_t length) +{ + fvec_t * win = new_fvec (length); + uint_t err; + if (win == NULL) { + return NULL; + } + err = fvec_set_window (win, window_type); + if (err != 0) { + del_fvec(win); + return NULL; + } + return win; +} + +uint_t fvec_set_window (fvec_t *win, char_t *window_type) { + smpl_t * w = win->data; + uint_t i, size = win->length; + aubio_window_type wintype; + if (window_type == NULL) { + AUBIO_ERR ("window type can not be null.\n"); + return 1; + } else if (strcmp (window_type, "ones") == 0) + wintype = aubio_win_ones; + else if (strcmp (window_type, "rectangle") == 0) + wintype = aubio_win_rectangle; + else if (strcmp (window_type, "hamming") == 0) + wintype = aubio_win_hamming; + else if (strcmp (window_type, "hanning") == 0) + wintype = aubio_win_hanning; + else if (strcmp (window_type, "hanningz") == 0) + wintype = aubio_win_hanningz; + else if (strcmp (window_type, "blackman") == 0) + wintype = aubio_win_blackman; + else if (strcmp (window_type, "blackman_harris") == 0) + wintype = aubio_win_blackman_harris; + else if (strcmp (window_type, "gaussian") == 0) + wintype = aubio_win_gaussian; + else if (strcmp (window_type, "welch") == 0) + wintype = aubio_win_welch; + else if (strcmp (window_type, "parzen") == 0) + wintype = aubio_win_parzen; + else if (strcmp (window_type, "default") == 0) + wintype = aubio_win_default; + else { + AUBIO_ERR ("unknown window type `%s`.\n", window_type); + return 1; + } + switch(wintype) { + case aubio_win_ones: + fvec_ones(win); + break; + case aubio_win_rectangle: + fvec_set_all(win, .5); + break; + case aubio_win_hamming: + for (i=0;idata, (int)s->length, &tmp); + return tmp; +#elif defined(HAVE_ACCELERATE) + aubio_vDSP_meanv(s->data, 1, &tmp, s->length); + return tmp; +#else + uint_t j; + for (j = 0; j < s->length; j++) { + tmp += s->data[j]; + } + return tmp / (smpl_t)(s->length); +#endif +} + +smpl_t +fvec_sum (fvec_t * s) +{ + smpl_t tmp = 0.0; +#if defined(HAVE_INTEL_IPP) + aubio_ippsSum(s->data, (int)s->length, &tmp); +#elif defined(HAVE_ACCELERATE) + aubio_vDSP_sve(s->data, 1, &tmp, s->length); +#else + uint_t j; + for (j = 0; j < s->length; j++) { + tmp += s->data[j]; + } +#endif + return tmp; +} + +smpl_t +fvec_max (fvec_t * s) +{ +#if defined(HAVE_INTEL_IPP) + smpl_t tmp = 0.; + aubio_ippsMax( s->data, (int)s->length, &tmp); +#elif defined(HAVE_ACCELERATE) + smpl_t tmp = 0.; + aubio_vDSP_maxv( s->data, 1, &tmp, s->length ); +#else + uint_t j; + smpl_t tmp = s->data[0]; + for (j = 1; j < s->length; j++) { + tmp = (tmp > s->data[j]) ? tmp : s->data[j]; + } +#endif + return tmp; +} + +smpl_t +fvec_min (fvec_t * s) +{ +#if defined(HAVE_INTEL_IPP) + smpl_t tmp = 0.; + aubio_ippsMin(s->data, (int)s->length, &tmp); +#elif defined(HAVE_ACCELERATE) + smpl_t tmp = 0.; + aubio_vDSP_minv(s->data, 1, &tmp, s->length); +#else + uint_t j; + smpl_t tmp = s->data[0]; + for (j = 1; j < s->length; j++) { + tmp = (tmp < s->data[j]) ? tmp : s->data[j]; + } +#endif + return tmp; +} + +uint_t +fvec_min_elem (fvec_t * s) +{ +#ifndef HAVE_ACCELERATE + uint_t j, pos = 0.; + smpl_t tmp = s->data[0]; + for (j = 0; j < s->length; j++) { + pos = (tmp < s->data[j]) ? pos : j; + tmp = (tmp < s->data[j]) ? tmp : s->data[j]; + } +#else + smpl_t tmp = 0.; + vDSP_Length pos = 0; + aubio_vDSP_minvi(s->data, 1, &tmp, &pos, s->length); +#endif + return (uint_t)pos; +} + +uint_t +fvec_max_elem (fvec_t * s) +{ +#ifndef HAVE_ACCELERATE + uint_t j, pos = 0; + smpl_t tmp = 0.0; + for (j = 0; j < s->length; j++) { + pos = (tmp > s->data[j]) ? pos : j; + tmp = (tmp > s->data[j]) ? tmp : s->data[j]; + } +#else + smpl_t tmp = 0.; + vDSP_Length pos = 0; + aubio_vDSP_maxvi(s->data, 1, &tmp, &pos, s->length); +#endif + return (uint_t)pos; +} + +void +fvec_shift (fvec_t * s) +{ + uint_t half = s->length / 2, start = half, j; + // if length is odd, middle element is moved to the end + if (2 * half < s->length) start ++; +#ifndef HAVE_BLAS + for (j = 0; j < half; j++) { + ELEM_SWAP (s->data[j], s->data[j + start]); + } +#else + aubio_cblas_swap(half, s->data, 1, s->data + start, 1); +#endif + if (start != half) { + for (j = 0; j < half; j++) { + ELEM_SWAP (s->data[j + start - 1], s->data[j + start]); + } + } +} + +void +fvec_ishift (fvec_t * s) +{ + uint_t half = s->length / 2, start = half, j; + // if length is odd, middle element is moved to the beginning + if (2 * half < s->length) start ++; +#ifndef HAVE_BLAS + for (j = 0; j < half; j++) { + ELEM_SWAP (s->data[j], s->data[j + start]); + } +#else + aubio_cblas_swap(half, s->data, 1, s->data + start, 1); +#endif + if (start != half) { + for (j = 0; j < half; j++) { + ELEM_SWAP (s->data[half], s->data[j]); + } + } +} + +void fvec_push(fvec_t *in, smpl_t new_elem) { + uint_t i; + for (i = 0; i < in->length - 1; i++) { + in->data[i] = in->data[i + 1]; + } + in->data[in->length - 1] = new_elem; +} + +void fvec_clamp(fvec_t *in, smpl_t absmax) { + uint_t i; + for (i = 0; i < in->length; i++) { + if (in->data[i] > 0 && in->data[i] > ABS(absmax)) { + in->data[i] = absmax; + } else if (in->data[i] < 0 && in->data[i] < -ABS(absmax)) { + in->data[i] = -absmax; + } + } +} + +smpl_t +aubio_level_lin (const fvec_t * f) +{ + smpl_t energy = 0.; +#ifndef HAVE_BLAS + uint_t j; + for (j = 0; j < f->length; j++) { + energy += SQR (f->data[j]); + } +#else + energy = aubio_cblas_dot(f->length, f->data, 1, f->data, 1); +#endif + return energy / f->length; +} + +smpl_t +fvec_local_hfc (fvec_t * v) +{ + smpl_t hfc = 0.; + uint_t j; + for (j = 0; j < v->length; j++) { + hfc += (j + 1) * v->data[j]; + } + return hfc; +} + +void +fvec_min_removal (fvec_t * v) +{ + smpl_t v_min = fvec_min (v); + fvec_add (v, - v_min ); +} + +smpl_t +fvec_alpha_norm (fvec_t * o, smpl_t alpha) +{ + uint_t j; + smpl_t tmp = 0.; + for (j = 0; j < o->length; j++) { + tmp += POW (ABS (o->data[j]), alpha); + } + return POW (tmp / o->length, 1. / alpha); +} + +void +fvec_alpha_normalise (fvec_t * o, smpl_t alpha) +{ + uint_t j; + smpl_t norm = fvec_alpha_norm (o, alpha); + for (j = 0; j < o->length; j++) { + o->data[j] /= norm; + } +} + +void +fvec_add (fvec_t * o, smpl_t val) +{ + uint_t j; + for (j = 0; j < o->length; j++) { + o->data[j] += val; + } +} + +void +fvec_mul (fvec_t *o, smpl_t val) +{ + uint_t j; + for (j = 0; j < o->length; j++) { + o->data[j] *= val; + } +} + +void fvec_adapt_thres(fvec_t * vec, fvec_t * tmp, + uint_t post, uint_t pre) { + uint_t length = vec->length, j; + for (j=0;jdata[j] -= fvec_moving_thres(vec, tmp, post, pre, j); + } +} + +smpl_t +fvec_moving_thres (fvec_t * vec, fvec_t * tmpvec, + uint_t post, uint_t pre, uint_t pos) +{ + uint_t k; + smpl_t *medar = (smpl_t *) tmpvec->data; + uint_t win_length = post + pre + 1; + uint_t length = vec->length; + /* post part of the buffer does not exist */ + if (pos < post + 1) { + for (k = 0; k < post + 1 - pos; k++) + medar[k] = 0.; /* 0-padding at the beginning */ + for (k = post + 1 - pos; k < win_length; k++) + medar[k] = vec->data[k + pos - post]; + /* the buffer is fully defined */ + } else if (pos + pre < length) { + for (k = 0; k < win_length; k++) + medar[k] = vec->data[k + pos - post]; + /* pre part of the buffer does not exist */ + } else { + for (k = 0; k < length - pos + post; k++) + medar[k] = vec->data[k + pos - post]; + for (k = length - pos + post; k < win_length; k++) + medar[k] = 0.; /* 0-padding at the end */ + } + return fvec_median (tmpvec); +} + +smpl_t fvec_median (fvec_t * input) { + uint_t n = input->length; + smpl_t * arr = (smpl_t *) input->data; + uint_t low, high ; + uint_t median; + uint_t middle, ll, hh; + + low = 0 ; high = n-1 ; median = (low + high) / 2; + for (;;) { + if (high <= low) /* One element only */ + return arr[median] ; + + if (high == low + 1) { /* Two elements only */ + if (arr[low] > arr[high]) + ELEM_SWAP(arr[low], arr[high]) ; + return arr[median] ; + } + + /* Find median of low, middle and high items; swap into position low */ + middle = (low + high) / 2; + if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]); + if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); + if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; + + /* Swap low item (now in position middle) into position (low+1) */ + ELEM_SWAP(arr[middle], arr[low+1]) ; + + /* Nibble from each end towards middle, swapping items when stuck */ + ll = low + 1; + hh = high; + for (;;) { + do ll++; while (arr[low] > arr[ll]) ; + do hh--; while (arr[hh] > arr[low]) ; + + if (hh < ll) + break; + + ELEM_SWAP(arr[ll], arr[hh]) ; + } + + /* Swap middle item (in position low) back into correct position */ + ELEM_SWAP(arr[low], arr[hh]) ; + + /* Re-set active partition */ + if (hh <= median) + low = ll; + if (hh >= median) + high = hh - 1; + } +} + +smpl_t fvec_quadratic_peak_pos (const fvec_t * x, uint_t pos) { + smpl_t s0, s1, s2; uint_t x0, x2; + smpl_t half = .5, two = 2.; + if (pos == 0 || pos == x->length - 1) return pos; + x0 = (pos < 1) ? pos : pos - 1; + x2 = (pos + 1 < x->length) ? pos + 1 : pos; + if (x0 == pos) return (x->data[pos] <= x->data[x2]) ? pos : x2; + if (x2 == pos) return (x->data[pos] <= x->data[x0]) ? pos : x0; + s0 = x->data[x0]; + s1 = x->data[pos]; + s2 = x->data[x2]; + return pos + half * (s0 - s2 ) / (s0 - two * s1 + s2); +} + +smpl_t fvec_quadratic_peak_mag (fvec_t *x, smpl_t pos) { + smpl_t x0, x1, x2; + uint_t index = (uint_t)(pos - .5) + 1; + if (pos >= x->length || pos < 0.) return 0.; + if ((smpl_t)index == pos) return x->data[index]; + x0 = x->data[index - 1]; + x1 = x->data[index]; + x2 = x->data[index + 1]; + return x1 - .25 * (x0 - x2) * (pos - index); +} + +uint_t fvec_peakpick(const fvec_t * onset, uint_t pos) { + uint_t tmp=0; + tmp = (onset->data[pos] > onset->data[pos-1] + && onset->data[pos] > onset->data[pos+1] + && onset->data[pos] > 0.); + return tmp; +} + +smpl_t +aubio_quadfrac (smpl_t s0, smpl_t s1, smpl_t s2, smpl_t pf) +{ + smpl_t tmp = + s0 + (pf / 2.) * (pf * (s0 - 2. * s1 + s2) - 3. * s0 + 4. * s1 - s2); + return tmp; +} + +smpl_t +aubio_freqtomidi (smpl_t freq) +{ + smpl_t midi; + if (freq < 2. || freq > 100000.) return 0.; // avoid nans and infs + /* log(freq/A-2)/log(2) */ + midi = freq / 6.875; + midi = LOG (midi) / 0.6931471805599453; + midi *= 12; + midi -= 3; + return midi; +} + +smpl_t +aubio_miditofreq (smpl_t midi) +{ + smpl_t freq; + if (midi > 140.) return 0.; // avoid infs + freq = (midi + 3.) / 12.; + freq = EXP (freq * 0.6931471805599453); + freq *= 6.875; + return freq; +} + +smpl_t +aubio_bintofreq (smpl_t bin, smpl_t samplerate, smpl_t fftsize) +{ + smpl_t freq = samplerate / fftsize; + return freq * MAX(bin, 0); +} + +smpl_t +aubio_bintomidi (smpl_t bin, smpl_t samplerate, smpl_t fftsize) +{ + smpl_t midi = aubio_bintofreq (bin, samplerate, fftsize); + return aubio_freqtomidi (midi); +} + +smpl_t +aubio_freqtobin (smpl_t freq, smpl_t samplerate, smpl_t fftsize) +{ + smpl_t bin = fftsize / samplerate; + return MAX(freq, 0) * bin; +} + +smpl_t +aubio_miditobin (smpl_t midi, smpl_t samplerate, smpl_t fftsize) +{ + smpl_t freq = aubio_miditofreq (midi); + return aubio_freqtobin (freq, samplerate, fftsize); +} + +uint_t +aubio_is_power_of_two (uint_t a) +{ + if ((a & (a - 1)) == 0) { + return 1; + } else { + return 0; + } +} + +uint_t +aubio_next_power_of_two (uint_t a) +{ + uint_t i = 1; + while (i < a) i <<= 1; + return i; +} + +uint_t +aubio_power_of_two_order (uint_t a) +{ + int order = 0; + int temp = aubio_next_power_of_two(a); + while (temp >>= 1) { + ++order; + } + return order; +} + +smpl_t +aubio_db_spl (const fvec_t * o) +{ + return 10. * LOG10 (aubio_level_lin (o)); +} + +uint_t +aubio_silence_detection (const fvec_t * o, smpl_t threshold) +{ + return (aubio_db_spl (o) < threshold); +} + +smpl_t +aubio_level_detection (const fvec_t * o, smpl_t threshold) +{ + smpl_t db_spl = aubio_db_spl (o); + if (db_spl < threshold) { + return 1.; + } else { + return db_spl; + } +} + +smpl_t +aubio_zero_crossing_rate (fvec_t * input) +{ + uint_t j; + uint_t zcr = 0; + for (j = 1; j < input->length; j++) { + // previous was strictly negative + if (input->data[j - 1] < 0.) { + // current is positive or null + if (input->data[j] >= 0.) { + zcr += 1; + } + // previous was positive or null + } else { + // current is strictly negative + if (input->data[j] < 0.) { + zcr += 1; + } + } + } + return zcr / (smpl_t) input->length; +} + +void +aubio_autocorr (const fvec_t * input, fvec_t * output) +{ + uint_t i, j, length = input->length; + smpl_t *data, *acf; + smpl_t tmp = 0; + data = input->data; + acf = output->data; + for (i = 0; i < length; i++) { + tmp = 0.; + for (j = i; j < length; j++) { + tmp += data[j - i] * data[j]; + } + acf[i] = tmp / (smpl_t) (length - i); + } +} + +void +aubio_cleanup (void) +{ +#ifdef HAVE_FFTW3F + fftwf_cleanup (); +#else +#ifdef HAVE_FFTW3 + fftw_cleanup (); +#endif +#endif +} diff --git a/deps/aubio/src/mathutils.h b/deps/aubio/src/mathutils.h new file mode 100644 index 0000000..4336d7e --- /dev/null +++ b/deps/aubio/src/mathutils.h @@ -0,0 +1,338 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Various math functions + + \example test-mathutils.c + \example test-mathutils-window.c + + */ + +#ifndef AUBIO_MATHUTILS_H +#define AUBIO_MATHUTILS_H + +#include "fvec.h" +#include "musicutils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** compute the mean of a vector + + \param s vector to compute mean from + \return the mean of `v` + +*/ +smpl_t fvec_mean (fvec_t * s); + +/** find the max of a vector + + \param s vector to get the max from + + \return the value of the minimum of v + +*/ +smpl_t fvec_max (fvec_t * s); + +/** find the min of a vector + + \param s vector to get the min from + + \return the value of the maximum of v + +*/ +smpl_t fvec_min (fvec_t * s); + +/** find the index of the min of a vector + + \param s vector to get the index from + + \return the index of the minimum element of v + +*/ +uint_t fvec_min_elem (fvec_t * s); + +/** find the index of the max of a vector + + \param s vector to get the index from + + \return the index of the maximum element of v + +*/ +uint_t fvec_max_elem (fvec_t * s); + +/** swap the left and right halves of a vector + + This function swaps the left part of the signal with the right part of the +signal. Therefore + + \f$ a[0], a[1], ..., a[\frac{N}{2}], a[\frac{N}{2}+1], ..., a[N-1], a[N] \f$ + + becomes + + \f$ a[\frac{N}{2}+1], ..., a[N-1], a[N], a[0], a[1], ..., a[\frac{N}{2}] \f$ + + This operation, known as 'fftshift' in the Matlab Signal Processing Toolbox, +can be used before computing the FFT to simplify the phase relationship of the +resulting spectrum. See Amalia de Götzen's paper referred to above. + +*/ +void fvec_shift (fvec_t * v); + +/** swap the left and right halves of a vector + + This function swaps the left part of the signal with the right part of the +signal. Therefore + + \f$ a[0], a[1], ..., a[\frac{N}{2}], a[\frac{N}{2}+1], ..., a[N-1], a[N] \f$ + + becomes + + \f$ a[\frac{N}{2}+1], ..., a[N-1], a[N], a[0], a[1], ..., a[\frac{N}{2}] \f$ + + This operation, known as 'ifftshift' in the Matlab Signal Processing Toolbox, +can be used after computing the inverse FFT to simplify the phase relationship +of the resulting spectrum. See Amalia de Götzen's paper referred to above. + +*/ +void fvec_ishift (fvec_t * v); + +/** push a new element to the end of a vector, erasing the first element and + * sliding all others + + \param in vector to push to + \param new_elem new_element to add at the end of the vector + + In numpy words, this is equivalent to: in = np.concatenate([in, [new_elem]])[1:] + +*/ +void fvec_push(fvec_t *in, smpl_t new_elem); + +/** compute the sum of all elements of a vector + + \param v vector to compute the sum of + + \return the sum of v + +*/ +smpl_t fvec_sum (fvec_t * v); + +/** compute the High Frequency Content of a vector + + The High Frequency Content is defined as \f$ \sum_0^{N-1} (k+1) v[k] \f$. + + \param v vector to get the energy from + + \return the HFC of v + +*/ +smpl_t fvec_local_hfc (fvec_t * v); + +/** computes the p-norm of a vector + + Computes the p-norm of a vector for \f$ p = \alpha \f$ + + \f$ L^p = ||x||_p = (|x_1|^p + |x_2|^p + ... + |x_n|^p ) ^ \frac{1}{p} \f$ + + If p = 1, the result is the Manhattan distance. + + If p = 2, the result is the Euclidean distance. + + As p tends towards large values, \f$ L^p \f$ tends towards the maximum of the +input vector. + + References: + + - \f$L^p\f$ space on + Wikipedia + + \param v vector to compute norm from + \param p order of the computed norm + + \return the p-norm of v + +*/ +smpl_t fvec_alpha_norm (fvec_t * v, smpl_t p); + +/** alpha normalisation + + This function divides all elements of a vector by the p-norm as computed by +fvec_alpha_norm(). + + \param v vector to compute norm from + \param p order of the computed norm + +*/ +void fvec_alpha_normalise (fvec_t * v, smpl_t p); + +/** add a constant to each elements of a vector + + \param v vector to add constant to + \param c constant to add to v + +*/ +void fvec_add (fvec_t * v, smpl_t c); + +/** multiply each elements of a vector by a scalar + + \param v vector to add constant to + \param s constant to scale v with + +*/ +void fvec_mul (fvec_t * v, smpl_t s); + +/** remove the minimum value of the vector to each elements + + \param v vector to remove minimum from + +*/ +void fvec_min_removal (fvec_t * v); + +/** compute moving median threshold of a vector + + This function computes the moving median threshold value of at the given +position of a vector, taking the median among post elements before and up to +pre elements after pos. + + \param v input vector + \param tmp temporary vector of length post+1+pre + \param post length of causal part to take before pos + \param pre length of anti-causal part to take after pos + \param pos index to compute threshold for + + \return moving median threshold value + +*/ +smpl_t fvec_moving_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre, + uint_t pos); + +/** apply adaptive threshold to a vector + + For each points at position p of an input vector, this function remove the +moving median threshold computed at p. + + \param v input vector + \param tmp temporary vector of length post+1+pre + \param post length of causal part to take before pos + \param pre length of anti-causal part to take after pos + +*/ +void fvec_adapt_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre); + +/** returns the median of a vector + + The QuickSelect routine is based on the algorithm described in "Numerical +recipes in C", Second Edition, Cambridge University Press, 1992, Section 8.5, +ISBN 0-521-43108-5 + + This implementation of the QuickSelect routine is based on Nicolas +Devillard's implementation, available at http://ndevilla.free.fr/median/median/ +and in the Public Domain. + + \param v vector to get median from + + \return the median of v + +*/ +smpl_t fvec_median (fvec_t * v); + +/** finds exact peak index by quadratic interpolation + + See [Quadratic Interpolation of Spectral + Peaks](https://ccrma.stanford.edu/~jos/sasp/Quadratic_Peak_Interpolation.html), + by Julius O. Smith III + + \f$ p_{frac} = \frac{1}{2} \frac {x[p-1] - x[p+1]} {x[p-1] - 2 x[p] + x[p+1]} \in [ -.5, .5] \f$ + + \param x vector to get the interpolated peak position from + \param p index of the peak in vector `x` + \return \f$ p + p_{frac} \f$ exact peak position of interpolated maximum or minimum + +*/ +smpl_t fvec_quadratic_peak_pos (const fvec_t * x, uint_t p); + +/** finds magnitude of peak by quadratic interpolation + + See [Quadratic Interpolation of Spectral + Peaks](https://ccrma.stanford.edu/~jos/sasp/Quadratic_Peak_Interpolation.html), + by Julius O. Smith III + + \param x vector to get the magnitude of the interpolated peak position from + \param p index of the peak in vector `x` + \return magnitude of interpolated peak + +*/ +smpl_t fvec_quadratic_peak_mag (fvec_t * x, smpl_t p); + +/** Quadratic interpolation using Lagrange polynomial. + + Inspired from ``Comparison of interpolation algorithms in real-time sound +processing'', Vladimir Arnost, + + \param s0,s1,s2 are 3 consecutive samples of a curve + \param pf is the floating point index [0;2] + + \return \f$ s0 + (pf/2.)*((pf-3.)*s0-2.*(pf-2.)*s1+(pf-1.)*s2); \f$ + +*/ +smpl_t aubio_quadfrac (smpl_t s0, smpl_t s1, smpl_t s2, smpl_t pf); + +/** return 1 if v[p] is a peak and positive, 0 otherwise + + This function returns 1 if a peak is found at index p in the vector v. The +peak is defined as follows: + + - v[p] is positive + - v[p-1] < v[p] + - v[p] > v[p+1] + + \param v input vector + \param p position of supposed for peak + + \return 1 if a peak is found, 0 otherwise + +*/ +uint_t fvec_peakpick (const fvec_t * v, uint_t p); + +/** return 1 if a is a power of 2, 0 otherwise */ +uint_t aubio_is_power_of_two(uint_t a); + +/** return the next power of power of 2 greater than a */ +uint_t aubio_next_power_of_two(uint_t a); + +/** return the log2 factor of the given power of 2 value a */ +uint_t aubio_power_of_two_order(uint_t a); + +/** compute normalised autocorrelation function + + \param input vector to compute autocorrelation from + \param output vector to store autocorrelation function to + +*/ +void aubio_autocorr (const fvec_t * input, fvec_t * output); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_MATHUTILS_H */ diff --git a/deps/aubio/src/musicutils.h b/deps/aubio/src/musicutils.h new file mode 100644 index 0000000..af222e5 --- /dev/null +++ b/deps/aubio/src/musicutils.h @@ -0,0 +1,270 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** @file + * various functions useful in audio signal processing + */ + +#ifndef AUBIO_MUSICUTILS_H +#define AUBIO_MUSICUTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** create window + + \param window_type type of the window to create + \param size length of the window to create (see fvec_set_window()) + +*/ +fvec_t *new_aubio_window (char_t * window_type, uint_t size); + +/** set elements of a vector to window coefficients + + \param window exsting ::fvec_t to use + \param window_type type of the window to create + + List of available window types: "rectangle", "hamming", "hanning", + "hanningz", "blackman", "blackman_harris", "gaussian", "welch", "parzen", + "default". + + "default" is equivalent to "hanningz". + + References: + + - Window +function on Wikipedia + - Amalia de Götzen, Nicolas Bernardini, and Daniel Arfib. Traditional (?) +implementations of a phase vocoder: the tricks of the trade. In Proceedings of +the International Conference on Digital Audio Effects (DAFx-00), pages 37–44, +Uni- versity of Verona, Italy, 2000. + ( + pdf) + + */ +uint_t fvec_set_window (fvec_t * window, char_t * window_type); + +/** compute the principal argument + + This function maps the input phase to its corresponding value wrapped in the +range \f$ [-\pi, \pi] \f$. + + \param phase unwrapped phase to map to the unit circle + + \return equivalent phase wrapped to the unit circle + +*/ +smpl_t aubio_unwrap2pi (smpl_t phase); + +/** convert frequency bin to midi value */ +smpl_t aubio_bintomidi (smpl_t bin, smpl_t samplerate, smpl_t fftsize); + +/** convert midi value to frequency bin */ +smpl_t aubio_miditobin (smpl_t midi, smpl_t samplerate, smpl_t fftsize); + +/** convert frequency bin to frequency (Hz) */ +smpl_t aubio_bintofreq (smpl_t bin, smpl_t samplerate, smpl_t fftsize); + +/** convert frequency (Hz) to frequency bin */ +smpl_t aubio_freqtobin (smpl_t freq, smpl_t samplerate, smpl_t fftsize); + +/** convert frequency (Hz) to mel + + \param freq input frequency, in Hz + + \return output mel + + Converts a scalar from the frequency domain to the mel scale using Slaney + Auditory Toolbox's implementation: + + If \f$ f < 1000 \f$, \f$ m = 3 f / 200 \f$. + + If \f$ f >= 1000 \f$, \f$ m = 1000 + 27 \frac{{ln}(f) - ln(1000))} + {{ln}(6400) - ln(1000)} + \f$ + + See also + -------- + + aubio_meltohz(), aubio_hztomel_htk(). + +*/ +smpl_t aubio_hztomel (smpl_t freq); + +/** convert mel to frequency (Hz) + + \param mel input mel + + \return output frequency, in Hz + + Converts a scalar from the mel scale to the frequency domain using Slaney + Auditory Toolbox's implementation: + + If \f$ f < 1000 \f$, \f$ f = 200 m/3 \f$. + + If \f$ f \geq 1000 \f$, \f$ f = 1000 + \left(\frac{6400}{1000}\right) + ^{\frac{m - 1000}{27}} \f$ + + See also + -------- + + aubio_hztomel(), aubio_meltohz_htk(). + + References + ---------- + + Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010* + https://engineering.purdue.edu/~malcolm/interval/1998-010/ + +*/ +smpl_t aubio_meltohz (smpl_t mel); + +/** convert frequency (Hz) to mel + + \param freq input frequency, in Hz + + \return output mel + + Converts a scalar from the frequency domain to the mel scale, using the + equation defined by O'Shaughnessy, as implemented in the HTK speech + recognition toolkit: + + \f$ m = 1127 + ln(1 + \frac{f}{700}) \f$ + + See also + -------- + + aubio_meltohz_htk(), aubio_hztomel(). + + References + ---------- + + Douglas O'Shaughnessy (1987). *Speech communication: human and machine*. + Addison-Wesley. p. 150. ISBN 978-0-201-16520-3. + + HTK Speech Recognition Toolkit: http://htk.eng.cam.ac.uk/ + + */ +smpl_t aubio_hztomel_htk (smpl_t freq); + +/** convert mel to frequency (Hz) + + \param mel input mel + + \return output frequency, in Hz + + Converts a scalar from the mel scale to the frequency domain, using the + equation defined by O'Shaughnessy, as implemented in the HTK speech + recognition toolkit: + + \f$ f = 700 * {e}^\left(\frac{f}{1127} - 1\right) \f$ + + See also + -------- + + aubio_hztomel_htk(), aubio_meltohz(). + +*/ +smpl_t aubio_meltohz_htk (smpl_t mel); + +/** convert frequency (Hz) to midi value (0-128) */ +smpl_t aubio_freqtomidi (smpl_t freq); + +/** convert midi value (0-128) to frequency (Hz) */ +smpl_t aubio_miditofreq (smpl_t midi); + +/** clean up cached memory at the end of program + + This function should be used at the end of programs to purge all cached + memory. So far it is only useful to clean FFTW's cache. + +*/ +void aubio_cleanup (void); + +/** zero-crossing rate (ZCR) + + The zero-crossing rate is the number of times a signal changes sign, + divided by the length of this signal. + + \param v vector to compute ZCR from + + \return zero-crossing rate of v + +*/ +smpl_t aubio_zero_crossing_rate (fvec_t * v); + +/** compute sound level on a linear scale + + This gives the average of the square amplitudes. + + \param v vector to compute level from + + \return level of v + +*/ +smpl_t aubio_level_lin (const fvec_t * v); + +/** compute sound pressure level (SPL) in dB + + This quantity is often wrongly called 'loudness'. + + This gives ten times the log10 of the average of the square amplitudes. + + \param v vector to compute dB SPL from + + \return level of v in dB SPL + +*/ +smpl_t aubio_db_spl (const fvec_t * v); + +/** check if buffer level in dB SPL is under a given threshold + + \param v vector to get level from + \param threshold threshold in dB SPL + + \return 1 if level is under the given threshold, 0 otherwise + +*/ +uint_t aubio_silence_detection (const fvec_t * v, smpl_t threshold); + +/** get buffer level if level >= threshold, 1. otherwise + + \param v vector to get level from + \param threshold threshold in dB SPL + + \return level in dB SPL if level >= threshold, 1. otherwise + +*/ +smpl_t aubio_level_detection (const fvec_t * v, smpl_t threshold); + +/** clamp the values of a vector within the range [-abs(max), abs(max)] + + \param in vector to clamp + \param absmax maximum value over which input vector elements should be clamped + +*/ +void fvec_clamp(fvec_t *in, smpl_t absmax); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_MUSICUTILS_H */ diff --git a/deps/aubio/src/pitch/pitch.c b/deps/aubio/src/pitch/pitch.c new file mode 100644 index 0000000..40cd7fc --- /dev/null +++ b/deps/aubio/src/pitch/pitch.c @@ -0,0 +1,530 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "lvec.h" +#include "mathutils.h" +#include "musicutils.h" +#include "spectral/phasevoc.h" +#include "temporal/filter.h" +#include "temporal/c_weighting.h" +#include "pitch/pitchmcomb.h" +#include "pitch/pitchyin.h" +#include "pitch/pitchfcomb.h" +#include "pitch/pitchschmitt.h" +#include "pitch/pitchyinfft.h" +#include "pitch/pitchyinfast.h" +#include "pitch/pitchspecacf.h" +#include "pitch/pitch.h" + +#define DEFAULT_PITCH_SILENCE -50. + +/** pitch detection algorithms */ +typedef enum +{ + aubio_pitcht_yin, /**< `yin`, YIN algorithm */ + aubio_pitcht_mcomb, /**< `mcomb`, Multi-comb filter */ + aubio_pitcht_schmitt, /**< `schmitt`, Schmitt trigger */ + aubio_pitcht_fcomb, /**< `fcomb`, Fast comb filter */ + aubio_pitcht_yinfft, /**< `yinfft`, Spectral YIN */ + aubio_pitcht_yinfast, /**< `yinfast`, YIN fast */ + aubio_pitcht_specacf, /**< `specacf`, Spectral autocorrelation */ + aubio_pitcht_default + = aubio_pitcht_yinfft, /**< `default` */ +} aubio_pitch_type; + +/** pitch detection output modes */ +typedef enum +{ + aubio_pitchm_freq, /**< Frequency (Hz) */ + aubio_pitchm_midi, /**< MIDI note (0.,127) */ + aubio_pitchm_cent, /**< Cent */ + aubio_pitchm_bin, /**< Frequency bin (0,bufsize) */ + aubio_pitchm_default = aubio_pitchm_freq, /**< the one used when "default" is asked */ +} aubio_pitch_mode; + +/** callback to get pitch candidate, defined below */ +typedef void (*aubio_pitch_detect_t) (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); + +/** callback to convert pitch from one unit to another, defined below */ +typedef smpl_t(*aubio_pitch_convert_t) (smpl_t value, uint_t samplerate, uint_t bufsize); + +/** callback to fetch the confidence of the algorithm */ +typedef smpl_t (*aubio_pitch_get_conf_t) (void * p); + +/** generic pitch detection structure */ +struct _aubio_pitch_t +{ + aubio_pitch_type type; /**< pitch detection mode */ + aubio_pitch_mode mode; /**< pitch detection output mode */ + uint_t samplerate; /**< samplerate */ + uint_t bufsize; /**< buffer size */ + void *p_object; /**< pointer to pitch object */ + aubio_filter_t *filter; /**< filter */ + fvec_t *filtered; /**< filtered input */ + aubio_pvoc_t *pv; /**< phase vocoder for mcomb */ + cvec_t *fftgrain; /**< spectral frame for mcomb */ + fvec_t *buf; /**< temporary buffer for yin */ + aubio_pitch_detect_t detect_cb; /**< callback to get the pitch candidates */ + aubio_pitch_convert_t conv_cb; /**< callback to convert it to the desired unit */ + aubio_pitch_get_conf_t conf_cb; /**< pointer to the current confidence callback */ + smpl_t silence; /**< silence threshold */ +}; + +/* callback functions for pitch detection */ +static void aubio_pitch_do_mcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); +static void aubio_pitch_do_yin (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); +static void aubio_pitch_do_schmitt (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); +static void aubio_pitch_do_fcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); +static void aubio_pitch_do_yinfft (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); +static void aubio_pitch_do_yinfast (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); +static void aubio_pitch_do_specacf (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf); + +/* internal functions for frequency conversion */ +static smpl_t freqconvbin (smpl_t f, uint_t samplerate, uint_t bufsize); +static smpl_t freqconvmidi (smpl_t f, uint_t samplerate, uint_t bufsize); +static smpl_t freqconvpass (smpl_t f, uint_t samplerate, uint_t bufsize); + +/* adapter to stack ibuf new samples at the end of buf, and trim `buf` to `bufsize` */ +void aubio_pitch_slideblock (aubio_pitch_t * p, const fvec_t * ibuf); + + +aubio_pitch_t * +new_aubio_pitch (const char_t * pitch_mode, + uint_t bufsize, uint_t hopsize, uint_t samplerate) +{ + aubio_pitch_t *p = AUBIO_NEW (aubio_pitch_t); + aubio_pitch_type pitch_type; + if (pitch_mode == NULL) { + AUBIO_ERR ("pitch: can not use ‘NULL‘ for pitch detection method\n"); + goto beach; + } + if (strcmp (pitch_mode, "mcomb") == 0) + pitch_type = aubio_pitcht_mcomb; + else if (strcmp (pitch_mode, "yinfast") == 0) + pitch_type = aubio_pitcht_yinfast; + else if (strcmp (pitch_mode, "yinfft") == 0) + pitch_type = aubio_pitcht_yinfft; + else if (strcmp (pitch_mode, "yin") == 0) + pitch_type = aubio_pitcht_yin; + else if (strcmp (pitch_mode, "schmitt") == 0) + pitch_type = aubio_pitcht_schmitt; + else if (strcmp (pitch_mode, "fcomb") == 0) + pitch_type = aubio_pitcht_fcomb; + else if (strcmp (pitch_mode, "specacf") == 0) + pitch_type = aubio_pitcht_specacf; + else if (strcmp (pitch_mode, "default") == 0) + pitch_type = aubio_pitcht_default; + else { + AUBIO_ERR ("pitch: unknown pitch detection method ‘%s’\n", pitch_mode); + goto beach; + } + + // check parameters are valid + if ((sint_t)hopsize < 1) { + AUBIO_ERR("pitch: got hopsize %d, but can not be < 1\n", hopsize); + goto beach; + } else if ((sint_t)bufsize < 1) { + AUBIO_ERR("pitch: got buffer_size %d, but can not be < 1\n", bufsize); + goto beach; + } else if (bufsize < hopsize) { + AUBIO_ERR("pitch: hop size (%d) is larger than win size (%d)\n", hopsize, bufsize); + goto beach; + } else if ((sint_t)samplerate < 1) { + AUBIO_ERR("pitch: samplerate (%d) can not be < 1\n", samplerate); + goto beach; + } + + p->samplerate = samplerate; + p->type = pitch_type; + aubio_pitch_set_unit (p, "default"); + p->bufsize = bufsize; + p->silence = DEFAULT_PITCH_SILENCE; + p->conf_cb = NULL; + switch (p->type) { + case aubio_pitcht_yin: + p->buf = new_fvec (bufsize); + p->p_object = new_aubio_pitchyin (bufsize); + if (!p->p_object) goto beach; + p->detect_cb = aubio_pitch_do_yin; + p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyin_get_confidence; + aubio_pitchyin_set_tolerance (p->p_object, 0.15); + break; + case aubio_pitcht_mcomb: + p->filtered = new_fvec (hopsize); + p->pv = new_aubio_pvoc (bufsize, hopsize); + if (!p->pv) goto beach; + p->fftgrain = new_cvec (bufsize); + p->p_object = new_aubio_pitchmcomb (bufsize, hopsize); + p->filter = new_aubio_filter_c_weighting (samplerate); + p->detect_cb = aubio_pitch_do_mcomb; + break; + case aubio_pitcht_fcomb: + p->buf = new_fvec (bufsize); + p->p_object = new_aubio_pitchfcomb (bufsize, hopsize); + if (!p->p_object) goto beach; + p->detect_cb = aubio_pitch_do_fcomb; + break; + case aubio_pitcht_schmitt: + p->buf = new_fvec (bufsize); + p->p_object = new_aubio_pitchschmitt (bufsize); + p->detect_cb = aubio_pitch_do_schmitt; + break; + case aubio_pitcht_yinfft: + p->buf = new_fvec (bufsize); + p->p_object = new_aubio_pitchyinfft (samplerate, bufsize); + if (!p->p_object) goto beach; + p->detect_cb = aubio_pitch_do_yinfft; + p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyinfft_get_confidence; + aubio_pitchyinfft_set_tolerance (p->p_object, 0.85); + break; + case aubio_pitcht_yinfast: + p->buf = new_fvec (bufsize); + p->p_object = new_aubio_pitchyinfast (bufsize); + if (!p->p_object) goto beach; + p->detect_cb = aubio_pitch_do_yinfast; + p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchyinfast_get_confidence; + aubio_pitchyinfast_set_tolerance (p->p_object, 0.15); + break; + case aubio_pitcht_specacf: + p->buf = new_fvec (bufsize); + p->p_object = new_aubio_pitchspecacf (bufsize); + if (!p->p_object) goto beach; + p->detect_cb = aubio_pitch_do_specacf; + p->conf_cb = (aubio_pitch_get_conf_t)aubio_pitchspecacf_get_tolerance; + aubio_pitchspecacf_set_tolerance (p->p_object, 0.85); + break; + default: + break; + } + return p; + +beach: + if (p->filtered) del_fvec(p->filtered); + if (p->buf) del_fvec(p->buf); + AUBIO_FREE(p); + return NULL; +} + +void +del_aubio_pitch (aubio_pitch_t * p) +{ + switch (p->type) { + case aubio_pitcht_yin: + del_fvec (p->buf); + del_aubio_pitchyin (p->p_object); + break; + case aubio_pitcht_mcomb: + del_fvec (p->filtered); + del_aubio_pvoc (p->pv); + del_cvec (p->fftgrain); + del_aubio_filter (p->filter); + del_aubio_pitchmcomb (p->p_object); + break; + case aubio_pitcht_schmitt: + del_fvec (p->buf); + del_aubio_pitchschmitt (p->p_object); + break; + case aubio_pitcht_fcomb: + del_fvec (p->buf); + del_aubio_pitchfcomb (p->p_object); + break; + case aubio_pitcht_yinfft: + del_fvec (p->buf); + del_aubio_pitchyinfft (p->p_object); + break; + case aubio_pitcht_yinfast: + del_fvec (p->buf); + del_aubio_pitchyinfast (p->p_object); + break; + case aubio_pitcht_specacf: + del_fvec (p->buf); + del_aubio_pitchspecacf (p->p_object); + break; + default: + break; + } + AUBIO_FREE (p); +} + +void +aubio_pitch_slideblock (aubio_pitch_t * p, const fvec_t * ibuf) +{ + uint_t overlap_size = p->buf->length - ibuf->length; +#if 1 //!HAVE_MEMCPY_HACKS + uint_t j; + for (j = 0; j < overlap_size; j++) { + p->buf->data[j] = p->buf->data[j + ibuf->length]; + } + for (j = 0; j < ibuf->length; j++) { + p->buf->data[j + overlap_size] = ibuf->data[j]; + } +#else + smpl_t *data = p->buf->data; + smpl_t *newdata = ibuf->data; + memmove(data, data + ibuf->length, overlap_size); + memcpy(data + overlap_size, newdata, ibuf->length); +#endif +} + +uint_t +aubio_pitch_set_unit (aubio_pitch_t * p, const char_t * pitch_unit) +{ + uint_t err = AUBIO_OK; + aubio_pitch_mode pitch_mode; + if (strcmp (pitch_unit, "freq") == 0) + pitch_mode = aubio_pitchm_freq; + else if (strcmp (pitch_unit, "hertz") == 0) + pitch_mode = aubio_pitchm_freq; + else if (strcmp (pitch_unit, "Hertz") == 0) + pitch_mode = aubio_pitchm_freq; + else if (strcmp (pitch_unit, "Hz") == 0) + pitch_mode = aubio_pitchm_freq; + else if (strcmp (pitch_unit, "f0") == 0) + pitch_mode = aubio_pitchm_freq; + else if (strcmp (pitch_unit, "midi") == 0) + pitch_mode = aubio_pitchm_midi; + else if (strcmp (pitch_unit, "cent") == 0) + pitch_mode = aubio_pitchm_cent; + else if (strcmp (pitch_unit, "bin") == 0) + pitch_mode = aubio_pitchm_bin; + else if (strcmp (pitch_unit, "default") == 0) + pitch_mode = aubio_pitchm_default; + else { + AUBIO_WRN("pitch: unknown pitch detection unit ‘%s’, using default\n", + pitch_unit); + pitch_mode = aubio_pitchm_default; + err = AUBIO_FAIL; + } + p->mode = pitch_mode; + switch (p->mode) { + case aubio_pitchm_freq: + p->conv_cb = freqconvpass; + break; + case aubio_pitchm_midi: + p->conv_cb = freqconvmidi; + break; + case aubio_pitchm_cent: + /* bug: not implemented */ + p->conv_cb = freqconvmidi; + break; + case aubio_pitchm_bin: + p->conv_cb = freqconvbin; + break; + default: + break; + } + return err; +} + +uint_t +aubio_pitch_set_tolerance (aubio_pitch_t * p, smpl_t tol) +{ + switch (p->type) { + case aubio_pitcht_yin: + aubio_pitchyin_set_tolerance (p->p_object, tol); + break; + case aubio_pitcht_yinfft: + aubio_pitchyinfft_set_tolerance (p->p_object, tol); + break; + case aubio_pitcht_yinfast: + aubio_pitchyinfast_set_tolerance (p->p_object, tol); + break; + default: + break; + } + return AUBIO_OK; +} + +smpl_t +aubio_pitch_get_tolerance (aubio_pitch_t * p) +{ + smpl_t tolerance = 1.; + switch (p->type) { + case aubio_pitcht_yin: + tolerance = aubio_pitchyin_get_tolerance (p->p_object); + break; + case aubio_pitcht_yinfft: + tolerance = aubio_pitchyinfft_get_tolerance (p->p_object); + break; + case aubio_pitcht_yinfast: + tolerance = aubio_pitchyinfast_get_tolerance (p->p_object); + break; + default: + break; + } + return tolerance; +} + +uint_t +aubio_pitch_set_silence (aubio_pitch_t * p, smpl_t silence) +{ + if (silence <= 0 && silence >= -200) { + p->silence = silence; + return AUBIO_OK; + } else { + AUBIO_WRN("pitch: could not set silence to %.2f\n", silence); + return AUBIO_FAIL; + } +} + +smpl_t +aubio_pitch_get_silence (aubio_pitch_t * p) +{ + return p->silence; +} + + +/* do method, calling the detection callback, then the conversion callback */ +void +aubio_pitch_do (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf) +{ + p->detect_cb (p, ibuf, obuf); + if (aubio_silence_detection(ibuf, p->silence) == 1) { + obuf->data[0] = 0.; + } + obuf->data[0] = p->conv_cb (obuf->data[0], p->samplerate, p->bufsize); +} + +/* do method for each algorithm */ +void +aubio_pitch_do_mcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf) +{ + aubio_filter_do_outplace (p->filter, ibuf, p->filtered); + aubio_pvoc_do (p->pv, ibuf, p->fftgrain); + aubio_pitchmcomb_do (p->p_object, p->fftgrain, obuf); + obuf->data[0] = aubio_bintofreq (obuf->data[0], p->samplerate, p->bufsize); +} + +void +aubio_pitch_do_yin (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf) +{ + smpl_t pitch = 0.; + aubio_pitch_slideblock (p, ibuf); + aubio_pitchyin_do (p->p_object, p->buf, obuf); + pitch = obuf->data[0]; + if (pitch > 0) { + pitch = p->samplerate / (pitch + 0.); + } else { + pitch = 0.; + } + obuf->data[0] = pitch; +} + + +void +aubio_pitch_do_yinfft (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf) +{ + smpl_t pitch = 0.; + aubio_pitch_slideblock (p, ibuf); + aubio_pitchyinfft_do (p->p_object, p->buf, obuf); + pitch = obuf->data[0]; + if (pitch > 0) { + pitch = p->samplerate / (pitch + 0.); + } else { + pitch = 0.; + } + obuf->data[0] = pitch; +} + +void +aubio_pitch_do_yinfast (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * obuf) +{ + smpl_t pitch = 0.; + aubio_pitch_slideblock (p, ibuf); + aubio_pitchyinfast_do (p->p_object, p->buf, obuf); + pitch = obuf->data[0]; + if (pitch > 0) { + pitch = p->samplerate / (pitch + 0.); + } else { + pitch = 0.; + } + obuf->data[0] = pitch; +} + +void +aubio_pitch_do_specacf (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out) +{ + smpl_t pitch = 0., period; + aubio_pitch_slideblock (p, ibuf); + aubio_pitchspecacf_do (p->p_object, p->buf, out); + //out->data[0] = aubio_bintofreq (out->data[0], p->samplerate, p->bufsize); + period = out->data[0]; + if (period > 0) { + pitch = p->samplerate / period; + } else { + pitch = 0.; + } + out->data[0] = pitch; +} + +void +aubio_pitch_do_fcomb (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out) +{ + aubio_pitch_slideblock (p, ibuf); + aubio_pitchfcomb_do (p->p_object, p->buf, out); + out->data[0] = aubio_bintofreq (out->data[0], p->samplerate, p->bufsize); +} + +void +aubio_pitch_do_schmitt (aubio_pitch_t * p, const fvec_t * ibuf, fvec_t * out) +{ + smpl_t period, pitch = 0.; + aubio_pitch_slideblock (p, ibuf); + aubio_pitchschmitt_do (p->p_object, p->buf, out); + period = out->data[0]; + if (period > 0) { + pitch = p->samplerate / period; + } else { + pitch = 0.; + } + out->data[0] = pitch; +} + +/* conversion callbacks */ +smpl_t +freqconvbin(smpl_t f, uint_t samplerate, uint_t bufsize) +{ + return aubio_freqtobin(f, samplerate, bufsize); +} + +smpl_t +freqconvmidi (smpl_t f, uint_t samplerate UNUSED, uint_t bufsize UNUSED) +{ + return aubio_freqtomidi (f); +} + +smpl_t +freqconvpass (smpl_t f, uint_t samplerate UNUSED, uint_t bufsize UNUSED) +{ + return f; +} + +/* confidence callbacks */ +smpl_t +aubio_pitch_get_confidence (aubio_pitch_t * p) +{ + if (p->conf_cb) { + return p->conf_cb(p->p_object); + } + return 0.; +} diff --git a/deps/aubio/src/pitch/pitch.h b/deps/aubio/src/pitch/pitch.h new file mode 100644 index 0000000..b807a6a --- /dev/null +++ b/deps/aubio/src/pitch/pitch.h @@ -0,0 +1,197 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_PITCH_H +#define AUBIO_PITCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + + Pitch detection object + + This file creates the objects required for the computation of the selected + pitch detection algorithm and output the results, in midi note or Hz. + + \section pitch Pitch detection methods + + A list of the pitch detection methods currently available follows. + + \b \p default : use the default method + + Currently, the default method is set to \p yinfft . + + \b \p schmitt : Schmitt trigger + + This pitch extraction method implements a Schmitt trigger to estimate the + period of a signal. + + This file was derived from the tuneit project, written by Mario Lang to + detect the fundamental frequency of a sound. + + See http://delysid.org/tuneit.html + + \b \p fcomb : a fast harmonic comb filter + + This pitch extraction method implements a fast harmonic comb filter to + determine the fundamental frequency of a harmonic sound. + + This file was derived from the tuneit project, written by Mario Lang to + detect the fundamental frequency of a sound. + + See http://delysid.org/tuneit.html + + \b \p mcomb : multiple-comb filter + + This fundamental frequency estimation algorithm implements spectral + flattening, multi-comb filtering and peak histogramming. + + This method was designed by Juan P. Bello and described in: + + Juan-Pablo Bello. ``Towards the Automated Analysis of Simple Polyphonic + Music''. PhD thesis, Centre for Digital Music, Queen Mary University of + London, London, UK, 2003. + + \b \p yin : YIN algorithm + + This algorithm was developed by A. de Cheveigne and H. Kawahara and + published in: + + De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency + estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930. + + see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html + + \b \p yinfast : Yinfast algorithm + + This algorithm is equivalent to the YIN algorithm, but computed in the + spectral domain for efficiency. See also `python/demos/demo_yin_compare.py`. + + \b \p yinfft : Yinfft algorithm + + This algorithm was derived from the YIN algorithm. In this implementation, a + Fourier transform is used to compute a tapered square difference function, + which allows spectral weighting. Because the difference function is tapered, + the selection of the period is simplified. + + Paul Brossier, [Automatic annotation of musical audio for interactive + systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis, + Centre for Digital music, Queen Mary University of London, London, UK, 2006. + + \example pitch/test-pitch.c + \example examples/aubiopitch.c + +*/ + +/** pitch detection object */ +typedef struct _aubio_pitch_t aubio_pitch_t; + +/** execute pitch detection on an input signal frame + + \param o pitch detection object as returned by new_aubio_pitch() + \param in input signal of size [hop_size] + \param out output pitch candidates of size [1] + +*/ +void aubio_pitch_do (aubio_pitch_t * o, const fvec_t * in, fvec_t * out); + +/** change yin or yinfft tolerance threshold + + \param o pitch detection object as returned by new_aubio_pitch() + \param tol tolerance default is 0.15 for yin and 0.85 for yinfft + +*/ +uint_t aubio_pitch_set_tolerance (aubio_pitch_t * o, smpl_t tol); + +/** get yin or yinfft tolerance threshold + + \param o pitch detection object as returned by new_aubio_pitch() + \return tolerance (default is 0.15 for yin and 0.85 for yinfft) + +*/ +smpl_t aubio_pitch_get_tolerance (aubio_pitch_t * o); + +/** deletion of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitch() + +*/ +void del_aubio_pitch (aubio_pitch_t * o); + +/** creation of the pitch detection object + + \param method set pitch detection algorithm + \param buf_size size of the input buffer to analyse + \param hop_size step size between two consecutive analysis instant + \param samplerate sampling rate of the signal + + \return newly created ::aubio_pitch_t + +*/ +aubio_pitch_t *new_aubio_pitch (const char_t * method, + uint_t buf_size, uint_t hop_size, uint_t samplerate); + +/** set the output unit of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitch() + \param mode set pitch units for output + + mode can be one of "Hz", "midi", "cent", or "bin". Defaults to "Hz". + + \return 0 if successfull, non-zero otherwise + +*/ +uint_t aubio_pitch_set_unit (aubio_pitch_t * o, const char_t * mode); + +/** set the silence threshold of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitch() + \param silence level threshold under which pitch should be ignored, in dB + + \return 0 if successfull, non-zero otherwise + +*/ +uint_t aubio_pitch_set_silence (aubio_pitch_t * o, smpl_t silence); + +/** set the silence threshold of the pitch detection object + + \param o pitch detection object as returned by ::new_aubio_pitch() + + \return level threshold under which pitch should be ignored, in dB + +*/ +smpl_t aubio_pitch_get_silence (aubio_pitch_t * o); + +/** get the current confidence + + \param o pitch detection object as returned by new_aubio_pitch() + + \return the current confidence of the pitch algorithm + +*/ +smpl_t aubio_pitch_get_confidence (aubio_pitch_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCH_H */ diff --git a/deps/aubio/src/pitch/pitchfcomb.c b/deps/aubio/src/pitch/pitchfcomb.c new file mode 100644 index 0000000..5cc49b9 --- /dev/null +++ b/deps/aubio/src/pitch/pitchfcomb.c @@ -0,0 +1,144 @@ +/* + Copyright (C) 2004, 2005 Mario Lang + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "musicutils.h" +#include "spectral/fft.h" +#include "pitch/pitchfcomb.h" + +#define MAX_PEAKS 8 + +typedef struct +{ + smpl_t bin; + smpl_t db; +} aubio_fpeak_t; + +struct _aubio_pitchfcomb_t +{ + uint_t fftSize; + uint_t stepSize; + uint_t rate; + fvec_t *winput; + fvec_t *win; + cvec_t *fftOut; + fvec_t *fftLastPhase; + aubio_fft_t *fft; +}; + +aubio_pitchfcomb_t * +new_aubio_pitchfcomb (uint_t bufsize, uint_t hopsize) +{ + aubio_pitchfcomb_t *p = AUBIO_NEW (aubio_pitchfcomb_t); + p->fftSize = bufsize; + p->stepSize = hopsize; + p->fft = new_aubio_fft (bufsize); + if (!p->fft) goto beach; + p->winput = new_fvec (bufsize); + p->fftOut = new_cvec (bufsize); + p->fftLastPhase = new_fvec (bufsize); + p->win = new_aubio_window ("hanning", bufsize); + return p; + +beach: + AUBIO_FREE(p); + return NULL; +} + +/* input must be stepsize long */ +void +aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, const fvec_t * input, fvec_t * output) +{ + uint_t k, l, maxharm = 0; + smpl_t phaseDifference = TWO_PI * (smpl_t) p->stepSize / (smpl_t) p->fftSize; + aubio_fpeak_t peaks[MAX_PEAKS]; + + for (k = 0; k < MAX_PEAKS; k++) { + peaks[k].db = -200.; + peaks[k].bin = 0.; + } + + for (k = 0; k < input->length; k++) { + p->winput->data[k] = p->win->data[k] * input->data[k]; + } + aubio_fft_do (p->fft, p->winput, p->fftOut); + + for (k = 0; k <= p->fftSize / 2; k++) { + smpl_t + magnitude = + 20. * LOG10 (2. * p->fftOut->norm[k] / (smpl_t) p->fftSize), + phase = p->fftOut->phas[k], tmp, bin; + + /* compute phase difference */ + tmp = phase - p->fftLastPhase->data[k]; + p->fftLastPhase->data[k] = phase; + + /* subtract expected phase difference */ + tmp -= (smpl_t) k *phaseDifference; + + /* map delta phase into +/- Pi interval */ + tmp = aubio_unwrap2pi (tmp); + + /* get deviation from bin frequency from the +/- Pi interval */ + tmp = p->fftSize / (smpl_t) p->stepSize * tmp / (TWO_PI); + + /* compute the k-th partials' true bin */ + bin = (smpl_t) k + tmp; + + if (bin > 0.0 && magnitude > peaks[0].db) { // && magnitude < 0) { + memmove (peaks + 1, peaks, sizeof (aubio_fpeak_t) * (MAX_PEAKS - 1)); + peaks[0].bin = bin; + peaks[0].db = magnitude; + } + } + + k = 0; + for (l = 1; l < MAX_PEAKS && peaks[l].bin > 0.0; l++) { + sint_t harmonic; + for (harmonic = 5; harmonic > 1; harmonic--) { + if (peaks[0].bin / peaks[l].bin < harmonic + .02 && + peaks[0].bin / peaks[l].bin > harmonic - .02) { + if (harmonic > (sint_t) maxharm && peaks[0].db < peaks[l].db / 2) { + maxharm = harmonic; + k = l; + } + } + } + } + output->data[0] = peaks[k].bin; + /* quick hack to clean output a bit */ + if (peaks[k].bin > 5000.) + output->data[0] = 0.; +} + +void +del_aubio_pitchfcomb (aubio_pitchfcomb_t * p) +{ + del_cvec (p->fftOut); + del_fvec (p->fftLastPhase); + del_fvec (p->win); + del_fvec (p->winput); + del_aubio_fft (p->fft); + AUBIO_FREE (p); +} diff --git a/deps/aubio/src/pitch/pitchfcomb.h b/deps/aubio/src/pitch/pitchfcomb.h new file mode 100644 index 0000000..5016708 --- /dev/null +++ b/deps/aubio/src/pitch/pitchfcomb.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Pitch detection using a fast harmonic comb filter + + This pitch extraction method implements a fast harmonic comb filter to + determine the fundamental frequency of a harmonic sound. + + This file was derived from the tuneit project, written by Mario Lang to + detect the fundamental frequency of a sound. + + See http://delysid.org/tuneit.html + + \example pitch/test-pitchfcomb.c + +*/ + +#ifndef AUBIO_PITCHFCOMB_H +#define AUBIO_PITCHFCOMB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchfcomb_t aubio_pitchfcomb_t; + +/** execute pitch detection on an input buffer + + \param p pitch detection object as returned by new_aubio_pitchfcomb + \param input input signal window (length as specified at creation time) + \param output pitch candidates in bins + +*/ +void aubio_pitchfcomb_do (aubio_pitchfcomb_t * p, const fvec_t * input, + fvec_t * output); + +/** creation of the pitch detection object + + \param buf_size size of the input buffer to analyse + \param hop_size step size between two consecutive analysis instant + +*/ +aubio_pitchfcomb_t *new_aubio_pitchfcomb (uint_t buf_size, uint_t hop_size); + +/** deletion of the pitch detection object + + \param p pitch detection object as returned by new_aubio_pitchfcomb + +*/ +void del_aubio_pitchfcomb (aubio_pitchfcomb_t * p); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCHFCOMB_H */ diff --git a/deps/aubio/src/pitch/pitchmcomb.c b/deps/aubio/src/pitch/pitchmcomb.c new file mode 100644 index 0000000..9ce160e --- /dev/null +++ b/deps/aubio/src/pitch/pitchmcomb.c @@ -0,0 +1,435 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "pitch/pitchmcomb.h" + +#define CAND_SWAP(a,b) { register aubio_spectralcandidate_t *t=(a);(a)=(b);(b)=t; } + +typedef struct _aubio_spectralpeak_t aubio_spectralpeak_t; +typedef struct _aubio_spectralcandidate_t aubio_spectralcandidate_t; +uint_t aubio_pitchmcomb_get_root_peak (aubio_spectralpeak_t * peaks, + uint_t length); +uint_t aubio_pitchmcomb_quadpick (aubio_spectralpeak_t * spectral_peaks, + const fvec_t * X); +void aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, const fvec_t * oldmag); +void aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, const fvec_t * newmag); +/* not used but useful : sort by amplitudes (or anything else) + * sort_pitchpeak(peaks, length); + */ +#if 0 +/** spectral_peak comparison function (must return signed int) */ +static sint_t aubio_pitchmcomb_sort_peak_comp (const void *x, const void *y); +/** sort spectral_peak against their mag */ +void aubio_pitchmcomb_sort_peak (aubio_spectralpeak_t * peaks, uint_t nbins); +/** select the best candidates */ +uint_t aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, + smpl_t * cands); +#endif + +/** sort spectral_candidate against their comb ene */ +void aubio_pitchmcomb_sort_cand_ene (aubio_spectralcandidate_t ** candidates, + uint_t nbins); +#if 0 +/** sort spectral_candidate against their frequency */ +void aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates, + uint_t nbins); +#endif + +struct _aubio_pitchmcomb_t +{ + smpl_t threshold; /**< offset threshold [0.033 or 0.01] */ + smpl_t alpha; /**< normalisation exponent [9] */ + smpl_t cutoff; /**< low-pass filter cutoff [0.34, 1] */ + smpl_t tol; /**< tolerance [0.05] */ + // smpl_t tau; /**< frequency precision [44100/4096] */ + uint_t win_post; /**< median filter window length */ + uint_t win_pre; /**< median filter window */ + uint_t ncand; /**< maximum number of candidates (combs) */ + uint_t npartials; /**< maximum number of partials per combs */ + uint_t count; /**< picked picks */ + uint_t goodcandidate; /**< best candidate */ + uint_t spec_partition; /**< spectrum partition to consider */ + aubio_spectralpeak_t *peaks; /**< up to length win/spec_partition */ + aubio_spectralcandidate_t **candidates; /** up to five candidates */ + /* some scratch pads */ + /** \bug (unnecessary copied from fftgrain?) */ + fvec_t *newmag; /**< vec to store mag */ + fvec_t *scratch; /**< vec to store modified mag */ + fvec_t *scratch2; /**< vec to compute moving median */ + fvec_t *theta; /**< vec to store phase */ + smpl_t phasediff; + smpl_t phasefreq; + /** threshfn: name or handle of fn for computing adaptive threshold [median] */ + /** aubio_thresholdfn_t thresholdfn; */ + /** picker: name or handle of fn for picking event times [quadpick] */ + /** aubio_pickerfn_t pickerfn; */ +}; + +/** spectral peak object */ +struct _aubio_spectralpeak_t +{ + uint_t bin; /**< bin [0-(length-1)] */ + smpl_t ebin; /**< estimated bin */ + smpl_t mag; /**< peak magnitude */ +}; + +/** spectral candidates array object */ +struct _aubio_spectralcandidate_t +{ + smpl_t ebin; /**< interpolated bin */ + smpl_t *ecomb; /**< comb */ + smpl_t ene; /**< candidate energy */ + smpl_t len; /**< length */ +}; + + +void +aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, fvec_t * output) +{ + uint_t j; + smpl_t instfreq; + fvec_t *newmag = (fvec_t *) p->newmag; + //smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta; + /* copy incoming grain to newmag */ + for (j = 0; j < newmag->length; j++) + newmag->data[j] = fftgrain->norm[j]; + /* detect only if local energy > 10. */ + //if (aubio_level_lin (newmag) * newmag->length > 10.) { + //hfc = fvec_local_hfc(newmag); //not used + aubio_pitchmcomb_spectral_pp (p, newmag); + aubio_pitchmcomb_combdet (p, newmag); + //aubio_pitchmcomb_sort_cand_freq(p->candidates,p->ncand); + //return p->candidates[p->goodcandidate]->ebin; + j = (uint_t) FLOOR (p->candidates[p->goodcandidate]->ebin + .5); + instfreq = aubio_unwrap2pi (fftgrain->phas[j] + - p->theta->data[j] - j * p->phasediff); + instfreq *= p->phasefreq; + /* store phase for next run */ + for (j = 0; j < p->theta->length; j++) { + p->theta->data[j] = fftgrain->phas[j]; + } + //return p->candidates[p->goodcandidate]->ebin; + output->data[0] = + FLOOR (p->candidates[p->goodcandidate]->ebin + .5) + instfreq; + /*} else { + return -1.; + } */ +} + +#if 0 +uint_t +aubio_pitch_cands (aubio_pitchmcomb_t * p, const cvec_t * fftgrain, smpl_t * cands) +{ + uint_t j; + uint_t k; + fvec_t *newmag = (fvec_t *) p->newmag; + aubio_spectralcandidate_t **scands = + (aubio_spectralcandidate_t **) (p->candidates); + //smpl_t hfc; //fe=instfreq(theta1,theta,ops); //theta1=theta; + /* copy incoming grain to newmag */ + for (j = 0; j < newmag->length; j++) + newmag->data[j] = fftgrain->norm[j]; + /* detect only if local energy > 10. */ + if (aubio_level_lin (newmag) * newmag->length > 10.) { + /* hfc = fvec_local_hfc(newmag); do not use */ + aubio_pitchmcomb_spectral_pp (p, newmag); + aubio_pitchmcomb_combdet (p, newmag); + aubio_pitchmcomb_sort_cand_freq (scands, p->ncand); + /* store ncand comb energies in cands[1:ncand] */ + for (k = 0; k < p->ncand; k++) + cands[k] = p->candidates[k]->ene; + /* store ncand[end] freq in cands[end] */ + cands[p->ncand] = p->candidates[p->ncand - 1]->ebin; + return 1; + } else { + for (k = 0; k < p->ncand; k++) + cands[k] = 0; + return 0; + } +} +#endif + +void +aubio_pitchmcomb_spectral_pp (aubio_pitchmcomb_t * p, const fvec_t * newmag) +{ + fvec_t *mag = (fvec_t *) p->scratch; + fvec_t *tmp = (fvec_t *) p->scratch2; + uint_t j; + uint_t length = mag->length; + /* copy newmag to mag (scracth) */ + for (j = 0; j < length; j++) { + mag->data[j] = newmag->data[j]; + } + fvec_min_removal (mag); /* min removal */ + fvec_alpha_normalise (mag, p->alpha); /* alpha normalisation */ + /* skipped *//* low pass filtering */ + /** \bug fvec_moving_thres may write out of bounds */ + fvec_adapt_thres (mag, tmp, p->win_post, p->win_pre); /* adaptative threshold */ + fvec_add (mag, -p->threshold); /* fixed threshold */ + { + aubio_spectralpeak_t *peaks = (aubio_spectralpeak_t *) p->peaks; + uint_t count; + /* return bin and ebin */ + count = aubio_pitchmcomb_quadpick (peaks, mag); + for (j = 0; j < count; j++) + peaks[j].mag = newmag->data[peaks[j].bin]; + /* reset non peaks */ + for (j = count; j < length; j++) + peaks[j].mag = 0.; + p->peaks = peaks; + p->count = count; + } +} + +void +aubio_pitchmcomb_combdet (aubio_pitchmcomb_t * p, const fvec_t * newmag) +{ + aubio_spectralpeak_t *peaks = (aubio_spectralpeak_t *) p->peaks; + aubio_spectralcandidate_t **candidate = + (aubio_spectralcandidate_t **) p->candidates; + + /* parms */ + uint_t N = p->npartials; /* maximum number of partials to be considered 10 */ + uint_t M = p->ncand; /* maximum number of combs to be considered 5 */ + uint_t length = newmag->length; + uint_t count = p->count; + uint_t k; + uint_t l; + uint_t d; + uint_t curlen = 0; + + smpl_t delta2; + smpl_t xx; + uint_t position = 0; + + uint_t root_peak = 0; + uint_t tmpl = 0; + smpl_t tmpene = 0.; + + /* get the biggest peak in the spectrum */ + root_peak = aubio_pitchmcomb_get_root_peak (peaks, count); + /* not enough partials in highest notes, could be forced */ + //if (peaks[root_peak].ebin >= aubio_miditofreq(85.)/p->tau) N=2; + //if (peaks[root_peak].ebin >= aubio_miditofreq(90.)/p->tau) N=1; + /* now calculate the energy of each of the 5 combs */ + for (l = 0; l < M; l++) { + smpl_t scaler = (1. / (l + 1.)); + candidate[l]->ene = 0.; /* reset ene and len sums */ + candidate[l]->len = 0.; + candidate[l]->ebin = scaler * peaks[root_peak].ebin; + /* if less than N peaks available, curlen < N */ + if (candidate[l]->ebin != 0.) + curlen = (uint_t) FLOOR (length / (candidate[l]->ebin)); + curlen = (N < curlen) ? N : curlen; + /* fill candidate[l]->ecomb[k] with (k+1)*candidate[l]->ebin */ + for (k = 0; k < curlen; k++) + candidate[l]->ecomb[k] = (candidate[l]->ebin) * (k + 1.); + for (k = curlen; k < length; k++) + candidate[l]->ecomb[k] = 0.; + /* for each in candidate[l]->ecomb[k] */ + for (k = 0; k < curlen; k++) { + xx = 100000.; + /** get the candidate->ecomb the closer to peaks.ebin + * (to cope with the inharmonicity)*/ + for (d = 0; d < count; d++) { + delta2 = ABS (candidate[l]->ecomb[k] - peaks[d].ebin); + if (delta2 <= xx) { + position = d; + xx = delta2; + } + } + /* for a Q factor of 17, maintaining "constant Q filtering", + * and sum energy and length over non null combs */ + if (17. * xx < candidate[l]->ecomb[k]) { + candidate[l]->ecomb[k] = peaks[position].ebin; + candidate[l]->ene += /* ecomb rounded to nearest int */ + POW (newmag->data[(uint_t) FLOOR (candidate[l]->ecomb[k] + .5)], + 0.25); + candidate[l]->len += 1. / curlen; + } else + candidate[l]->ecomb[k] = 0.; + } + /* punishment */ + /*if (candidate[l]->len<0.6) + candidate[l]->ene=0.; */ + /* remember best candidate energy (in polyphonic, could check for + * tmpene*1.1 < candidate->ene to reduce jumps towards low frequencies) */ + if (tmpene < candidate[l]->ene) { + tmpl = l; + tmpene = candidate[l]->ene; + } + } + //p->candidates=candidate; + //p->peaks=peaks; + p->goodcandidate = tmpl; +} + +/** T=quadpick(X): return indices of elements of X which are peaks and positive + * exact peak positions are retrieved by quadratic interpolation + * + * \bug peak-picking too picky, sometimes counts too many peaks ? + */ +uint_t +aubio_pitchmcomb_quadpick (aubio_spectralpeak_t * spectral_peaks, const fvec_t * X) +{ + uint_t j, ispeak, count = 0; + for (j = 1; j < X->length - 1; j++) { + ispeak = fvec_peakpick (X, j); + if (ispeak) { + count += ispeak; + spectral_peaks[count - 1].bin = j; + spectral_peaks[count - 1].ebin = fvec_quadratic_peak_pos (X, j); + } + } + return count; +} + +/* get predominant partial */ +uint_t +aubio_pitchmcomb_get_root_peak (aubio_spectralpeak_t * peaks, uint_t length) +{ + uint_t i, pos = 0; + smpl_t tmp = 0.; + for (i = 0; i < length; i++) + if (tmp <= peaks[i].mag) { + pos = i; + tmp = peaks[i].mag; + } + return pos; +} + +#if 0 +void +aubio_pitchmcomb_sort_peak (aubio_spectralpeak_t * peaks, uint_t nbins) +{ + qsort (peaks, nbins, sizeof (aubio_spectralpeak_t), + aubio_pitchmcomb_sort_peak_comp); +} + +static sint_t +aubio_pitchmcomb_sort_peak_comp (const void *x, const void *y) +{ + return (((aubio_spectralpeak_t *) y)->mag - + ((aubio_spectralpeak_t *) x)->mag); +} + + +void +aubio_pitchmcomb_sort_cand_ene (aubio_spectralcandidate_t ** candidates, + uint_t nbins) +{ + uint_t cur = 0; + uint_t run = 0; + for (cur = 0; cur < nbins; cur++) { + for (run = cur + 1; run < nbins; run++) { + if (candidates[run]->ene > candidates[cur]->ene) + CAND_SWAP (candidates[run], candidates[cur]); + } + } +} + +void +aubio_pitchmcomb_sort_cand_freq (aubio_spectralcandidate_t ** candidates, + uint_t nbins) +{ + uint_t cur = 0; + uint_t run = 0; + for (cur = 0; cur < nbins; cur++) { + for (run = cur + 1; run < nbins; run++) { + if (candidates[run]->ebin < candidates[cur]->ebin) + CAND_SWAP (candidates[run], candidates[cur]); + } + } +} +#endif + +aubio_pitchmcomb_t * +new_aubio_pitchmcomb (uint_t bufsize, uint_t hopsize) +{ + aubio_pitchmcomb_t *p = AUBIO_NEW (aubio_pitchmcomb_t); + /* bug: should check if size / 8 > post+pre+1 */ + uint_t i, j; + uint_t spec_size; + p->spec_partition = 2; + p->ncand = 5; + p->npartials = 5; + p->cutoff = 1.; + p->threshold = 0.01; + p->win_post = 8; + p->win_pre = 7; + // p->tau = samplerate/bufsize; + p->alpha = 9.; + p->goodcandidate = 0; + p->phasefreq = bufsize / hopsize / TWO_PI; + p->phasediff = TWO_PI * hopsize / bufsize; + spec_size = bufsize / p->spec_partition + 1; + //p->pickerfn = quadpick; + //p->biquad = new_biquad(0.1600,0.3200,0.1600, -0.5949, 0.2348); + /* allocate temp memory */ + p->newmag = new_fvec (spec_size); + /* array for median */ + p->scratch = new_fvec (spec_size); + /* array for phase */ + p->theta = new_fvec (spec_size); + /* array for adaptative threshold */ + p->scratch2 = new_fvec (p->win_post + p->win_pre + 1); + /* array of spectral peaks */ + p->peaks = AUBIO_ARRAY (aubio_spectralpeak_t, spec_size); + for (i = 0; i < spec_size; i++) { + p->peaks[i].bin = 0.; + p->peaks[i].ebin = 0.; + p->peaks[i].mag = 0.; + } + /* array of pointers to spectral candidates */ + p->candidates = AUBIO_ARRAY (aubio_spectralcandidate_t *, p->ncand); + for (i = 0; i < p->ncand; i++) { + p->candidates[i] = AUBIO_NEW (aubio_spectralcandidate_t); + p->candidates[i]->ecomb = AUBIO_ARRAY (smpl_t, spec_size); + for (j = 0; j < spec_size; j++) { + p->candidates[i]->ecomb[j] = 0.; + } + p->candidates[i]->ene = 0.; + p->candidates[i]->ebin = 0.; + p->candidates[i]->len = 0.; + } + return p; +} + + +void +del_aubio_pitchmcomb (aubio_pitchmcomb_t * p) +{ + uint_t i; + del_fvec (p->newmag); + del_fvec (p->scratch); + del_fvec (p->theta); + del_fvec (p->scratch2); + AUBIO_FREE (p->peaks); + for (i = 0; i < p->ncand; i++) { + AUBIO_FREE (p->candidates[i]->ecomb); + AUBIO_FREE (p->candidates[i]); + } + AUBIO_FREE (p->candidates); + AUBIO_FREE (p); +} diff --git a/deps/aubio/src/pitch/pitchmcomb.h b/deps/aubio/src/pitch/pitchmcomb.h new file mode 100644 index 0000000..88f117f --- /dev/null +++ b/deps/aubio/src/pitch/pitchmcomb.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Pitch detection using multiple-comb filter + + This fundamental frequency estimation algorithm implements spectral + flattening, multi-comb filtering and peak histogramming. + + This method was designed by Juan P. Bello and described in: + + Juan-Pablo Bello. ``Towards the Automated Analysis of Simple Polyphonic + Music''. PhD thesis, Centre for Digital Music, Queen Mary University of + London, London, UK, 2003. + + \example pitch/test-pitchmcomb.c + +*/ + +#ifndef AUBIO_PITCHMCOMB_H +#define AUBIO_PITCHMCOMB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchmcomb_t aubio_pitchmcomb_t; + +/** execute pitch detection on an input spectral frame + + \param p pitch detection object as returned by new_aubio_pitchmcomb + \param in_fftgrain input signal spectrum as computed by aubio_pvoc_do + \param out_cands pitch candidate frequenciess, in bins + +*/ +void aubio_pitchmcomb_do (aubio_pitchmcomb_t * p, const cvec_t * in_fftgrain, + fvec_t * out_cands); + +/** creation of the pitch detection object + + \param buf_size size of the input buffer to analyse + \param hop_size step size between two consecutive analysis instant + +*/ +aubio_pitchmcomb_t *new_aubio_pitchmcomb (uint_t buf_size, uint_t hop_size); + +/** deletion of the pitch detection object + + \param p pitch detection object as returned by new_aubio_pitchfcomb + +*/ +void del_aubio_pitchmcomb (aubio_pitchmcomb_t * p); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCHMCOMB_H */ diff --git a/deps/aubio/src/pitch/pitchschmitt.c b/deps/aubio/src/pitch/pitchschmitt.c new file mode 100644 index 0000000..06a34e8 --- /dev/null +++ b/deps/aubio/src/pitch/pitchschmitt.c @@ -0,0 +1,119 @@ +/* + Copyright (C) 2004, 2005 Mario Lang + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "pitch/pitchschmitt.h" + +smpl_t aubio_schmittS16LE (aubio_pitchschmitt_t * p, uint_t nframes, + signed short int *indata); + +struct _aubio_pitchschmitt_t +{ + uint_t blockSize; + uint_t rate; + signed short int *schmittBuffer; + signed short int *schmittPointer; + signed short int *buf; +}; + +aubio_pitchschmitt_t * +new_aubio_pitchschmitt (uint_t size) +{ + aubio_pitchschmitt_t *p = AUBIO_NEW (aubio_pitchschmitt_t); + p->blockSize = size; + p->schmittBuffer = AUBIO_ARRAY (signed short int, p->blockSize); + p->buf = AUBIO_ARRAY (signed short int, p->blockSize); + p->schmittPointer = p->schmittBuffer; + return p; +} + +void +aubio_pitchschmitt_do (aubio_pitchschmitt_t * p, const fvec_t * input, + fvec_t * output) +{ + uint_t j; + for (j = 0; j < input->length; j++) { + p->buf[j] = input->data[j] * 32768.; + } + output->data[0] = aubio_schmittS16LE (p, input->length, p->buf); +} + +smpl_t +aubio_schmittS16LE (aubio_pitchschmitt_t * p, uint_t nframes, + signed short int *indata) +{ + uint_t i, j; + uint_t blockSize = p->blockSize; + signed short int *schmittBuffer = p->schmittBuffer; + signed short int *schmittPointer = p->schmittPointer; + + smpl_t period = 0., trigfact = 0.6; + + for (i = 0; i < nframes; i++) { + *schmittPointer++ = indata[i]; + if (schmittPointer - schmittBuffer >= (sint_t) blockSize) { + sint_t endpoint, startpoint, t1, t2, A1, A2, tc, schmittTriggered; + + schmittPointer = schmittBuffer; + + for (j = 0, A1 = 0, A2 = 0; j < blockSize; j++) { + if (schmittBuffer[j] > 0 && A1 < schmittBuffer[j]) + A1 = schmittBuffer[j]; + if (schmittBuffer[j] < 0 && A2 < -schmittBuffer[j]) + A2 = -schmittBuffer[j]; + } + t1 = (sint_t) (A1 * trigfact + 0.5); + t2 = -(sint_t) (A2 * trigfact + 0.5); + startpoint = 0; + for (j = 1; j < blockSize && schmittBuffer[j] <= t1; j++); + for ( ; j < blockSize - 1 && !(schmittBuffer[j] >= t2 && + schmittBuffer[j + 1] < t2); j++); + startpoint = j; + schmittTriggered = 0; + endpoint = startpoint + 1; + for (j = startpoint, tc = 0; j < blockSize; j++) { + if (!schmittTriggered) { + schmittTriggered = (schmittBuffer[j] >= t1); + } else if (schmittBuffer[j] >= t2 && schmittBuffer[j + 1] < t2) { + endpoint = j; + tc++; + schmittTriggered = 0; + } + } + if ((endpoint > startpoint) && (tc > 0)) { + period = (smpl_t) (endpoint - startpoint) / tc; + } + } + } + + p->schmittBuffer = schmittBuffer; + p->schmittPointer = schmittPointer; + return period; +} + +void +del_aubio_pitchschmitt (aubio_pitchschmitt_t * p) +{ + AUBIO_FREE (p->schmittBuffer); + AUBIO_FREE (p->buf); + AUBIO_FREE (p); +} diff --git a/deps/aubio/src/pitch/pitchschmitt.h b/deps/aubio/src/pitch/pitchschmitt.h new file mode 100644 index 0000000..db952c3 --- /dev/null +++ b/deps/aubio/src/pitch/pitchschmitt.h @@ -0,0 +1,75 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Pitch detection using a Schmitt trigger + + This pitch extraction method implements a Schmitt trigger to estimate the + period of a signal. + + This file was derived from the tuneit project, written by Mario Lang to + detect the fundamental frequency of a sound. + + See http://delysid.org/tuneit.html + + \example pitch/test-pitchschmitt.c + +*/ + +#ifndef AUBIO_PITCHSCHMITT_H +#define AUBIO_PITCHSCHMITT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchschmitt_t aubio_pitchschmitt_t; + +/** execute pitch detection on an input buffer + + \param p pitch detection object as returned by new_aubio_pitchschmitt + \param samples_in input signal vector (length as specified at creation time) + \param cands_out pitch period estimates, in samples + +*/ +void aubio_pitchschmitt_do (aubio_pitchschmitt_t * p, const fvec_t * samples_in, + fvec_t * cands_out); + +/** creation of the pitch detection object + + \param buf_size size of the input buffer to analyse + +*/ +aubio_pitchschmitt_t *new_aubio_pitchschmitt (uint_t buf_size); + +/** deletion of the pitch detection object + + \param p pitch detection object as returned by new_aubio_pitchschmitt + +*/ +void del_aubio_pitchschmitt (aubio_pitchschmitt_t * p); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCHSCHMITT_H */ diff --git a/deps/aubio/src/pitch/pitchspecacf.c b/deps/aubio/src/pitch/pitchspecacf.c new file mode 100644 index 0000000..170cfa3 --- /dev/null +++ b/deps/aubio/src/pitch/pitchspecacf.c @@ -0,0 +1,116 @@ +/* + Copyright (C) 2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/fft.h" +#include "pitch/pitchspecacf.h" + +/** pitch specacf structure */ +struct _aubio_pitchspecacf_t +{ + fvec_t *win; /**< temporal weighting window */ + fvec_t *winput; /**< windowed spectrum */ + aubio_fft_t *fft; /**< fft object to compute*/ + fvec_t *fftout; /**< Fourier transform output */ + fvec_t *sqrmag; /**< square magnitudes */ + fvec_t *acf; /**< auto correlation function */ + smpl_t tol; /**< tolerance */ + smpl_t confidence; /**< confidence */ +}; + +aubio_pitchspecacf_t * +new_aubio_pitchspecacf (uint_t bufsize) +{ + aubio_pitchspecacf_t *p = AUBIO_NEW (aubio_pitchspecacf_t); + p->fft = new_aubio_fft (bufsize); + if (!p->fft) goto beach; + p->win = new_aubio_window ("hanningz", bufsize); + p->winput = new_fvec (bufsize); + p->fftout = new_fvec (bufsize); + p->sqrmag = new_fvec (bufsize); + p->acf = new_fvec (bufsize / 2 + 1); + p->tol = 1.; + p->confidence = 0.; + return p; + +beach: + AUBIO_FREE(p); + return NULL; +} + +void +aubio_pitchspecacf_do (aubio_pitchspecacf_t * p, const fvec_t * input, fvec_t * output) +{ + uint_t l, tau; + fvec_t *fftout = p->fftout; + // window the input + for (l = 0; l < input->length; l++) { + p->winput->data[l] = p->win->data[l] * input->data[l]; + } + // get the real / imag parts of its fft + aubio_fft_do_complex (p->fft, p->winput, fftout); + for (l = 0; l < input->length / 2 + 1; l++) { + p->sqrmag->data[l] = SQR(fftout->data[l]); + } + // get the real / imag parts of the fft of the squared magnitude + aubio_fft_do_complex (p->fft, p->sqrmag, fftout); + // copy real part to acf + for (l = 0; l < fftout->length / 2 + 1; l++) { + p->acf->data[l] = fftout->data[l]; + } + // get the minimum + tau = fvec_min_elem (p->acf); + // get the interpolated minimum + output->data[0] = fvec_quadratic_peak_pos (p->acf, tau) * 2.; +} + +void +del_aubio_pitchspecacf (aubio_pitchspecacf_t * p) +{ + del_fvec (p->win); + del_fvec (p->winput); + del_aubio_fft (p->fft); + del_fvec (p->sqrmag); + del_fvec (p->fftout); + del_fvec (p->acf); + AUBIO_FREE (p); +} + +smpl_t +aubio_pitchspecacf_get_confidence (const aubio_pitchspecacf_t * o) { + // no confidence for now + return o->confidence; +} + +uint_t +aubio_pitchspecacf_set_tolerance (aubio_pitchspecacf_t * p, smpl_t tol) +{ + p->tol = tol; + return 0; +} + +smpl_t +aubio_pitchspecacf_get_tolerance (const aubio_pitchspecacf_t * p) +{ + return p->tol; +} diff --git a/deps/aubio/src/pitch/pitchspecacf.h b/deps/aubio/src/pitch/pitchspecacf.h new file mode 100644 index 0000000..e3c9c4c --- /dev/null +++ b/deps/aubio/src/pitch/pitchspecacf.h @@ -0,0 +1,103 @@ +/* + Copyright (C) 2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Pitch detection using spectral auto correlation + + This algorithm implements pitch detection by computing the autocorrelation + function as the cosine transform of the square spectral magnitudes. + + Anssi Klapuri. Qualitative and quantitative aspects in the design of + periodicity esti- mation algorithms. In Proceedings of the European Signal + Processing Conference (EUSIPCO), 2000. + + Paul Brossier, [Automatic annotation of musical audio for interactive + systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, Autocorrelation, + pp. 75-77, PhD thesis, Centre for Digital music, Queen Mary University of + London, London, UK, 2006. + + \example pitch/test-pitchspecacf.c + +*/ + +#ifndef AUBIO_PITCHSPECACF_H +#define AUBIO_PITCHSPECACF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchspecacf_t aubio_pitchspecacf_t; + +/** execute pitch detection on an input buffer + + \param o pitch detection object as returned by new_aubio_pitchspecacf + \param samples_in input signal vector (length as specified at creation time) + \param cands_out pitch period candidates, in samples + +*/ +void aubio_pitchspecacf_do (aubio_pitchspecacf_t * o, const fvec_t * samples_in, fvec_t * cands_out); +/** creation of the pitch detection object + + \param buf_size size of the input buffer to analyse + +*/ +aubio_pitchspecacf_t *new_aubio_pitchspecacf (uint_t buf_size); +/** deletion of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitchspecacf() + +*/ +void del_aubio_pitchspecacf (aubio_pitchspecacf_t * o); + +/** get tolerance parameter for `specacf` pitch detection object + + \param o pitch detection object + + \return tolerance parameter for minima selection [default 1.] + +*/ +smpl_t aubio_pitchspecacf_get_tolerance (const aubio_pitchspecacf_t * o); + +/** set tolerance parameter for `specacf` pitch detection object + + \param o pitch detection object + \param tol tolerance parameter for minima selection [default 1.] + + \return `1` on error, `0` on success + +*/ +uint_t aubio_pitchspecacf_set_tolerance (aubio_pitchspecacf_t * o, smpl_t tol); + +/** get currenct confidence for `specacf` pitch detection object + + \param o pitch detection object + \return confidence parameter + +*/ +smpl_t aubio_pitchspecacf_get_confidence (const aubio_pitchspecacf_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCHSPECACF_H */ diff --git a/deps/aubio/src/pitch/pitchyin.c b/deps/aubio/src/pitch/pitchyin.c new file mode 100644 index 0000000..85b4566 --- /dev/null +++ b/deps/aubio/src/pitch/pitchyin.c @@ -0,0 +1,189 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/* This algorithm was developed by A. de Cheveigné and H. Kawahara and + * published in: + * + * de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency + * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930. + * + * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html + */ + +#include "aubio_priv.h" +#include "fvec.h" +#include "mathutils.h" +#include "pitch/pitchyin.h" + +struct _aubio_pitchyin_t +{ + fvec_t *yin; + smpl_t tol; + uint_t peak_pos; +}; + +#if 0 +/** compute difference function + + \param input input signal + \param yinbuf output buffer to store difference function (half shorter than input) + +*/ +void aubio_pitchyin_diff (fvec_t * input, fvec_t * yinbuf); + +/** in place computation of the YIN cumulative normalised function + + \param yinbuf input signal (a square difference function), also used to store function + +*/ +void aubio_pitchyin_getcum (fvec_t * yinbuf); + +/** detect pitch in a YIN function + + \param yinbuf input buffer as computed by aubio_pitchyin_getcum + +*/ +uint_t aubio_pitchyin_getpitch (const fvec_t * yinbuf); +#endif + +aubio_pitchyin_t * +new_aubio_pitchyin (uint_t bufsize) +{ + aubio_pitchyin_t *o = AUBIO_NEW (aubio_pitchyin_t); + o->yin = new_fvec (bufsize / 2); + o->tol = 0.15; + o->peak_pos = 0; + return o; +} + +void +del_aubio_pitchyin (aubio_pitchyin_t * o) +{ + del_fvec (o->yin); + AUBIO_FREE (o); +} + +#if 0 +/* outputs the difference function */ +void +aubio_pitchyin_diff (fvec_t * input, fvec_t * yin) +{ + uint_t j, tau; + smpl_t tmp; + for (tau = 0; tau < yin->length; tau++) { + yin->data[tau] = 0.; + } + for (tau = 1; tau < yin->length; tau++) { + for (j = 0; j < yin->length; j++) { + tmp = input->data[j] - input->data[j + tau]; + yin->data[tau] += SQR (tmp); + } + } +} + +/* cumulative mean normalized difference function */ +void +aubio_pitchyin_getcum (fvec_t * yin) +{ + uint_t tau; + smpl_t tmp = 0.; + yin->data[0] = 1.; + //AUBIO_DBG("%f\t",yin->data[0]); + for (tau = 1; tau < yin->length; tau++) { + tmp += yin->data[tau]; + yin->data[tau] *= tau / tmp; + //AUBIO_DBG("%f\t",yin->data[tau]); + } + //AUBIO_DBG("\n"); +} + +uint_t +aubio_pitchyin_getpitch (const fvec_t * yin) +{ + uint_t tau = 1; + do { + if (yin->data[tau] < 0.1) { + while (yin->data[tau + 1] < yin->data[tau]) { + tau++; + } + return tau; + } + tau++; + } while (tau < yin->length); + //AUBIO_DBG("No pitch found"); + return 0; +} +#endif + +/* all the above in one */ +void +aubio_pitchyin_do (aubio_pitchyin_t * o, const fvec_t * input, fvec_t * out) +{ + const smpl_t tol = o->tol; + fvec_t* yin = o->yin; + const smpl_t *input_data = input->data; + const uint_t length = yin->length; + smpl_t *yin_data = yin->data; + uint_t j, tau; + sint_t period; + smpl_t tmp, tmp2 = 0.; + + yin_data[0] = 1.; + for (tau = 1; tau < length; tau++) { + yin_data[tau] = 0.; + for (j = 0; j < length; j++) { + tmp = input_data[j] - input_data[j + tau]; + yin_data[tau] += SQR (tmp); + } + tmp2 += yin_data[tau]; + if (tmp2 != 0) { + yin->data[tau] *= tau / tmp2; + } else { + yin->data[tau] = 1.; + } + period = tau - 3; + if (tau > 4 && (yin_data[period] < tol) && + (yin_data[period] < yin_data[period + 1])) { + o->peak_pos = (uint_t)period; + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); + return; + } + } + o->peak_pos = (uint_t)fvec_min_elem (yin); + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); +} + +smpl_t +aubio_pitchyin_get_confidence (aubio_pitchyin_t * o) { + return 1. - o->yin->data[o->peak_pos]; +} + +uint_t +aubio_pitchyin_set_tolerance (aubio_pitchyin_t * o, smpl_t tol) +{ + o->tol = tol; + return 0; +} + +smpl_t +aubio_pitchyin_get_tolerance (aubio_pitchyin_t * o) +{ + return o->tol; +} diff --git a/deps/aubio/src/pitch/pitchyin.h b/deps/aubio/src/pitch/pitchyin.h new file mode 100644 index 0000000..fa32b8d --- /dev/null +++ b/deps/aubio/src/pitch/pitchyin.h @@ -0,0 +1,100 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Pitch detection using the YIN algorithm + + This algorithm was developed by A. de Cheveigne and H. Kawahara and + published in: + + De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency + estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930. + + see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html + http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf + + \example pitch/test-pitchyin.c + +*/ + +#ifndef AUBIO_PITCHYIN_H +#define AUBIO_PITCHYIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchyin_t aubio_pitchyin_t; + +/** creation of the pitch detection object + + \param buf_size size of the input buffer to analyse + +*/ +aubio_pitchyin_t *new_aubio_pitchyin (uint_t buf_size); + +/** deletion of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitchyin() + +*/ +void del_aubio_pitchyin (aubio_pitchyin_t * o); + +/** execute pitch detection an input buffer + + \param o pitch detection object as returned by new_aubio_pitchyin() + \param samples_in input signal vector (length as specified at creation time) + \param cands_out pitch period candidates, in samples + +*/ +void aubio_pitchyin_do (aubio_pitchyin_t * o, const fvec_t * samples_in, fvec_t * cands_out); + + +/** set tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + \param tol tolerance parameter for minima selection [default 0.15] + +*/ +uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t * o, smpl_t tol); + +/** get tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + \return tolerance parameter for minima selection [default 0.15] + +*/ +smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t * o); + +/** get current confidence of YIN algorithm + + \param o YIN pitch detection object + \return confidence parameter + +*/ +smpl_t aubio_pitchyin_get_confidence (aubio_pitchyin_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCHYIN_H */ diff --git a/deps/aubio/src/pitch/pitchyinfast.c b/deps/aubio/src/pitch/pitchyinfast.c new file mode 100644 index 0000000..b2dcadc --- /dev/null +++ b/deps/aubio/src/pitch/pitchyinfast.c @@ -0,0 +1,201 @@ +/* + Copyright (C) 2003-2017 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/* This algorithm was developed by A. de Cheveigné and H. Kawahara and + * published in: + * + * de Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency + * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930. + * + * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html + */ + +#include "aubio_priv.h" +#include "fvec.h" +#include "mathutils.h" +#include "cvec.h" +#include "spectral/fft.h" +#include "pitch/pitchyinfast.h" + +struct _aubio_pitchyinfast_t +{ + fvec_t *yin; + smpl_t tol; + uint_t peak_pos; + fvec_t *tmpdata; + fvec_t *sqdiff; + fvec_t *kernel; + fvec_t *samples_fft; + fvec_t *kernel_fft; + aubio_fft_t *fft; +}; + +aubio_pitchyinfast_t * +new_aubio_pitchyinfast (uint_t bufsize) +{ + aubio_pitchyinfast_t *o = AUBIO_NEW (aubio_pitchyinfast_t); + o->yin = new_fvec (bufsize / 2); + o->tmpdata = new_fvec (bufsize); + o->sqdiff = new_fvec (bufsize / 2); + o->kernel = new_fvec (bufsize); + o->samples_fft = new_fvec (bufsize); + o->kernel_fft = new_fvec (bufsize); + o->fft = new_aubio_fft (bufsize); + if (!o->yin || !o->tmpdata || !o->tmpdata || !o->sqdiff + || !o->kernel || !o->samples_fft || !o->kernel || !o->fft) + { + del_aubio_pitchyinfast(o); + return NULL; + } + o->tol = 0.15; + o->peak_pos = 0; + return o; +} + +void +del_aubio_pitchyinfast (aubio_pitchyinfast_t * o) +{ + if (o->yin) + del_fvec (o->yin); + if (o->tmpdata) + del_fvec (o->tmpdata); + if (o->sqdiff) + del_fvec (o->sqdiff); + if (o->kernel) + del_fvec (o->kernel); + if (o->samples_fft) + del_fvec (o->samples_fft); + if (o->kernel_fft) + del_fvec (o->kernel_fft); + if (o->fft) + del_aubio_fft (o->fft); + AUBIO_FREE (o); +} + +/* all the above in one */ +void +aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * input, fvec_t * out) +{ + const smpl_t tol = o->tol; + fvec_t* yin = o->yin; + const uint_t length = yin->length; + uint_t B = o->tmpdata->length; + uint_t W = o->yin->length; // B / 2 + fvec_t tmp_slice, kernel_ptr; + uint_t tau; + sint_t period; + smpl_t tmp2 = 0.; + + // compute r_t(0) + r_t+tau(0) + { + fvec_t *squares = o->tmpdata; + fvec_weighted_copy(input, input, squares); +#if 0 + for (tau = 0; tau < W; tau++) { + tmp_slice.data = squares->data + tau; + tmp_slice.length = W; + o->sqdiff->data[tau] = fvec_sum(&tmp_slice); + } +#else + tmp_slice.data = squares->data; + tmp_slice.length = W; + o->sqdiff->data[0] = fvec_sum(&tmp_slice); + for (tau = 1; tau < W; tau++) { + o->sqdiff->data[tau] = o->sqdiff->data[tau-1]; + o->sqdiff->data[tau] -= squares->data[tau-1]; + o->sqdiff->data[tau] += squares->data[W+tau-1]; + } +#endif + fvec_add(o->sqdiff, o->sqdiff->data[0]); + } + // compute r_t(tau) = -2.*ifft(fft(samples)*fft(samples[W-1::-1])) + { + fvec_t *compmul = o->tmpdata; + fvec_t *rt_of_tau = o->samples_fft; + aubio_fft_do_complex(o->fft, input, o->samples_fft); + // build kernel, take a copy of first half of samples + tmp_slice.data = input->data; + tmp_slice.length = W; + kernel_ptr.data = o->kernel->data + 1; + kernel_ptr.length = W; + fvec_copy(&tmp_slice, &kernel_ptr); + // reverse them + fvec_rev(&kernel_ptr); + // compute fft(kernel) + aubio_fft_do_complex(o->fft, o->kernel, o->kernel_fft); + // compute complex product + compmul->data[0] = o->kernel_fft->data[0] * o->samples_fft->data[0]; + for (tau = 1; tau < W; tau++) { + compmul->data[tau] = o->kernel_fft->data[tau] * o->samples_fft->data[tau]; + compmul->data[tau] -= o->kernel_fft->data[B-tau] * o->samples_fft->data[B-tau]; + } + compmul->data[W] = o->kernel_fft->data[W] * o->samples_fft->data[W]; + for (tau = 1; tau < W; tau++) { + compmul->data[B-tau] = o->kernel_fft->data[B-tau] * o->samples_fft->data[tau]; + compmul->data[B-tau] += o->kernel_fft->data[tau] * o->samples_fft->data[B-tau]; + } + // compute inverse fft + aubio_fft_rdo_complex(o->fft, compmul, rt_of_tau); + // compute square difference r_t(tau) = sqdiff - 2 * r_t_tau[W-1:-1] + for (tau = 0; tau < W; tau++) { + yin->data[tau] = o->sqdiff->data[tau] - 2. * rt_of_tau->data[tau+W]; + } + } + + // now build yin and look for first minimum + fvec_zeros(out); + yin->data[0] = 1.; + for (tau = 1; tau < length; tau++) { + tmp2 += yin->data[tau]; + if (tmp2 != 0) { + yin->data[tau] *= tau / tmp2; + } else { + yin->data[tau] = 1.; + } + period = tau - 3; + if (tau > 4 && (yin->data[period] < tol) && + (yin->data[period] < yin->data[period + 1])) { + o->peak_pos = (uint_t)period; + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); + return; + } + } + // use global minimum + o->peak_pos = (uint_t)fvec_min_elem (yin); + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); +} + +smpl_t +aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o) { + return 1. - o->yin->data[o->peak_pos]; +} + +uint_t +aubio_pitchyinfast_set_tolerance (aubio_pitchyinfast_t * o, smpl_t tol) +{ + o->tol = tol; + return 0; +} + +smpl_t +aubio_pitchyinfast_get_tolerance (aubio_pitchyinfast_t * o) +{ + return o->tol; +} diff --git a/deps/aubio/src/pitch/pitchyinfast.h b/deps/aubio/src/pitch/pitchyinfast.h new file mode 100644 index 0000000..abb8139 --- /dev/null +++ b/deps/aubio/src/pitch/pitchyinfast.h @@ -0,0 +1,102 @@ +/* + Copyright (C) 2003-2017 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Pitch detection using YIN algorithm (fast implementation) + + This algorithm was developed by A. de Cheveigne and H. Kawahara and + published in: + + De Cheveigné, A., Kawahara, H. (2002) "YIN, a fundamental frequency + estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930. + + This implementation compute the autocorrelation function using time domain + convolution computed in the spectral domain. + + see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html + http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf + +*/ + +#ifndef AUBIO_PITCHYINFAST_H +#define AUBIO_PITCHYINFAST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchyinfast_t aubio_pitchyinfast_t; + +/** creation of the pitch detection object + + \param buf_size size of the input buffer to analyse + +*/ +aubio_pitchyinfast_t *new_aubio_pitchyinfast (uint_t buf_size); + +/** deletion of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitchyin() + +*/ +void del_aubio_pitchyinfast (aubio_pitchyinfast_t * o); + +/** execute pitch detection an input buffer + + \param o pitch detection object as returned by new_aubio_pitchyin() + \param samples_in input signal vector (length as specified at creation time) + \param cands_out pitch period candidates, in samples + +*/ +void aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * samples_in, fvec_t * cands_out); + + +/** set tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + \param tol tolerance parameter for minima selection [default 0.15] + +*/ +uint_t aubio_pitchyinfast_set_tolerance (aubio_pitchyinfast_t * o, smpl_t tol); + +/** get tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + \return tolerance parameter for minima selection [default 0.15] + +*/ +smpl_t aubio_pitchyinfast_get_tolerance (aubio_pitchyinfast_t * o); + +/** get current confidence of YIN algorithm + + \param o YIN pitch detection object + \return confidence parameter + +*/ +smpl_t aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCHYINFAST_H */ + diff --git a/deps/aubio/src/pitch/pitchyinfft.c b/deps/aubio/src/pitch/pitchyinfft.c new file mode 100644 index 0000000..b613f60 --- /dev/null +++ b/deps/aubio/src/pitch/pitchyinfft.c @@ -0,0 +1,208 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/fft.h" +#include "pitch/pitchyinfft.h" + +/** pitch yinfft structure */ +struct _aubio_pitchyinfft_t +{ + fvec_t *win; /**< temporal weighting window */ + fvec_t *winput; /**< windowed spectrum */ + fvec_t *sqrmag; /**< square difference function */ + fvec_t *weight; /**< spectral weighting window (psychoacoustic model) */ + fvec_t *fftout; /**< Fourier transform output */ + aubio_fft_t *fft; /**< fft object to compute square difference function */ + fvec_t *yinfft; /**< Yin function */ + smpl_t tol; /**< Yin tolerance */ + uint_t peak_pos; /**< currently selected peak pos*/ + uint_t short_period; /** shortest period under which to check for octave error */ +}; + +static const smpl_t freqs[] = { + 0., 20., 25., 31.5, 40., 50., 63., 80., 100., 125., + 160., 200., 250., 315., 400., 500., 630., 800., 1000., 1250., + 1600., 2000., 2500., 3150., 4000., 5000., 6300., 8000., 9000., 10000., + 12500., 15000., 20000., 25100., -1. +}; + +static const smpl_t weight[] = { + -75.8, -70.1, -60.8, -52.1, -44.2, -37.5, -31.3, -25.6, -20.9, -16.5, + -12.6, -9.60, -7.00, -4.70, -3.00, -1.80, -0.80, -0.20, -0.00, 0.50, + 1.60, 3.20, 5.40, 7.80, 8.10, 5.30, -2.40, -11.1, -12.8, -12.2, + -7.40, -17.8, -17.8, -17.8 +}; + +aubio_pitchyinfft_t * +new_aubio_pitchyinfft (uint_t samplerate, uint_t bufsize) +{ + uint_t i = 0, j = 1; + smpl_t freq = 0, a0 = 0, a1 = 0, f0 = 0, f1 = 0; + aubio_pitchyinfft_t *p = AUBIO_NEW (aubio_pitchyinfft_t); + p->winput = new_fvec (bufsize); + p->fft = new_aubio_fft (bufsize); + if (!p->fft) goto beach; + p->fftout = new_fvec (bufsize); + p->sqrmag = new_fvec (bufsize); + p->yinfft = new_fvec (bufsize / 2 + 1); + p->tol = 0.85; + p->peak_pos = 0; + p->win = new_aubio_window ("hanningz", bufsize); + p->weight = new_fvec (bufsize / 2 + 1); + for (i = 0; i < p->weight->length; i++) { + freq = (smpl_t) i / (smpl_t) bufsize *(smpl_t) samplerate; + while (freq > freqs[j] && freqs[j] > 0) { + //AUBIO_DBG("freq %3.5f > %3.5f \tsamplerate %d (Hz) \t" + // "(weight length %d, bufsize %d) %d %d\n", freq, freqs[j], + // samplerate, p->weight->length, bufsize, i, j); + j += 1; + } + a0 = weight[j - 1]; + f0 = freqs[j - 1]; + a1 = weight[j]; + f1 = freqs[j]; + if (f0 == f1) { // just in case + p->weight->data[i] = a0; + } else if (f0 == 0) { // y = ax+b + p->weight->data[i] = (a1 - a0) / f1 * freq + a0; + } else { + p->weight->data[i] = (a1 - a0) / (f1 - f0) * freq + + (a0 - (a1 - a0) / (f1 / f0 - 1.)); + } + while (freq > freqs[j]) { + j += 1; + } + //AUBIO_DBG("%f\n",p->weight->data[i]); + p->weight->data[i] = DB2LIN (p->weight->data[i]); + //p->weight->data[i] = SQRT(DB2LIN(p->weight->data[i])); + } + // check for octave errors above 1300 Hz + p->short_period = (uint_t)ROUND(samplerate / 1300.); + return p; + +beach: + if (p->winput) del_fvec(p->winput); + AUBIO_FREE(p); + return NULL; +} + +void +aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, const fvec_t * input, fvec_t * output) +{ + uint_t tau, l; + uint_t length = p->fftout->length; + uint_t halfperiod; + fvec_t *fftout = p->fftout; + fvec_t *yin = p->yinfft; + smpl_t tmp = 0., sum = 0.; + // window the input + fvec_weighted_copy(input, p->win, p->winput); + // get the real / imag parts of its fft + aubio_fft_do_complex (p->fft, p->winput, fftout); + // get the squared magnitude spectrum, applying some weight + p->sqrmag->data[0] = SQR(fftout->data[0]); + p->sqrmag->data[0] *= p->weight->data[0]; + for (l = 1; l < length / 2; l++) { + p->sqrmag->data[l] = SQR(fftout->data[l]) + SQR(fftout->data[length - l]); + p->sqrmag->data[l] *= p->weight->data[l]; + p->sqrmag->data[length - l] = p->sqrmag->data[l]; + } + p->sqrmag->data[length / 2] = SQR(fftout->data[length / 2]); + p->sqrmag->data[length / 2] *= p->weight->data[length / 2]; + // get sum of weighted squared mags + for (l = 0; l < length / 2 + 1; l++) { + sum += p->sqrmag->data[l]; + } + sum *= 2.; + // get the real / imag parts of the fft of the squared magnitude + aubio_fft_do_complex (p->fft, p->sqrmag, fftout); + yin->data[0] = 1.; + for (tau = 1; tau < yin->length; tau++) { + // compute the square differences + yin->data[tau] = sum - fftout->data[tau]; + // and the cumulative mean normalized difference function + tmp += yin->data[tau]; + if (tmp != 0) { + yin->data[tau] *= tau / tmp; + } else { + yin->data[tau] = 1.; + } + } + // find best candidates + tau = fvec_min_elem (yin); + if (yin->data[tau] < p->tol) { + // no interpolation, directly return the period as an integer + //output->data[0] = tau; + //return; + + // 3 point quadratic interpolation + //return fvec_quadratic_peak_pos (yin,tau,1); + /* additional check for (unlikely) octave doubling in higher frequencies */ + if (tau > p->short_period) { + output->data[0] = fvec_quadratic_peak_pos (yin, tau); + } else { + /* should compare the minimum value of each interpolated peaks */ + halfperiod = FLOOR (tau / 2 + .5); + if (yin->data[halfperiod] < p->tol) + p->peak_pos = halfperiod; + else + p->peak_pos = tau; + output->data[0] = fvec_quadratic_peak_pos (yin, p->peak_pos); + } + } else { + p->peak_pos = 0; + output->data[0] = 0.; + } +} + +void +del_aubio_pitchyinfft (aubio_pitchyinfft_t * p) +{ + del_fvec (p->win); + del_aubio_fft (p->fft); + del_fvec (p->yinfft); + del_fvec (p->sqrmag); + del_fvec (p->fftout); + del_fvec (p->winput); + del_fvec (p->weight); + AUBIO_FREE (p); +} + +smpl_t +aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o) { + return 1. - o->yinfft->data[o->peak_pos]; +} + +uint_t +aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * p, smpl_t tol) +{ + p->tol = tol; + return 0; +} + +smpl_t +aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * p) +{ + return p->tol; +} diff --git a/deps/aubio/src/pitch/pitchyinfft.h b/deps/aubio/src/pitch/pitchyinfft.h new file mode 100644 index 0000000..ccd4e51 --- /dev/null +++ b/deps/aubio/src/pitch/pitchyinfft.h @@ -0,0 +1,99 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Pitch detection using a spectral implementation of the YIN algorithm + + This algorithm was derived from the YIN algorithm. In this implementation, a + Fourier transform is used to compute a tapered square difference function, + which allows spectral weighting. Because the difference function is tapered, + the selection of the period is simplified. + + Paul Brossier, [Automatic annotation of musical audio for interactive + systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis, + Centre for Digital music, Queen Mary University of London, London, UK, 2006. + + \example pitch/test-pitchyinfft.c + +*/ + +#ifndef AUBIO_PITCHYINFFT_H +#define AUBIO_PITCHYINFFT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** pitch detection object */ +typedef struct _aubio_pitchyinfft_t aubio_pitchyinfft_t; + +/** execute pitch detection on an input buffer + + \param o pitch detection object as returned by new_aubio_pitchyinfft + \param samples_in input signal vector (length as specified at creation time) + \param cands_out pitch period candidates, in samples + +*/ +void aubio_pitchyinfft_do (aubio_pitchyinfft_t * o, const fvec_t * samples_in, fvec_t * cands_out); +/** creation of the pitch detection object + + \param samplerate samplerate of the input signal + \param buf_size size of the input buffer to analyse + +*/ +aubio_pitchyinfft_t *new_aubio_pitchyinfft (uint_t samplerate, uint_t buf_size); +/** deletion of the pitch detection object + + \param o pitch detection object as returned by new_aubio_pitchyinfft() + +*/ +void del_aubio_pitchyinfft (aubio_pitchyinfft_t * o); + +/** get tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + + \return tolerance parameter for minima selection [default 0.15] + +*/ +smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * o); + +/** set tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + \param tol tolerance parameter for minima selection [default 0.15] + +*/ +uint_t aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * o, smpl_t tol); + +/** get current confidence of YIN algorithm + + \param o YIN pitch detection object + \return confidence parameter + +*/ +smpl_t aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PITCHYINFFT_H */ diff --git a/deps/aubio/src/spectral/fft.c b/deps/aubio/src/spectral/fft.c new file mode 100644 index 0000000..679231a --- /dev/null +++ b/deps/aubio/src/spectral/fft.c @@ -0,0 +1,582 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/fft.h" + +#ifdef HAVE_FFTW3 // using FFTW3 +/* note that is not included here but only in aubio_priv.h, so that + * c++ projects can still use their own complex definition. */ +#include +#include + +#ifdef HAVE_COMPLEX_H +#ifdef HAVE_FFTW3F +/** fft data type with complex.h and fftw3f */ +#define FFTW_TYPE fftwf_complex +#else +/** fft data type with complex.h and fftw3 */ +#define FFTW_TYPE fftw_complex +#endif +#else +#ifdef HAVE_FFTW3F +/** fft data type without complex.h and with fftw3f */ +#define FFTW_TYPE float +#else +/** fft data type without complex.h and with fftw */ +#define FFTW_TYPE double +#endif +#endif + +/** fft data type */ +typedef FFTW_TYPE fft_data_t; + +#ifdef HAVE_FFTW3F +#define fftw_malloc fftwf_malloc +#define fftw_free fftwf_free +#define fftw_execute fftwf_execute +#define fftw_plan_dft_r2c_1d fftwf_plan_dft_r2c_1d +#define fftw_plan_dft_c2r_1d fftwf_plan_dft_c2r_1d +#define fftw_plan_r2r_1d fftwf_plan_r2r_1d +#define fftw_plan fftwf_plan +#define fftw_destroy_plan fftwf_destroy_plan +#endif + +#ifdef HAVE_FFTW3F +#if HAVE_AUBIO_DOUBLE +#error "Using aubio in double precision with fftw3 in single precision" +#endif /* HAVE_AUBIO_DOUBLE */ +#define real_t float +#elif defined (HAVE_FFTW3) /* HAVE_FFTW3F */ +#if !HAVE_AUBIO_DOUBLE +#error "Using aubio in single precision with fftw3 in double precision" +#endif /* HAVE_AUBIO_DOUBLE */ +#define real_t double +#endif /* HAVE_FFTW3F */ + +#ifndef __MOD_DEVICES__ +// a global mutex for FFTW thread safety +pthread_mutex_t aubio_fftw_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +#elif defined HAVE_ACCELERATE // using ACCELERATE +// https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html +#include + +#if !HAVE_AUBIO_DOUBLE +#define aubio_vDSP_ctoz vDSP_ctoz +#define aubio_vDSP_fft_zrip vDSP_fft_zrip +#define aubio_vDSP_ztoc vDSP_ztoc +#define aubio_vDSP_zvmags vDSP_zvmags +#define aubio_vDSP_zvphas vDSP_zvphas +#define aubio_vDSP_vsadd vDSP_vsadd +#define aubio_vDSP_vsmul vDSP_vsmul +#define aubio_DSPComplex DSPComplex +#define aubio_DSPSplitComplex DSPSplitComplex +#define aubio_vDSP_DFT_Setup vDSP_DFT_Setup +#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetup +#define aubio_vDSP_DFT_Execute vDSP_DFT_Execute +#define aubio_vDSP_DFT_DestroySetup vDSP_DFT_DestroySetup +#define aubio_vvsqrt vvsqrtf +#else +#define aubio_vDSP_ctoz vDSP_ctozD +#define aubio_vDSP_fft_zrip vDSP_fft_zripD +#define aubio_vDSP_ztoc vDSP_ztocD +#define aubio_vDSP_zvmags vDSP_zvmagsD +#define aubio_vDSP_zvphas vDSP_zvphasD +#define aubio_vDSP_vsadd vDSP_vsaddD +#define aubio_vDSP_vsmul vDSP_vsmulD +#define aubio_DSPComplex DSPDoubleComplex +#define aubio_DSPSplitComplex DSPDoubleSplitComplex +#define aubio_vDSP_DFT_Setup vDSP_DFT_SetupD +#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetupD +#define aubio_vDSP_DFT_Execute vDSP_DFT_ExecuteD +#define aubio_vDSP_DFT_DestroySetup vDSP_DFT_DestroySetupD +#define aubio_vvsqrt vvsqrt +#endif /* HAVE_AUBIO_DOUBLE */ + +#elif defined HAVE_INTEL_IPP // using INTEL IPP + +#if !HAVE_AUBIO_DOUBLE +#define aubio_IppFloat Ipp32f +#define aubio_IppComplex Ipp32fc +#define aubio_FFTSpec FFTSpec_R_32f +#define aubio_ippsMalloc_complex ippsMalloc_32fc +#define aubio_ippsFFTInit_R ippsFFTInit_R_32f +#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_32f +#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_32f +#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_32f +#define aubio_ippsAtan2 ippsAtan2_32f_A21 +#else /* HAVE_AUBIO_DOUBLE */ +#define aubio_IppFloat Ipp64f +#define aubio_IppComplex Ipp64fc +#define aubio_FFTSpec FFTSpec_R_64f +#define aubio_ippsMalloc_complex ippsMalloc_64fc +#define aubio_ippsFFTInit_R ippsFFTInit_R_64f +#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_64f +#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_64f +#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_64f +#define aubio_ippsAtan2 ippsAtan2_64f_A50 +#endif + + +#else // using OOURA +// let's use ooura instead +extern void aubio_ooura_rdft(int, int, smpl_t *, int *, smpl_t *); + +#endif + +struct _aubio_fft_t { + uint_t winsize; + uint_t fft_size; + +#ifdef HAVE_FFTW3 // using FFTW3 + real_t *in, *out; + fftw_plan pfw, pbw; + fft_data_t * specdata; /* complex spectral data */ + +#elif defined HAVE_ACCELERATE // using ACCELERATE + aubio_vDSP_DFT_Setup fftSetupFwd; + aubio_vDSP_DFT_Setup fftSetupBwd; + aubio_DSPSplitComplex spec; + smpl_t *in, *out; + +#elif defined HAVE_INTEL_IPP // using Intel IPP + smpl_t *in, *out; + Ipp8u* memSpec; + Ipp8u* memInit; + Ipp8u* memBuffer; + struct aubio_FFTSpec* fftSpec; + aubio_IppComplex* complexOut; +#else // using OOURA + smpl_t *in, *out; + smpl_t *w; + int *ip; +#endif /* using OOURA */ + + fvec_t * compspec; +}; + +aubio_fft_t * new_aubio_fft (uint_t winsize) { + aubio_fft_t * s = AUBIO_NEW(aubio_fft_t); + if ((sint_t)winsize < 2) { + AUBIO_ERR("fft: got winsize %d, but can not be < 2\n", winsize); + goto beach; + } + +#ifdef HAVE_FFTW3 + uint_t i; + s->winsize = winsize; + /* allocate memory */ + s->in = AUBIO_ARRAY(real_t,winsize); + s->out = AUBIO_ARRAY(real_t,winsize); + s->compspec = new_fvec(winsize); + /* create plans */ +#ifndef __MOD_DEVICES__ + pthread_mutex_lock(&aubio_fftw_mutex); +#endif +#ifdef HAVE_COMPLEX_H + s->fft_size = winsize/2 + 1; + s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); + s->pfw = fftw_plan_dft_r2c_1d(winsize, s->in, s->specdata, FFTW_ESTIMATE); + s->pbw = fftw_plan_dft_c2r_1d(winsize, s->specdata, s->out, FFTW_ESTIMATE); +#else + s->fft_size = winsize; + s->specdata = (fft_data_t*)fftw_malloc(sizeof(fft_data_t)*s->fft_size); + s->pfw = fftw_plan_r2r_1d(winsize, s->in, s->specdata, FFTW_R2HC, FFTW_ESTIMATE); + s->pbw = fftw_plan_r2r_1d(winsize, s->specdata, s->out, FFTW_HC2R, FFTW_ESTIMATE); +#endif +#ifndef __MOD_DEVICES__ + pthread_mutex_unlock(&aubio_fftw_mutex); +#endif + for (i = 0; i < s->winsize; i++) { + s->in[i] = 0.; + s->out[i] = 0.; + } + for (i = 0; i < s->fft_size; i++) { + s->specdata[i] = 0.; + } + +#elif defined HAVE_ACCELERATE // using ACCELERATE + { + uint_t radix = winsize; + uint_t order = 0; + while ((radix / 2) * 2 == radix) { + radix /= 2; + order++; + } + if (order < 4 || (radix != 1 && radix != 3 && radix != 5 && radix != 15)) { + AUBIO_ERR("fft: vDSP/Accelerate supports FFT with sizes = " + "f * 2 ** n, where n > 4 and f in [1, 3, 5, 15], but requested %d. " + "Use the closest power of two, or try recompiling aubio with " + "--enable-fftw3.\n", winsize); + goto beach; + } + } + s->winsize = winsize; + s->fft_size = winsize; + s->compspec = new_fvec(winsize); + s->in = AUBIO_ARRAY(smpl_t, s->fft_size); + s->out = AUBIO_ARRAY(smpl_t, s->fft_size); + s->spec.realp = AUBIO_ARRAY(smpl_t, s->fft_size/2); + s->spec.imagp = AUBIO_ARRAY(smpl_t, s->fft_size/2); + s->fftSetupFwd = aubio_vDSP_DFT_zrop_CreateSetup(NULL, + s->fft_size, vDSP_DFT_FORWARD); + s->fftSetupBwd = aubio_vDSP_DFT_zrop_CreateSetup(s->fftSetupFwd, + s->fft_size, vDSP_DFT_INVERSE); + +#elif defined HAVE_INTEL_IPP // using Intel IPP + const IppHintAlgorithm qualityHint = ippAlgHintAccurate; // OR ippAlgHintFast; + const int flags = IPP_FFT_NODIV_BY_ANY; // we're scaling manually afterwards + int order = aubio_power_of_two_order(winsize); + int sizeSpec, sizeInit, sizeBuffer; + IppStatus status; + + if (winsize <= 4 || aubio_is_power_of_two(winsize) != 1) + { + AUBIO_ERR("intel IPP fft: can only create with sizes > 4 and power of two, requested %d," + " try recompiling aubio with --enable-fftw3\n", winsize); + goto beach; + } + + status = aubio_ippsFFTGetSize_R(order, flags, qualityHint, + &sizeSpec, &sizeInit, &sizeBuffer); + if (status != ippStsNoErr) { + AUBIO_ERR("fft: failed to initialize fft. IPP error: %d\n", status); + goto beach; + } + s->fft_size = s->winsize = winsize; + s->compspec = new_fvec(winsize); + s->in = AUBIO_ARRAY(smpl_t, s->winsize); + s->out = AUBIO_ARRAY(smpl_t, s->winsize); + s->memSpec = ippsMalloc_8u(sizeSpec); + s->memBuffer = ippsMalloc_8u(sizeBuffer); + if (sizeInit > 0 ) { + s->memInit = ippsMalloc_8u(sizeInit); + } + s->complexOut = aubio_ippsMalloc_complex(s->fft_size / 2 + 1); + status = aubio_ippsFFTInit_R( + &s->fftSpec, order, flags, qualityHint, s->memSpec, s->memInit); + if (status != ippStsNoErr) { + AUBIO_ERR("fft: failed to initialize. IPP error: %d\n", status); + goto beach; + } + +#else // using OOURA + if (aubio_is_power_of_two(winsize) != 1) { + AUBIO_ERR("fft: can only create with sizes power of two, requested %d," + " try recompiling aubio with --enable-fftw3\n", winsize); + goto beach; + } + s->winsize = winsize; + s->fft_size = winsize / 2 + 1; + s->compspec = new_fvec(winsize); + s->in = AUBIO_ARRAY(smpl_t, s->winsize); + s->out = AUBIO_ARRAY(smpl_t, s->winsize); + s->ip = AUBIO_ARRAY(int , s->fft_size); + s->w = AUBIO_ARRAY(smpl_t, s->fft_size); + s->ip[0] = 0; +#endif /* using OOURA */ + + return s; + +beach: + AUBIO_FREE(s); + return NULL; +} + +void del_aubio_fft(aubio_fft_t * s) { + /* destroy data */ +#ifdef HAVE_FFTW3 // using FFTW3 +#ifndef __MOD_DEVICES__ + pthread_mutex_lock(&aubio_fftw_mutex); +#endif + fftw_destroy_plan(s->pfw); + fftw_destroy_plan(s->pbw); + fftw_free(s->specdata); +#ifndef __MOD_DEVICES__ + pthread_mutex_unlock(&aubio_fftw_mutex); +#endif + +#elif defined HAVE_ACCELERATE // using ACCELERATE + AUBIO_FREE(s->spec.realp); + AUBIO_FREE(s->spec.imagp); + aubio_vDSP_DFT_DestroySetup(s->fftSetupBwd); + aubio_vDSP_DFT_DestroySetup(s->fftSetupFwd); + +#elif defined HAVE_INTEL_IPP // using Intel IPP + ippFree(s->memSpec); + ippFree(s->memInit); + ippFree(s->memBuffer); + ippFree(s->complexOut); + +#else // using OOURA + AUBIO_FREE(s->w); + AUBIO_FREE(s->ip); +#endif + + del_fvec(s->compspec); + AUBIO_FREE(s->in); + AUBIO_FREE(s->out); + AUBIO_FREE(s); +} + +void aubio_fft_do(aubio_fft_t * s, const fvec_t * input, cvec_t * spectrum) { + aubio_fft_do_complex(s, input, s->compspec); + aubio_fft_get_spectrum(s->compspec, spectrum); +} + +void aubio_fft_rdo(aubio_fft_t * s, const cvec_t * spectrum, fvec_t * output) { + aubio_fft_get_realimag(spectrum, s->compspec); + aubio_fft_rdo_complex(s, s->compspec, output); +} + +void aubio_fft_do_complex(aubio_fft_t * s, const fvec_t * input, fvec_t * compspec) { + uint_t i; +#ifndef HAVE_MEMCPY_HACKS + for (i=0; i < s->winsize; i++) { + s->in[i] = input->data[i]; + } +#else + memcpy(s->in, input->data, s->winsize * sizeof(smpl_t)); +#endif /* HAVE_MEMCPY_HACKS */ + +#ifdef HAVE_FFTW3 // using FFTW3 + fftw_execute(s->pfw); +#ifdef HAVE_COMPLEX_H + compspec->data[0] = REAL(s->specdata[0]); + for (i = 1; i < s->fft_size -1 ; i++) { + compspec->data[i] = REAL(s->specdata[i]); + compspec->data[compspec->length - i] = IMAG(s->specdata[i]); + } + compspec->data[s->fft_size-1] = REAL(s->specdata[s->fft_size-1]); +#else /* HAVE_COMPLEX_H */ + for (i = 0; i < s->fft_size; i++) { + compspec->data[i] = s->specdata[i]; + } +#endif /* HAVE_COMPLEX_H */ + +#elif defined HAVE_ACCELERATE // using ACCELERATE + // convert real data to even/odd format used in vDSP + aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2); + // compute the FFT + aubio_vDSP_DFT_Execute(s->fftSetupFwd, s->spec.realp, s->spec.imagp, + s->spec.realp, s->spec.imagp); + // convert from vDSP complex split to [ r0, r1, ..., rN, iN-1, .., i2, i1] + compspec->data[0] = s->spec.realp[0]; + compspec->data[s->fft_size / 2] = s->spec.imagp[0]; + for (i = 1; i < s->fft_size / 2; i++) { + compspec->data[i] = s->spec.realp[i]; + compspec->data[s->fft_size - i] = s->spec.imagp[i]; + } + // apply scaling + smpl_t scale = 1./2.; + aubio_vDSP_vsmul(compspec->data, 1, &scale, compspec->data, 1, s->fft_size); + +#elif defined HAVE_INTEL_IPP // using Intel IPP + + // apply fft + aubio_ippsFFTFwd_RToCCS(s->in, (aubio_IppFloat*)s->complexOut, s->fftSpec, s->memBuffer); + // convert complex buffer to [ r0, r1, ..., rN, iN-1, .., i2, i1] + compspec->data[0] = s->complexOut[0].re; + compspec->data[s->fft_size / 2] = s->complexOut[s->fft_size / 2].re; + for (i = 1; i < s->fft_size / 2; i++) { + compspec->data[i] = s->complexOut[i].re; + compspec->data[s->fft_size - i] = s->complexOut[i].im; + } + +#else // using OOURA + aubio_ooura_rdft(s->winsize, 1, s->in, s->ip, s->w); + compspec->data[0] = s->in[0]; + compspec->data[s->winsize / 2] = s->in[1]; + for (i = 1; i < s->fft_size - 1; i++) { + compspec->data[i] = s->in[2 * i]; + compspec->data[s->winsize - i] = - s->in[2 * i + 1]; + } +#endif /* using OOURA */ +} + +void aubio_fft_rdo_complex(aubio_fft_t * s, const fvec_t * compspec, fvec_t * output) { + uint_t i; +#ifdef HAVE_FFTW3 + const smpl_t renorm = 1./(smpl_t)s->winsize; +#ifdef HAVE_COMPLEX_H + s->specdata[0] = compspec->data[0]; + for (i=1; i < s->fft_size - 1; i++) { + s->specdata[i] = compspec->data[i] + + I * compspec->data[compspec->length - i]; + } + s->specdata[s->fft_size - 1] = compspec->data[s->fft_size - 1]; +#else + for (i=0; i < s->fft_size; i++) { + s->specdata[i] = compspec->data[i]; + } +#endif + fftw_execute(s->pbw); + for (i = 0; i < output->length; i++) { + output->data[i] = s->out[i]*renorm; + } + +#elif defined HAVE_ACCELERATE // using ACCELERATE + // convert from real imag [ r0, r1, ..., rN, iN-1, .., i2, i1] + // to vDSP packed format [ r0, rN, r1, i1, ..., rN-1, iN-1 ] + s->out[0] = compspec->data[0]; + s->out[1] = compspec->data[s->winsize / 2]; + for (i = 1; i < s->fft_size / 2; i++) { + s->out[2 * i] = compspec->data[i]; + s->out[2 * i + 1] = compspec->data[s->winsize - i]; + } + // convert to split complex format used in vDSP + aubio_vDSP_ctoz((aubio_DSPComplex*)s->out, 2, &s->spec, 1, s->fft_size/2); + // compute the FFT + aubio_vDSP_DFT_Execute(s->fftSetupBwd, s->spec.realp, s->spec.imagp, + s->spec.realp, s->spec.imagp); + // convert result to real output + aubio_vDSP_ztoc(&s->spec, 1, (aubio_DSPComplex*)output->data, 2, s->fft_size/2); + // apply scaling + smpl_t scale = 1.0 / s->winsize; + aubio_vDSP_vsmul(output->data, 1, &scale, output->data, 1, s->fft_size); + +#elif defined HAVE_INTEL_IPP // using Intel IPP + + // convert from real imag [ r0, 0, ..., rN, iN-1, .., i2, i1, iN-1] to complex format + s->complexOut[0].re = compspec->data[0]; + s->complexOut[0].im = 0; + s->complexOut[s->fft_size / 2].re = compspec->data[s->fft_size / 2]; + s->complexOut[s->fft_size / 2].im = 0.0; + for (i = 1; i < s->fft_size / 2; i++) { + s->complexOut[i].re = compspec->data[i]; + s->complexOut[i].im = compspec->data[s->fft_size - i]; + } + // apply fft + aubio_ippsFFTInv_CCSToR((const aubio_IppFloat *)s->complexOut, output->data, s->fftSpec, s->memBuffer); + // apply scaling + aubio_ippsMulC(output->data, 1.0 / s->winsize, output->data, s->fft_size); + +#else // using OOURA + smpl_t scale = 2.0 / s->winsize; + s->out[0] = compspec->data[0]; + s->out[1] = compspec->data[s->winsize / 2]; + for (i = 1; i < s->fft_size - 1; i++) { + s->out[2 * i] = compspec->data[i]; + s->out[2 * i + 1] = - compspec->data[s->winsize - i]; + } + aubio_ooura_rdft(s->winsize, -1, s->out, s->ip, s->w); + for (i=0; i < s->winsize; i++) { + output->data[i] = s->out[i] * scale; + } +#endif +} + +void aubio_fft_get_spectrum(const fvec_t * compspec, cvec_t * spectrum) { + aubio_fft_get_phas(compspec, spectrum); + aubio_fft_get_norm(compspec, spectrum); +} + +void aubio_fft_get_realimag(const cvec_t * spectrum, fvec_t * compspec) { + aubio_fft_get_imag(spectrum, compspec); + aubio_fft_get_real(spectrum, compspec); +} + +void aubio_fft_get_phas(const fvec_t * compspec, cvec_t * spectrum) { + uint_t i; + if (compspec->data[0] < 0) { + spectrum->phas[0] = PI; + } else { + spectrum->phas[0] = 0.; + } +#if defined(HAVE_INTEL_IPP) + // convert from real imag [ r0, r1, ..., rN, iN-1, ..., i2, i1, i0] + // to [ r0, r1, ..., rN, i0, i1, i2, ..., iN-1] + for (i = 1; i < spectrum->length / 2; i++) { + ELEM_SWAP(compspec->data[compspec->length - i], + compspec->data[spectrum->length + i - 1]); + } + aubio_ippsAtan2(compspec->data + spectrum->length, + compspec->data + 1, spectrum->phas + 1, spectrum->length - 1); + // revert the imaginary part back again + for (i = 1; i < spectrum->length / 2; i++) { + ELEM_SWAP(compspec->data[spectrum->length + i - 1], + compspec->data[compspec->length - i]); + } +#else + for (i=1; i < spectrum->length - 1; i++) { + spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i], + compspec->data[i]); + } +#endif +#ifdef HAVE_FFTW3 + // for even length only, make sure last element is 0 or PI + if (2 * (compspec->length / 2) == compspec->length) { +#endif + if (compspec->data[compspec->length/2] < 0) { + spectrum->phas[spectrum->length - 1] = PI; + } else { + spectrum->phas[spectrum->length - 1] = 0.; + } +#ifdef HAVE_FFTW3 + } else { + i = spectrum->length - 1; + spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i], + compspec->data[i]); + } +#endif +} + +void aubio_fft_get_norm(const fvec_t * compspec, cvec_t * spectrum) { + uint_t i = 0; + spectrum->norm[0] = ABS(compspec->data[0]); + for (i=1; i < spectrum->length - 1; i++) { + spectrum->norm[i] = SQRT(SQR(compspec->data[i]) + + SQR(compspec->data[compspec->length - i]) ); + } +#ifdef HAVE_FFTW3 + // for even length, make sure last element is > 0 + if (2 * (compspec->length / 2) == compspec->length) { +#endif + spectrum->norm[spectrum->length-1] = + ABS(compspec->data[compspec->length/2]); +#ifdef HAVE_FFTW3 + } else { + i = spectrum->length - 1; + spectrum->norm[i] = SQRT(SQR(compspec->data[i]) + + SQR(compspec->data[compspec->length - i]) ); + } +#endif +} + +void aubio_fft_get_imag(const cvec_t * spectrum, fvec_t * compspec) { + uint_t i; + for (i = 1; i < ( compspec->length + 1 ) / 2 /*- 1 + 1*/; i++) { + compspec->data[compspec->length - i] = + spectrum->norm[i]*SIN(spectrum->phas[i]); + } +} + +void aubio_fft_get_real(const cvec_t * spectrum, fvec_t * compspec) { + uint_t i; + for (i = 0; i < compspec->length / 2 + 1; i++) { + compspec->data[i] = + spectrum->norm[i]*COS(spectrum->phas[i]); + } +} diff --git a/deps/aubio/src/spectral/fft.h b/deps/aubio/src/spectral/fft.h new file mode 100644 index 0000000..21072c8 --- /dev/null +++ b/deps/aubio/src/spectral/fft.h @@ -0,0 +1,144 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Fast Fourier Transform + + Depending on how aubio was compiled, FFT are computed using one of: + - [Ooura](http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html) + - [FFTW3](http://www.fftw.org) + - [vDSP](https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html) + + \example spectral/test-fft.c + +*/ + +#ifndef AUBIO_FFT_H +#define AUBIO_FFT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** FFT object + + This object computes forward and backward FFTs. + +*/ +typedef struct _aubio_fft_t aubio_fft_t; + +/** create new FFT computation object + + \param size length of the FFT + +*/ +aubio_fft_t * new_aubio_fft (uint_t size); +/** delete FFT object + + \param s fft object as returned by new_aubio_fft + +*/ +void del_aubio_fft(aubio_fft_t * s); + +/** compute forward FFT + + \param s fft object as returned by new_aubio_fft + \param input input signal + \param spectrum output spectrum + +*/ +void aubio_fft_do (aubio_fft_t *s, const fvec_t * input, cvec_t * spectrum); +/** compute backward (inverse) FFT + + \param s fft object as returned by new_aubio_fft + \param spectrum input spectrum + \param output output signal + +*/ +void aubio_fft_rdo (aubio_fft_t *s, const cvec_t * spectrum, fvec_t * output); + +/** compute forward FFT + + \param s fft object as returned by new_aubio_fft + \param input real input signal + \param compspec complex output fft real/imag + +*/ +void aubio_fft_do_complex (aubio_fft_t *s, const fvec_t * input, fvec_t * compspec); +/** compute backward (inverse) FFT from real/imag + + \param s fft object as returned by new_aubio_fft + \param compspec real/imag input fft array + \param output real output array + +*/ +void aubio_fft_rdo_complex (aubio_fft_t *s, const fvec_t * compspec, fvec_t * output); + +/** convert real/imag spectrum to norm/phas spectrum + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_spectrum(const fvec_t * compspec, cvec_t * spectrum); +/** convert real/imag spectrum to norm/phas spectrum + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_realimag(const cvec_t * spectrum, fvec_t * compspec); + +/** compute phas spectrum from real/imag parts + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_phas(const fvec_t * compspec, cvec_t * spectrum); +/** compute imaginary part from the norm/phas cvec + + \param spectrum norm/phas input array + \param compspec real/imag output fft array + +*/ +void aubio_fft_get_imag(const cvec_t * spectrum, fvec_t * compspec); + +/** compute norm component from real/imag parts + + \param compspec real/imag input fft array + \param spectrum cvec norm/phas output array + +*/ +void aubio_fft_get_norm(const fvec_t * compspec, cvec_t * spectrum); +/** compute real part from norm/phas components + + \param spectrum norm/phas input array + \param compspec real/imag output fft array + +*/ +void aubio_fft_get_real(const cvec_t * spectrum, fvec_t * compspec); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_FFT_H */ diff --git a/deps/aubio/src/spectral/phasevoc.c b/deps/aubio/src/spectral/phasevoc.c new file mode 100644 index 0000000..05ebdb0 --- /dev/null +++ b/deps/aubio/src/spectral/phasevoc.c @@ -0,0 +1,224 @@ +/* + Copyright (C) 2003-2014 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/fft.h" +#include "spectral/phasevoc.h" + +/** phasevocoder internal object */ +struct _aubio_pvoc_t { + uint_t win_s; /** grain length */ + uint_t hop_s; /** overlap step */ + aubio_fft_t * fft; /** fft object */ + fvec_t * data; /** current input grain, [win_s] frames */ + fvec_t * dataold; /** memory of past grain, [win_s-hop_s] frames */ + fvec_t * synth; /** current output grain, [win_s] frames */ + fvec_t * synthold; /** memory of past grain, [win_s-hop_s] frames */ + fvec_t * w; /** grain window [win_s] */ + uint_t start; /** where to start additive synthesis */ + uint_t end; /** where to end it */ + smpl_t scale; /** scaling factor for synthesis */ + uint_t end_datasize; /** size of memory to end */ + uint_t hop_datasize; /** size of memory to hop_s */ +}; + + +/** returns data and dataold slided by hop_s */ +static void aubio_pvoc_swapbuffers(aubio_pvoc_t *pv, const fvec_t *new); + +/** do additive synthesis from 'old' and 'cur' */ +static void aubio_pvoc_addsynth(aubio_pvoc_t *pv, fvec_t * synthnew); + +void aubio_pvoc_do(aubio_pvoc_t *pv, const fvec_t * datanew, cvec_t *fftgrain) { + /* slide */ + aubio_pvoc_swapbuffers(pv, datanew); + /* windowing */ + fvec_weight(pv->data, pv->w); + /* shift */ + fvec_shift(pv->data); + /* calculate fft */ + aubio_fft_do (pv->fft,pv->data,fftgrain); +} + +void aubio_pvoc_rdo(aubio_pvoc_t *pv,cvec_t * fftgrain, fvec_t * synthnew) { + /* calculate rfft */ + aubio_fft_rdo(pv->fft,fftgrain,pv->synth); + /* unshift */ + fvec_ishift(pv->synth); + /* windowing */ + // if overlap = 50%, do not apply window (identity) + if (pv->hop_s * 2 < pv->win_s) { + fvec_weight(pv->synth, pv->w); + } + /* additive synthesis */ + aubio_pvoc_addsynth(pv, synthnew); +} + +aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s) { + aubio_pvoc_t * pv = AUBIO_NEW(aubio_pvoc_t); + + /* if (win_s < 2*hop_s) { + AUBIO_WRN("Hop size bigger than half the window size!\n"); + } */ + + if ((sint_t)hop_s < 1) { + AUBIO_ERR("pvoc: got hop_size %d, but can not be < 1\n", hop_s); + goto beach; + } else if ((sint_t)win_s < 2) { + AUBIO_ERR("pvoc: got buffer_size %d, but can not be < 2\n", win_s); + goto beach; + } else if (win_s < hop_s) { + AUBIO_ERR("pvoc: hop size (%d) is larger than win size (%d)\n", hop_s, win_s); + goto beach; + } + + pv->fft = new_aubio_fft (win_s); + if (pv->fft == NULL) { + goto beach; + } + + /* remember old */ + pv->data = new_fvec (win_s); + pv->synth = new_fvec (win_s); + + /* new input output */ + if (win_s > hop_s) { + pv->dataold = new_fvec (win_s-hop_s); + pv->synthold = new_fvec (win_s-hop_s); + } else { + pv->dataold = new_fvec (1); + pv->synthold = new_fvec (1); + } + pv->w = new_aubio_window ("hanningz", win_s); + + pv->hop_s = hop_s; + pv->win_s = win_s; + + /* more than 50% overlap, overlap anyway */ + if (win_s < 2 * hop_s) pv->start = 0; + /* less than 50% overlap, reset latest grain trail */ + else pv->start = win_s - hop_s - hop_s; + + if (win_s > hop_s) pv->end = win_s - hop_s; + else pv->end = 0; + + pv->end_datasize = pv->end * sizeof(smpl_t); + pv->hop_datasize = pv->hop_s * sizeof(smpl_t); + + // for reconstruction with 75% overlap + if (win_s == hop_s * 4) { + pv->scale = 2./3.; + } else if (win_s == hop_s * 8) { + pv->scale = 1./3.; + } else if (win_s == hop_s * 2) { + pv->scale = 1.; + } else { + pv->scale = .5; + } + + return pv; + +beach: + AUBIO_FREE (pv); + return NULL; +} + +uint_t aubio_pvoc_set_window(aubio_pvoc_t *pv, const char_t *window) { + return fvec_set_window(pv->w, (char_t*)window); +} + +void del_aubio_pvoc(aubio_pvoc_t *pv) { + del_fvec(pv->data); + del_fvec(pv->synth); + del_fvec(pv->dataold); + del_fvec(pv->synthold); + del_fvec(pv->w); + del_aubio_fft(pv->fft); + AUBIO_FREE(pv); +} + +static void aubio_pvoc_swapbuffers(aubio_pvoc_t *pv, const fvec_t *new) +{ + /* some convenience pointers */ + smpl_t * data = pv->data->data; + smpl_t * dataold = pv->dataold->data; + smpl_t * datanew = new->data; +#ifndef HAVE_MEMCPY_HACKS + uint_t i; + for (i = 0; i < pv->end; i++) + data[i] = dataold[i]; + for (i = 0; i < pv->hop_s; i++) + data[pv->end + i] = datanew[i]; + for (i = 0; i < pv->end; i++) + dataold[i] = data[i + pv->hop_s]; +#else + memcpy(data, dataold, pv->end_datasize); + data += pv->end; + memcpy(data, datanew, pv->hop_datasize); + data -= pv->end; + data += pv->hop_s; + memcpy(dataold, data, pv->end_datasize); +#endif +} + +static void aubio_pvoc_addsynth(aubio_pvoc_t *pv, fvec_t *synth_new) +{ + uint_t i; + /* some convenience pointers */ + smpl_t * synth = pv->synth->data; + smpl_t * synthold = pv->synthold->data; + smpl_t * synthnew = synth_new->data; + + /* put new result in synthnew */ + for (i = 0; i < pv->hop_s; i++) + synthnew[i] = synth[i] * pv->scale; + + /* no overlap, nothing else to do */ + if (pv->end == 0) return; + + /* add new synth to old one */ + for (i = 0; i < pv->hop_s; i++) + synthnew[i] += synthold[i]; + + /* shift synthold */ + for (i = 0; i < pv->start; i++) + synthold[i] = synthold[i + pv->hop_s]; + + /* erase last frame in synthold */ + for (i = pv->start; i < pv->end; i++) + synthold[i] = 0.; + + /* additive synth */ + for (i = 0; i < pv->end; i++) + synthold[i] += synth[i + pv->hop_s] * pv->scale; +} + +uint_t aubio_pvoc_get_win(aubio_pvoc_t* pv) +{ + return pv->win_s; +} + +uint_t aubio_pvoc_get_hop(aubio_pvoc_t* pv) +{ + return pv->hop_s; +} diff --git a/deps/aubio/src/spectral/phasevoc.h b/deps/aubio/src/spectral/phasevoc.h new file mode 100644 index 0000000..e3caf2d --- /dev/null +++ b/deps/aubio/src/spectral/phasevoc.h @@ -0,0 +1,113 @@ +/* + Copyright (C) 2003-2013 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Phase vocoder object + + This object implements a phase vocoder. The spectral frames are computed + using a HanningZ window and a swapped version of the signal to simplify the + phase relationships across frames. The window sizes and overlap are specified + at creation time. + + \example spectral/test-phasevoc.c + +*/ + +#ifndef AUBIO_PHASEVOC_H +#define AUBIO_PHASEVOC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** phasevocoder object */ +typedef struct _aubio_pvoc_t aubio_pvoc_t; + +/** create phase vocoder object + + \param win_s size of analysis buffer (and length the FFT transform) + \param hop_s step size between two consecutive analysis + +*/ +aubio_pvoc_t * new_aubio_pvoc (uint_t win_s, uint_t hop_s); +/** delete phase vocoder object + + \param pv phase vocoder object as returned by new_aubio_pvoc + +*/ +void del_aubio_pvoc(aubio_pvoc_t *pv); + +/** compute spectral frame + + This function accepts an input vector of size [hop_s]. The + analysis buffer is rotated and filled with the new data. After windowing of + this signal window, the Fourier transform is computed and returned in + fftgrain as two vectors, magnitude and phase. + + \param pv phase vocoder object as returned by new_aubio_pvoc + \param in new input signal (hop_s long) + \param fftgrain output spectral frame + +*/ +void aubio_pvoc_do(aubio_pvoc_t *pv, const fvec_t *in, cvec_t * fftgrain); +/** compute signal from spectral frame + + This function takes an input spectral frame fftgrain of size + [buf_s] and computes its inverse Fourier transform. Overlap-add + synthesis is then computed using the previously synthetised frames, and the + output stored in out. + + \param pv phase vocoder object as returned by new_aubio_pvoc + \param fftgrain input spectral frame + \param out output signal (hop_s long) + +*/ +void aubio_pvoc_rdo(aubio_pvoc_t *pv, cvec_t * fftgrain, fvec_t *out); + +/** get window size + + \param pv phase vocoder to get the window size from + +*/ +uint_t aubio_pvoc_get_win(aubio_pvoc_t* pv); + +/** get hop size + + \param pv phase vocoder to get the hop size from + +*/ +uint_t aubio_pvoc_get_hop(aubio_pvoc_t* pv); + +/** set window type + + \param pv phase vocoder to set the window type + \param window_type a string representing a window + + \return 0 if successful, non-zero otherwise + + */ +uint_t aubio_pvoc_set_window(aubio_pvoc_t *pv, const char_t *window_type); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_PHASEVOC_H */ diff --git a/deps/aubio/src/temporal/a_weighting.c b/deps/aubio/src/temporal/a_weighting.c new file mode 100644 index 0000000..f19f566 --- /dev/null +++ b/deps/aubio/src/temporal/a_weighting.c @@ -0,0 +1,262 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "types.h" +#include "fvec.h" +#include "lvec.h" +#include "temporal/filter.h" +#include "temporal/a_weighting.h" + +uint_t +aubio_filter_set_a_weighting (aubio_filter_t * f, uint_t samplerate) +{ + uint_t order; lsmp_t *a, *b; lvec_t *as, *bs; + + if ((sint_t)samplerate <= 0) { + AUBIO_ERROR("aubio_filter: failed setting A-weighting with samplerate %d\n", samplerate); + return AUBIO_FAIL; + } + if (f == NULL) { + AUBIO_ERROR("aubio_filter: failed setting A-weighting with filter NULL\n"); + return AUBIO_FAIL; + } + + order = aubio_filter_get_order (f); + if (order != 7) { + AUBIO_ERROR ("aubio_filter: order of A-weighting filter must be 7, not %d\n", order); + return 1; + } + + aubio_filter_set_samplerate (f, samplerate); + bs = aubio_filter_get_feedforward (f); + as = aubio_filter_get_feedback (f); + b = bs->data, a = as->data; + + /* select coefficients according to sampling frequency */ + switch (samplerate) { + + case 8000: + b[0] = 6.306209468238731519207362907764036208391189575195312500e-01; + b[1] = -1.261241893647746525886077506584115326404571533203125000e+00; + b[2] = -6.306209468238730408984338282607495784759521484375000000e-01; + b[3] = 2.522483787295493051772155013168230652809143066406250000e+00; + b[4] = -6.306209468238730408984338282607495784759521484375000000e-01; + b[5] = -1.261241893647746525886077506584115326404571533203125000e+00; + b[6] = 6.306209468238731519207362907764036208391189575195312500e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -2.128467193009123015201566886389628052711486816406250000e+00; + a[2] = 2.948668980101234460278192273108288645744323730468750000e-01; + a[3] = 1.824183830735050637628091863007284700870513916015625000e+00; + a[4] = -8.056628943119792385374466903158463537693023681640625000e-01; + a[5] = -3.947497982842933517133587884018197655677795410156250000e-01; + a[6] = 2.098548546080332977137317129745497368276119232177734375e-01; + break; + + case 11025: + b[0] = 6.014684165832374640459079273568931967020034790039062500e-01; + b[1] = -1.202936833166475150136420779745094478130340576171875000e+00; + b[2] = -6.014684165832373530236054648412391543388366699218750000e-01; + b[3] = 2.405873666332950300272841559490188956260681152343750000e+00; + b[4] = -6.014684165832373530236054648412391543388366699218750000e-01; + b[5] = -1.202936833166475150136420779745094478130340576171875000e+00; + b[6] = 6.014684165832374640459079273568931967020034790039062500e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -2.463578747722854345170162559952586889266967773437500000e+00; + a[2] = 1.096799662705210121060872552334330976009368896484375000e+00; + a[3] = 1.381222210556041218865175324026495218276977539062500000e+00; + a[4] = -1.013875696476876031582037285261321812868118286132812500e+00; + a[5] = -1.839132734476921215982514468123554252088069915771484375e-01; + a[6] = 1.833526393172056623281918064094497822225093841552734375e-01; + break; + + case 16000: + b[0] = 5.314898298235570806014038680586963891983032226562500000e-01; + b[1] = -1.062979659647114161202807736117392778396606445312500000e+00; + b[2] = -5.314898298235570806014038680586963891983032226562500000e-01; + b[3] = 2.125959319294228322405615472234785556793212890625000000e+00; + b[4] = -5.314898298235570806014038680586963891983032226562500000e-01; + b[5] = -1.062979659647114161202807736117392778396606445312500000e+00; + b[6] = 5.314898298235570806014038680586963891983032226562500000e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -2.867832572992162987191022693878039717674255371093750000e+00; + a[2] = 2.221144410202312347024644623161293566226959228515625000e+00; + a[3] = 4.552683347886614662058946123579517006874084472656250000e-01; + a[4] = -9.833868636162828025248927588108927011489868164062500000e-01; + a[5] = 5.592994142413361402521587706360151059925556182861328125e-02; + a[6] = 1.188781038285612462468421313133148942142724990844726562e-01; + break; + + case 22050: + b[0] = 4.492998504299193784916610638902056962251663208007812500e-01; + b[1] = -8.985997008598388680056245902960654348134994506835937500e-01; + b[2] = -4.492998504299192674693586013745516538619995117187500000e-01; + b[3] = 1.797199401719677958055854105623438954353332519531250000e+00; + b[4] = -4.492998504299192674693586013745516538619995117187500000e-01; + b[5] = -8.985997008598388680056245902960654348134994506835937500e-01; + b[6] = 4.492998504299193784916610638902056962251663208007812500e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -3.229078805225074955131958631682209670543670654296875000e+00; + a[2] = 3.354494881236033787530459449044428765773773193359375000e+00; + a[3] = -7.317843680657351024265722116979304701089859008789062500e-01; + a[4] = -6.271627581807257545420952737913466989994049072265625000e-01; + a[5] = 1.772142005020879151899748649157118052244186401367187500e-01; + a[6] = 5.631716697383508385410522123493137769401073455810546875e-02; + break; + + case 24000: + b[0] = 4.256263892891054001488271296693710610270500183105468750e-01; + b[1] = -8.512527785782106892753517968230880796909332275390625000e-01; + b[2] = -4.256263892891054556599783609271980822086334228515625000e-01; + b[3] = 1.702505557156421378550703593646176159381866455078125000e+00; + b[4] = -4.256263892891054556599783609271980822086334228515625000e-01; + b[5] = -8.512527785782106892753517968230880796909332275390625000e-01; + b[6] = 4.256263892891054001488271296693710610270500183105468750e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -3.325996004241962733516402295208536088466644287109375000e+00; + a[2] = 3.677161079286316969216841243905946612358093261718750000e+00; + a[3] = -1.106476076828482035807610373012721538543701171875000000e+00; + a[4] = -4.726706734908718843257702246773988008499145507812500000e-01; + a[5] = 1.861941760230954034938122276798821985721588134765625000e-01; + a[6] = 4.178771337829546850262119050967157818377017974853515625e-02; + break; + + case 32000: + b[0] = 3.434583386824304196416335344110848382115364074707031250e-01; + b[1] = -6.869166773648609503055695313378237187862396240234375000e-01; + b[2] = -3.434583386824303641304823031532578170299530029296875000e-01; + b[3] = 1.373833354729721900611139062675647437572479248046875000e+00; + b[4] = -3.434583386824303641304823031532578170299530029296875000e-01; + b[5] = -6.869166773648609503055695313378237187862396240234375000e-01; + b[6] = 3.434583386824304196416335344110848382115364074707031250e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -3.656446043233668063976438133977353572845458984375000000e+00; + a[2] = 4.831468450652579349480220116674900054931640625000000000e+00; + a[3] = -2.557597496581567764195597192156128585338592529296875000e+00; + a[4] = 2.533680394205302666144064005493419244885444641113281250e-01; + a[5] = 1.224430322452567110325105659285327419638633728027343750e-01; + a[6] = 6.764072168342137418572956875095769646577537059783935547e-03; + break; + + case 44100: + b[0] = 2.557411252042575133813784304948057979345321655273437500e-01; + b[1] = -5.114822504085150267627568609896115958690643310546875000e-01; + b[2] = -2.557411252042575133813784304948057979345321655273437500e-01; + b[3] = 1.022964500817030053525513721979223191738128662109375000e+00; + b[4] = -2.557411252042575133813784304948057979345321655273437500e-01; + b[5] = -5.114822504085150267627568609896115958690643310546875000e-01; + b[6] = 2.557411252042575133813784304948057979345321655273437500e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -4.019576181115832369528106937650591135025024414062500000e+00; + a[2] = 6.189406442920693862674852425698190927505493164062500000e+00; + a[3] = -4.453198903544116404873420833609998226165771484375000000e+00; + a[4] = 1.420842949621876627475103305187076330184936523437500000e+00; + a[5] = -1.418254738303044160119270600262098014354705810546875000e-01; + a[6] = 4.351177233495117681327801761881346465088427066802978516e-03; + break; + + case 48000: + b[0] = 2.343017922995132285013397677175817079842090606689453125e-01; + b[1] = -4.686035845990265125138307666929904371500015258789062500e-01; + b[2] = -2.343017922995132007457641520886681973934173583984375000e-01; + b[3] = 9.372071691980530250276615333859808743000030517578125000e-01; + b[4] = -2.343017922995132007457641520886681973934173583984375000e-01; + b[5] = -4.686035845990265125138307666929904371500015258789062500e-01; + b[6] = 2.343017922995132285013397677175817079842090606689453125e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -4.113043408775872045168853219365701079368591308593750000e+00; + a[2] = 6.553121752655050258340452273841947317123413085937500000e+00; + a[3] = -4.990849294163385074796224216697737574577331542968750000e+00; + a[4] = 1.785737302937575599059982778271660208702087402343750000e+00; + a[5] = -2.461905953194876706113802811159985139966011047363281250e-01; + a[6] = 1.122425003323123879339640041052916785702109336853027344e-02; + break; + + case 88200: + b[0] = 1.118876366882113199130444058937428053468465805053710938e-01; + b[1] = -2.237752733764226120705131961585721001029014587402343750e-01; + b[2] = -1.118876366882113337908322137081995606422424316406250000e-01; + b[3] = 4.475505467528452241410263923171442002058029174804687500e-01; + b[4] = -1.118876366882113337908322137081995606422424316406250000e-01; + b[5] = -2.237752733764226120705131961585721001029014587402343750e-01; + b[6] = 1.118876366882113199130444058937428053468465805053710938e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -4.726938565651158441482948546763509511947631835937500000e+00; + a[2] = 9.076897983832765248735086061060428619384765625000000000e+00; + a[3] = -9.014855113464800950850985827855765819549560546875000000e+00; + a[4] = 4.852772261031594425162438710685819387435913085937500000e+00; + a[5] = -1.333877820398965186043938047077972441911697387695312500e+00; + a[6] = 1.460012549591642450064199465487035922706127166748046875e-01; + break; + + case 96000: + b[0] = 9.951898975972744976203898659150581806898117065429687500e-02; + b[1] = -1.990379795194548995240779731830116361379623413085937500e-01; + b[2] = -9.951898975972744976203898659150581806898117065429687500e-02; + b[3] = 3.980759590389097990481559463660232722759246826171875000e-01; + b[4] = -9.951898975972744976203898659150581806898117065429687500e-02; + b[5] = -1.990379795194548995240779731830116361379623413085937500e-01; + b[6] = 9.951898975972744976203898659150581806898117065429687500e-02; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -4.802203044225376693532325589330866932868957519531250000e+00; + a[2] = 9.401807218627226347962277941405773162841796875000000000e+00; + a[3] = -9.566143943569164420637207513209432363510131835937500000e+00; + a[4] = 5.309775930392619081032989925006404519081115722656250000e+00; + a[5] = -1.517333360452622237346531619550660252571105957031250000e+00; + a[6] = 1.740971994228911745583587844521389342844486236572265625e-01; + break; + + case 192000: + b[0] = 3.433213424548713782469278044118254911154508590698242188e-02; + b[1] = -6.866426849097426177159775306790834292769432067871093750e-02; + b[2] = -3.433213424548714476358668434841092675924301147460937500e-02; + b[3] = 1.373285369819485235431955061358166858553886413574218750e-01; + b[4] = -3.433213424548714476358668434841092675924301147460937500e-02; + b[5] = -6.866426849097426177159775306790834292769432067871093750e-02; + b[6] = 3.433213424548713782469278044118254911154508590698242188e-02; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -5.305923689674640009172890131594613194465637207031250000e+00; + a[2] = 1.165952437466175695135461864992976188659667968750000000e+01; + a[3] = -1.357560092700591525272102444432675838470458984375000000e+01; + a[4] = 8.828906932824192921316353022120893001556396484375000000e+00; + a[5] = -3.039490120988216581565666274400427937507629394531250000e+00; + a[6] = 4.325834301870381537469256727490574121475219726562500000e-01; + break; + + default: + AUBIO_ERROR ("sampling rate of A-weighting filter is %d, should be one of\ + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 192000.\n", samplerate); + return 1; + + } + + return 0; +} + +aubio_filter_t * +new_aubio_filter_a_weighting (uint_t samplerate) +{ + aubio_filter_t *f = new_aubio_filter (7); + if (aubio_filter_set_a_weighting(f,samplerate) != AUBIO_OK) { + del_aubio_filter(f); + return NULL; + } + return f; +} diff --git a/deps/aubio/src/temporal/a_weighting.h b/deps/aubio/src/temporal/a_weighting.h new file mode 100644 index 0000000..49dd4d5 --- /dev/null +++ b/deps/aubio/src/temporal/a_weighting.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_FILTER_A_DESIGN_H +#define AUBIO_FILTER_A_DESIGN_H + +/** \file + + A-weighting filter coefficients + + This file creates an A-weighting digital filter, which reduces low and high + frequencies and enhance the middle ones to reflect the ability of the human + hearing. + + The implementation is based on the following standard: + + - IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov. 1996, + for A- and C-weighting filters. + + See also: + + - A-Weighting on + Wikipedia + - Weighting filter on + Wikipedia + - Christophe + Couvreur's 'octave' toolbox + + The coefficients in this file have been computed using Christophe Couvreur's + scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal + 1.0.9-1+b1 on i386), with
 [b, a] = adsign(1/Fs) 
for various + sampling frequencies (8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, + 88200, 96000, and 192000 Hz). + + The sampling frequency should normally be higher than 20kHz, but most common + file sampling rates have been included for completeness. + + \example temporal/test-a_weighting.c + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** create new A-design filter + + \param samplerate sampling frequency of the signal to filter. Should be one of + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and + 192000 Hz + + \return a new filter object + +*/ +aubio_filter_t *new_aubio_filter_a_weighting (uint_t samplerate); + +/** set feedback and feedforward coefficients of a A-weighting filter + + \param f filter object to get coefficients from + \param samplerate sampling frequency of the signal to filter. Should be one of + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and + 192000 Hz + +*/ +uint_t aubio_filter_set_a_weighting (aubio_filter_t * f, uint_t samplerate); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_FILTER_A_DESIGN_H */ diff --git a/deps/aubio/src/temporal/biquad.c b/deps/aubio/src/temporal/biquad.c new file mode 100644 index 0000000..426b64f --- /dev/null +++ b/deps/aubio/src/temporal/biquad.c @@ -0,0 +1,54 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "lvec.h" +#include "temporal/filter.h" +#include "temporal/biquad.h" + +uint_t +aubio_filter_set_biquad (aubio_filter_t * f, lsmp_t b0, lsmp_t b1, lsmp_t b2, + lsmp_t a1, lsmp_t a2) +{ + uint_t order = aubio_filter_get_order (f); + lvec_t *bs = aubio_filter_get_feedforward (f); + lvec_t *as = aubio_filter_get_feedback (f); + + if (order != 3) { + AUBIO_ERROR ("order of biquad filter must be 3, not %d\n", order); + return AUBIO_FAIL; + } + bs->data[0] = b0; + bs->data[1] = b1; + bs->data[2] = b2; + as->data[0] = 1.; + as->data[1] = a1; + as->data[2] = a2; + return AUBIO_OK; +} + +aubio_filter_t * +new_aubio_filter_biquad (lsmp_t b0, lsmp_t b1, lsmp_t b2, lsmp_t a1, lsmp_t a2) +{ + aubio_filter_t *f = new_aubio_filter (3); + aubio_filter_set_biquad (f, b0, b1, b2, a1, a2); + return f; +} diff --git a/deps/aubio/src/temporal/biquad.h b/deps/aubio/src/temporal/biquad.h new file mode 100644 index 0000000..1d19d94 --- /dev/null +++ b/deps/aubio/src/temporal/biquad.h @@ -0,0 +1,75 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_FILTER_BIQUAD_H +#define AUBIO_FILTER_BIQUAD_H + +/** \file + + Second order Infinite Impulse Response filter + + This file implements a normalised biquad filter (second order IIR): + + \f$ y[n] = b_0 x[n] + b_1 x[n-1] + b_2 x[n-2] - a_1 y[n-1] - a_2 y[n-2] \f$ + + The filtfilt version runs the filter twice, forward and backward, to + compensate the phase shifting of the forward operation. + + See also Digital + biquad filter on wikipedia. + + \example temporal/test-biquad.c + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** set coefficients of a biquad filter + + \param f filter object as returned by new_aubio_filter() + \param b0 forward filter coefficient + \param b1 forward filter coefficient + \param b2 forward filter coefficient + \param a1 feedback filter coefficient + \param a2 feedback filter coefficient + +*/ +uint_t aubio_filter_set_biquad (aubio_filter_t * f, lsmp_t b0, lsmp_t b1, + lsmp_t b2, lsmp_t a1, lsmp_t a2); + +/** create biquad filter with `b0`, `b1`, `b2`, `a1`, `a2` coeffs + + \param b0 forward filter coefficient + \param b1 forward filter coefficient + \param b2 forward filter coefficient + \param a1 feedback filter coefficient + \param a2 feedback filter coefficient + +*/ +aubio_filter_t *new_aubio_filter_biquad (lsmp_t b0, lsmp_t b1, lsmp_t b2, + lsmp_t a1, lsmp_t a2); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_FILTER_BIQUAD_H */ diff --git a/deps/aubio/src/temporal/c_weighting.c b/deps/aubio/src/temporal/c_weighting.c new file mode 100644 index 0000000..91ada71 --- /dev/null +++ b/deps/aubio/src/temporal/c_weighting.c @@ -0,0 +1,217 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "types.h" +#include "fvec.h" +#include "lvec.h" +#include "temporal/filter.h" +#include "temporal/c_weighting.h" + +uint_t +aubio_filter_set_c_weighting (aubio_filter_t * f, uint_t samplerate) +{ + uint_t order; lsmp_t *a, *b; lvec_t *as, *bs; + + if ((sint_t)samplerate <= 0) { + AUBIO_ERROR("aubio_filter: failed setting C-weighting with samplerate %d\n", samplerate); + return AUBIO_FAIL; + } + if (f == NULL) { + AUBIO_ERROR("aubio_filter: failed setting C-weighting with filter NULL\n"); + return AUBIO_FAIL; + } + + order = aubio_filter_get_order (f); + if ( order != 5 ) { + AUBIO_ERROR ("aubio_filter: order of C-weighting filter must be 5, not %d\n", order); + return 1; + } + + aubio_filter_set_samplerate (f, samplerate); + bs = aubio_filter_get_feedforward (f); + as = aubio_filter_get_feedback (f); + b = bs->data, a = as->data; + + /* select coefficients according to sampling frequency */ + switch (samplerate) { + + case 8000: + b[0] = 6.782173932405135552414776611840352416038513183593750000e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -1.356434786481027110482955322368070483207702636718750000e+00; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 6.782173932405135552414776611840352416038513183593750000e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -6.589092811505605773447769024642184376716613769531250000e-01; + a[2] = -1.179445664897062595599663836765103042125701904296875000e+00; + a[3] = 4.243329729632123736848825501510873436927795410156250000e-01; + a[4] = 4.147270002091348328754349950031610205769538879394531250e-01; + break; + + case 11025: + b[0] = 6.002357155402652244546857218665536493062973022460937500e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -1.200471431080530448909371443733107298612594604492187500e+00; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 6.002357155402652244546857218665536493062973022460937500e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -8.705602141280316397242700077185872942209243774414062500e-01; + a[2] = -9.037199507150940336330791069485712796449661254882812500e-01; + a[3] = 4.758433040929530011275971901341108605265617370605468750e-01; + a[4] = 2.987653956523212417373258631414500996470451354980468750e-01; + break; + + case 16000: + b[0] = 4.971057193673903418229542694461997598409652709960937500e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -9.942114387347806836459085388923995196819305419921875000e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 4.971057193673903418229542694461997598409652709960937500e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -1.162322939286873690889478893950581550598144531250000000e+00; + a[2] = -4.771961355734982701548574368644040077924728393554687500e-01; + a[3] = 4.736145114694704227886745684372726827859878540039062500e-01; + a[4] = 1.660337524309875301131711466950946487486362457275390625e-01; + break; + + case 22050: + b[0] = 4.033381299002754549754001800465630367398262023925781250e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -8.066762598005509099508003600931260734796524047851562500e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 4.033381299002754549754001800465630367398262023925781250e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -1.449545371157945350404361306573264300823211669921875000e+00; + a[2] = -1.030104190885922088583015465701464563608169555664062500e-02; + a[3] = 3.881857047554073680828423675848171114921569824218750000e-01; + a[4] = 7.171589940116777917022972133054281584918498992919921875e-02; + break; + + case 24000: + b[0] = 3.786678621924967069745093795063439756631851196289062500e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -7.573357243849934139490187590126879513263702392578125000e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 3.786678621924967069745093795063439756631851196289062500e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -1.529945307555420797029910318087786436080932617187500000e+00; + a[2] = 1.283553182116208835061854642844991758465766906738281250e-01; + a[3] = 3.494608072385725350272878131363540887832641601562500000e-01; + a[4] = 5.217291949300089520802359288609295617789030075073242188e-02; + break; + + case 32000: + b[0] = 2.977986488230693340462096330156782642006874084472656250e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -5.955972976461386680924192660313565284013748168945312500e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 2.977986488230693340462096330156782642006874084472656250e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -1.812455387128179218336754274787381291389465332031250000e+00; + a[2] = 6.425013281155662614452239722595550119876861572265625000e-01; + a[3] = 1.619857574578579817448087396769551560282707214355468750e-01; + a[4] = 7.987649713547682189807019881300220731645822525024414062e-03; + break; + + case 44100: + b[0] = 2.170085619492190254220531642204150557518005371093750000e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -4.340171238984380508441063284408301115036010742187500000e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 2.170085619492190254220531642204150557518005371093750000e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -2.134674963687040794013682898366823792457580566406250000e+00; + a[2] = 1.279333533236062692139967111870646476745605468750000000e+00; + a[3] = -1.495598460893957093453821016737492755055427551269531250e-01; + a[4] = 4.908700174624683852664386307651511742733418941497802734e-03; + break; + + case 48000: + b[0] = 1.978871200263932761398422144338837824761867523193359375e-01; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -3.957742400527865522796844288677675649523735046386718750e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 1.978871200263932761398422144338837824761867523193359375e-01; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -2.219172914052801814932536217384040355682373046875000000e+00; + a[2] = 1.455135878947171557129536267893854528665542602539062500e+00; + a[3] = -2.484960738877830532800317087094299495220184326171875000e-01; + a[4] = 1.253882314727246607977129144728678511455655097961425781e-02; + break; + + case 88200: + b[0] = 9.221909851156021020734954163344809785485267639160156250e-02; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -1.844381970231204204146990832668961957097053527832031250e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 9.221909851156021020734954163344809785485267639160156250e-02; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -2.785795902923448696952846148633398115634918212890625000e+00; + a[2] = 2.727736758747444145711824603495188057422637939453125000e+00; + a[3] = -1.097007502819661528548067508381791412830352783203125000e+00; + a[4] = 1.550674356752141103132913713125162757933139801025390625e-01; + break; + + case 96000: + b[0] = 8.182864044979756834585771230194950476288795471191406250e-02; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -1.636572808995951366917154246038990095257759094238281250e-01; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 8.182864044979756834585771230194950476288795471191406250e-02; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -2.856378516857566829401093855267390608787536621093750000e+00; + a[2] = 2.897640237559524045707348705036565661430358886718750000e+00; + a[3] = -1.225265958339703198376469117647502571344375610351562500e+00; + a[4] = 1.840048283551226071530493300087982788681983947753906250e-01; + break; + + case 192000: + b[0] = 2.784755468532278815940728122768632601946592330932617188e-02; + b[1] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[2] = -5.569510937064557631881456245537265203893184661865234375e-02; + b[3] = 0.000000000000000000000000000000000000000000000000000000e+00; + b[4] = 2.784755468532278815940728122768632601946592330932617188e-02; + a[0] = 1.000000000000000000000000000000000000000000000000000000e+00; + a[1] = -3.333298856144166322224009491037577390670776367187500000e+00; + a[2] = 4.111467536240339448738723149290308356285095214843750000e+00; + a[3] = -2.222889041651291641699117462849244475364685058593750000e+00; + a[4] = 4.447204118126878991112960193277103826403617858886718750e-01; + break; + + default: + AUBIO_ERROR ( "sampling rate of C-weighting filter is %d, should be one of\ + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 192000.\n", + samplerate ); + return 1; + + } + + return 0; +} + +aubio_filter_t * new_aubio_filter_c_weighting (uint_t samplerate) { + aubio_filter_t * f = new_aubio_filter(5); + if (aubio_filter_set_c_weighting(f,samplerate) != AUBIO_OK) { + del_aubio_filter(f); + return NULL; + } + return f; +} diff --git a/deps/aubio/src/temporal/c_weighting.h b/deps/aubio/src/temporal/c_weighting.h new file mode 100644 index 0000000..d87f61f --- /dev/null +++ b/deps/aubio/src/temporal/c_weighting.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_FILTER_C_DESIGN_H +#define AUBIO_FILTER_C_DESIGN_H + +/** \file + + C-weighting filter coefficients + + This file creates a C-weighting digital filter, which reduces low and high + frequencies and enhance the middle ones to reflect the ability of the human + hearing. + + The implementation is based on the following standard: + + - IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov. 1996, + for A- and C-weighting filters. + + See also: + + - A-Weighting on + Wikipedia + - Weighting filter on + Wikipedia + - Christophe + Couvreur's 'octave' toolbox + + The coefficients in this file have been computed using Christophe Couvreur's + scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal + 1.0.9-1+b1 on i386), with
 [b, a] = cdsign(1/Fs) 
for various + sampling frequencies (8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, + 88200, 96000, and 192000 Hz). + + The sampling frequency should normally be higher than 20kHz, but most common + file sampling rates have been included for completeness. + + \example temporal/test-c_weighting.c + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** create new C-design filter + + \param samplerate sampling frequency of the signal to filter. Should be one of + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and + 192000 Hz + + \return a new filter object + +*/ +aubio_filter_t *new_aubio_filter_c_weighting (uint_t samplerate); + +/** set feedback and feedforward coefficients of a C-weighting filter + + \param f filter object to get coefficients from + \param samplerate sampling frequency of the signal to filter. Should be one of + 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and + 192000 Hz + +*/ +uint_t aubio_filter_set_c_weighting (aubio_filter_t * f, uint_t samplerate); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_FILTER_C_DESIGN_H */ diff --git a/deps/aubio/src/temporal/filter.c b/deps/aubio/src/temporal/filter.c new file mode 100644 index 0000000..776d2e6 --- /dev/null +++ b/deps/aubio/src/temporal/filter.c @@ -0,0 +1,163 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + + +/* Requires lsmp_t to be long or double. float will NOT give reliable + * results */ + +#include "aubio_priv.h" +#include "fvec.h" +#include "lvec.h" +#include "mathutils.h" +#include "temporal/filter.h" + +struct _aubio_filter_t +{ + uint_t order; + uint_t samplerate; + lvec_t *a; + lvec_t *b; + lvec_t *y; + lvec_t *x; +}; + +void +aubio_filter_do_outplace (aubio_filter_t * f, const fvec_t * in, fvec_t * out) +{ + fvec_copy (in, out); + aubio_filter_do (f, out); +} + +void +aubio_filter_do (aubio_filter_t * f, fvec_t * in) +{ + uint_t j, l, order = f->order; + lsmp_t *x = f->x->data; + lsmp_t *y = f->y->data; + lsmp_t *a = f->a->data; + lsmp_t *b = f->b->data; + + for (j = 0; j < in->length; j++) { + /* new input */ + x[0] = KILL_DENORMAL (in->data[j]); + y[0] = b[0] * x[0]; + for (l = 1; l < order; l++) { + y[0] += b[l] * x[l]; + y[0] -= a[l] * y[l]; + } + /* new output */ + in->data[j] = y[0]; + /* store for next sample */ + for (l = order - 1; l > 0; l--) { + x[l] = x[l - 1]; + y[l] = y[l - 1]; + } + } +} + +/* The rough way: reset memory of filter between each run to avoid end effects. */ +void +aubio_filter_do_filtfilt (aubio_filter_t * f, fvec_t * in, fvec_t * tmp) +{ + uint_t j; + uint_t length = in->length; + /* apply filtering */ + aubio_filter_do (f, in); + aubio_filter_do_reset (f); + /* mirror */ + for (j = 0; j < length; j++) + tmp->data[length - j - 1] = in->data[j]; + /* apply filtering on mirrored */ + aubio_filter_do (f, tmp); + aubio_filter_do_reset (f); + /* invert back */ + for (j = 0; j < length; j++) + in->data[j] = tmp->data[length - j - 1]; +} + +lvec_t * +aubio_filter_get_feedback (const aubio_filter_t * f) +{ + return f->a; +} + +lvec_t * +aubio_filter_get_feedforward (const aubio_filter_t * f) +{ + return f->b; +} + +uint_t +aubio_filter_get_order (const aubio_filter_t * f) +{ + return f->order; +} + +uint_t +aubio_filter_get_samplerate (const aubio_filter_t * f) +{ + return f->samplerate; +} + +uint_t +aubio_filter_set_samplerate (aubio_filter_t * f, uint_t samplerate) +{ + f->samplerate = samplerate; + return AUBIO_OK; +} + +void +aubio_filter_do_reset (aubio_filter_t * f) +{ + lvec_zeros (f->x); + lvec_zeros (f->y); +} + +aubio_filter_t * +new_aubio_filter (uint_t order) +{ + aubio_filter_t *f = AUBIO_NEW (aubio_filter_t); + if ((sint_t)order < 1) { + AUBIO_FREE(f); + return NULL; + } + f->x = new_lvec (order); + f->y = new_lvec (order); + f->a = new_lvec (order); + f->b = new_lvec (order); + /* by default, samplerate is not set */ + f->samplerate = 0; + f->order = order; + /* set default to identity */ + f->a->data[0] = 1.; + f->b->data[0] = 1.; + return f; +} + +void +del_aubio_filter (aubio_filter_t * f) +{ + del_lvec (f->a); + del_lvec (f->b); + del_lvec (f->x); + del_lvec (f->y); + AUBIO_FREE (f); + return; +} diff --git a/deps/aubio/src/temporal/filter.h b/deps/aubio/src/temporal/filter.h new file mode 100644 index 0000000..b8b678e --- /dev/null +++ b/deps/aubio/src/temporal/filter.h @@ -0,0 +1,176 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_FILTER_H +#define AUBIO_FILTER_H + +/** \file + + Digital filter + + This object stores a digital filter of order \f$n\f$. + It contains the following data: + - \f$ n*1 b_i \f$ feedforward coefficients + - \f$ n*1 a_i \f$ feedback coefficients + - \f$ n*c x_i \f$ input signal + - \f$ n*c y_i \f$ output signal + + For convenience, the samplerate of the input signal is also stored in the + object. + + Feedforward and feedback parameters can be modified using + aubio_filter_get_feedback() and aubio_filter_get_feedforward(). + + The function aubio_filter_do_outplace() computes the following output signal + \f$ y[n] \f$ from the input signal \f$ x[n] \f$: + + \f{eqnarray*}{ + y[n] = b_0 x[n] & + & b_1 x[n-1] + b_2 x[n-2] + ... + b_P x[n-P] \\ + & - & a_1 y[n-1] - a_2 y[n-2] - ... - a_P y[n-P] \\ + \f} + + The function aubio_filter_do() executes the same computation but modifies + directly the input signal (in-place). + + The function aubio_filter_do_filtfilt() version runs the filter twice, first + forward then backward, to compensate with the phase shifting of the forward + operation. + + Some convenience functions are provided: + - new_aubio_filter_a_weighting() and aubio_filter_set_a_weighting(), + - new_aubio_filter_c_weighting() and aubio_filter_set_c_weighting(). + - new_aubio_filter_biquad() and aubio_filter_set_biquad(). + + \example temporal/test-filter.c + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Digital filter + +*/ +typedef struct _aubio_filter_t aubio_filter_t; + +/** filter input vector (in-place) + + \param f filter object as returned by new_aubio_filter() + \param in input vector to filter + +*/ +void aubio_filter_do (aubio_filter_t * f, fvec_t * in); + +/** filter input vector (out-of-place) + + \param f filter object as returned by new_aubio_filter() + \param in input vector to filter + \param out output vector to store filtered input + +*/ +void aubio_filter_do_outplace (aubio_filter_t * f, const fvec_t * in, fvec_t * out); + +/** filter input vector forward and backward + + \param f ::aubio_filter_t object as returned by new_aubio_filter() + \param in ::fvec_t input vector to filter + \param tmp memory space to use for computation + +*/ +void aubio_filter_do_filtfilt (aubio_filter_t * f, fvec_t * in, fvec_t * tmp); + +/** returns a pointer to feedback coefficients \f$ a_i \f$ + + \param f filter object to get parameters from + + \return a pointer to the \f$ a_0 ... a_i ... a_P \f$ coefficients + +*/ +lvec_t *aubio_filter_get_feedback (const aubio_filter_t * f); + +/** returns a pointer to feedforward coefficients \f$ b_i \f$ + + \param f filter object to get coefficients from + + \return a pointer to the \f$ b_0 ... b_i ... b_P \f$ coefficients + +*/ +lvec_t *aubio_filter_get_feedforward (const aubio_filter_t * f); + +/** get order of the filter + + \param f filter to get order from + + \return the order of the filter + +*/ +uint_t aubio_filter_get_order (const aubio_filter_t * f); + +/** get sampling rate of the filter + + \param f filter to get sampling rate from + + \return the sampling rate of the filter, in Hz + +*/ +uint_t aubio_filter_get_samplerate (const aubio_filter_t * f); + +/** get sampling rate of the filter + + \param f filter to get sampling rate from + \param samplerate sample rate to set the filter to + + \return the sampling rate of the filter, in Hz + +*/ +uint_t aubio_filter_set_samplerate (aubio_filter_t * f, uint_t samplerate); + +/** reset filter memory + + \param f filter object as returned by new_aubio_filter() + +*/ +void aubio_filter_do_reset (aubio_filter_t * f); + +/** create new filter object + + This function creates a new ::aubio_filter_t object, given the order of the + filter. + + \param order order of the filter (number of coefficients) + + \return the newly created filter object + +*/ +aubio_filter_t *new_aubio_filter (uint_t order); + +/** delete a filter object + + \param f filter object to delete + +*/ +void del_aubio_filter (aubio_filter_t * f); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_FILTER_H */ diff --git a/deps/aubio/src/temporal/resampler.c b/deps/aubio/src/temporal/resampler.c new file mode 100644 index 0000000..adfb08f --- /dev/null +++ b/deps/aubio/src/temporal/resampler.c @@ -0,0 +1,100 @@ +/* + Copyright (C) 2003-2009 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "fvec.h" +#include "temporal/resampler.h" + +#ifdef HAVE_SAMPLERATE + +#if HAVE_AUBIO_DOUBLE +#error "Should not use libsamplerate with aubio in double precision" +#endif + +#include /* from libsamplerate */ + +struct _aubio_resampler_t +{ + SRC_DATA *proc; + SRC_STATE *stat; + smpl_t ratio; + uint_t type; +}; + +aubio_resampler_t * +new_aubio_resampler (smpl_t ratio, uint_t type) +{ + aubio_resampler_t *s = AUBIO_NEW (aubio_resampler_t); + int error = 0; + s->stat = src_new (type, 1, &error); /* only one channel */ + if (error) { + AUBIO_ERR ("Failed creating resampler: %s\n", src_strerror (error)); + del_aubio_resampler(s); + return NULL; + } + s->proc = AUBIO_NEW (SRC_DATA); + s->ratio = ratio; + return s; +} + +void +del_aubio_resampler (aubio_resampler_t * s) +{ + if (s->stat) src_delete (s->stat); + AUBIO_FREE (s->proc); + AUBIO_FREE (s); +} + +void +aubio_resampler_do (aubio_resampler_t * s, const fvec_t * input, fvec_t * output) +{ + s->proc->input_frames = input->length; + s->proc->output_frames = output->length; + s->proc->src_ratio = (double) s->ratio; + /* make SRC_PROC data point to input outputs */ + s->proc->data_in = (float *) input->data; + s->proc->data_out = (float *) output->data; + /* do resampling */ + src_process (s->stat, s->proc); +} + +#else +struct _aubio_resampler_t +{ + void *dummy; +}; + +aubio_resampler_t * +new_aubio_resampler (smpl_t ratio UNUSED, uint_t type UNUSED) +{ + AUBIO_ERR ("aubio was not compiled with libsamplerate\n"); + return NULL; +} + +void +del_aubio_resampler (aubio_resampler_t * s UNUSED) +{ +} + +void +aubio_resampler_do (aubio_resampler_t * s UNUSED, const fvec_t * input UNUSED, fvec_t * output UNUSED) +{ +} +#endif /* HAVE_SAMPLERATE */ diff --git a/deps/aubio/src/temporal/resampler.h b/deps/aubio/src/temporal/resampler.h new file mode 100644 index 0000000..7528e8a --- /dev/null +++ b/deps/aubio/src/temporal/resampler.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_RESAMPLER_H +#define AUBIO_RESAMPLER_H + +/** \file + + Resampling object + + This object resamples an input vector into an output vector using + libsamplerate. See http://www.mega-nerd.com/SRC/ + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** resampler object */ +typedef struct _aubio_resampler_t aubio_resampler_t; + +/** create resampler object + + \param ratio output_sample_rate / input_sample_rate + \param type libsamplerate resampling type, see http://www.mega-nerd.com/SRC/api_misc.html#Converters + +*/ +aubio_resampler_t *new_aubio_resampler (smpl_t ratio, uint_t type); + +/** delete resampler object */ +void del_aubio_resampler (aubio_resampler_t * s); + +/** resample input in output + + \param s resampler object + \param input input buffer of size N + \param output output buffer of size N*ratio + +*/ +void aubio_resampler_do (aubio_resampler_t * s, const fvec_t * input, + fvec_t * output); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_RESAMPLER_H */ diff --git a/deps/aubio/src/types.h b/deps/aubio/src/types.h new file mode 100644 index 0000000..57df2e0 --- /dev/null +++ b/deps/aubio/src/types.h @@ -0,0 +1,70 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_TYPES_H +#define AUBIO_TYPES_H + +/** \file + + Definition of data types used in aubio + +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_AUBIO_DOUBLE +/** defined to 1 if aubio is compiled in double precision */ +#define HAVE_AUBIO_DOUBLE 0 +#endif + +/** short sample format (32 or 64 bits) */ +#if !HAVE_AUBIO_DOUBLE +typedef float smpl_t; +/** print format for sample in single precision */ +#define AUBIO_SMPL_FMT "%f" +#else +typedef double smpl_t; +/** print format for double in single precision */ +#define AUBIO_SMPL_FMT "%lf" +#endif +/** long sample format (64 bits or more) */ +#if !HAVE_AUBIO_DOUBLE +typedef double lsmp_t; +/** print format for sample in double precision */ +#define AUBIO_LSMP_FMT "%lf" +#else +typedef long double lsmp_t; +/** print format for double in double precision */ +#define AUBIO_LSMP_FMT "%Lf" +#endif +/** unsigned integer */ +typedef unsigned int uint_t; +/** signed integer */ +typedef int sint_t; +/** character */ +typedef char char_t; + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_TYPES_H */ diff --git a/deps/aubio/src/utils/log.c b/deps/aubio/src/utils/log.c new file mode 100644 index 0000000..967c2d6 --- /dev/null +++ b/deps/aubio/src/utils/log.c @@ -0,0 +1,92 @@ +/* + Copyright (C) 2016 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#include "aubio_priv.h" +#include "log.h" + +/** array of pointers to logging functions, one per level */ +static aubio_log_function_t aubio_log_function[AUBIO_LOG_LAST_LEVEL]; +/** array of pointers to closure passed to logging functions, one per level */ +static void* aubio_log_user_data[AUBIO_LOG_LAST_LEVEL]; +/** buffer for logging messages */ +static char aubio_log_buffer[512]; + +/** private function used by default by logging functions */ +void +aubio_default_log(sint_t level, const char_t *message, void * data UNUSED) +{ + FILE *out; + out = stdout; + if (level == AUBIO_LOG_ERR || level == AUBIO_LOG_DBG || level == AUBIO_LOG_WRN) { + out = stderr; + } + fprintf(out, "%s", message); + //fflush(out); +} + +uint_t +aubio_log(sint_t level, const char_t *fmt, ...) +{ + aubio_log_function_t fun = NULL; + + va_list args; + va_start(args, fmt); + vsnprintf(aubio_log_buffer, sizeof(aubio_log_buffer), fmt, args); + va_end(args); + + if ((level >= 0) && (level < AUBIO_LOG_LAST_LEVEL)) { + fun = aubio_log_function[level]; + if (fun != NULL) { + (*fun)(level, aubio_log_buffer, aubio_log_user_data[level]); + } else { + aubio_default_log(level, aubio_log_buffer, NULL); + } + } + return AUBIO_FAIL; +} + +void +aubio_log_reset(void) +{ + uint_t i = 0; + for (i = 0; i < AUBIO_LOG_LAST_LEVEL; i++) { + aubio_log_set_level_function(i, aubio_default_log, NULL); + } +} + +aubio_log_function_t +aubio_log_set_level_function(sint_t level, aubio_log_function_t fun, void * data) +{ + aubio_log_function_t old = NULL; + if ((level >= 0) && (level < AUBIO_LOG_LAST_LEVEL)) { + old = aubio_log_function[level]; + aubio_log_function[level] = fun; + aubio_log_user_data[level] = data; + } + return old; +} + +void +aubio_log_set_function(aubio_log_function_t fun, void * data) { + uint_t i = 0; + for (i = 0; i < AUBIO_LOG_LAST_LEVEL; i++) { + aubio_log_set_level_function(i, fun, data); + } +} diff --git a/deps/aubio/src/utils/log.h b/deps/aubio/src/utils/log.h new file mode 100644 index 0000000..091e91d --- /dev/null +++ b/deps/aubio/src/utils/log.h @@ -0,0 +1,99 @@ +/* + Copyright (C) 2016 Paul Brossier + + This file is part of aubio. + + aubio 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. + + aubio 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 aubio. If not, see . + +*/ + +#ifndef AUBIO_LOG_H +#define AUBIO_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + + Logging features + + This file specifies ::aubio_log_set_function and + ::aubio_log_set_level_function, which let you define one or several custom + logging functions to redirect warnings and errors from aubio to your + application. The custom function should have the prototype defined in + ::aubio_log_function_t. + + After a call to ::aubio_log_set_level_function, ::aubio_log_reset can be used + to reset each logging functions to the default ones. + + \example utils/test-log.c + +*/ + +/** list of logging levels */ +enum aubio_log_level { + AUBIO_LOG_ERR, /**< critical errors */ + AUBIO_LOG_INF, /**< infos */ + AUBIO_LOG_MSG, /**< general messages */ + AUBIO_LOG_DBG, /**< debug messages */ + AUBIO_LOG_WRN, /**< warnings */ + AUBIO_LOG_LAST_LEVEL, /**< number of valid levels */ +}; + +/** Logging function prototype, to be passed to ::aubio_log_set_function + + \param level log level + \param message text to log + \param data optional closure used by the callback + + See @ref utils/test-log.c for an example of logging function. + + */ +typedef void (*aubio_log_function_t)(sint_t level, const char_t *message, void + *data); + +/** Set logging function for all levels + + \param fun the function to be used to log, of type ::aubio_log_function_t + \param data optional closure to be passed to the function (can be NULL if + nothing to pass) + + */ +void aubio_log_set_function(aubio_log_function_t fun, void* data); + +/** Set logging function for a given level + + \param level the level for which to set the logging function + \param fun the function to be used to log, of type ::aubio_log_function_t + \param data optional closure to be passed to the function (can be NULL if + nothing to pass) + +*/ +aubio_log_function_t aubio_log_set_level_function(sint_t level, + aubio_log_function_t fun, void* data); + +/** Reset all logging functions to the default one + + After calling this function, the default logging function will be used to + print error, warning, normal, and debug messages to `stdout` or `stderr`. + + */ +void aubio_log_reset(void); + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_LOG_H */ diff --git a/plugins/Cardinal/src/AudioToCVPitch.cpp b/plugins/Cardinal/src/AudioToCVPitch.cpp index cca3b8b..16bf061 100644 --- a/plugins/Cardinal/src/AudioToCVPitch.cpp +++ b/plugins/Cardinal/src/AudioToCVPitch.cpp @@ -120,7 +120,7 @@ struct AudioToCVPitch : Module { if (detectedPitchInHz > 0.f && pitchConfidence >= params[PARAM_CONFIDENCETHRESHOLD].getValue() * 0.01f) { - const float linearPitch = 12.f * (log2f(detectedPitchInHz / 440.f) + octave - 1) + 69.f; + const float linearPitch = 12.f * (log2f(detectedPitchInHz / 440.f) + octave - 5) + 69.f; cvPitch = std::max(-10.f, std::min(10.f, linearPitch * (1.f/12.f))); lastKnownPitchInHz = detectedPitchInHz; cvSignal = 10.f;