diff --git a/CMakeLists.txt b/CMakeLists.txt index 89164eb..72ad941 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,12 +62,22 @@ if (DEFINED WIN32) include_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll32 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release ) link_directories ( ${PROJECT_SOURCE_DIR}/external/fftw-3.3.4-dll32 ${PROJECT_SOURCE_DIR}/external/rtl-sdr-release/x32 ) set(FFTW_LIB fftw3-3) + + include_directories ( ${PROJECT_SOURCE_DIR}/external/portaudio/include ) + link_directories ( ${PROJECT_SOURCE_DIR}/external/portaudio/libs ) + SET (PORTAUDIO_LIBRARY portaudio.dll winmm) + + link_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/lib ) + include_directories ( ${PROJECT_SOURCE_DIR}/external/liquid-dsp/include ) else (DEFINED WIN32) set(RTLSDR_INCLUDE "/opt/local/include" CACHE FILEPATH "RTL-SDR Include Path") set(RTLSDR_LIB "/opt/local/lib" CACHE FILEPATH "RTL-SDR Lib Path") include_directories(${RTLSDR_INCLUDE}) link_directories(${RTLSDR_LIB}) + set(FFTW_LIB fftw3) + + SET (PORTAUDIO_LIBRARY portaudio) endif (DEFINED WIN32) @@ -80,6 +90,7 @@ SET (cubicsdr_sources src/AppFrame.cpp src/SDRThreadQueue.cpp src/SDRThreadTask.cpp + src/Demodulator.cpp ) SET (cubicsdr_headers @@ -91,14 +102,15 @@ SET (cubicsdr_headers src/CubicSDRDefs.h src/SDRThreadQueue.h src/SDRThreadTask.h + src/Demodulator.h ) #configure_files(${PROJECT_SOURCE_DIR}/shaders ${PROJECT_BINARY_DIR}/shaders COPYONLY) #configure_files(${PROJECT_SOURCE_DIR}/png ${PROJECT_BINARY_DIR}/png COPYONLY) add_executable(CubicSDR ${cubicsdr_sources} ${cubicsdr_headers}) -target_link_libraries(CubicSDR rtlsdr ${FFTW_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES}) -# cubicvr2 glfw ${GLFW_LIBRARIES} ${OPENAL_LIBRARY} +target_link_libraries(CubicSDR rtlsdr liquid ${FFTW_LIB} ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${PORTAUDIO_LIBRARY}) +# cubicvr2 glfw ${GLFW_LIBRARIES} diff --git a/external/liquid-dsp/COPYING b/external/liquid-dsp/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/external/liquid-dsp/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/external/liquid-dsp/include/liquid/liquid.h b/external/liquid-dsp/include/liquid/liquid.h new file mode 100644 index 0000000..933b7b3 --- /dev/null +++ b/external/liquid-dsp/include/liquid/liquid.h @@ -0,0 +1,5729 @@ +/* + * Copyright (c) 2007 - 2014 Joseph Gaeddert + * + * This file is part of liquid. + * + * liquid 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. + * + * liquid 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 liquid. If not, see . + */ +#ifndef __LIQUID_H__ +#define __LIQUID_H__ + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4003 ) +#endif + + +#ifdef __cplusplus +extern "C" { +# define LIQUID_USE_COMPLEX_H 0 +#else +# define LIQUID_USE_COMPLEX_H 1 +#endif // __cplusplus + +// +// Make sure the version and version number macros weren't defined by +// some prevoiusly included header file. +// +#ifdef LIQUID_VERSION +# undef LIQUID_VERSION +#endif +#ifdef LIQUID_VERSION_NUMBER +# undef LIQUID_VERSION_NUMBER +#endif + +// +// Compile-time version numbers +// +// LIQUID_VERSION = "X.Y.Z" +// LIQUID_VERSION_NUMBER = (X*1000000 + Y*1000 + Z) +// +#define LIQUID_VERSION "1.2.0" +#define LIQUID_VERSION_NUMBER 1002000 + +// +// Run-time library version numbers +// +extern const char liquid_version[]; +const char * liquid_libversion(void); +int liquid_libversion_number(void); + +// run-time library validation +#define LIQUID_VALIDATE_LIBVERSION \ + if (LIQUID_VERSION_NUMBER != liquid_libversion_number()) { \ + fprintf(stderr,"%s:%u: ", __FILE__,__LINE__); \ + fprintf(stderr,"error: invalid liquid runtime library\n"); \ + exit(1); \ + } \ + +#define LIQUID_CONCAT(prefix, name) prefix ## name +#define LIQUID_VALIDATE_INPUT + +/* + * Compile-time complex data type definitions + * + * Default: use the C99 complex data type, otherwise + * define complex type compatible with the C++ complex standard, + * otherwise resort to defining binary compatible array. + */ +#if LIQUID_USE_COMPLEX_H==1 +# include +# define LIQUID_DEFINE_COMPLEX(R,C) typedef R _Complex C +#elif defined _GLIBCXX_COMPLEX || defined _LIBCPP_COMPLEX +# define LIQUID_DEFINE_COMPLEX(R,C) typedef std::complex C +#else +# define LIQUID_DEFINE_COMPLEX(R,C) typedef struct {R real; R imag;} C; +#endif +//# define LIQUID_DEFINE_COMPLEX(R,C) typedef R C[2] + +LIQUID_DEFINE_COMPLEX(float, liquid_float_complex); +LIQUID_DEFINE_COMPLEX(double, liquid_double_complex); + +// +// MODULE : agc (automatic gain control) +// + +#define AGC_MANGLE_CRCF(name) LIQUID_CONCAT(agc_crcf, name) +#define AGC_MANGLE_RRRF(name) LIQUID_CONCAT(agc_rrrf, name) + +// large macro +// AGC : name-mangling macro +// T : primitive data type +// TC : input/output data type +#define LIQUID_AGC_DEFINE_API(AGC,T,TC) \ +typedef struct AGC(_s) * AGC(); \ + \ +/* create automatic gain control object */ \ +AGC() AGC(_create)(void); \ + \ +/* destroy object, freeing all internally-allocated memory */ \ +void AGC(_destroy)(AGC() _q); \ + \ +/* print object properties to stdout */ \ +void AGC(_print)(AGC() _q); \ + \ +/* reset object's internal state */ \ +void AGC(_reset)(AGC() _q); \ + \ +/* execute automatic gain control on an single input sample */ \ +/* _q : automatic gain control object */ \ +/* _x : input sample */ \ +/* _y : output sample */ \ +void AGC(_execute)(AGC() _q, \ + TC _x, \ + TC * _y); \ + \ +/* execute automatic gain control on block of samples */ \ +/* _q : automatic gain control object */ \ +/* _x : input data array, [size: _n x 1] */ \ +/* _n : number of input, output samples */ \ +/* _y : output data array, [szie: _n x 1] */ \ +void AGC(_execute_block)(AGC() _q, \ + TC * _x, \ + unsigned int _n, \ + TC * _y); \ + \ +/* lock/unlock gain control */ \ +void AGC(_lock)( AGC() _q); \ +void AGC(_unlock)(AGC() _q); \ + \ +/* get/set loop filter bandwidth; attack/release time */ \ +float AGC(_get_bandwidth)(AGC() _q); \ +void AGC(_set_bandwidth)(AGC() _q, float _bt); \ + \ +/* get/set signal level (linear) relative to unity energy */ \ +float AGC(_get_signal_level)(AGC() _q); \ +void AGC(_set_signal_level)(AGC() _q, float _signal_level); \ + \ +/* get/set signal level (dB) relative to unity energy */ \ +float AGC(_get_rssi)(AGC() _q); \ +void AGC(_set_rssi)(AGC() _q, float _rssi); \ + \ +/* get/set gain value (linear) relative to unity energy */ \ +float AGC(_get_gain)(AGC() _q); \ +void AGC(_set_gain)(AGC() _q, float _gain); \ + \ +/* initialize internal gain on input array */ \ +/* _q : automatic gain control object */ \ +/* _x : input data array, [size: _n x 1] */ \ +/* _n : number of input, output samples */ \ +void AGC(_init)(AGC() _q, \ + TC * _x, \ + unsigned int _n); \ + +// Define agc APIs +LIQUID_AGC_DEFINE_API(AGC_MANGLE_CRCF, float, liquid_float_complex) +LIQUID_AGC_DEFINE_API(AGC_MANGLE_RRRF, float, float) + + + +// +// MODULE : audio +// + +// CVSD: continuously variable slope delta +typedef struct cvsd_s * cvsd; + +// create cvsd object +// _num_bits : number of adjacent bits to observe (4 recommended) +// _zeta : slope adjustment multiplier (1.5 recommended) +// _alpha : pre-/post-emphasis filter coefficient (0.9 recommended) +// NOTE: _alpha must be in [0,1] +cvsd cvsd_create(unsigned int _num_bits, + float _zeta, + float _alpha); + +// destroy cvsd object +void cvsd_destroy(cvsd _q); + +// print cvsd object parameters +void cvsd_print(cvsd _q); + +// encode/decode single sample +unsigned char cvsd_encode(cvsd _q, float _audio_sample); +float cvsd_decode(cvsd _q, unsigned char _bit); + +// encode/decode 8 samples at a time +void cvsd_encode8(cvsd _q, float * _audio, unsigned char * _data); +void cvsd_decode8(cvsd _q, unsigned char _data, float * _audio); + + +// +// MODULE : buffer +// + +// circular buffer +#define CBUFFER_MANGLE_FLOAT(name) LIQUID_CONCAT(cbufferf, name) +#define CBUFFER_MANGLE_CFLOAT(name) LIQUID_CONCAT(cbuffercf, name) + +// large macro +// CBUFFER : name-mangling macro +// T : data type +#define LIQUID_CBUFFER_DEFINE_API(CBUFFER,T) \ +typedef struct CBUFFER(_s) * CBUFFER(); \ + \ +/* create circular buffer object of a particular size */ \ +CBUFFER() CBUFFER(_create)(unsigned int _max_size); \ + \ +/* create circular buffer object of a particular size and */ \ +/* specify the maximum number of elements that can be read */ \ +/* at any given time. */ \ +CBUFFER() CBUFFER(_create_max)(unsigned int _max_size, \ + unsigned int _max_read); \ + \ +/* destroy cbuffer object, freeing all internal memory */ \ +void CBUFFER(_destroy)(CBUFFER() _q); \ + \ +/* print cbuffer object properties */ \ +void CBUFFER(_print)(CBUFFER() _q); \ + \ +/* print cbuffer object properties and internal state */ \ +void CBUFFER(_debug_print)(CBUFFER() _q); \ + \ +/* clear internal buffer */ \ +void CBUFFER(_clear)(CBUFFER() _q); \ + \ +/* get the number of elements currently in the buffer */ \ +unsigned int CBUFFER(_size)(CBUFFER() _q); \ + \ +/* get the maximum number of elements the buffer can hold */ \ +unsigned int CBUFFER(_max_size)(CBUFFER() _q); \ + \ +/* get the maximum number of elements you may read at once */ \ +unsigned int CBUFFER(_max_read)(CBUFFER() _q); \ + \ +/* get the number of available slots (max_size - size) */ \ +unsigned int CBUFFER(_space_available)(CBUFFER() _q); \ + \ +/* is buffer full? */ \ +int CBUFFER(_is_full)(CBUFFER() _q); \ + \ +/* write a single sample into the buffer */ \ +/* _q : circular buffer object */ \ +/* _v : input sample */ \ +void CBUFFER(_push)(CBUFFER() _q, \ + T _v); \ + \ +/* write samples to the buffer */ \ +/* _q : circular buffer object */ \ +/* _v : output array */ \ +/* _n : number of samples to write */ \ +void CBUFFER(_write)(CBUFFER() _q, \ + T * _v, \ + unsigned int _n); \ + \ +/* remove and return a single element from the buffer */ \ +/* _q : circular buffer object */ \ +/* _v : pointer to sample output */ \ +void CBUFFER(_pop)(CBUFFER() _q, \ + T * _v); \ + \ +/* read buffer contents */ \ +/* _q : circular buffer object */ \ +/* _num_requested : number of elements requested */ \ +/* _v : output pointer */ \ +/* _nr : number of elements referenced by _v */ \ +void CBUFFER(_read)(CBUFFER() _q, \ + unsigned int _num_requested, \ + T ** _v, \ + unsigned int * _num_read); \ + \ +/* release _n samples from the buffer */ \ +void CBUFFER(_release)(CBUFFER() _q, \ + unsigned int _n); \ + +// Define buffer APIs +LIQUID_CBUFFER_DEFINE_API(CBUFFER_MANGLE_FLOAT, float) +LIQUID_CBUFFER_DEFINE_API(CBUFFER_MANGLE_CFLOAT, liquid_float_complex) + + + +// Windowing functions +#define WINDOW_MANGLE_FLOAT(name) LIQUID_CONCAT(windowf, name) +#define WINDOW_MANGLE_CFLOAT(name) LIQUID_CONCAT(windowcf, name) + +// large macro +// WINDOW : name-mangling macro +// T : data type +#define LIQUID_WINDOW_DEFINE_API(WINDOW,T) \ + \ +typedef struct WINDOW(_s) * WINDOW(); \ + \ +/* create window buffer object of length _n */ \ +WINDOW() WINDOW(_create)(unsigned int _n); \ + \ +/* recreate window buffer object with new length */ \ +/* _q : old window object */ \ +/* _n : new window length */ \ +WINDOW() WINDOW(_recreate)(WINDOW() _q, unsigned int _n); \ + \ +/* destroy window object, freeing all internally memory */ \ +void WINDOW(_destroy)(WINDOW() _q); \ + \ +/* print window object to stdout */ \ +void WINDOW(_print)(WINDOW() _q); \ + \ +/* print window object to stdout (with extra information) */ \ +void WINDOW(_debug_print)(WINDOW() _q); \ + \ +/* clear/reset window object (initialize to zeros) */ \ +void WINDOW(_clear)(WINDOW() _q); \ + \ +/* read window buffer contents */ \ +/* _q : window object */ \ +/* _v : output pointer (set to internal array) */ \ +void WINDOW(_read)(WINDOW() _q, T ** _v); \ + \ +/* index single element in buffer at a particular index */ \ +/* _q : window object */ \ +/* _i : index of element to read */ \ +/* _v : output value pointer */ \ +void WINDOW(_index)(WINDOW() _q, \ + unsigned int _i, \ + T * _v); \ + \ +/* push single element onto window buffer */ \ +/* _q : window object */ \ +/* _v : single input element */ \ +void WINDOW(_push)(WINDOW() _q, \ + T _v); \ + \ +/* write array of elements onto window buffer */ \ +/* _q : window object */ \ +/* _v : input array of values to write */ \ +/* _n : number of input values to write */ \ +void WINDOW(_write)(WINDOW() _q, \ + T * _v, \ + unsigned int _n); \ + +// Define window APIs +LIQUID_WINDOW_DEFINE_API(WINDOW_MANGLE_FLOAT, float) +LIQUID_WINDOW_DEFINE_API(WINDOW_MANGLE_CFLOAT, liquid_float_complex) +//LIQUID_WINDOW_DEFINE_API(WINDOW_MANGLE_UINT, unsigned int) + + +// wdelay functions : windowed-delay +// Implements an efficient z^-k delay with minimal memory +#define WDELAY_MANGLE_FLOAT(name) LIQUID_CONCAT(wdelayf, name) +#define WDELAY_MANGLE_CFLOAT(name) LIQUID_CONCAT(wdelaycf, name) +#define WDELAY_MANGLE_UINT(name) LIQUID_CONCAT(wdelayui, name) + +// large macro +// WDELAY : name-mangling macro +// T : data type +#define LIQUID_WDELAY_DEFINE_API(WDELAY,T) \ +typedef struct WDELAY(_s) * WDELAY(); \ + \ +/* create delay buffer object with '_delay' samples */ \ +WDELAY() WDELAY(_create)(unsigned int _delay); \ + \ +/* re-create delay buffer object with '_delay' samples */ \ +/* _q : old delay buffer object */ \ +/* _delay : delay for new object */ \ +WDELAY() WDELAY(_recreate)(WDELAY() _q, \ + unsigned int _delay); \ + \ +/* destroy delay buffer object, freeing internal memory */ \ +void WDELAY(_destroy)(WDELAY() _q); \ + \ +/* print delay buffer object's state to stdout */ \ +void WDELAY(_print)(WDELAY() _q); \ + \ +/* clear/reset state of object */ \ +void WDELAY(_clear)(WDELAY() _q); \ + \ +/* read delayed sample from delay buffer object */ \ +/* _q : delay buffer object */ \ +/* _v : value of delayed element */ \ +void WDELAY(_read)(WDELAY() _q, \ + T * _v); \ + \ +/* push new sample into delay buffer object */ \ +/* _q : delay buffer object */ \ +/* _v : new value to be added to buffer */ \ +void WDELAY(_push)(WDELAY() _q, \ + T _v); \ + +// Define wdelay APIs +LIQUID_WDELAY_DEFINE_API(WDELAY_MANGLE_FLOAT, float) +LIQUID_WDELAY_DEFINE_API(WDELAY_MANGLE_CFLOAT, liquid_float_complex) +//LIQUID_WDELAY_DEFINE_API(WDELAY_MANGLE_UINT, unsigned int) + + + +// +// MODULE : dotprod (vector dot product) +// + +#define DOTPROD_MANGLE_RRRF(name) LIQUID_CONCAT(dotprod_rrrf,name) +#define DOTPROD_MANGLE_CCCF(name) LIQUID_CONCAT(dotprod_cccf,name) +#define DOTPROD_MANGLE_CRCF(name) LIQUID_CONCAT(dotprod_crcf,name) + +// large macro +// DOTPROD : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_DOTPROD_DEFINE_API(DOTPROD,TO,TC,TI) \ + \ +/* run dot product without creating object [unrolled loop] */ \ +/* _v : coefficients array [size: _n x 1] */ \ +/* _x : input array [size: _n x 1] */ \ +/* _n : dotprod length, _n > 0 */ \ +/* _y : output sample pointer */ \ +void DOTPROD(_run)( TC *_v, TI *_x, unsigned int _n, TO *_y); \ +void DOTPROD(_run4)(TC *_v, TI *_x, unsigned int _n, TO *_y); \ + \ +typedef struct DOTPROD(_s) * DOTPROD(); \ + \ +/* create dot product object */ \ +/* _v : coefficients array [size: _n x 1] */ \ +/* _n : dotprod length, _n > 0 */ \ +DOTPROD() DOTPROD(_create)(TC * _v, \ + unsigned int _n); \ + \ +/* re-create dot product object */ \ +/* _q : old dotprod object */ \ +/* _v : coefficients array [size: _n x 1] */ \ +/* _n : dotprod length, _n > 0 */ \ +DOTPROD() DOTPROD(_recreate)(DOTPROD() _q, \ + TC * _v, \ + unsigned int _n); \ + \ +/* destroy dotprod object, freeing all internal memory */ \ +void DOTPROD(_destroy)(DOTPROD() _q); \ + \ +/* print dotprod object internals to standard output */ \ +void DOTPROD(_print)(DOTPROD() _q); \ + \ +/* execute dot product */ \ +/* _q : dotprod object */ \ +/* _x : input array [size: _n x 1] */ \ +/* _y : output sample pointer */ \ +void DOTPROD(_execute)(DOTPROD() _q, \ + TI * _x, \ + TO * _y); \ + +LIQUID_DOTPROD_DEFINE_API(DOTPROD_MANGLE_RRRF, + float, + float, + float) + +LIQUID_DOTPROD_DEFINE_API(DOTPROD_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +LIQUID_DOTPROD_DEFINE_API(DOTPROD_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +// +// sum squared methods +// + +float liquid_sumsqf(float * _v, + unsigned int _n); + +float liquid_sumsqcf(liquid_float_complex * _v, + unsigned int _n); + + +// +// MODULE : equalization +// + +// least mean-squares (LMS) +#define EQLMS_MANGLE_RRRF(name) LIQUID_CONCAT(eqlms_rrrf,name) +#define EQLMS_MANGLE_CCCF(name) LIQUID_CONCAT(eqlms_cccf,name) + +// large macro +// EQLMS : name-mangling macro +// T : data type +#define LIQUID_EQLMS_DEFINE_API(EQLMS,T) \ +typedef struct EQLMS(_s) * EQLMS(); \ + \ +/* create LMS EQ initialized with external coefficients */ \ +/* _h : filter coefficients (NULL for {1,0,0...}) */ \ +/* _p : filter length */ \ +EQLMS() EQLMS(_create)(T * _h, \ + unsigned int _p); \ + \ +/* create LMS EQ initialized with square-root Nyquist */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RRC) */ \ +/* _k : samples/symbol */ \ +/* _m : filter delay (symbols) */ \ +/* _beta : rolloff factor (0 < beta <= 1) */ \ +/* _dt : fractional sample delay */ \ +EQLMS() EQLMS(_create_rnyquist)(int _type, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + float _dt); \ + \ +/* re-create EQ initialized with external coefficients */ \ +/* _q : equalizer object */ \ +/* _h : filter coefficients (NULL for {1,0,0...}) */ \ +/* _p : filter length */ \ +EQLMS() EQLMS(_recreate)(EQLMS() _q, \ + T * _h, \ + unsigned int _p); \ + \ +/* destroy equalizer object, freeing all internal memory */ \ +void EQLMS(_destroy)(EQLMS() _q); \ + \ +/* reset equalizer object, clearing internal state */ \ +void EQLMS(_reset)(EQLMS() _q); \ + \ +/* print equalizer internal state */ \ +void EQLMS(_print)(EQLMS() _q); \ + \ +/* get/set equalizer learning rate */ \ +float EQLMS(_get_bw)(EQLMS() _q); \ +void EQLMS(_set_bw)(EQLMS() _q, \ + float _lambda); \ + \ +/* push sample into equalizer internal buffer */ \ +void EQLMS(_push)(EQLMS() _q, \ + T _x); \ + \ +/* execute internal dot product and return result */ \ +/* _q : equalizer object */ \ +/* _y : output sample */ \ +void EQLMS(_execute)(EQLMS() _q, \ + T * _y); \ + \ +/* step through one cycle of equalizer training */ \ +/* _q : equalizer object */ \ +/* _d : desired output */ \ +/* _d_hat : actual output */ \ +void EQLMS(_step)(EQLMS() _q, \ + T _d, \ + T _d_hat); \ + \ +/* get equalizer's internal coefficients */ \ +/* _q : equalizer object */ \ +/* _w : weights [size: _p x 1] */ \ +void EQLMS(_get_weights)(EQLMS() _q, \ + T * _w); \ + \ +/* train equalizer object on group of samples */ \ +/* _q : equalizer object */ \ +/* _w : input/output weights [size: _p x 1] */ \ +/* _x : received sample vector [size: _n x 1] */ \ +/* _d : desired output vector [size: _n x 1] */ \ +/* _n : input, output vector length */ \ +void EQLMS(_train)(EQLMS() _q, \ + T * _w, \ + T * _x, \ + T * _d, \ + unsigned int _n); \ + +LIQUID_EQLMS_DEFINE_API(EQLMS_MANGLE_RRRF, float); +LIQUID_EQLMS_DEFINE_API(EQLMS_MANGLE_CCCF, liquid_float_complex); + + +// recursive least-squares (RLS) +#define EQRLS_MANGLE_RRRF(name) LIQUID_CONCAT(eqrls_rrrf,name) +#define EQRLS_MANGLE_CCCF(name) LIQUID_CONCAT(eqrls_cccf,name) + +// large macro +// EQRLS : name-mangling macro +// T : data type +#define LIQUID_EQRLS_DEFINE_API(EQRLS,T) \ +typedef struct EQRLS(_s) * EQRLS(); \ + \ +/* create RLS EQ initialized with external coefficients */ \ +/* _h : filter coefficients (NULL for {1,0,0...}) */ \ +/* _p : filter length */ \ +EQRLS() EQRLS(_create)(T * _h, \ + unsigned int _p); \ + \ +/* re-create RLS EQ initialized with external coefficients */ \ +/* _q : initial equalizer object */ \ +/* _h : filter coefficients (NULL for {1,0,0...}) */ \ +/* _p : filter length */ \ +EQRLS() EQRLS(_recreate)(EQRLS() _q, \ + T * _h, \ + unsigned int _p); \ + \ +/* destroy equalizer object, freeing all internal memory */ \ +void EQRLS(_destroy)(EQRLS() _q); \ + \ +/* print equalizer internal state */ \ +void EQRLS(_print)(EQRLS() _q); \ + \ +/* reset equalizer object, clearing internal state */ \ +void EQRLS(_reset)(EQRLS() _q); \ + \ +/* get/set equalizer learning rate */ \ +float EQRLS(_get_bw)(EQRLS() _q); \ +void EQRLS(_set_bw)(EQRLS() _q, \ + float _mu); \ + \ +/* push sample into equalizer internal buffer */ \ +void EQRLS(_push)(EQRLS() _q, T _x); \ + \ +/* execute internal dot product and return result */ \ +/* _q : equalizer object */ \ +/* _y : output sample */ \ +void EQRLS(_execute)(EQRLS() _q, T * _y); \ + \ +/* step through one cycle of equalizer training */ \ +/* _q : equalizer object */ \ +/* _d : desired output */ \ +/* _d_hat : actual output */ \ +void EQRLS(_step)(EQRLS() _q, T _d, T _d_hat); \ + \ +/* retrieve internal filter coefficients */ \ +/* _q : equalizer object */ \ +/* _w : weights [size: _p x 1] */ \ +void EQRLS(_get_weights)(EQRLS() _q, \ + T * _w); \ + \ +/* train equalizer object on group of samples */ \ +/* _q : equalizer object */ \ +/* _w : input/output weights [size: _p x 1] */ \ +/* _x : received sample vector [size: _n x 1] */ \ +/* _d : desired output vector [size: _n x 1] */ \ +/* _n : input, output vector length */ \ +void EQRLS(_train)(EQRLS() _q, \ + T * _w, \ + T * _x, \ + T * _d, \ + unsigned int _n); + +LIQUID_EQRLS_DEFINE_API(EQRLS_MANGLE_RRRF, float); +LIQUID_EQRLS_DEFINE_API(EQRLS_MANGLE_CCCF, liquid_float_complex); + + + + +// +// MODULE : fec (forward error-correction) +// + +// soft bit values +#define LIQUID_SOFTBIT_0 (0) +#define LIQUID_SOFTBIT_1 (255) +#define LIQUID_SOFTBIT_ERASURE (127) + +// available CRC schemes +#define LIQUID_CRC_NUM_SCHEMES 7 +typedef enum { + LIQUID_CRC_UNKNOWN=0, // unknown/unavailable CRC scheme + LIQUID_CRC_NONE, // no error-detection + LIQUID_CRC_CHECKSUM, // 8-bit checksum + LIQUID_CRC_8, // 8-bit CRC + LIQUID_CRC_16, // 16-bit CRC + LIQUID_CRC_24, // 24-bit CRC + LIQUID_CRC_32 // 32-bit CRC +} crc_scheme; + +// pretty names for crc schemes +extern const char * crc_scheme_str[LIQUID_CRC_NUM_SCHEMES][2]; + +// Print compact list of existing and available CRC schemes +void liquid_print_crc_schemes(); + +// returns crc_scheme based on input string +crc_scheme liquid_getopt_str2crc(const char * _str); + +// get length of CRC (bytes) +unsigned int crc_get_length(crc_scheme _scheme); + +// generate error-detection key +// +// _scheme : error-detection scheme +// _msg : input data message, [size: _n x 1] +// _n : input data message size +unsigned int crc_generate_key(crc_scheme _scheme, + unsigned char * _msg, + unsigned int _n); + +// validate message using error-detection key +// +// _scheme : error-detection scheme +// _msg : input data message, [size: _n x 1] +// _n : input data message size +// _key : error-detection key +int crc_validate_message(crc_scheme _scheme, + unsigned char * _msg, + unsigned int _n, + unsigned int _key); + + +// available FEC schemes +#define LIQUID_FEC_NUM_SCHEMES 28 +typedef enum { + LIQUID_FEC_UNKNOWN=0, // unknown/unsupported scheme + LIQUID_FEC_NONE, // no error-correction + LIQUID_FEC_REP3, // simple repeat code, r1/3 + LIQUID_FEC_REP5, // simple repeat code, r1/5 + LIQUID_FEC_HAMMING74, // Hamming (7,4) block code, r1/2 (really 4/7) + LIQUID_FEC_HAMMING84, // Hamming (7,4) with extra parity bit, r1/2 + LIQUID_FEC_HAMMING128, // Hamming (12,8) block code, r2/3 + + LIQUID_FEC_GOLAY2412, // Golay (24,12) block code, r1/2 + LIQUID_FEC_SECDED2216, // SEC-DED (22,16) block code, r8/11 + LIQUID_FEC_SECDED3932, // SEC-DED (39,32) block code + LIQUID_FEC_SECDED7264, // SEC-DED (72,64) block code, r8/9 + + // codecs not defined internally (see http://www.ka9q.net/code/fec/) + LIQUID_FEC_CONV_V27, // r1/2, K=7, dfree=10 + LIQUID_FEC_CONV_V29, // r1/2, K=9, dfree=12 + LIQUID_FEC_CONV_V39, // r1/3, K=9, dfree=18 + LIQUID_FEC_CONV_V615, // r1/6, K=15, dfree<=57 (Heller 1968) + + // punctured (perforated) codes + LIQUID_FEC_CONV_V27P23, // r2/3, K=7, dfree=6 + LIQUID_FEC_CONV_V27P34, // r3/4, K=7, dfree=5 + LIQUID_FEC_CONV_V27P45, // r4/5, K=7, dfree=4 + LIQUID_FEC_CONV_V27P56, // r5/6, K=7, dfree=4 + LIQUID_FEC_CONV_V27P67, // r6/7, K=7, dfree=3 + LIQUID_FEC_CONV_V27P78, // r7/8, K=7, dfree=3 + + LIQUID_FEC_CONV_V29P23, // r2/3, K=9, dfree=7 + LIQUID_FEC_CONV_V29P34, // r3/4, K=9, dfree=6 + LIQUID_FEC_CONV_V29P45, // r4/5, K=9, dfree=5 + LIQUID_FEC_CONV_V29P56, // r5/6, K=9, dfree=5 + LIQUID_FEC_CONV_V29P67, // r6/7, K=9, dfree=4 + LIQUID_FEC_CONV_V29P78, // r7/8, K=9, dfree=4 + + // Reed-Solomon codes + LIQUID_FEC_RS_M8 // m=8, n=255, k=223 +} fec_scheme; + +// pretty names for fec schemes +extern const char * fec_scheme_str[LIQUID_FEC_NUM_SCHEMES][2]; + +// Print compact list of existing and available FEC schemes +void liquid_print_fec_schemes(); + +// returns fec_scheme based on input string +fec_scheme liquid_getopt_str2fec(const char * _str); + +// fec object (pointer to fec structure) +typedef struct fec_s * fec; + +// return the encoded message length using a particular error- +// correction scheme (object-independent method) +// _scheme : forward error-correction scheme +// _msg_len : raw, uncoded message length +unsigned int fec_get_enc_msg_length(fec_scheme _scheme, + unsigned int _msg_len); + +// get the theoretical rate of a particular forward error- +// correction scheme (object-independent method) +float fec_get_rate(fec_scheme _scheme); + +// create a fec object of a particular scheme +// _scheme : error-correction scheme +// _opts : (ignored) +fec fec_create(fec_scheme _scheme, + void *_opts); + +// recreate fec object +// _q : old fec object +// _scheme : new error-correction scheme +// _opts : (ignored) +fec fec_recreate(fec _q, + fec_scheme _scheme, + void *_opts); + +// destroy fec object +void fec_destroy(fec _q); + +// print fec object internals +void fec_print(fec _q); + +// encode a block of data using a fec scheme +// _q : fec object +// _dec_msg_len : decoded message length +// _msg_dec : decoded message +// _msg_enc : encoded message +void fec_encode(fec _q, + unsigned int _dec_msg_len, + unsigned char * _msg_dec, + unsigned char * _msg_enc); + +// decode a block of data using a fec scheme +// _q : fec object +// _dec_msg_len : decoded message length +// _msg_enc : encoded message +// _msg_dec : decoded message +void fec_decode(fec _q, + unsigned int _dec_msg_len, + unsigned char * _msg_enc, + unsigned char * _msg_dec); + +// decode a block of data using a fec scheme (soft decision) +// _q : fec object +// _dec_msg_len : decoded message length +// _msg_enc : encoded message (soft bits) +// _msg_dec : decoded message +void fec_decode_soft(fec _q, + unsigned int _dec_msg_len, + unsigned char * _msg_enc, + unsigned char * _msg_dec); + +// +// Packetizer +// + +// computes the number of encoded bytes after packetizing +// +// _n : number of uncoded input bytes +// _crc : error-detecting scheme +// _fec0 : inner forward error-correction code +// _fec1 : outer forward error-correction code +unsigned int packetizer_compute_enc_msg_len(unsigned int _n, + int _crc, + int _fec0, + int _fec1); + +// computes the number of decoded bytes before packetizing +// +// _k : number of encoded bytes +// _crc : error-detecting scheme +// _fec0 : inner forward error-correction code +// _fec1 : outer forward error-correction code +unsigned int packetizer_compute_dec_msg_len(unsigned int _k, + int _crc, + int _fec0, + int _fec1); + +typedef struct packetizer_s * packetizer; + +// create packetizer object +// +// _n : number of uncoded input bytes +// _crc : error-detecting scheme +// _fec0 : inner forward error-correction code +// _fec1 : outer forward error-correction code +packetizer packetizer_create(unsigned int _dec_msg_len, + int _crc, + int _fec0, + int _fec1); + +// re-create packetizer object +// +// _p : initialz packetizer object +// _n : number of uncoded input bytes +// _crc : error-detecting scheme +// _fec0 : inner forward error-correction code +// _fec1 : outer forward error-correction code +packetizer packetizer_recreate(packetizer _p, + unsigned int _dec_msg_len, + int _crc, + int _fec0, + int _fec1); + +// destroy packetizer object +void packetizer_destroy(packetizer _p); + +// print packetizer object internals +void packetizer_print(packetizer _p); + +unsigned int packetizer_get_dec_msg_len(packetizer _p); +unsigned int packetizer_get_enc_msg_len(packetizer _p); + + +// packetizer_encode() +// +// Execute the packetizer on an input message +// +// _p : packetizer object +// _msg : input message (uncoded bytes) +// _pkt : encoded output message +void packetizer_encode(packetizer _p, + unsigned char * _msg, + unsigned char * _pkt); + +// packetizer_decode() +// +// Execute the packetizer to decode an input message, return validity +// check of resulting data +// +// _p : packetizer object +// _pkt : input message (coded bytes) +// _msg : decoded output message +int packetizer_decode(packetizer _p, + unsigned char * _pkt, + unsigned char * _msg); + +// Execute the packetizer to decode an input message, return validity +// check of resulting data +// +// _p : packetizer object +// _pkt : input message (coded soft bits) +// _msg : decoded output message +int packetizer_decode_soft(packetizer _p, + unsigned char * _pkt, + unsigned char * _msg); + + +// +// interleaver +// +typedef struct interleaver_s * interleaver; + +// create interleaver +// _n : number of bytes +interleaver interleaver_create(unsigned int _n); + +// destroy interleaver object +void interleaver_destroy(interleaver _q); + +// print interleaver object internals +void interleaver_print(interleaver _q); + +// set depth (number of internal iterations) +// _q : interleaver object +// _depth : depth +void interleaver_set_depth(interleaver _q, + unsigned int _depth); + +// execute forward interleaver (encoder) +// _q : interleaver object +// _msg_dec : decoded (un-interleaved) message +// _msg_enc : encoded (interleaved) message +void interleaver_encode(interleaver _q, + unsigned char * _msg_dec, + unsigned char * _msg_enc); + +// execute forward interleaver (encoder) on soft bits +// _q : interleaver object +// _msg_dec : decoded (un-interleaved) message +// _msg_enc : encoded (interleaved) message +void interleaver_encode_soft(interleaver _q, + unsigned char * _msg_dec, + unsigned char * _msg_enc); + +// execute reverse interleaver (decoder) +// _q : interleaver object +// _msg_enc : encoded (interleaved) message +// _msg_dec : decoded (un-interleaved) message +void interleaver_decode(interleaver _q, + unsigned char * _msg_enc, + unsigned char * _msg_dec); + +// execute reverse interleaver (decoder) on soft bits +// _q : interleaver object +// _msg_enc : encoded (interleaved) message +// _msg_dec : decoded (un-interleaved) message +void interleaver_decode_soft(interleaver _q, + unsigned char * _msg_enc, + unsigned char * _msg_dec); + + + +// +// MODULE : fft (fast Fourier transform) +// + +// type of transform +typedef enum { + LIQUID_FFT_UNKNOWN = 0, // unknown transform type + + // regular complex one-dimensional transforms + LIQUID_FFT_FORWARD = +1, // complex one-dimensional FFT + LIQUID_FFT_BACKWARD = -1, // complex one-dimensional inverse FFT + + // discrete cosine transforms + LIQUID_FFT_REDFT00 = 10, // real one-dimensional DCT-I + LIQUID_FFT_REDFT10 = 11, // real one-dimensional DCT-II + LIQUID_FFT_REDFT01 = 12, // real one-dimensional DCT-III + LIQUID_FFT_REDFT11 = 13, // real one-dimensional DCT-IV + + // discrete sine transforms + LIQUID_FFT_RODFT00 = 20, // real one-dimensional DST-I + LIQUID_FFT_RODFT10 = 21, // real one-dimensional DST-II + LIQUID_FFT_RODFT01 = 22, // real one-dimensional DST-III + LIQUID_FFT_RODFT11 = 23, // real one-dimensional DST-IV + + // modified discrete cosine transform + LIQUID_FFT_MDCT = 30, // MDCT + LIQUID_FFT_IMDCT = 31, // IMDCT +} liquid_fft_type; + +#define LIQUID_FFT_MANGLE_FLOAT(name) LIQUID_CONCAT(fft,name) + +// Macro : FFT +// FFT : name-mangling macro +// T : primitive data type +// TC : primitive data type (complex) +#define LIQUID_FFT_DEFINE_API(FFT,T,TC) \ + \ +typedef struct FFT(plan_s) * FFT(plan); \ + \ +/* create regular complex one-dimensional transform */ \ +/* _n : transform size */ \ +/* _x : pointer to input array [size: _n x 1] */ \ +/* _y : pointer to output array [size: _n x 1] */ \ +/* _dir : direction (e.g. LIQUID_FFT_FORWARD) */ \ +/* _flags : options, optimization */ \ +FFT(plan) FFT(_create_plan)(unsigned int _n, \ + TC * _x, \ + TC * _y, \ + int _dir, \ + int _flags); \ + \ +/* create real-to-real transform */ \ +/* _n : transform size */ \ +/* _x : pointer to input array [size: _n x 1] */ \ +/* _y : pointer to output array [size: _n x 1] */ \ +/* _type : transform type (e.g. LIQUID_FFT_REDFT00) */ \ +/* _flags : options, optimization */ \ +FFT(plan) FFT(_create_plan_r2r_1d)(unsigned int _n, \ + T * _x, \ + T * _y, \ + int _type, \ + int _flags); \ + \ +/* destroy transform */ \ +void FFT(_destroy_plan)(FFT(plan) _p); \ + \ +/* print transform plan and internal strategy */ \ +void FFT(_print_plan)(FFT(plan) _p); \ + \ +/* run the transform */ \ +void FFT(_execute)(FFT(plan) _p); \ + \ +/* object-independent methods */ \ + \ +/* perform n-point FFT allocating plan internally */ \ +/* _nfft : fft size */ \ +/* _x : input array [size: _nfft x 1] */ \ +/* _y : output array [size: _nfft x 1] */ \ +/* _dir : fft direction: LIQUID_FFT_{FORWARD,BACKWARD} */ \ +/* _flags : fft flags */ \ +void FFT(_run)(unsigned int _n, \ + TC * _x, \ + TC * _y, \ + int _dir, \ + int _flags); \ + \ +/* perform n-point real FFT allocating plan internally */ \ +/* _nfft : fft size */ \ +/* _x : input array [size: _nfft x 1] */ \ +/* _y : output array [size: _nfft x 1] */ \ +/* _type : fft type, e.g. LIQUID_FFT_REDFT10 */ \ +/* _flags : fft flags */ \ +void FFT(_r2r_1d_run)(unsigned int _n, \ + T * _x, \ + T * _y, \ + int _type, \ + int _flags); \ + \ +/* perform _n-point fft shift */ \ +void FFT(_shift)(TC * _x, \ + unsigned int _n); \ + + +LIQUID_FFT_DEFINE_API(LIQUID_FFT_MANGLE_FLOAT,float,liquid_float_complex) + +// antiquated fft methods +// FFT(plan) FFT(_create_plan_mdct)(unsigned int _n, +// T * _x, +// T * _y, +// int _kind, +// int _flags); + + +// +// spectral periodogram +// + +#define LIQUID_SPGRAM_MANGLE_CFLOAT(name) LIQUID_CONCAT(spgramcf,name) +#define LIQUID_SPGRAM_MANGLE_FLOAT(name) LIQUID_CONCAT(spgramf, name) + +// Macro : SPGRAM +// SPGRAM : name-mangling macro +// T : primitive data type +// TC : primitive data type (complex) +// TI : primitive data type (input) +#define LIQUID_SPGRAM_DEFINE_API(SPGRAM,T,TC,TI) \ + \ +typedef struct SPGRAM(_s) * SPGRAM(); \ + \ +/* create spgram object */ \ +/* _nfft : FFT size */ \ +/* _window : window [size: _window_len x 1] */ \ +/* _window_len : window length */ \ +SPGRAM() SPGRAM(_create)(unsigned int _nfft, \ + float * _window, \ + unsigned int _window_len); \ + \ +/* create spgram object with Kaiser-Bessel window */ \ +/* _nfft : FFT size */ \ +/* _window_len : window length */ \ +/* _beta : Kaiser-Bessel parameter (_beta > 0) */ \ +SPGRAM() SPGRAM(_create_kaiser)(unsigned int _nfft, \ + unsigned int _window_len, \ + float _beta); \ + \ +/* destroy spgram object */ \ +void SPGRAM(_destroy)(SPGRAM() _q); \ + \ +/* resets the internal state of the spgram object */ \ +void SPGRAM(_reset)(SPGRAM() _q); \ + \ +/* push samples into spgram object */ \ +/* _q : spgram object */ \ +/* _x : input buffer [size: _n x 1] */ \ +/* _n : input buffer length */ \ +void SPGRAM(_push)(SPGRAM() _q, \ + TI * _x, \ + unsigned int _n); \ + \ +/* compute spectral periodogram output from current buffer */ \ +/* contents */ \ +/* _q : spgram object */ \ +/* _X : output complex spectrum [size: _nfft x 1] */ \ +void SPGRAM(_execute)(SPGRAM() _q, \ + TC * _X); \ + \ +/* accumulate power spectral density */ \ +/* _q : spgram object */ \ +/* _x : input buffer [size: _n x 1] */ \ +/* _n : input buffer length */ \ +void SPGRAM(_accumulate_psd)(SPGRAM() _q, \ + TI * _x, \ + unsigned int _n); \ + \ +/* write accumulated psd */ \ +/* _q : spgram object */ \ +/* _x : input buffer [size: _n x 1] */ \ +/* _n : input buffer length [size: _nfft x 1] */ \ +void SPGRAM(_write_accumulation)(SPGRAM() _q, \ + T * _x); \ + \ +/* estimate spectrum on input signal */ \ +/* _q : spgram object */ \ +/* _x : input signal [size: _n x 1] */ \ +/* _n : input signal length */ \ +/* _psd : output spectrum, [size: _nfft x 1] */ \ +void SPGRAM(_estimate_psd)(SPGRAM() _q, \ + TI * _x, \ + unsigned int _n, \ + T * _psd); \ + +LIQUID_SPGRAM_DEFINE_API(LIQUID_SPGRAM_MANGLE_CFLOAT, + float, + liquid_float_complex, + liquid_float_complex) + +LIQUID_SPGRAM_DEFINE_API(LIQUID_SPGRAM_MANGLE_FLOAT, + float, + liquid_float_complex, + float) + + +// ascii spectrogram +typedef struct asgram_s * asgram; + +// create asgram object +// _nfft : FFT size +asgram asgram_create(unsigned int _nfft); +void asgram_destroy(asgram _q); +void asgram_reset(asgram _q); +void asgram_set_scale(asgram _q, float _offset, float _scale); + +// push samples into asgram object +// _q : asgram object +// _x : input buffer [size: _n x 1] +// _n : input buffer length +void asgram_push(asgram _q, + liquid_float_complex * _x, + unsigned int _n); + +// execute asgram +// _q : asgram object +// _ascii : ASCII character output buffer [size: _nfft x 1] +// _peakval : peak PSD value [dB] +// _peakfreq : normalized frequency of peak PSD value +void asgram_execute(asgram _q, + char * _ascii, + float * _peakval, + float * _peakfreq); + +// +// MODULE : filter +// + +// +// firdes: finite impulse response filter design +// + +// prototypes +typedef enum { + LIQUID_FIRFILT_UNKNOWN=0, // unknown filter type + + // Nyquist filter prototypes + LIQUID_FIRFILT_KAISER, // Nyquist Kaiser filter + LIQUID_FIRFILT_PM, // Parks-McClellan filter + LIQUID_FIRFILT_RCOS, // raised-cosine filter + LIQUID_FIRFILT_FEXP, // flipped exponential + LIQUID_FIRFILT_FSECH, // flipped hyperbolic secant + LIQUID_FIRFILT_FARCSECH, // flipped arc-hyperbolic secant + + // root-Nyquist filter prototypes + LIQUID_FIRFILT_ARKAISER, // root-Nyquist Kaiser (approximate optimum) + LIQUID_FIRFILT_RKAISER, // root-Nyquist Kaiser (true optimum) + LIQUID_FIRFILT_RRC, // root raised-cosine + LIQUID_FIRFILT_hM3, // harris-Moerder-3 filter + LIQUID_FIRFILT_GMSKTX, // GMSK transmit filter + LIQUID_FIRFILT_GMSKRX, // GMSK receive filter + LIQUID_FIRFILT_RFEXP, // flipped exponential + LIQUID_FIRFILT_RFSECH, // flipped hyperbolic secant + LIQUID_FIRFILT_RFARCSECH, // flipped arc-hyperbolic secant +} liquid_firfilt_type; + +// returns filter type based on input string +int liquid_getopt_str2firfilt(const char * _str); + +// estimate required filter length given +// _df : transition bandwidth (0 < _b < 0.5) +// _As : stop-band attenuation [dB], _As > 0 +unsigned int estimate_req_filter_len(float _df, + float _As); + +// estimate filter stop-band attenuation given +// _df : transition bandwidth (0 < _b < 0.5) +// _N : filter length +float estimate_req_filter_As(float _df, + unsigned int _N); + +// estimate filter transition bandwidth given +// _As : stop-band attenuation [dB], _As > 0 +// _N : filter length +float estimate_req_filter_df(float _As, + unsigned int _N); + + +// returns the Kaiser window beta factor give the filter's target +// stop-band attenuation (As) [Vaidyanathan:1993] +// _As : target filter's stop-band attenuation [dB], _As > 0 +float kaiser_beta_As(float _As); + + +// Design Nyquist filter +// _type : filter type (e.g. LIQUID_FIRFILT_RCOS) +// _k : samples/symbol +// _m : symbol delay +// _beta : excess bandwidth factor, _beta in [0,1] +// _dt : fractional sample delay +// _h : output coefficient buffer (length: 2*k*m+1) +void liquid_firdes_nyquist(liquid_firfilt_type _type, + unsigned int _k, + unsigned int _m, + float _beta, + float _dt, + float * _h); + + +// Design FIR filter using Parks-McClellan algorithm + +// band type specifier +typedef enum { + LIQUID_FIRDESPM_BANDPASS=0, // regular band-pass filter + LIQUID_FIRDESPM_DIFFERENTIATOR, // differentiating filter + LIQUID_FIRDESPM_HILBERT // Hilbert transform +} liquid_firdespm_btype; + +// weighting type specifier +typedef enum { + LIQUID_FIRDESPM_FLATWEIGHT=0, // flat weighting + LIQUID_FIRDESPM_EXPWEIGHT, // exponential weighting + LIQUID_FIRDESPM_LINWEIGHT, // linear weighting +} liquid_firdespm_wtype; + +// run filter design (full life cycle of object) +// _h_len : length of filter (number of taps) +// _num_bands : number of frequency bands +// _bands : band edges, f in [0,0.5], [size: _num_bands x 2] +// _des : desired response [size: _num_bands x 1] +// _weights : response weighting [size: _num_bands x 1] +// _wtype : weight types (e.g. LIQUID_FIRDESPM_FLATWEIGHT) [size: _num_bands x 1] +// _btype : band type (e.g. LIQUID_FIRDESPM_BANDPASS) +// _h : output coefficients array [size: _h_len x 1] +void firdespm_run(unsigned int _h_len, + unsigned int _num_bands, + float * _bands, + float * _des, + float * _weights, + liquid_firdespm_wtype * _wtype, + liquid_firdespm_btype _btype, + float * _h); + +// structured object +typedef struct firdespm_s * firdespm; + +// create firdespm object +// _h_len : length of filter (number of taps) +// _num_bands : number of frequency bands +// _bands : band edges, f in [0,0.5], [size: _num_bands x 2] +// _des : desired response [size: _num_bands x 1] +// _weights : response weighting [size: _num_bands x 1] +// _wtype : weight types (e.g. LIQUID_FIRDESPM_FLATWEIGHT) [size: _num_bands x 1] +// _btype : band type (e.g. LIQUID_FIRDESPM_BANDPASS) +firdespm firdespm_create(unsigned int _h_len, + unsigned int _num_bands, + float * _bands, + float * _des, + float * _weights, + liquid_firdespm_wtype * _wtype, + liquid_firdespm_btype _btype); + +// destroy firdespm object +void firdespm_destroy(firdespm _q); + +// print firdespm object internals +void firdespm_print(firdespm _q); + +// execute filter design, storing result in _h +void firdespm_execute(firdespm _q, float * _h); + + +// Design FIR using kaiser window +// _n : filter length, _n > 0 +// _fc : cutoff frequency, 0 < _fc < 0.5 +// _As : stop-band attenuation [dB], _As > 0 +// _mu : fractional sample offset, -0.5 < _mu < 0.5 +// _h : output coefficient buffer, [size: _n x 1] +void liquid_firdes_kaiser(unsigned int _n, + float _fc, + float _As, + float _mu, + float *_h); + +// Design FIR doppler filter +// _n : filter length +// _fd : normalized doppler frequency (0 < _fd < 0.5) +// _K : Rice fading factor (K >= 0) +// _theta : LoS component angle of arrival +// _h : output coefficient buffer +void liquid_firdes_doppler(unsigned int _n, + float _fd, + float _K, + float _theta, + float *_h); + + +// Design Nyquist raised-cosine filter +// _k : samples/symbol +// _m : symbol delay +// _beta : rolloff factor (0 < beta <= 1) +// _dt : fractional sample delay +// _h : output coefficient buffer (length: 2*k*m+1) +void liquid_firdes_rcos(unsigned int _k, + unsigned int _m, + float _beta, + float _dt, + float * _h); + +// Design root-Nyquist filter +// _type : filter type (e.g. LIQUID_FIRFILT_RRC) +// _k : samples/symbol, _k > 1 +// _m : symbol delay, _m > 0 +// _beta : excess bandwidth factor, _beta in [0,1) +// _dt : fractional sample delay, _dt in [-1,1] +// _h : output coefficient buffer (length: 2*_k*_m+1) +void liquid_firdes_rnyquist(liquid_firfilt_type _type, + unsigned int _k, + unsigned int _m, + float _beta, + float _dt, + float * _h); + +// Design root-Nyquist raised-cosine filter +void liquid_firdes_rrcos(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Design root-Nyquist Kaiser filter +void liquid_firdes_rkaiser(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Design (approximate) root-Nyquist Kaiser filter +void liquid_firdes_arkaiser(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Design root-Nyquist harris-Moerder filter +void liquid_firdes_hM3(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Design GMSK transmit and receive filters +void liquid_firdes_gmsktx(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); +void liquid_firdes_gmskrx(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Design flipped exponential Nyquist/root-Nyquist filters +void liquid_firdes_fexp( unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); +void liquid_firdes_rfexp(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Design flipped hyperbolic secand Nyquist/root-Nyquist filters +void liquid_firdes_fsech( unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); +void liquid_firdes_rfsech(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Design flipped arc-hyperbolic secand Nyquist/root-Nyquist filters +void liquid_firdes_farcsech( unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); +void liquid_firdes_rfarcsech(unsigned int _k, unsigned int _m, float _beta, float _dt, float * _h); + +// Compute group delay for an FIR filter +// _h : filter coefficients array +// _n : filter length +// _fc : frequency at which delay is evaluated (-0.5 < _fc < 0.5) +float fir_group_delay(float * _h, + unsigned int _n, + float _fc); + +// Compute group delay for an IIR filter +// _b : filter numerator coefficients +// _nb : filter numerator length +// _a : filter denominator coefficients +// _na : filter denominator length +// _fc : frequency at which delay is evaluated (-0.5 < _fc < 0.5) +float iir_group_delay(float * _b, + unsigned int _nb, + float * _a, + unsigned int _na, + float _fc); + + +// liquid_filter_autocorr() +// +// Compute auto-correlation of filter at a specific lag. +// +// _h : filter coefficients [size: _h_len x 1] +// _h_len : filter length +// _lag : auto-correlation lag (samples) +float liquid_filter_autocorr(float * _h, + unsigned int _h_len, + int _lag); + +// liquid_filter_crosscorr() +// +// Compute cross-correlation of two filters at a specific lag. +// +// _h : filter coefficients [size: _h_len] +// _h_len : filter length +// _g : filter coefficients [size: _g_len] +// _g_len : filter length +// _lag : cross-correlation lag (samples) +float liquid_filter_crosscorr(float * _h, + unsigned int _h_len, + float * _g, + unsigned int _g_len, + int _lag); + +// liquid_filter_isi() +// +// Compute inter-symbol interference (ISI)--both RMS and +// maximum--for the filter _h. +// +// _h : filter coefficients [size: 2*_k*_m+1 x 1] +// _k : filter over-sampling rate (samples/symbol) +// _m : filter delay (symbols) +// _rms : output root mean-squared ISI +// _max : maximum ISI +void liquid_filter_isi(float * _h, + unsigned int _k, + unsigned int _m, + float * _rms, + float * _max); + +// Compute relative out-of-band energy +// +// _h : filter coefficients [size: _h_len x 1] +// _h_len : filter length +// _fc : analysis cut-off frequency +// _nfft : fft size +float liquid_filter_energy(float * _h, + unsigned int _h_len, + float _fc, + unsigned int _nfft); + + +// +// IIR filter design +// + +// IIR filter design filter type +typedef enum { + LIQUID_IIRDES_BUTTER=0, + LIQUID_IIRDES_CHEBY1, + LIQUID_IIRDES_CHEBY2, + LIQUID_IIRDES_ELLIP, + LIQUID_IIRDES_BESSEL +} liquid_iirdes_filtertype; + +// IIR filter design band type +typedef enum { + LIQUID_IIRDES_LOWPASS=0, + LIQUID_IIRDES_HIGHPASS, + LIQUID_IIRDES_BANDPASS, + LIQUID_IIRDES_BANDSTOP +} liquid_iirdes_bandtype; + +// IIR filter design coefficients format +typedef enum { + LIQUID_IIRDES_SOS=0, + LIQUID_IIRDES_TF +} liquid_iirdes_format; + +// IIR filter design template +// _ftype : filter type (e.g. LIQUID_IIRDES_BUTTER) +// _btype : band type (e.g. LIQUID_IIRDES_BANDPASS) +// _format : coefficients format (e.g. LIQUID_IIRDES_SOS) +// _n : filter order +// _fc : low-pass prototype cut-off frequency +// _f0 : center frequency (band-pass, band-stop) +// _Ap : pass-band ripple in dB +// _As : stop-band ripple in dB +// _B : numerator +// _A : denominator +void liquid_iirdes(liquid_iirdes_filtertype _ftype, + liquid_iirdes_bandtype _btype, + liquid_iirdes_format _format, + unsigned int _n, + float _fc, + float _f0, + float _Ap, + float _As, + float * _B, + float * _A); + +// compute analog zeros, poles, gain for specific filter types +void butter_azpkf(unsigned int _n, + liquid_float_complex * _za, + liquid_float_complex * _pa, + liquid_float_complex * _ka); +void cheby1_azpkf(unsigned int _n, + float _ep, + liquid_float_complex * _z, + liquid_float_complex * _p, + liquid_float_complex * _k); +void cheby2_azpkf(unsigned int _n, + float _es, + liquid_float_complex * _z, + liquid_float_complex * _p, + liquid_float_complex * _k); +void ellip_azpkf(unsigned int _n, + float _ep, + float _es, + liquid_float_complex * _z, + liquid_float_complex * _p, + liquid_float_complex * _k); +void bessel_azpkf(unsigned int _n, + liquid_float_complex * _z, + liquid_float_complex * _p, + liquid_float_complex * _k); + +// compute frequency pre-warping factor +float iirdes_freqprewarp(liquid_iirdes_bandtype _btype, + float _fc, + float _f0); + +// convert analog z/p/k form to discrete z/p/k form (bilinear z-transform) +// _za : analog zeros [length: _nza] +// _nza : number of analog zeros +// _pa : analog poles [length: _npa] +// _npa : number of analog poles +// _m : frequency pre-warping factor +// _zd : output digital zeros [length: _npa] +// _pd : output digital poles [length: _npa] +// _kd : output digital gain (should actually be real-valued) +void bilinear_zpkf(liquid_float_complex * _za, + unsigned int _nza, + liquid_float_complex * _pa, + unsigned int _npa, + liquid_float_complex _ka, + float _m, + liquid_float_complex * _zd, + liquid_float_complex * _pd, + liquid_float_complex * _kd); + +// digital z/p/k low-pass to high-pass +// _zd : digital zeros (low-pass prototype), [length: _n] +// _pd : digital poles (low-pass prototype), [length: _n] +// _n : low-pass filter order +// _zdt : output digital zeros transformed [length: _n] +// _pdt : output digital poles transformed [length: _n] +void iirdes_dzpk_lp2hp(liquid_float_complex * _zd, + liquid_float_complex * _pd, + unsigned int _n, + liquid_float_complex * _zdt, + liquid_float_complex * _pdt); + +// digital z/p/k low-pass to band-pass +// _zd : digital zeros (low-pass prototype), [length: _n] +// _pd : digital poles (low-pass prototype), [length: _n] +// _n : low-pass filter order +// _f0 : center frequency +// _zdt : output digital zeros transformed [length: 2*_n] +// _pdt : output digital poles transformed [length: 2*_n] +void iirdes_dzpk_lp2bp(liquid_float_complex * _zd, + liquid_float_complex * _pd, + unsigned int _n, + float _f0, + liquid_float_complex * _zdt, + liquid_float_complex * _pdt); + +// convert discrete z/p/k form to transfer function +// _zd : digital zeros [length: _n] +// _pd : digital poles [length: _n] +// _n : filter order +// _kd : digital gain +// _b : output numerator [length: _n+1] +// _a : output denominator [length: _n+1] +void iirdes_dzpk2tff(liquid_float_complex * _zd, + liquid_float_complex * _pd, + unsigned int _n, + liquid_float_complex _kd, + float * _b, + float * _a); + +// convert discrete z/p/k form to second-order sections +// _zd : digital zeros [length: _n] +// _pd : digital poles [length: _n] +// _n : filter order +// _kd : digital gain +// _B : output numerator [size: 3 x L+r] +// _A : output denominator [size: 3 x L+r] +// where r = _n%2, L = (_n-r)/2 +void iirdes_dzpk2sosf(liquid_float_complex * _zd, + liquid_float_complex * _pd, + unsigned int _n, + liquid_float_complex _kd, + float * _B, + float * _A); + +// additional IIR filter design templates + +// design 2nd-order IIR filter (active lag) +// 1 + t2 * s +// F(s) = ------------ +// 1 + t1 * s +// +// _w : filter bandwidth +// _zeta : damping factor (1/sqrt(2) suggested) +// _K : loop gain (1000 suggested) +// _b : output feed-forward coefficients [size: 3 x 1] +// _a : output feed-back coefficients [size: 3 x 1] +void iirdes_pll_active_lag(float _w, + float _zeta, + float _K, + float * _b, + float * _a); + +// design 2nd-order IIR filter (active PI) +// 1 + t2 * s +// F(s) = ------------ +// t1 * s +// +// _w : filter bandwidth +// _zeta : damping factor (1/sqrt(2) suggested) +// _K : loop gain (1000 suggested) +// _b : output feed-forward coefficients [size: 3 x 1] +// _a : output feed-back coefficients [size: 3 x 1] +void iirdes_pll_active_PI(float _w, + float _zeta, + float _K, + float * _b, + float * _a); + +// checks stability of iir filter +// _b : feed-forward coefficients [size: _n x 1] +// _a : feed-back coefficients [size: _n x 1] +// _n : number of coefficients +int iirdes_isstable(float * _b, + float * _a, + unsigned int _n); + +// +// linear prediction +// + +// compute the linear prediction coefficients for an input signal _x +// _x : input signal [size: _n x 1] +// _n : input signal length +// _p : prediction filter order +// _a : prediction filter [size: _p+1 x 1] +// _e : prediction error variance [size: _p+1 x 1] +void liquid_lpc(float * _x, + unsigned int _n, + unsigned int _p, + float * _a, + float * _g); + +// solve the Yule-Walker equations using Levinson-Durbin recursion +// for _symmetric_ autocorrelation +// _r : autocorrelation array [size: _p+1 x 1] +// _p : filter order +// _a : output coefficients [size: _p+1 x 1] +// _e : error variance [size: _p+1 x 1] +// +// NOTES: +// By definition _a[0] = 1.0 +void liquid_levinson(float * _r, + unsigned int _p, + float * _a, + float * _e); + +// +// auto-correlator (delay cross-correlation) +// + +#define AUTOCORR_MANGLE_CCCF(name) LIQUID_CONCAT(autocorr_cccf,name) +#define AUTOCORR_MANGLE_RRRF(name) LIQUID_CONCAT(autocorr_rrrf,name) + +// Macro: +// AUTOCORR : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_AUTOCORR_DEFINE_API(AUTOCORR,TO,TC,TI) \ + \ +typedef struct AUTOCORR(_s) * AUTOCORR(); \ + \ +/* create auto-correlator object */ \ +/* _window_size : size of the correlator window */ \ +/* _delay : correlator delay [samples] */ \ +AUTOCORR() AUTOCORR(_create)(unsigned int _window_size, \ + unsigned int _delay); \ + \ +/* destroy auto-correlator object, freeing internal memory */ \ +void AUTOCORR(_destroy)(AUTOCORR() _q); \ + \ +/* reset auto-correlator object's internals */ \ +void AUTOCORR(_reset)(AUTOCORR() _q); \ + \ +/* print auto-correlator parameters to stdout */ \ +void AUTOCORR(_print)(AUTOCORR() _q); \ + \ +/* push sample into auto-correlator object */ \ +void AUTOCORR(_push)(AUTOCORR() _q, \ + TI _x); \ + \ +/* compute single auto-correlation output */ \ +void AUTOCORR(_execute)(AUTOCORR() _q, \ + TO * _rxx); \ + \ +/* compute auto-correlation on block of samples; the input */ \ +/* and output arrays may have the same pointer */ \ +/* _q : auto-correlation object */ \ +/* _x : input array [size: _n x 1] */ \ +/* _n : number of input, output samples */ \ +/* _rxx : input array [size: _n x 1] */ \ +void AUTOCORR(_execute_block)(AUTOCORR() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _rxx); \ + \ +/* return sum of squares of buffered samples */ \ +float AUTOCORR(_get_energy)(AUTOCORR() _q); \ + +LIQUID_AUTOCORR_DEFINE_API(AUTOCORR_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +LIQUID_AUTOCORR_DEFINE_API(AUTOCORR_MANGLE_RRRF, + float, + float, + float) + + +// +// Finite impulse response filter +// + +#define FIRFILT_MANGLE_RRRF(name) LIQUID_CONCAT(firfilt_rrrf,name) +#define FIRFILT_MANGLE_CRCF(name) LIQUID_CONCAT(firfilt_crcf,name) +#define FIRFILT_MANGLE_CCCF(name) LIQUID_CONCAT(firfilt_cccf,name) + +// Macro: +// FIRFILT : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_FIRFILT_DEFINE_API(FIRFILT,TO,TC,TI) \ +typedef struct FIRFILT(_s) * FIRFILT(); \ + \ +FIRFILT() FIRFILT(_create)(TC * _h, unsigned int _n); \ + \ +/* create using Kaiser-Bessel windowed sinc method */ \ +/* _n : filter length, _n > 0 */ \ +/* _fc : filter cut-off frequency 0 < _fc < 0.5 */ \ +/* _As : filter stop-band attenuation [dB], _As > 0 */ \ +/* _mu : fractional sample offset, -0.5 < _mu < 0.5 */ \ +FIRFILT() FIRFILT(_create_kaiser)(unsigned int _n, \ + float _fc, \ + float _As, \ + float _mu); \ + \ +/* create from square-root Nyquist prototype */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RRC) */ \ +/* _k : nominal samples/symbol, _k > 1 */ \ +/* _m : filter delay [symbols], _m > 0 */ \ +/* _beta : rolloff factor, 0 < beta <= 1 */ \ +/* _mu : fractional sample offset,-0.5 < _mu < 0.5 */ \ +FIRFILT() FIRFILT(_create_rnyquist)(int _type, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + float _mu); \ + \ +/* re-create filter */ \ +/* _q : original filter object */ \ +/* _h : pointer to filter coefficients [size: _n x 1] */ \ +/* _n : filter length, _n > 0 */ \ +FIRFILT() FIRFILT(_recreate)(FIRFILT() _q, \ + TC * _h, \ + unsigned int _n); \ + \ +/* destroy filter object and free all internal memory */ \ +void FIRFILT(_destroy)(FIRFILT() _q); \ + \ +/* reset filter object's internal buffer */ \ +void FIRFILT(_reset)(FIRFILT() _q); \ + \ +/* print filter object information */ \ +void FIRFILT(_print)(FIRFILT() _q); \ + \ +/* set output scaling for filter */ \ +void FIRFILT(_set_scale)(FIRFILT() _q, \ + TC _g); \ + \ +/* push sample into filter object's internal buffer */ \ +/* _q : filter object */ \ +/* _x : single input sample */ \ +void FIRFILT(_push)(FIRFILT() _q, \ + TI _x); \ + \ +/* execute the filter on internal buffer and coefficients */ \ +/* _q : filter object */ \ +/* _y : pointer to single output sample */ \ +void FIRFILT(_execute)(FIRFILT() _q, \ + TO * _y); \ + \ +/* execute the filter on a block of input samples; the */ \ +/* input and output buffers may be the same */ \ +/* _q : filter object */ \ +/* _x : pointer to input array [size: _n x 1] */ \ +/* _n : number of input, output samples */ \ +/* _y : pointer to output array [size: _n x 1] */ \ +void FIRFILT(_execute_block)(FIRFILT() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _y); \ + \ +/* return length of filter object */ \ +unsigned int FIRFILT(_get_length)(FIRFILT() _q); \ + \ +/* compute complex frequency response of filter object */ \ +/* _q : filter object */ \ +/* _fc : frequency to evaluate */ \ +/* _H : pointer to output complex frequency response */ \ +void FIRFILT(_freqresponse)(FIRFILT() _q, \ + float _fc, \ + liquid_float_complex * _H); \ + \ +/* compute and return group delay of filter object */ \ +/* _q : filter object */ \ +/* _fc : frequency to evaluate */ \ +float FIRFILT(_groupdelay)(FIRFILT() _q, \ + float _fc); \ + +LIQUID_FIRFILT_DEFINE_API(FIRFILT_MANGLE_RRRF, + float, + float, + float) + +LIQUID_FIRFILT_DEFINE_API(FIRFILT_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_FIRFILT_DEFINE_API(FIRFILT_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +// +// FIR Hilbert transform +// 2:1 real-to-complex decimator +// 1:2 complex-to-real interpolator +// + +#define FIRHILB_MANGLE_FLOAT(name) LIQUID_CONCAT(firhilbf, name) +//#define FIRHILB_MANGLE_DOUBLE(name) LIQUID_CONCAT(firhilb, name) + +// NOTES: +// Although firhilb is a placeholder for both decimation and +// interpolation, separate objects should be used for each task. +#define LIQUID_FIRHILB_DEFINE_API(FIRHILB,T,TC) \ +typedef struct FIRHILB(_s) * FIRHILB(); \ + \ +/* create finite impulse reponse Hilbert transform */ \ +/* _m : filter semi-length, delay is 2*m+1 */ \ +/* _As : filter stop-band attenuation [dB] */ \ +FIRHILB() FIRHILB(_create)(unsigned int _m, \ + float _As); \ + \ +/* destroy finite impulse reponse Hilbert transform */ \ +void FIRHILB(_destroy)(FIRHILB() _q); \ + \ +/* print firhilb object internals to stdout */ \ +void FIRHILB(_print)(FIRHILB() _q); \ + \ +/* reset firhilb object internal state */ \ +void FIRHILB(_reset)(FIRHILB() _q); \ + \ +/* execute Hilbert transform (real to complex) */ \ +/* _q : Hilbert transform object */ \ +/* _x : real-valued input sample */ \ +/* _y : complex-valued output sample */ \ +void FIRHILB(_r2c_execute)(FIRHILB() _q, \ + T _x, \ + TC * _y); \ + \ +/* execute Hilbert transform (complex to real) */ \ +/* _q : Hilbert transform object */ \ +/* _x : complex-valued input sample */ \ +/* _y : real-valued output sample */ \ +void FIRHILB(_c2r_execute)(FIRHILB() _q, \ + TC _x, \ + T * _y); \ + \ +/* execute Hilbert transform decimator (real to complex) */ \ +/* _q : Hilbert transform object */ \ +/* _x : real-valued input array [size: 2 x 1] */ \ +/* _y : complex-valued output sample */ \ +void FIRHILB(_decim_execute)(FIRHILB() _q, \ + T * _x, \ + TC * _y); \ + \ +/* execute Hilbert transform interpolator (real to complex) */ \ +/* _q : Hilbert transform object */ \ +/* _x : complex-valued input sample */ \ +/* _y : real-valued output array [size: 2 x 1] */ \ +void FIRHILB(_interp_execute)(FIRHILB() _q, \ + TC _x, \ + T * _y); \ + +LIQUID_FIRHILB_DEFINE_API(FIRHILB_MANGLE_FLOAT, float, liquid_float_complex) +//LIQUID_FIRHILB_DEFINE_API(FIRHILB_MANGLE_DOUBLE, double, liquid_double_complex) + + +// +// FFT-based finite impulse response filter +// + +#define FFTFILT_MANGLE_RRRF(name) LIQUID_CONCAT(fftfilt_rrrf,name) +#define FFTFILT_MANGLE_CRCF(name) LIQUID_CONCAT(fftfilt_crcf,name) +#define FFTFILT_MANGLE_CCCF(name) LIQUID_CONCAT(fftfilt_cccf,name) + +// Macro: +// FFTFILT : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_FFTFILT_DEFINE_API(FFTFILT,TO,TC,TI) \ +typedef struct FFTFILT(_s) * FFTFILT(); \ + \ +/* create FFT-based FIR filter using external coefficients */ \ +/* _h : filter coefficients [size: _h_len x 1] */ \ +/* _h_len : filter length, _h_len > 0 */ \ +/* _n : block size = nfft/2, at least _h_len-1 */ \ +FFTFILT() FFTFILT(_create)(TC * _h, \ + unsigned int _h_len, \ + unsigned int _n); \ + \ +/* destroy filter object and free all internal memory */ \ +void FFTFILT(_destroy)(FFTFILT() _q); \ + \ +/* reset filter object's internal buffer */ \ +void FFTFILT(_reset)(FFTFILT() _q); \ + \ +/* print filter object information */ \ +void FFTFILT(_print)(FFTFILT() _q); \ + \ +/* set output scaling for filter */ \ +void FFTFILT(_set_scale)(FFTFILT() _q, \ + TC _g); \ + \ +/* execute the filter on internal buffer and coefficients */ \ +/* _q : filter object */ \ +/* _x : pointer to input data array [size: _n x 1] */ \ +/* _y : pointer to output data array [size: _n x 1] */ \ +void FFTFILT(_execute)(FFTFILT() _q, \ + TI * _x, \ + TO * _y); \ + \ +/* return length of filter object's internal coefficients */ \ +unsigned int FFTFILT(_get_length)(FFTFILT() _q); \ + +LIQUID_FFTFILT_DEFINE_API(FFTFILT_MANGLE_RRRF, + float, + float, + float) + +LIQUID_FFTFILT_DEFINE_API(FFTFILT_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_FFTFILT_DEFINE_API(FFTFILT_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// Infinite impulse response filter +// + +#define IIRFILT_MANGLE_RRRF(name) LIQUID_CONCAT(iirfilt_rrrf,name) +#define IIRFILT_MANGLE_CRCF(name) LIQUID_CONCAT(iirfilt_crcf,name) +#define IIRFILT_MANGLE_CCCF(name) LIQUID_CONCAT(iirfilt_cccf,name) + +// Macro: +// IIRFILT : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_IIRFILT_DEFINE_API(IIRFILT,TO,TC,TI) \ + \ +typedef struct IIRFILT(_s) * IIRFILT(); \ + \ +/* create infinite impulse reponse filter */ \ +/* _b : feed-forward coefficients [size: _nb x 1] */ \ +/* _nb : number of feed-forward coefficients */ \ +/* _a : feed-back coefficients [size: _na x 1] */ \ +/* _na : number of feed-back coefficients */ \ +IIRFILT() IIRFILT(_create)(TC * _b, \ + unsigned int _nb, \ + TC * _a, \ + unsigned int _na); \ + \ +/* create IIR filter using 2nd-order secitons */ \ +/* _B : feed-forward coefficients [size: _nsos x 3] */ \ +/* _A : feed-back coefficients [size: _nsos x 3] */ \ +IIRFILT() IIRFILT(_create_sos)(TC * _B, \ + TC * _A, \ + unsigned int _nsos); \ + \ +/* create IIR filter from design template */ \ +/* _ftype : filter type (e.g. LIQUID_IIRDES_BUTTER) */ \ +/* _btype : band type (e.g. LIQUID_IIRDES_BANDPASS) */ \ +/* _format : coefficients format (e.g. LIQUID_IIRDES_SOS) */ \ +/* _n : filter order */ \ +/* _fc : low-pass prototype cut-off frequency */ \ +/* _f0 : center frequency (band-pass, band-stop) */ \ +/* _Ap : pass-band ripple in dB */ \ +/* _As : stop-band ripple in dB */ \ +IIRFILT() IIRFILT(_create_prototype)( \ + liquid_iirdes_filtertype _ftype, \ + liquid_iirdes_bandtype _btype, \ + liquid_iirdes_format _format, \ + unsigned int _order, \ + float _fc, \ + float _f0, \ + float _Ap, \ + float _As); \ + \ +/* create 8th-order integrator filter */ \ +IIRFILT() IIRFILT(_create_integrator)(); \ + \ +/* create 8th-order differentiator filter */ \ +IIRFILT() IIRFILT(_create_differentiator)(); \ + \ +/* create simple DC-blocking filter */ \ +IIRFILT() IIRFILT(_create_dc_blocker)(float _alpha); \ + \ +/* create phase-locked loop iirfilt object */ \ +/* _w : filter bandwidth */ \ +/* _zeta : damping factor (1/sqrt(2) suggested) */ \ +/* _K : loop gain (1000 suggested) */ \ +IIRFILT() IIRFILT(_create_pll)(float _w, \ + float _zeta, \ + float _K); \ + \ +/* destroy iirfilt object, freeing all internal memory */ \ +void IIRFILT(_destroy)(IIRFILT() _q); \ + \ +/* print iirfilt object properties to stdout */ \ +void IIRFILT(_print)(IIRFILT() _q); \ + \ +/* clear/reset iirfilt object internals */ \ +void IIRFILT(_reset)(IIRFILT() _q); \ + \ +/* compute filter output */ \ +/* _q : iirfilt object */ \ +/* _x : input sample */ \ +/* _y : output sample pointer */ \ +void IIRFILT(_execute)(IIRFILT() _q, \ + TI _x, \ + TO * _y); \ + \ +/* execute the filter on a block of input samples; the */ \ +/* input and output buffers may be the same */ \ +/* _q : filter object */ \ +/* _x : pointer to input array [size: _n x 1] */ \ +/* _n : number of input, output samples */ \ +/* _y : pointer to output array [size: _n x 1] */ \ +void IIRFILT(_execute_block)(IIRFILT() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _y); \ + \ +/* return iirfilt object's filter length (order + 1) */ \ +unsigned int IIRFILT(_get_length)(IIRFILT() _q); \ + \ +/* compute complex frequency response of filter object */ \ +/* _q : filter object */ \ +/* _fc : frequency to evaluate */ \ +/* _H : pointer to output complex frequency response */ \ +void IIRFILT(_freqresponse)(IIRFILT() _q, \ + float _fc, \ + liquid_float_complex * _H); \ + \ +/* compute and return group delay of filter object */ \ +/* _q : filter object */ \ +/* _fc : frequency to evaluate */ \ +float IIRFILT(_groupdelay)(IIRFILT() _q, float _fc); \ + +LIQUID_IIRFILT_DEFINE_API(IIRFILT_MANGLE_RRRF, + float, + float, + float) + +LIQUID_IIRFILT_DEFINE_API(IIRFILT_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_IIRFILT_DEFINE_API(IIRFILT_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// FIR Polyphase filter bank +// +#define FIRPFB_MANGLE_RRRF(name) LIQUID_CONCAT(firpfb_rrrf,name) +#define FIRPFB_MANGLE_CRCF(name) LIQUID_CONCAT(firpfb_crcf,name) +#define FIRPFB_MANGLE_CCCF(name) LIQUID_CONCAT(firpfb_cccf,name) + +// Macro: +// FIRPFB : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_FIRPFB_DEFINE_API(FIRPFB,TO,TC,TI) \ + \ +typedef struct FIRPFB(_s) * FIRPFB(); \ + \ +/* create firpfb from external coefficients */ \ +/* _M : number of filters in the bank */ \ +/* _h : coefficients [size: _M*_h_len x 1] */ \ +/* _h_len : filter delay (symbols) */ \ +FIRPFB() FIRPFB(_create)(unsigned int _M, \ + TC * _h, \ + unsigned int _h_len); \ + \ +/* create firpfb from square-root Nyquist prototype */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RRC) */ \ +/* _npfb : number of filters in the bank */ \ +/* _k : nominal samples/symbol */ \ +/* _m : filter delay (symbols) */ \ +/* _beta : rolloff factor (0 < beta <= 1) */ \ +FIRPFB() FIRPFB(_create_rnyquist)(int _type, \ + unsigned int _npfb, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta); \ + \ +/* create from square-root derivative Nyquist prototype */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RRC) */ \ +/* _npfb : number of filters in the bank */ \ +/* _k : nominal samples/symbol */ \ +/* _m : filter delay (symbols) */ \ +/* _beta : rolloff factor (0 < beta <= 1) */ \ +FIRPFB() FIRPFB(_create_drnyquist)(int _type, \ + unsigned int _npfb, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta); \ + \ +/* re-create filterbank object */ \ +/* _q : original firpfb object */ \ +/* _M : number of filters in the bank */ \ +/* _h : coefficients [size: _M x _h_len] */ \ +/* _h_len : length of each filter */ \ +FIRPFB() FIRPFB(_recreate)(FIRPFB() _q, \ + unsigned int _M, \ + TC * _h, \ + unsigned int _h_len); \ + \ +/* destroy firpfb object, freeing all internal memory */ \ +void FIRPFB(_destroy)(FIRPFB() _q); \ + \ +/* print firpfb object's parameters */ \ +void FIRPFB(_print)(FIRPFB() _q); \ + \ +/* clear/reset firpfb object internal state */ \ +void FIRPFB(_reset)(FIRPFB() _q); \ + \ +/* push sample into firpfb internal buffer */ \ +void FIRPFB(_push)(FIRPFB() _q, TI _x); \ + \ +/* execute the filter on internal buffer and coefficients */ \ +/* _q : firpfb object */ \ +/* _i : index of filter to use */ \ +/* _y : pointer to output sample */ \ +void FIRPFB(_execute)(FIRPFB() _q, \ + unsigned int _i, \ + TO * _y); \ + +LIQUID_FIRPFB_DEFINE_API(FIRPFB_MANGLE_RRRF, + float, + float, + float) + +LIQUID_FIRPFB_DEFINE_API(FIRPFB_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_FIRPFB_DEFINE_API(FIRPFB_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +// +// Interpolators +// + +// firinterp : finite impulse response interpolator +#define FIRINTERP_MANGLE_RRRF(name) LIQUID_CONCAT(firinterp_rrrf,name) +#define FIRINTERP_MANGLE_CRCF(name) LIQUID_CONCAT(firinterp_crcf,name) +#define FIRINTERP_MANGLE_CCCF(name) LIQUID_CONCAT(firinterp_cccf,name) + +#define LIQUID_FIRINTERP_DEFINE_API(FIRINTERP,TO,TC,TI) \ + \ +typedef struct FIRINTERP(_s) * FIRINTERP(); \ + \ +/* create interpolator from external coefficients */ \ +/* _M : interpolation factor */ \ +/* _h : filter coefficients [size: _h_len x 1] */ \ +/* _h_len : filter length */ \ +FIRINTERP() FIRINTERP(_create)(unsigned int _M, \ + TC * _h, \ + unsigned int _h_len); \ + \ +/* create interpolator from prototype */ \ +/* _M : interpolation factor */ \ +/* _m : filter delay (symbols) */ \ +/* _As : stop-band attenuation [dB] */ \ +FIRINTERP() FIRINTERP(_create_prototype)(unsigned int _M, \ + unsigned int _m, \ + float _As); \ + \ +/* create Nyquist interpolator */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RCOS) */ \ +/* _k : samples/symbol, _k > 1 */ \ +/* _m : filter delay (symbols), _m > 0 */ \ +/* _beta : excess bandwidth factor, _beta < 1 */ \ +/* _dt : fractional sample delay, _dt in (-1, 1) */ \ +FIRINTERP() FIRINTERP(_create_nyquist)(int _type, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + float _dt); \ + \ +/* create square-root Nyquist interpolator */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RRC) */ \ +/* _k : samples/symbol, _k > 1 */ \ +/* _m : filter delay (symbols), _m > 0 */ \ +/* _beta : excess bandwidth factor, _beta < 1 */ \ +/* _dt : fractional sample delay, _dt in (-1, 1) */ \ +FIRINTERP() FIRINTERP(_create_rnyquist)(int _type, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + float _dt); \ + \ +/* destroy firinterp object, freeing all internal memory */ \ +void FIRINTERP(_destroy)(FIRINTERP() _q); \ + \ +/* print firinterp object's internal properties to stdout */ \ +void FIRINTERP(_print)(FIRINTERP() _q); \ + \ +/* reset internal state */ \ +void FIRINTERP(_reset)(FIRINTERP() _q); \ + \ +/* execute interpolation on single input sample */ \ +/* _q : firinterp object */ \ +/* _x : input sample */ \ +/* _y : output sample array [size: _M x 1] */ \ +void FIRINTERP(_execute)(FIRINTERP() _q, \ + TI _x, \ + TO * _y); \ + \ +/* execute interpolation on block of input samples */ \ +/* _q : firinterp object */ \ +/* _x : input array [size: _n x 1] */ \ +/* _n : size of input array */ \ +/* _y : output sample array [size: _M*_n x 1] */ \ +void FIRINTERP(_execute_block)(FIRINTERP() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _y); \ + +LIQUID_FIRINTERP_DEFINE_API(FIRINTERP_MANGLE_RRRF, + float, + float, + float) + +LIQUID_FIRINTERP_DEFINE_API(FIRINTERP_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_FIRINTERP_DEFINE_API(FIRINTERP_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +// iirinterp : infinite impulse response interpolator +#define IIRINTERP_MANGLE_RRRF(name) LIQUID_CONCAT(iirinterp_rrrf,name) +#define IIRINTERP_MANGLE_CRCF(name) LIQUID_CONCAT(iirinterp_crcf,name) +#define IIRINTERP_MANGLE_CCCF(name) LIQUID_CONCAT(iirinterp_cccf,name) + +#define LIQUID_IIRINTERP_DEFINE_API(IIRINTERP,TO,TC,TI) \ +typedef struct IIRINTERP(_s) * IIRINTERP(); \ + \ +/* create interpolator from external coefficients */ \ +/* _M : interpolation factor */ \ +/* _b : feed-back coefficients [size: _nb x 1] */ \ +/* _nb : feed-back coefficients length */ \ +/* _a : feed-forward coefficients [size: _na x 1] */ \ +/* _na : feed-forward coefficients length */ \ +IIRINTERP() IIRINTERP(_create)(unsigned int _M, \ + TC * _b, \ + unsigned int _nb, \ + TC * _a, \ + unsigned int _na); \ + \ +/* create interpolator from prototype */ \ +/* _M : interpolation factor */ \ +IIRINTERP() IIRINTERP(_create_prototype)( \ + unsigned int _M, \ + liquid_iirdes_filtertype _ftype, \ + liquid_iirdes_bandtype _btype, \ + liquid_iirdes_format _format, \ + unsigned int _order, \ + float _fc, \ + float _f0, \ + float _Ap, \ + float _As); \ + \ +/* destroy interpolator object and free internal memory */ \ +void IIRINTERP(_destroy)(IIRINTERP() _q); \ + \ +/* print interpolator object internals */ \ +void IIRINTERP(_print)(IIRINTERP() _q); \ + \ +/* reset interpolator object */ \ +void IIRINTERP(_reset)(IIRINTERP() _q); \ + \ +/* execute interpolation on single input sample */ \ +/* _q : iirinterp object */ \ +/* _x : input sample */ \ +/* _y : output sample array [size: _M x 1] */ \ +void IIRINTERP(_execute)(IIRINTERP() _q, \ + TI _x, \ + TO * _y); \ + \ +/* execute interpolation on block of input samples */ \ +/* _q : iirinterp object */ \ +/* _x : input array [size: _n x 1] */ \ +/* _n : size of input array */ \ +/* _y : output sample array [size: _M*_n x 1] */ \ +void IIRINTERP(_execute_block)(IIRINTERP() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _y); \ + \ +/* get system group delay at frequency _fc */ \ +float IIRINTERP(_groupdelay)(IIRINTERP() _q, float _fc); \ + +LIQUID_IIRINTERP_DEFINE_API(IIRINTERP_MANGLE_RRRF, + float, + float, + float) + +LIQUID_IIRINTERP_DEFINE_API(IIRINTERP_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_IIRINTERP_DEFINE_API(IIRINTERP_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +// +// Decimators +// + +// firdecim : finite impulse response decimator +#define FIRDECIM_MANGLE_RRRF(name) LIQUID_CONCAT(firdecim_rrrf,name) +#define FIRDECIM_MANGLE_CRCF(name) LIQUID_CONCAT(firdecim_crcf,name) +#define FIRDECIM_MANGLE_CCCF(name) LIQUID_CONCAT(firdecim_cccf,name) + +#define LIQUID_FIRDECIM_DEFINE_API(FIRDECIM,TO,TC,TI) \ +typedef struct FIRDECIM(_s) * FIRDECIM(); \ + \ +/* create decimator from external coefficients */ \ +/* _M : decimation factor */ \ +/* _h : filter coefficients [size: _h_len x 1] */ \ +/* _h_len : filter coefficients length */ \ +FIRDECIM() FIRDECIM(_create)(unsigned int _M, \ + TC * _h, \ + unsigned int _h_len); \ + \ +/* create decimator from prototype */ \ +/* _M : decimation factor */ \ +/* _m : filter delay (symbols) */ \ +/* _As : stop-band attenuation [dB] */ \ +FIRDECIM() FIRDECIM(_create_prototype)(unsigned int _M, \ + unsigned int _m, \ + float _As); \ + \ +/* create square-root Nyquist decimator */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RRC) */ \ +/* _M : samples/symbol (decimation factor) */ \ +/* _m : filter delay (symbols) */ \ +/* _beta : rolloff factor (0 < beta <= 1) */ \ +/* _dt : fractional sample delay */ \ +FIRDECIM() FIRDECIM(_create_rnyquist)(int _type, \ + unsigned int _M, \ + unsigned int _m, \ + float _beta, \ + float _dt); \ + \ +/* destroy decimator object */ \ +void FIRDECIM(_destroy)(FIRDECIM() _q); \ + \ +/* print decimator object propreties to stdout */ \ +void FIRDECIM(_print)(FIRDECIM() _q); \ + \ +/* reset decimator object internal state */ \ +void FIRDECIM(_clear)(FIRDECIM() _q); \ + \ +/* execute decimator on _M input samples */ \ +/* _q : decimator object */ \ +/* _x : input samples [size: _M x 1] */ \ +/* _y : output sample pointer */ \ +void FIRDECIM(_execute)(FIRDECIM() _q, \ + TI * _x, \ + TO * _y); \ + \ +/* execute decimator on block of _n*_M input samples */ \ +/* _q : decimator object */ \ +/* _x : input array [size: _n*_M x 1] */ \ +/* _n : number of _output_ samples */ \ +/* _y : output array [_sze: _n x 1] */ \ +void FIRDECIM(_execute_block)(FIRDECIM() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _y); \ + +LIQUID_FIRDECIM_DEFINE_API(FIRDECIM_MANGLE_RRRF, + float, + float, + float) + +LIQUID_FIRDECIM_DEFINE_API(FIRDECIM_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_FIRDECIM_DEFINE_API(FIRDECIM_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// iirdecim : infinite impulse response decimator +#define IIRDECIM_MANGLE_RRRF(name) LIQUID_CONCAT(iirdecim_rrrf,name) +#define IIRDECIM_MANGLE_CRCF(name) LIQUID_CONCAT(iirdecim_crcf,name) +#define IIRDECIM_MANGLE_CCCF(name) LIQUID_CONCAT(iirdecim_cccf,name) + +#define LIQUID_IIRDECIM_DEFINE_API(IIRDECIM,TO,TC,TI) \ +typedef struct IIRDECIM(_s) * IIRDECIM(); \ + \ +/* create decimator from external coefficients */ \ +/* _M : decimation factor */ \ +/* _b : feed-back coefficients [size: _nb x 1] */ \ +/* _nb : feed-back coefficients length */ \ +/* _a : feed-forward coefficients [size: _na x 1] */ \ +/* _na : feed-forward coefficients length */ \ +IIRDECIM() IIRDECIM(_create)(unsigned int _M, \ + TC * _b, \ + unsigned int _nb, \ + TC * _a, \ + unsigned int _na); \ + \ +/* create decimator from prototype */ \ +/* _M : decimation factor */ \ +IIRDECIM() IIRDECIM(_create_prototype)( \ + unsigned int _M, \ + liquid_iirdes_filtertype _ftype, \ + liquid_iirdes_bandtype _btype, \ + liquid_iirdes_format _format, \ + unsigned int _order, \ + float _fc, \ + float _f0, \ + float _Ap, \ + float _As); \ + \ +/* destroy decimator object and free internal memory */ \ +void IIRDECIM(_destroy)(IIRDECIM() _q); \ + \ +/* print decimator object internals */ \ +void IIRDECIM(_print)(IIRDECIM() _q); \ + \ +/* reset decimator object */ \ +void IIRDECIM(_reset)(IIRDECIM() _q); \ + \ +/* execute decimator on _M input samples */ \ +/* _q : decimator object */ \ +/* _x : input samples [size: _M x 1] */ \ +/* _y : output sample pointer */ \ +void IIRDECIM(_execute)(IIRDECIM() _q, \ + TI * _x, \ + TO * _y); \ + \ +/* execute decimator on block of _n*_M input samples */ \ +/* _q : decimator object */ \ +/* _x : input array [size: _n*_M x 1] */ \ +/* _n : number of _output_ samples */ \ +/* _y : output array [_sze: _n x 1] */ \ +void IIRDECIM(_execute_block)(IIRDECIM() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _y); \ + \ +/* get system group delay at frequency _fc */ \ +float IIRDECIM(_groupdelay)(IIRDECIM() _q, float _fc); \ + +LIQUID_IIRDECIM_DEFINE_API(IIRDECIM_MANGLE_RRRF, + float, + float, + float) + +LIQUID_IIRDECIM_DEFINE_API(IIRDECIM_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_IIRDECIM_DEFINE_API(IIRDECIM_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + + +// +// Half-band resampler +// +#define RESAMP2_MANGLE_RRRF(name) LIQUID_CONCAT(resamp2_rrrf,name) +#define RESAMP2_MANGLE_CRCF(name) LIQUID_CONCAT(resamp2_crcf,name) +#define RESAMP2_MANGLE_CCCF(name) LIQUID_CONCAT(resamp2_cccf,name) + +#define LIQUID_RESAMP2_DEFINE_API(RESAMP2,TO,TC,TI) \ +typedef struct RESAMP2(_s) * RESAMP2(); \ + \ +/* create half-band resampler */ \ +/* _m : filter semi-length (h_len = 4*m+1) */ \ +/* _f0 : filter center frequency */ \ +/* _As : stop-band attenuation [dB] */ \ +RESAMP2() RESAMP2(_create)(unsigned int _m, \ + float _f0, \ + float _As); \ + \ +/* re-create half-band resampler with new properties */ \ +/* _q : original half-band resampler object */ \ +/* _m : filter semi-length (h_len = 4*m+1) */ \ +/* _f0 : filter center frequency */ \ +/* _As : stop-band attenuation [dB] */ \ +RESAMP2() RESAMP2(_recreate)(RESAMP2() _q, \ + unsigned int _m, \ + float _f0, \ + float _As); \ + \ +/* destroy half-band resampler */ \ +void RESAMP2(_destroy)(RESAMP2() _q); \ + \ +/* print resamp2 object's internals */ \ +void RESAMP2(_print)(RESAMP2() _q); \ + \ +/* reset internal buffer */ \ +void RESAMP2(_clear)(RESAMP2() _q); \ + \ +/* get resampler filter delay (semi-length m) */ \ +unsigned int RESAMP2(_get_delay)(RESAMP2() _q); \ + \ +/* execute resamp2 as half-band filter */ \ +/* _q : resamp2 object */ \ +/* _x : input sample */ \ +/* _y0 : output sample pointer (low frequency) */ \ +/* _y1 : output sample pointer (high frequency) */ \ +void RESAMP2(_filter_execute)(RESAMP2() _q, \ + TI _x, \ + TO * _y0, \ + TO * _y1); \ + \ +/* execute resamp2 as half-band analysis filterbank */ \ +/* _q : resamp2 object */ \ +/* _x : input array [size: 2 x 1] */ \ +/* _y : output array [size: 2 x 1] */ \ +void RESAMP2(_analyzer_execute)(RESAMP2() _q, \ + TI * _x, \ + TO * _y); \ + \ +/* execute resamp2 as half-band synthesis filterbank */ \ +/* _q : resamp2 object */ \ +/* _x : input array [size: 2 x 1] */ \ +/* _y : output array [size: 2 x 1] */ \ +void RESAMP2(_synthesizer_execute)(RESAMP2() _q, \ + TI * _x, \ + TO * _y); \ + \ +/* execute resamp2 as half-band decimator */ \ +/* _q : resamp2 object */ \ +/* _x : input array [size: 2 x 1] */ \ +/* _y : output sample pointer */ \ +void RESAMP2(_decim_execute)(RESAMP2() _q, \ + TI * _x, \ + TO * _y); \ + \ +/* execute resamp2 as half-band interpolator */ \ +/* _q : resamp2 object */ \ +/* _x : input sample */ \ +/* _y : output array [size: 2 x 1] */ \ +void RESAMP2(_interp_execute)(RESAMP2() _q, \ + TI _x, \ + TO * _y); \ + +LIQUID_RESAMP2_DEFINE_API(RESAMP2_MANGLE_RRRF, + float, + float, + float) + +LIQUID_RESAMP2_DEFINE_API(RESAMP2_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_RESAMP2_DEFINE_API(RESAMP2_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// Arbitrary resampler +// +#define RESAMP_MANGLE_RRRF(name) LIQUID_CONCAT(resamp_rrrf,name) +#define RESAMP_MANGLE_CRCF(name) LIQUID_CONCAT(resamp_crcf,name) +#define RESAMP_MANGLE_CCCF(name) LIQUID_CONCAT(resamp_cccf,name) + +#define LIQUID_RESAMP_DEFINE_API(RESAMP,TO,TC,TI) \ +typedef struct RESAMP(_s) * RESAMP(); \ + \ +/* create arbitrary resampler object */ \ +/* _rate : arbitrary resampling rate */ \ +/* _m : filter semi-length (delay) */ \ +/* _fc : filter cutoff frequency, 0 < _fc < 0.5 */ \ +/* _As : filter stop-band attenuation [dB] */ \ +/* _npfb : number of filters in the bank */ \ +RESAMP() RESAMP(_create)(float _rate, \ + unsigned int _m, \ + float _fc, \ + float _As, \ + unsigned int _npfb); \ + \ +/* destroy arbitrary resampler object */ \ +void RESAMP(_destroy)(RESAMP() _q); \ + \ +/* print resamp object internals to stdout */ \ +void RESAMP(_print)(RESAMP() _q); \ + \ +/* reset resamp object internals */ \ +void RESAMP(_reset)(RESAMP() _q); \ + \ +/* get resampler delay (output samples) */ \ +unsigned int RESAMP(_get_delay)(RESAMP() _q); \ + \ +/* set rate of arbitrary resampler */ \ +void RESAMP(_setrate)(RESAMP() _q, float _rate); \ + \ +/* execute arbitrary resampler */ \ +/* _q : resamp object */ \ +/* _x : single input sample */ \ +/* _y : output sample array (pointer) */ \ +/* _num_written : number of samples written to _y */ \ +void RESAMP(_execute)(RESAMP() _q, \ + TI _x, \ + TO * _y, \ + unsigned int * _num_written); \ + \ +/* execute arbitrary resampler on a block of samples */ \ +/* _q : resamp object */ \ +/* _x : input buffer [size: _nx x 1] */ \ +/* _nx : input buffer */ \ +/* _y : output sample array (pointer) */ \ +/* _ny : number of samples written to _y */ \ +void RESAMP(_execute_block)(RESAMP() _q, \ + TI * _x, \ + unsigned int _nx, \ + TO * _y, \ + unsigned int * _ny); \ + +LIQUID_RESAMP_DEFINE_API(RESAMP_MANGLE_RRRF, + float, + float, + float) + +LIQUID_RESAMP_DEFINE_API(RESAMP_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_RESAMP_DEFINE_API(RESAMP_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// Multi-stage half-band resampler +// + +// resampling type (interpolator/decimator) +typedef enum { + LIQUID_RESAMP_INTERP=0, // interpolator + LIQUID_RESAMP_DECIM, // decimator +} liquid_resamp_type; + +#define MSRESAMP2_MANGLE_RRRF(name) LIQUID_CONCAT(msresamp2_rrrf,name) +#define MSRESAMP2_MANGLE_CRCF(name) LIQUID_CONCAT(msresamp2_crcf,name) +#define MSRESAMP2_MANGLE_CCCF(name) LIQUID_CONCAT(msresamp2_cccf,name) + +#define LIQUID_MSRESAMP2_DEFINE_API(MSRESAMP2,TO,TC,TI) \ +typedef struct MSRESAMP2(_s) * MSRESAMP2(); \ + \ +/* create multi-stage half-band resampler */ \ +/* _type : resampler type (e.g. LIQUID_RESAMP_DECIM) */ \ +/* _num_stages : number of resampling stages */ \ +/* _fc : filter cut-off frequency 0 < _fc < 0.5 */ \ +/* _f0 : filter center frequency */ \ +/* _As : stop-band attenuation [dB] */ \ +MSRESAMP2() MSRESAMP2(_create)(int _type, \ + unsigned int _num_stages, \ + float _fc, \ + float _f0, \ + float _As); \ + \ +/* destroy multi-stage half-bandresampler */ \ +void MSRESAMP2(_destroy)(MSRESAMP2() _q); \ + \ +/* print msresamp object internals to stdout */ \ +void MSRESAMP2(_print)(MSRESAMP2() _q); \ + \ +/* reset msresamp object internal state */ \ +void MSRESAMP2(_reset)(MSRESAMP2() _q); \ + \ +/* get group delay (number of output samples) */ \ +float MSRESAMP2(_get_delay)(MSRESAMP2() _q); \ + \ +/* execute multi-stage resampler, M = 2^num_stages */ \ +/* LIQUID_RESAMP_INTERP: input: 1, output: M */ \ +/* LIQUID_RESAMP_DECIM: input: M, output: 1 */ \ +/* _q : msresamp object */ \ +/* _x : input sample array */ \ +/* _y : output sample array */ \ +void MSRESAMP2(_execute)(MSRESAMP2() _q, \ + TI * _x, \ + TO * _y); \ + +LIQUID_MSRESAMP2_DEFINE_API(MSRESAMP2_MANGLE_RRRF, + float, + float, + float) + +LIQUID_MSRESAMP2_DEFINE_API(MSRESAMP2_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_MSRESAMP2_DEFINE_API(MSRESAMP2_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// Multi-stage arbitrary resampler +// +#define MSRESAMP_MANGLE_RRRF(name) LIQUID_CONCAT(msresamp_rrrf,name) +#define MSRESAMP_MANGLE_CRCF(name) LIQUID_CONCAT(msresamp_crcf,name) +#define MSRESAMP_MANGLE_CCCF(name) LIQUID_CONCAT(msresamp_cccf,name) + +#define LIQUID_MSRESAMP_DEFINE_API(MSRESAMP,TO,TC,TI) \ +typedef struct MSRESAMP(_s) * MSRESAMP(); \ + \ +/* create multi-stage arbitrary resampler */ \ +/* _r : resampling rate [output/input] */ \ +/* _As : stop-band attenuation [dB] */ \ +MSRESAMP() MSRESAMP(_create)(float _r, \ + float _As); \ + \ +/* destroy multi-stage arbitrary resampler */ \ +void MSRESAMP(_destroy)(MSRESAMP() _q); \ + \ +/* print msresamp object internals to stdout */ \ +void MSRESAMP(_print)(MSRESAMP() _q); \ + \ +/* reset msresamp object internal state */ \ +void MSRESAMP(_reset)(MSRESAMP() _q); \ + \ +/* get filter delay (output samples) */ \ +float MSRESAMP(_get_delay)(MSRESAMP() _q); \ + \ +/* execute multi-stage resampler */ \ +/* _q : msresamp object */ \ +/* _x : input sample array [size: _nx x 1] */ \ +/* _nx : input sample array size */ \ +/* _y : output sample array [size: variable] */ \ +/* _ny : number of samples written to _y */ \ +void MSRESAMP(_execute)(MSRESAMP() _q, \ + TI * _x, \ + unsigned int _nx, \ + TO * _y, \ + unsigned int * _ny); \ + +LIQUID_MSRESAMP_DEFINE_API(MSRESAMP_MANGLE_RRRF, + float, + float, + float) + +LIQUID_MSRESAMP_DEFINE_API(MSRESAMP_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_MSRESAMP_DEFINE_API(MSRESAMP_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// Symbol timing recovery (symbol synchronizer) +// +#define SYMSYNC_MANGLE_RRRF(name) LIQUID_CONCAT(symsync_rrrf,name) +#define SYMSYNC_MANGLE_CRCF(name) LIQUID_CONCAT(symsync_crcf,name) + +#define LIQUID_SYMSYNC_DEFINE_API(SYMSYNC,TO,TC,TI) \ + \ +typedef struct SYMSYNC(_s) * SYMSYNC(); \ + \ +/* create synchronizer object from external coefficients */ \ +/* _k : samples per symbol */ \ +/* _M : number of filters in the bank */ \ +/* _h : matched filter coefficients [size: */ \ +/* _h_len : length of matched filter */ \ +SYMSYNC() SYMSYNC(_create)(unsigned int _k, \ + unsigned int _M, \ + TC * _h, \ + unsigned int _h_len); \ + \ +/* create square-root Nyquist symbol synchronizer */ \ +/* _type : filter type (e.g. LIQUID_FIRFILT_RRC) */ \ +/* _k : samples/symbol */ \ +/* _m : symbol delay */ \ +/* _beta : rolloff factor, beta in (0,1] */ \ +/* _M : number of filters in the bank */ \ +SYMSYNC() SYMSYNC(_create_rnyquist)(int _type, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + unsigned int _M); \ + \ +/* create symsync using Kaiser filter interpolator; useful */ \ +/* when the input signal has matched filter applied already */ \ +/* _k : input samples/symbol */ \ +/* _m : symbol delay */ \ +/* _beta : rolloff factor, beta in (0,1] */ \ +/* _M : number of filters in the bank */ \ +SYMSYNC() SYMSYNC(_create_kaiser)(unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + unsigned int _M); \ + \ +/* destroy symsync object, freeing all internal memory */ \ +void SYMSYNC(_destroy)(SYMSYNC() _q); \ + \ +/* print symsync object's parameters */ \ +void SYMSYNC(_print)(SYMSYNC() _q); \ + \ +/* reset symsync internal state */ \ +void SYMSYNC(_reset)(SYMSYNC() _q); \ + \ +/* lock/unlock loop control */ \ +void SYMSYNC(_lock)( SYMSYNC() _q); \ +void SYMSYNC(_unlock)(SYMSYNC() _q); \ + \ +/* set synchronizer output rate (samples/symbol) */ \ +/* _q : synchronizer object */ \ +/* _k_out : output samples/symbol */ \ +void SYMSYNC(_set_output_rate)(SYMSYNC() _q, \ + unsigned int _k_out); \ + \ +/* set loop-filter bandwidth */ \ +/* _q : synchronizer object */ \ +/* _bt : loop bandwidth */ \ +void SYMSYNC(_set_lf_bw)(SYMSYNC() _q, \ + float _bt); \ + \ +/* return instantaneous fractional timing offset estimate */ \ +float SYMSYNC(_get_tau)(SYMSYNC() _q); \ + \ +/* execute synchronizer on input data array */ \ +/* _q : synchronizer object */ \ +/* _x : input data array */ \ +/* _nx : number of input samples */ \ +/* _y : output data array */ \ +/* _ny : number of samples written to output buffer */ \ +void SYMSYNC(_execute)(SYMSYNC() _q, \ + TI * _x, \ + unsigned int _nx, \ + TO * _y, \ + unsigned int * _ny); \ + +LIQUID_SYMSYNC_DEFINE_API(SYMSYNC_MANGLE_RRRF, + float, + float, + float) + +LIQUID_SYMSYNC_DEFINE_API(SYMSYNC_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + + +// +// Finite impulse response Farrow filter +// + +#define FIRFARROW_MANGLE_RRRF(name) LIQUID_CONCAT(firfarrow_rrrf,name) +#define FIRFARROW_MANGLE_CRCF(name) LIQUID_CONCAT(firfarrow_crcf,name) +//#define FIRFARROW_MANGLE_CCCF(name) LIQUID_CONCAT(firfarrow_cccf,name) + +// Macro: +// FIRFARROW : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_FIRFARROW_DEFINE_API(FIRFARROW,TO,TC,TI) \ + \ +typedef struct FIRFARROW(_s) * FIRFARROW(); \ + \ +/* create firfarrow object */ \ +/* _h_len : filter length */ \ +/* _p : polynomial order */ \ +/* _fc : filter cutoff frequency */ \ +/* _As : stopband attenuation [dB] */ \ +FIRFARROW() FIRFARROW(_create)(unsigned int _h_len, \ + unsigned int _p, \ + float _fc, \ + float _As); \ + \ +/* destroy firfarrow object, freeing all internal memory */ \ +void FIRFARROW(_destroy)(FIRFARROW() _q); \ + \ +/* print firfarrow object's internal properties */ \ +void FIRFARROW(_print)(FIRFARROW() _q); \ + \ +/* reset firfarrow object's internal state */ \ +void FIRFARROW(_reset)(FIRFARROW() _q); \ + \ +/* push sample into firfarrow object */ \ +/* _q : firfarrow object */ \ +/* _x : input sample */ \ +void FIRFARROW(_push)(FIRFARROW() _q, \ + TI _x); \ + \ +/* set fractional delay of firfarrow object */ \ +/* _q : firfarrow object */ \ +/* _mu : fractional sample delay */ \ +void FIRFARROW(_set_delay)(FIRFARROW() _q, \ + float _mu); \ + \ +/* execute firfarrow internal dot product */ \ +/* _q : firfarrow object */ \ +/* _y : output sample pointer */ \ +void FIRFARROW(_execute)(FIRFARROW() _q, \ + TO * _y); \ + \ +/* compute firfarrow filter on block of samples; the input */ \ +/* and output arrays may have the same pointer */ \ +/* _q : firfarrow object */ \ +/* _x : input array [size: _n x 1] */ \ +/* _n : input, output array size */ \ +/* _y : output array [size: _n x 1] */ \ +void FIRFARROW(_execute_block)(FIRFARROW() _q, \ + TI * _x, \ + unsigned int _n, \ + TO * _y); \ + \ +/* get length of firfarrow object (number of filter taps) */ \ +unsigned int FIRFARROW(_get_length)(FIRFARROW() _q); \ + \ +/* get coefficients of firfarrow object */ \ +/* _q : firfarrow object */ \ +/* _h : output coefficients pointer */ \ +void FIRFARROW(_get_coefficients)(FIRFARROW() _q, \ + float * _h); \ + \ +/* compute complex frequency response */ \ +/* _q : filter object */ \ +/* _fc : frequency */ \ +/* _H : output frequency response */ \ +void FIRFARROW(_freqresponse)(FIRFARROW() _q, \ + float _fc, \ + liquid_float_complex * _H); \ + \ +/* compute group delay [samples] */ \ +/* _q : filter object */ \ +/* _fc : frequency */ \ +float FIRFARROW(_groupdelay)(FIRFARROW() _q, \ + float _fc); \ + +LIQUID_FIRFARROW_DEFINE_API(FIRFARROW_MANGLE_RRRF, + float, + float, + float) + +LIQUID_FIRFARROW_DEFINE_API(FIRFARROW_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + + + +// +// MODULE : framing +// + +// framesyncstats : generic frame synchronizer statistic structure + +typedef struct { + // signal quality + float evm; // error vector magnitude [dB] + float rssi; // received signal strength indicator [dB] + float cfo; // carrier frequency offset (f/Fs) + + // demodulated frame symbols + liquid_float_complex * framesyms; // pointer to array [size: framesyms x 1] + unsigned int num_framesyms; // length of framesyms + + // modulation/coding scheme etc. + unsigned int mod_scheme; // modulation scheme + unsigned int mod_bps; // modulation depth (bits/symbol) + unsigned int check; // data validity check (crc, checksum) + unsigned int fec0; // forward error-correction (inner) + unsigned int fec1; // forward error-correction (outer) +} framesyncstats_s; + +// external framesyncstats default object +extern framesyncstats_s framesyncstats_default; + +// initialize framesyncstats object on default +void framesyncstats_init_default(framesyncstats_s * _stats); + +// print framesyncstats object +void framesyncstats_print(framesyncstats_s * _stats); + +// Generic frame synchronizer callback function type +// _header : header data [size: 8 bytes] +// _header_valid : is header valid? (0:no, 1:yes) +// _payload : payload data [size: _payload_len] +// _payload_len : length of payload (bytes) +// _payload_valid : is payload valid? (0:no, 1:yes) +// _stats : frame statistics object +// _userdata : pointer to userdata +typedef int (*framesync_callback)(unsigned char * _header, + int _header_valid, + unsigned char * _payload, + unsigned int _payload_len, + int _payload_valid, + framesyncstats_s _stats, + void * _userdata); + +// framesync csma callback functions invoked when signal levels is high or low +// _userdata : user-defined data pointer +typedef void (*framesync_csma_callback)(void * _userdata); + + +// +// Basic frame generator (64 bytes data payload) +// + +// frame length in samples +#define LIQUID_FRAME64_LEN (1340) + +typedef struct framegen64_s * framegen64; + +// create frame generator +framegen64 framegen64_create(); + +// destroy frame generator +void framegen64_destroy(framegen64 _q); + +// print frame generator internal properties +void framegen64_print(framegen64 _q); + +// generate frame +// _q : frame generator object +// _header : 8-byte header data +// _payload : 64-byte payload data +// _frame : output frame samples [size: LIQUID_FRAME64_LEN x 1] +void framegen64_execute(framegen64 _q, + unsigned char * _header, + unsigned char * _payload, + liquid_float_complex * _frame); + +typedef struct framesync64_s * framesync64; + +// create framesync64 object +// _callback : callback function +// _userdata : user data pointer passed to callback function +framesync64 framesync64_create(framesync_callback _callback, + void * _userdata); + +// destroy frame synchronizer +void framesync64_destroy(framesync64 _q); + +// print frame synchronizer internal properties +void framesync64_print(framesync64 _q); + +// reset frame synchronizer internal state +void framesync64_reset(framesync64 _q); + +// push samples through frame synchronizer +// _q : frame synchronizer object +// _x : input samples [size: _n x 1] +// _n : number of input samples +void framesync64_execute(framesync64 _q, + liquid_float_complex * _x, + unsigned int _n); + +// enable/disable debugging +void framesync64_debug_enable(framesync64 _q); +void framesync64_debug_disable(framesync64 _q); +void framesync64_debug_print(framesync64 _q, const char * _filename); + +#if 0 +// advanced modes +void framesync64_set_csma_callbacks(framesync64 _q, + framesync_csma_callback _csma_lock, + framesync_csma_callback _csma_unlock, + void * _csma_userdata); +#endif + +// +// Flexible frame : adjustable payload, mod scheme, etc., but bring +// your own error correction, redundancy check +// + +// frame generator +typedef struct { + unsigned int check; // data validity check + unsigned int fec0; // forward error-correction scheme (inner) + unsigned int fec1; // forward error-correction scheme (outer) + unsigned int mod_scheme; // modulation scheme +} flexframegenprops_s; + +void flexframegenprops_init_default(flexframegenprops_s * _fgprops); + +typedef struct flexframegen_s * flexframegen; + +// create flexframegen object +// _props : frame properties (modulation scheme, etc.) +flexframegen flexframegen_create(flexframegenprops_s * _props); + +// destroy flexframegen object +void flexframegen_destroy(flexframegen _q); + +// print flexframegen object internals +void flexframegen_print(flexframegen _q); + +// reset flexframegen object internals +void flexframegen_reset(flexframegen _q); + +// is frame assembled? +int flexframegen_is_assembled(flexframegen _q); + +// get frame properties +void flexframegen_getprops(flexframegen _q, flexframegenprops_s * _props); + +// set frame properties +void flexframegen_setprops(flexframegen _q, flexframegenprops_s * _props); + +// get length of assembled frame (samples) +unsigned int flexframegen_getframelen(flexframegen _q); + +// assemble a frame from an array of data +// _q : frame generator object +// _header : frame header +// _payload : payload data [size: _payload_len x 1] +// _payload_len : payload data length +void flexframegen_assemble(flexframegen _q, + unsigned char * _header, + unsigned char * _payload, + unsigned int _payload_len); + +// write samples of assembled frame, two samples at a time, returning +// '1' when frame is complete, '0' otherwise +// _q : frame generator object +// _buffer : output buffer [size: 2 x 1] +int flexframegen_write_samples(flexframegen _q, + liquid_float_complex * _buffer); + +// frame synchronizer + +typedef struct flexframesync_s * flexframesync; + +// create flexframesync object +// _callback : callback function +// _userdata : user data pointer passed to callback function +flexframesync flexframesync_create(framesync_callback _callback, + void * _userdata); + +// destroy frame synchronizer +void flexframesync_destroy(flexframesync _q); + +// print frame synchronizer internal properties +void flexframesync_print(flexframesync _q); + +// reset frame synchronizer internal state +void flexframesync_reset(flexframesync _q); + +// push samples through frame synchronizer +// _q : frame synchronizer object +// _x : input samples [size: _n x 1] +// _n : number of input samples +void flexframesync_execute(flexframesync _q, + liquid_float_complex * _x, + unsigned int _n); + +// enable/disable debugging +void flexframesync_debug_enable(flexframesync _q); +void flexframesync_debug_disable(flexframesync _q); +void flexframesync_debug_print(flexframesync _q, + const char * _filename); +#if 0 +// advanced modes +void flexframesync_set_csma_callbacks(flexframesync _fs, + framesync_csma_callback _csma_lock, + framesync_csma_callback _csma_unlock, + void * _csma_userdata); +#endif + + +// +// bpacket : binary packet suitable for data streaming +// + +// +// bpacket generator/encoder +// +typedef struct bpacketgen_s * bpacketgen; + +// create bpacketgen object +// _m : p/n sequence length (ignored) +// _dec_msg_len : decoded message length (original uncoded data) +// _crc : data validity check (e.g. cyclic redundancy check) +// _fec0 : inner forward error-correction code scheme +// _fec1 : outer forward error-correction code scheme +bpacketgen bpacketgen_create(unsigned int _m, + unsigned int _dec_msg_len, + int _crc, + int _fec0, + int _fec1); + +// re-create bpacketgen object from old object +// _q : old bpacketgen object +// _m : p/n sequence length (ignored) +// _dec_msg_len : decoded message length (original uncoded data) +// _crc : data validity check (e.g. cyclic redundancy check) +// _fec0 : inner forward error-correction code scheme +// _fec1 : outer forward error-correction code scheme +bpacketgen bpacketgen_recreate(bpacketgen _q, + unsigned int _m, + unsigned int _dec_msg_len, + int _crc, + int _fec0, + int _fec1); + +// destroy bpacketgen object, freeing all internally-allocated memory +void bpacketgen_destroy(bpacketgen _q); + +// print bpacketgen internals +void bpacketgen_print(bpacketgen _q); + +// return length of full packet +unsigned int bpacketgen_get_packet_len(bpacketgen _q); + +// encode packet +void bpacketgen_encode(bpacketgen _q, + unsigned char * _msg_dec, + unsigned char * _packet); + +// +// bpacket synchronizer/decoder +// +typedef struct bpacketsync_s * bpacketsync; +typedef int (*bpacketsync_callback)(unsigned char * _payload, + int _payload_valid, + unsigned int _payload_len, + framesyncstats_s _stats, + void * _userdata); +bpacketsync bpacketsync_create(unsigned int _m, + bpacketsync_callback _callback, + void * _userdata); +void bpacketsync_destroy(bpacketsync _q); +void bpacketsync_print(bpacketsync _q); +void bpacketsync_reset(bpacketsync _q); + +// run synchronizer on array of input bytes +// _q : bpacketsync object +// _bytes : input data array [size: _n x 1] +// _n : input array size +void bpacketsync_execute(bpacketsync _q, + unsigned char * _bytes, + unsigned int _n); + +// run synchronizer on input byte +// _q : bpacketsync object +// _byte : input byte +void bpacketsync_execute_byte(bpacketsync _q, + unsigned char _byte); + +// run synchronizer on input symbol +// _q : bpacketsync object +// _sym : input symbol with _bps significant bits +// _bps : number of bits in input symbol +void bpacketsync_execute_sym(bpacketsync _q, + unsigned char _sym, + unsigned int _bps); + +// execute one bit at a time +void bpacketsync_execute_bit(bpacketsync _q, + unsigned char _bit); + +// +// GMSK frame generator +// + +typedef struct gmskframegen_s * gmskframegen; + +// create GMSK frame generator +gmskframegen gmskframegen_create(); +void gmskframegen_destroy(gmskframegen _fg); +void gmskframegen_print(gmskframegen _fg); +void gmskframegen_reset(gmskframegen _fg); +void gmskframegen_assemble(gmskframegen _fg, + unsigned char * _header, + unsigned char * _payload, + unsigned int _payload_len, + crc_scheme _check, + fec_scheme _fec0, + fec_scheme _fec1); +unsigned int gmskframegen_getframelen(gmskframegen _q); +int gmskframegen_write_samples(gmskframegen _fg, + liquid_float_complex * _y); + + +// +// GMSK frame synchronizer +// + +typedef struct gmskframesync_s * gmskframesync; + +// create GMSK frame synchronizer +// _callback : callback function +// _userdata : user data pointer passed to callback function +gmskframesync gmskframesync_create(framesync_callback _callback, + void * _userdata); +void gmskframesync_destroy(gmskframesync _q); +void gmskframesync_print(gmskframesync _q); +void gmskframesync_reset(gmskframesync _q); +void gmskframesync_execute(gmskframesync _q, + liquid_float_complex * _x, + unsigned int _n); + +// debugging +void gmskframesync_debug_enable(gmskframesync _q); +void gmskframesync_debug_disable(gmskframesync _q); +void gmskframesync_debug_print(gmskframesync _q, const char * _filename); + + +// +// OFDM flexframe generator +// + +// ofdm frame generator properties +typedef struct { + unsigned int check; // data validity check + unsigned int fec0; // forward error-correction scheme (inner) + unsigned int fec1; // forward error-correction scheme (outer) + unsigned int mod_scheme; // modulation scheme + //unsigned int block_size; // framing block size +} ofdmflexframegenprops_s; +void ofdmflexframegenprops_init_default(ofdmflexframegenprops_s * _props); + +typedef struct ofdmflexframegen_s * ofdmflexframegen; + +// create OFDM flexible framing generator object +// _M : number of subcarriers, >10 typical +// _cp_len : cyclic prefix length +// _taper_len : taper length (OFDM symbol overlap) +// _p : subcarrier allocation (null, pilot, data), [size: _M x 1] +// _fgprops : frame properties (modulation scheme, etc.) +ofdmflexframegen ofdmflexframegen_create(unsigned int _M, + unsigned int _cp_len, + unsigned int _taper_len, + unsigned char * _p, + ofdmflexframegenprops_s * _fgprops); + +// destroy ofdmflexframegen object +void ofdmflexframegen_destroy(ofdmflexframegen _q); + +// print parameters, properties, etc. +void ofdmflexframegen_print(ofdmflexframegen _q); + +// reset ofdmflexframegen object internals +void ofdmflexframegen_reset(ofdmflexframegen _q); + +// is frame assembled? +int ofdmflexframegen_is_assembled(ofdmflexframegen _q); + +// get properties +void ofdmflexframegen_getprops(ofdmflexframegen _q, + ofdmflexframegenprops_s * _props); + +// set properties +void ofdmflexframegen_setprops(ofdmflexframegen _q, + ofdmflexframegenprops_s * _props); + +// get length of frame (symbols) +// _q : OFDM frame generator object +unsigned int ofdmflexframegen_getframelen(ofdmflexframegen _q); + +// assemble a frame from an array of data +// _q : OFDM frame generator object +// _header : frame header [8 bytes] +// _payload : payload data [size: _payload_len x 1] +// _payload_len : payload data length +void ofdmflexframegen_assemble(ofdmflexframegen _q, + unsigned char * _header, + unsigned char * _payload, + unsigned int _payload_len); + +// write symbols of assembled frame +// _q : OFDM frame generator object +// _buffer : output buffer [size: M+cp_len x 1] +int ofdmflexframegen_writesymbol(ofdmflexframegen _q, + liquid_float_complex * _buffer); + +// +// OFDM flex frame synchronizer +// + +typedef struct ofdmflexframesync_s * ofdmflexframesync; + +// create OFDM flexible framing synchronizer object +// _M : number of subcarriers +// _cp_len : cyclic prefix length +// _taper_len : taper length (OFDM symbol overlap) +// _p : subcarrier allocation (null, pilot, data), [size: _M x 1] +// _callback : user-defined callback function +// _userdata : user-defined data pointer +ofdmflexframesync ofdmflexframesync_create(unsigned int _M, + unsigned int _cp_len, + unsigned int _taper_len, + unsigned char * _p, + framesync_callback _callback, + void * _userdata); + +void ofdmflexframesync_destroy(ofdmflexframesync _q); +void ofdmflexframesync_print(ofdmflexframesync _q); +void ofdmflexframesync_reset(ofdmflexframesync _q); +void ofdmflexframesync_execute(ofdmflexframesync _q, + liquid_float_complex * _x, + unsigned int _n); + +// query the received signal strength indication +float ofdmflexframesync_get_rssi(ofdmflexframesync _q); + +// query the received carrier offset estimate +float ofdmflexframesync_get_cfo(ofdmflexframesync _q); + +// enable/disable debugging +void ofdmflexframesync_debug_enable(ofdmflexframesync _q); +void ofdmflexframesync_debug_disable(ofdmflexframesync _q); +void ofdmflexframesync_debug_print(ofdmflexframesync _q, + const char * _filename); + + + +// +// Binary P/N synchronizer +// +#define BSYNC_MANGLE_RRRF(name) LIQUID_CONCAT(bsync_rrrf,name) +#define BSYNC_MANGLE_CRCF(name) LIQUID_CONCAT(bsync_crcf,name) +#define BSYNC_MANGLE_CCCF(name) LIQUID_CONCAT(bsync_cccf,name) + +// Macro: +// BSYNC : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_BSYNC_DEFINE_API(BSYNC,TO,TC,TI) \ +typedef struct BSYNC(_s) * BSYNC(); \ + \ +BSYNC() BSYNC(_create)(unsigned int _n, TC * _v); \ + \ +/* create binary synchronizer from m-sequence */ \ +/* _g : m-sequence generator polynomial */ \ +/* _k : samples/symbol (over-sampling factor) */ \ +BSYNC() BSYNC(_create_msequence)(unsigned int _g, \ + unsigned int _k); \ +void BSYNC(_destroy)(BSYNC() _fs); \ +void BSYNC(_print)(BSYNC() _fs); \ +void BSYNC(_correlate)(BSYNC() _fs, TI _sym, TO * _y); + +LIQUID_BSYNC_DEFINE_API(BSYNC_MANGLE_RRRF, + float, + float, + float) + +LIQUID_BSYNC_DEFINE_API(BSYNC_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_BSYNC_DEFINE_API(BSYNC_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// Pre-demodulation synchronizers (binary and otherwise) +// +#define PRESYNC_MANGLE_CCCF(name) LIQUID_CONCAT( presync_cccf,name) +#define BPRESYNC_MANGLE_CCCF(name) LIQUID_CONCAT(bpresync_cccf,name) + +// Macro: +// PRESYNC : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_PRESYNC_DEFINE_API(PRESYNC,TO,TC,TI) \ +typedef struct PRESYNC(_s) * PRESYNC(); \ + \ +/* create pre-demod synchronizer */ \ +/* _v : baseband sequence */ \ +/* _n : baseband sequence length */ \ +/* _dphi_max : maximum absolute frequency deviation */ \ +/* _m : number of correlators */ \ +PRESYNC() PRESYNC(_create)(TC * _v, \ + unsigned int _n, \ + float _dphi_max, \ + unsigned int _m); \ + \ +/* destroy pre-demod synchronizer */ \ +void PRESYNC(_destroy)(PRESYNC() _q); \ + \ +/* print pre-demod synchronizer internal state */ \ +void PRESYNC(_print)(PRESYNC() _q); \ + \ +/* reset pre-demod synchronizer internal state */ \ +void PRESYNC(_reset)(PRESYNC() _q); \ + \ +/* push input sample into pre-demod synchronizer */ \ +/* _q : pre-demod synchronizer object */ \ +/* _x : input sample */ \ +void PRESYNC(_push)(PRESYNC() _q, \ + TI _x); \ + \ +/* correlate input sequence */ \ +/* _q : pre-demod synchronizer object */ \ +/* _rxy : output cross correlation */ \ +/* _dphi_hat : output frequency offset estiamte */ \ +void PRESYNC(_correlate)(PRESYNC() _q, \ + TO * _rxy, \ + float * _dphi_hat); \ + +// non-binary pre-demodulation synchronizer +LIQUID_PRESYNC_DEFINE_API(PRESYNC_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +// binary pre-demodulation synchronizer +LIQUID_PRESYNC_DEFINE_API(BPRESYNC_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + +// +// Pre-demodulation detector +// + +typedef struct detector_cccf_s * detector_cccf; + +// create pre-demod detector +// _s : sequence +// _n : sequence length +// _threshold : detection threshold (default: 0.7) +// _dphi_max : maximum carrier offset +detector_cccf detector_cccf_create(liquid_float_complex * _s, + unsigned int _n, + float _threshold, + float _dphi_max); + +// destroy pre-demo detector object +void detector_cccf_destroy(detector_cccf _q); + +// print pre-demod detector internal state +void detector_cccf_print(detector_cccf _q); + +// reset pre-demod detector internal state +void detector_cccf_reset(detector_cccf _q); + +// Run sample through pre-demod detector's correlator. +// Returns '1' if signal was detected, '0' otherwise +// _q : pre-demod detector +// _x : input sample +// _tau_hat : fractional sample offset estimate (set when detected) +// _dphi_hat : carrier frequency offset estimate (set when detected) +// _gamma_hat : channel gain estimate (set when detected) +int detector_cccf_correlate(detector_cccf _q, + liquid_float_complex _x, + float * _tau_hat, + float * _dphi_hat, + float * _gamma_hat); + + +// +// MODULE : math +// + +// ln( Gamma(z) ) +float liquid_lngammaf(float _z); + +// Gamma(z) +float liquid_gammaf(float _z); + +// ln( gamma(z,alpha) ) : lower incomplete gamma function +float liquid_lnlowergammaf(float _z, float _alpha); + +// ln( Gamma(z,alpha) ) : upper incomplete gamma function +float liquid_lnuppergammaf(float _z, float _alpha); + +// gamma(z,alpha) : lower incomplete gamma function +float liquid_lowergammaf(float _z, float _alpha); + +// Gamma(z,alpha) : upper incomplete gamma function +float liquid_uppergammaf(float _z, float _alpha); + +// n! +float liquid_factorialf(unsigned int _n); + + + +// ln(I_v(z)) : log Modified Bessel function of the first kind +float liquid_lnbesselif(float _nu, float _z); + +// I_v(z) : Modified Bessel function of the first kind +float liquid_besselif(float _nu, float _z); + +// I_0(z) : Modified Bessel function of the first kind (order zero) +float liquid_besseli0f(float _z); + +// J_v(z) : Bessel function of the first kind +float liquid_besseljf(float _nu, float _z); + +// J_0(z) : Bessel function of the first kind (order zero) +float liquid_besselj0f(float _z); + + +// Q function +float liquid_Qf(float _z); + +// Marcum Q-function +float liquid_MarcumQf(int _M, + float _alpha, + float _beta); + +// Marcum Q-function (M=1) +float liquid_MarcumQ1f(float _alpha, + float _beta); + +// sin(pi x) / (pi x) +float sincf(float _x); + +// next power of 2 : y = ceil(log2(_x)) +unsigned int liquid_nextpow2(unsigned int _x); + +// (n choose k) = n! / ( k! (n-k)! ) +float liquid_nchoosek(unsigned int _n, unsigned int _k); + +// +// Windowing functions +// + +// Kaiser-Bessel derived window (single sample) +// _n : index (0 <= _n < _N) +// _N : length of filter (must be even) +// _beta : Kaiser window parameter (_beta > 0) +float liquid_kbd(unsigned int _n, unsigned int _N, float _beta); + +// Kaiser-Bessel derived window (full window) +// _n : length of filter (must be even) +// _beta : Kaiser window parameter (_beta > 0) +// _w : resulting window +void liquid_kbd_window(unsigned int _n, float _beta, float * _w); + +// Kaiser window +// _n : window index +// _N : full window length +// _beta : Kaiser-Bessel window shape parameter +// _dt : fractional sample offset +float kaiser(unsigned int _n, + unsigned int _N, + float _beta, + float _dt); + +// Hamming window +// _n : window index +// _N : full window length +float hamming(unsigned int _n, unsigned int _N); + +// Hann window +// _n : window index +// _N : full window length +float hann(unsigned int _n, unsigned int _N); + +// Blackman-harris window +// _n : window index +// _N : full window length +float blackmanharris(unsigned int _n, unsigned int _N); + + +// polynomials + + +#define POLY_MANGLE_DOUBLE(name) LIQUID_CONCAT(poly, name) +#define POLY_MANGLE_FLOAT(name) LIQUID_CONCAT(polyf, name) + +#define POLY_MANGLE_CDOUBLE(name) LIQUID_CONCAT(polyc, name) +#define POLY_MANGLE_CFLOAT(name) LIQUID_CONCAT(polycf, name) + +// large macro +// POLY : name-mangling macro +// T : data type +// TC : data type (complex) +#define LIQUID_POLY_DEFINE_API(POLY,T,TC) \ +/* evaluate polynomial _p (order _k-1) at value _x */ \ +T POLY(_val)(T * _p, unsigned int _k, T _x); \ + \ +/* least-squares polynomial fit (order _k-1) */ \ +void POLY(_fit)(T * _x, \ + T * _y, \ + unsigned int _n, \ + T * _p, \ + unsigned int _k); \ + \ +/* Lagrange polynomial exact fit (order _n-1) */ \ +void POLY(_fit_lagrange)(T * _x, \ + T * _y, \ + unsigned int _n, \ + T * _p); \ + \ +/* Lagrange polynomial interpolation */ \ +T POLY(_interp_lagrange)(T * _x, \ + T * _y, \ + unsigned int _n, \ + T _x0); \ + \ +/* Lagrange polynomial fit (barycentric form) */ \ +void POLY(_fit_lagrange_barycentric)(T * _x, \ + unsigned int _n, \ + T * _w); \ + \ +/* Lagrange polynomial interpolation (barycentric form) */ \ +T POLY(_val_lagrange_barycentric)(T * _x, \ + T * _y, \ + T * _w, \ + T _x0, \ + unsigned int _n); \ + \ +/* expands the polynomial: \ + * P_n(x) = (1+x)^n \ + * as \ + * P_n(x) = p[0] + p[1]*x + p[2]*x^2 + ... + p[n]x^n \ + * NOTE: _p has order n=m+k (array is length n+1) \ + */ \ +void POLY(_expandbinomial)(unsigned int _n, \ + T * _p); \ + \ +/* expands the polynomial: \ + * P_n(x) = (1+x)^m * (1-x)^k \ + * as \ + * P_n(x) = p[0] + p[1]*x + p[2]*x^2 + ... + p[n]x^n \ + * NOTE: _p has order n=m+k (array is length n+1) \ + */ \ +void POLY(_expandbinomial_pm)(unsigned int _m, \ + unsigned int _k, \ + T * _p); \ + \ +/* expands the polynomial: \ + * P_n(x) = (x-r[0]) * (x-r[1]) * ... * (x-r[n-1]) \ + * as \ + * P_n(x) = c[0] + c[1]*x + ... + c[n]*x^n \ + * where r[0],r[1],...,r[n-1] are the roots of P_n(x) \ + * NOTE: _c has order _n (array is length _n+1) \ + */ \ +void POLY(_expandroots)(T * _a, \ + unsigned int _n, \ + T * _c); \ + \ +/* expands the polynomial: \ + * P_n(x) = \ + * (x*b[0]-a[0]) * (x*b[1]-a[1]) * ... * (x*b[n-1]-a[n-1]) \ + * as \ + * P_n(x) = c[0] + c[1]*x + ... + c[n]*x^n \ + * NOTE: _c has order _n (array is length _n+1) \ + */ \ +void POLY(_expandroots2)(T * _a, \ + T * _b, \ + unsigned int _n, \ + T * _c); \ + \ +/* find roots of the polynomial (complex) */ \ +/* _poly : poly array, ascending powers [size: _k x 1] */ \ +/* _k : poly length (poly order = _k - 1) */ \ +/* _roots : resulting complex roots [size: _k-1 x 1] */ \ +void POLY(_findroots)(T * _poly, \ + unsigned int _n, \ + TC * _roots); \ + \ +/* find the complex roots of the polynomial using the */ \ +/* Durand-Kerner method */ \ +void POLY(_findroots_durandkerner)(T * _poly, \ + unsigned int _k, \ + TC * _roots); \ + \ +/* find the complex roots of the polynomial using */ \ +/* Bairstow's method */ \ +void POLY(_findroots_bairstow)(T * _poly, \ + unsigned int _k, \ + TC * _roots); \ + \ +/* expands the multiplication of two polynomials */ \ +void POLY(_mul)(T * _a, \ + unsigned int _order_a, \ + T * _b, \ + unsigned int _order_b, \ + T * _c); \ + +LIQUID_POLY_DEFINE_API(POLY_MANGLE_DOUBLE, + double, + liquid_double_complex) + +LIQUID_POLY_DEFINE_API(POLY_MANGLE_FLOAT, + float, + liquid_float_complex) + +LIQUID_POLY_DEFINE_API(POLY_MANGLE_CDOUBLE, + liquid_double_complex, + liquid_double_complex) + +LIQUID_POLY_DEFINE_API(POLY_MANGLE_CFLOAT, + liquid_float_complex, + liquid_float_complex) + +#if 0 +// expands the polynomial: (1+x)^n +void poly_binomial_expand(unsigned int _n, int * _c); + +// expands the polynomial: (1+x)^k * (1-x)^(n-k) +void poly_binomial_expand_pm(unsigned int _n, + unsigned int _k, + int * _c); +#endif + +// +// modular arithmetic, etc. +// + +// maximum number of factors +#define LIQUID_MAX_FACTORS (40) + +// is number prime? +int liquid_is_prime(unsigned int _n); + +// compute number's prime factors +// _n : number to factor +// _factors : pre-allocated array of factors [size: LIQUID_MAX_FACTORS x 1] +// _num_factors: number of factors found, sorted ascending +void liquid_factor(unsigned int _n, + unsigned int * _factors, + unsigned int * _num_factors); + +// compute number's unique prime factors +// _n : number to factor +// _factors : pre-allocated array of factors [size: LIQUID_MAX_FACTORS x 1] +// _num_factors: number of unique factors found, sorted ascending +void liquid_unique_factor(unsigned int _n, + unsigned int * _factors, + unsigned int * _num_factors); + +// compute c = base^exp (mod n) +unsigned int liquid_modpow(unsigned int _base, + unsigned int _exp, + unsigned int _n); + +// find smallest primitive root of _n +unsigned int liquid_primitive_root(unsigned int _n); + +// find smallest primitive root of _n, assuming _n is prime +unsigned int liquid_primitive_root_prime(unsigned int _n); + +// Euler's totient function +unsigned int liquid_totient(unsigned int _n); + + +// +// MODULE : matrix +// + +#define MATRIX_MANGLE_DOUBLE(name) LIQUID_CONCAT(matrix, name) +#define MATRIX_MANGLE_FLOAT(name) LIQUID_CONCAT(matrixf, name) + +#define MATRIX_MANGLE_CDOUBLE(name) LIQUID_CONCAT(matrixc, name) +#define MATRIX_MANGLE_CFLOAT(name) LIQUID_CONCAT(matrixcf, name) + +// large macro +// MATRIX : name-mangling macro +// T : data type +#define LIQUID_MATRIX_DEFINE_API(MATRIX,T) \ +void MATRIX(_print)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx); \ +void MATRIX(_add)(T * _x, \ + T * _y, \ + T * _z, \ + unsigned int _r, \ + unsigned int _c); \ +void MATRIX(_sub)(T * _x, \ + T * _y, \ + T * _z, \ + unsigned int _r, \ + unsigned int _c); \ +void MATRIX(_pmul)(T * _x, \ + T * _y, \ + T * _z, \ + unsigned int _r, \ + unsigned int _c); \ +void MATRIX(_pdiv)(T * _x, \ + T * _y, \ + T * _z, \ + unsigned int _r, \ + unsigned int _c); \ +void MATRIX(_mul)(T * _x, unsigned int _rx, unsigned int _cx, \ + T * _y, unsigned int _ry, unsigned int _cy, \ + T * _z, unsigned int _rz, unsigned int _cz); \ +void MATRIX(_div)(T * _x, T * _y, T * _z, unsigned int _n); \ +T MATRIX(_det)(T * _x, unsigned int _r, unsigned int _c); \ +void MATRIX(_trans)(T * _x, unsigned int _rx, unsigned int _cx);\ +void MATRIX(_hermitian)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx); \ + \ +/* compute x*x' on [m x n] matrix, result: [m x m] */ \ +void MATRIX(_mul_transpose)(T * _x, \ + unsigned int _m, \ + unsigned int _n, \ + T * _xxT); \ +/* compute x'*x on [m x n] matrix, result: [n x n] */ \ +void MATRIX(_transpose_mul)(T * _x, \ + unsigned int _m, \ + unsigned int _n, \ + T * _xTx); \ +/* compute x*x.' on [m x n] matrix, result: [m x m] */ \ +void MATRIX(_mul_hermitian)(T * _x, \ + unsigned int _m, \ + unsigned int _n, \ + T * _xxH); \ +/* compute x.'*x on [m x n] matrix, result: [n x n] */ \ +void MATRIX(_hermitian_mul)(T * _x, \ + unsigned int _m, \ + unsigned int _n, \ + T * _xHx); \ + \ +void MATRIX(_aug)(T * _x, unsigned int _rx, unsigned int _cx, \ + T * _y, unsigned int _ry, unsigned int _cy, \ + T * _z, unsigned int _rz, unsigned int _cz); \ +void MATRIX(_inv)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx); \ +void MATRIX(_eye)(T * _x, \ + unsigned int _n); \ +void MATRIX(_ones)(T * _x, \ + unsigned int _r, \ + unsigned int _c); \ +void MATRIX(_zeros)(T * _x, \ + unsigned int _r, \ + unsigned int _c); \ +void MATRIX(_gjelim)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx); \ +void MATRIX(_pivot)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx, \ + unsigned int _r, \ + unsigned int _c); \ +void MATRIX(_swaprows)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx, \ + unsigned int _r1, \ + unsigned int _r2); \ +void MATRIX(_linsolve)(T * _A, \ + unsigned int _r, \ + T * _b, \ + T * _x, \ + void * _opts); \ +void MATRIX(_cgsolve)(T * _A, \ + unsigned int _r, \ + T * _b, \ + T * _x, \ + void * _opts); \ +void MATRIX(_ludecomp_crout)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx, \ + T * _L, \ + T * _U, \ + T * _P); \ +void MATRIX(_ludecomp_doolittle)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx, \ + T * _L, \ + T * _U, \ + T * _P); \ +void MATRIX(_gramschmidt)(T * _A, \ + unsigned int _rx, \ + unsigned int _cx, \ + T * _U); \ +void MATRIX(_qrdecomp_gramschmidt)(T * _x, \ + unsigned int _rx, \ + unsigned int _cx, \ + T * _Q, \ + T * _R); \ +void MATRIX(_chol)(T * _A, \ + unsigned int _n, \ + T * _L); \ + +#define matrix_access(X,R,C,r,c) ((X)[(r)*(C)+(c)]) + +#define matrixc_access(X,R,C,r,c) matrix_access(X,R,C,r,c) +#define matrixf_access(X,R,C,r,c) matrix_access(X,R,C,r,c) +#define matrixcf_access(X,R,C,r,c) matrix_access(X,R,C,r,c) + +LIQUID_MATRIX_DEFINE_API(MATRIX_MANGLE_FLOAT, float) +LIQUID_MATRIX_DEFINE_API(MATRIX_MANGLE_DOUBLE, double) + +LIQUID_MATRIX_DEFINE_API(MATRIX_MANGLE_CFLOAT, liquid_float_complex) +LIQUID_MATRIX_DEFINE_API(MATRIX_MANGLE_CDOUBLE, liquid_double_complex) + + +#define SMATRIX_MANGLE_BOOL(name) LIQUID_CONCAT(smatrixb, name) +#define SMATRIX_MANGLE_FLOAT(name) LIQUID_CONCAT(smatrixf, name) +#define SMATRIX_MANGLE_INT(name) LIQUID_CONCAT(smatrixi, name) + +// sparse 'alist' matrix type (similar to MacKay, Davey Lafferty convention) +// large macro +// SMATRIX : name-mangling macro +// T : primitive data type +#define LIQUID_SMATRIX_DEFINE_API(SMATRIX,T) \ +typedef struct SMATRIX(_s) * SMATRIX(); \ + \ +/* create _M x _N matrix, initialized with zeros */ \ +SMATRIX() SMATRIX(_create)(unsigned int _M, \ + unsigned int _N); \ + \ +/* create _M x _N matrix, initialized on array */ \ +SMATRIX() SMATRIX(_create_array)(T * _x, \ + unsigned int _m, \ + unsigned int _n); \ + \ +/* destroy object */ \ +void SMATRIX(_destroy)(SMATRIX() _q); \ + \ +/* print compact form */ \ +void SMATRIX(_print)(SMATRIX() _q); \ + \ +/* print expanded form */ \ +void SMATRIX(_print_expanded)(SMATRIX() _q); \ + \ +/* query properties methods */ \ +void SMATRIX(_size)(SMATRIX() _q, \ + unsigned int * _m, \ + unsigned int * _n); \ + \ +/* zero all elements */ \ +void SMATRIX(_clear)(SMATRIX() _q); /* zero and keep memory */ \ +void SMATRIX(_reset)(SMATRIX() _q); /* zero and clear memory */ \ + \ +/* determine if value has been set (allocated memory) */ \ +int SMATRIX(_isset)(SMATRIX() _q, \ + unsigned int _m, \ + unsigned int _n); \ + \ +/* inserts/deletes element at index (memory allocation) */ \ +void SMATRIX(_insert)(SMATRIX() _q, \ + unsigned int _m, \ + unsigned int _n, \ + T _v); \ +void SMATRIX(_delete)(SMATRIX() _q, \ + unsigned int _m, \ + unsigned int _n); \ + \ +/* sets/gets the value (with memory allocation if needed) */ \ +void SMATRIX(_set)(SMATRIX() _q, \ + unsigned int _m, \ + unsigned int _n, \ + T _v); \ +T SMATRIX(_get)(SMATRIX() _q, \ + unsigned int _m, \ + unsigned int _n); \ + \ +/* initialize to identity matrix */ \ +void SMATRIX(_eye)(SMATRIX() _q); \ + \ +/* multiply two sparse binary matrices */ \ +void SMATRIX(_mul)(SMATRIX() _x, \ + SMATRIX() _y, \ + SMATRIX() _z); \ + \ +/* multiply sparse matrix by vector */ \ +/* _q : sparse matrix */ \ +/* _x : input vector [size: _N x 1] */ \ +/* _y : output vector [size: _M x 1] */ \ +void SMATRIX(_vmul)(SMATRIX() _q, \ + T * _x, \ + T * _y); \ + +LIQUID_SMATRIX_DEFINE_API(SMATRIX_MANGLE_BOOL, unsigned char) +LIQUID_SMATRIX_DEFINE_API(SMATRIX_MANGLE_FLOAT, float) +LIQUID_SMATRIX_DEFINE_API(SMATRIX_MANGLE_INT, short int) + +// +// smatrix cross methods +// + +// multiply sparse binary matrix by floating-point matrix +// _q : sparse matrix [size: A->M x A->N] +// _x : input vector [size: mx x nx ] +// _y : output vector [size: my x ny ] +void smatrixb_mulf(smatrixb _A, + float * _x, + unsigned int _mx, + unsigned int _nx, + float * _y, + unsigned int _my, + unsigned int _ny); + +// multiply sparse binary matrix by floating-point vector +// _q : sparse matrix +// _x : input vector [size: _N x 1] +// _y : output vector [size: _M x 1] +void smatrixb_vmulf(smatrixb _q, + float * _x, + float * _y); + + +// +// MODULE : modem (modulator/demodulator) +// + +// Maximum number of allowed bits per symbol +#define MAX_MOD_BITS_PER_SYMBOL 8 + +// Modulation schemes available +#define LIQUID_MODEM_NUM_SCHEMES (52) + +typedef enum { + LIQUID_MODEM_UNKNOWN=0, // Unknown modulation scheme + + // Phase-shift keying (PSK) + LIQUID_MODEM_PSK2, LIQUID_MODEM_PSK4, + LIQUID_MODEM_PSK8, LIQUID_MODEM_PSK16, + LIQUID_MODEM_PSK32, LIQUID_MODEM_PSK64, + LIQUID_MODEM_PSK128, LIQUID_MODEM_PSK256, + + // Differential phase-shift keying (DPSK) + LIQUID_MODEM_DPSK2, LIQUID_MODEM_DPSK4, + LIQUID_MODEM_DPSK8, LIQUID_MODEM_DPSK16, + LIQUID_MODEM_DPSK32, LIQUID_MODEM_DPSK64, + LIQUID_MODEM_DPSK128, LIQUID_MODEM_DPSK256, + + // amplitude-shift keying + LIQUID_MODEM_ASK2, LIQUID_MODEM_ASK4, + LIQUID_MODEM_ASK8, LIQUID_MODEM_ASK16, + LIQUID_MODEM_ASK32, LIQUID_MODEM_ASK64, + LIQUID_MODEM_ASK128, LIQUID_MODEM_ASK256, + + // rectangular quadrature amplitude-shift keying (QAM) + LIQUID_MODEM_QAM4, + LIQUID_MODEM_QAM8, LIQUID_MODEM_QAM16, + LIQUID_MODEM_QAM32, LIQUID_MODEM_QAM64, + LIQUID_MODEM_QAM128, LIQUID_MODEM_QAM256, + + // amplitude phase-shift keying (APSK) + LIQUID_MODEM_APSK4, + LIQUID_MODEM_APSK8, LIQUID_MODEM_APSK16, + LIQUID_MODEM_APSK32, LIQUID_MODEM_APSK64, + LIQUID_MODEM_APSK128, LIQUID_MODEM_APSK256, + + // specific modem types + LIQUID_MODEM_BPSK, // Specific: binary PSK + LIQUID_MODEM_QPSK, // specific: quaternary PSK + LIQUID_MODEM_OOK, // Specific: on/off keying + LIQUID_MODEM_SQAM32, // 'square' 32-QAM + LIQUID_MODEM_SQAM128, // 'square' 128-QAM + LIQUID_MODEM_V29, // V.29 star constellation + LIQUID_MODEM_ARB16OPT, // optimal 16-QAM + LIQUID_MODEM_ARB32OPT, // optimal 32-QAM + LIQUID_MODEM_ARB64OPT, // optimal 64-QAM + LIQUID_MODEM_ARB128OPT, // optimal 128-QAM + LIQUID_MODEM_ARB256OPT, // optimal 256-QAM + LIQUID_MODEM_ARB64VT, // Virginia Tech logo + + // arbitrary modem type + LIQUID_MODEM_ARB // arbitrary QAM +} modulation_scheme; + +// structure for holding full modulation type descriptor +struct modulation_type_s { + const char * name; // short name (e.g. 'bpsk') + const char * fullname; // full name (e.g. 'binary phase-shift keying') + modulation_scheme scheme; // modulation scheme (e.g. LIQUID_MODEM_BPSK) + unsigned int bps; // modulation depth (e.g. 1) +}; + +// full modulation type descriptor +extern const struct modulation_type_s modulation_types[LIQUID_MODEM_NUM_SCHEMES]; + +// Print compact list of existing and available modulation schemes +void liquid_print_modulation_schemes(); + +// returns modulation_scheme based on input string +modulation_scheme liquid_getopt_str2mod(const char * _str); + +// query basic modulation types +int liquid_modem_is_psk(modulation_scheme _ms); +int liquid_modem_is_dpsk(modulation_scheme _ms); +int liquid_modem_is_ask(modulation_scheme _ms); +int liquid_modem_is_qam(modulation_scheme _ms); +int liquid_modem_is_apsk(modulation_scheme _ms); + +// useful functions + +// counts the number of different bits between two symbols +unsigned int count_bit_errors(unsigned int _s1, unsigned int _s2); + +// counts the number of different bits between two arrays of symbols +// _msg0 : original message [size: _n x 1] +// _msg1 : copy of original message [size: _n x 1] +// _n : message size +unsigned int count_bit_errors_array(unsigned char * _msg0, + unsigned char * _msg1, + unsigned int _n); + +// converts binary-coded decimal (BCD) to gray, ensuring successive values +// differ by exactly one bit +unsigned int gray_encode(unsigned int symbol_in); + +// converts a gray-encoded symbol to binary-coded decimal (BCD) +unsigned int gray_decode(unsigned int symbol_in); + +// pack soft bits into symbol +// _soft_bits : soft input bits [size: _bps x 1] +// _bps : bits per symbol +// _sym_out : output symbol, value in [0,2^_bps) +void liquid_pack_soft_bits(unsigned char * _soft_bits, + unsigned int _bps, + unsigned int * _sym_out); + +// unpack soft bits into symbol +// _sym_in : input symbol, value in [0,2^_bps) +// _bps : bits per symbol +// _soft_bits : soft output bits [size: _bps x 1] +void liquid_unpack_soft_bits(unsigned int _sym_in, + unsigned int _bps, + unsigned char * _soft_bits); + + +// +// Linear modem +// + +#define LIQUID_MODEM_MANGLE_FLOAT(name) LIQUID_CONCAT(modem,name) + +// Macro : MODEM +// MODEM : name-mangling macro +// T : primitive data type +// TC : primitive data type (complex) +#define LIQUID_MODEM_DEFINE_API(MODEM,T,TC) \ + \ +/* define struct pointer */ \ +typedef struct MODEM(_s) * MODEM(); \ + \ +/* create digital modem object, allocating memory as necessary */ \ +MODEM() MODEM(_create)(modulation_scheme _scheme); \ + \ +/* create arbitrary digital modem object */ \ +MODEM() MODEM(_create_arbitrary)(TC * _table, unsigned int _M); \ + \ +/* recreate modulation scheme, re-allocating memory as necessary */ \ +MODEM() MODEM(_recreate)(MODEM() _q, \ + modulation_scheme _scheme); \ + \ +void MODEM(_destroy)(MODEM() _q); \ +void MODEM(_print)( MODEM() _q); \ +void MODEM(_reset)( MODEM() _q); \ + \ +/* generate random symbol */ \ +unsigned int MODEM(_gen_rand_sym)(MODEM() _q); \ + \ +/* Accessor functions */ \ +unsigned int MODEM(_get_bps)(MODEM() _q); \ + \ +/* generic modulate function; simply queries modem scheme */ \ +/* and calls appropriate subroutine */ \ +/* _q : modem object */ \ +/* _s : input symbol */ \ +/* _x : output sample */ \ +void MODEM(_modulate)(MODEM() _q, \ + unsigned int _s, \ + TC *_y); \ + \ +/* generic hard-decision demodulation function */ \ +/* _q : modem object */ \ +/* _x : input sample */ \ +/* _s : output symbol */ \ +void MODEM(_demodulate)(MODEM() _q, \ + TC _x, \ + unsigned int * _s); \ + \ +/* generic soft-decision demodulation function */ \ +/* _q : modem object */ \ +/* _x : input sample */ \ +/* _s : output hard symbol */ \ +/* _soft_bits : output soft bits */ \ +void MODEM(_demodulate_soft)(MODEM() _q, \ + TC _x, \ + unsigned int * _s, \ + unsigned char * _soft_bits); \ + \ +/* get demodulator's estimated transmit sample */ \ +void MODEM(_get_demodulator_sample)(MODEM() _q, \ + TC * _x_hat); \ + \ +/* get demodulator phase error */ \ +float MODEM(_get_demodulator_phase_error)(MODEM() _q); \ + \ +/* get demodulator error vector magnitude */ \ +float MODEM(_get_demodulator_evm)(MODEM() _q); \ + +// define modem APIs +LIQUID_MODEM_DEFINE_API(LIQUID_MODEM_MANGLE_FLOAT,float,liquid_float_complex) + + +// +// continuous-phase modulation +// + +// gmskmod : GMSK modulator +typedef struct gmskmod_s * gmskmod; + +// create gmskmod object +// _k : samples/symbol +// _m : filter delay (symbols) +// _BT : excess bandwidth factor +gmskmod gmskmod_create(unsigned int _k, + unsigned int _m, + float _BT); +void gmskmod_destroy(gmskmod _q); +void gmskmod_print(gmskmod _q); +void gmskmod_reset(gmskmod _q); +void gmskmod_modulate(gmskmod _q, + unsigned int _sym, + liquid_float_complex * _y); + + +// gmskdem : GMSK demodulator +typedef struct gmskdem_s * gmskdem; + +// create gmskdem object +// _k : samples/symbol +// _m : filter delay (symbols) +// _BT : excess bandwidth factor +gmskdem gmskdem_create(unsigned int _k, + unsigned int _m, + float _BT); +void gmskdem_destroy(gmskdem _q); +void gmskdem_print(gmskdem _q); +void gmskdem_reset(gmskdem _q); +void gmskdem_set_eq_bw(gmskdem _q, float _bw); +void gmskdem_demodulate(gmskdem _q, + liquid_float_complex * _y, + unsigned int * _sym); + +// +// Analog frequency modulator +// +#define LIQUID_FREQMOD_MANGLE_FLOAT(name) LIQUID_CONCAT(freqmod,name) + +// Macro : FREQMOD (analog frequency modulator) +// FREQMOD : name-mangling macro +// T : primitive data type +// TC : primitive data type (complex) +#define LIQUID_FREQMOD_DEFINE_API(FREQMOD,T,TC) \ + \ +/* define struct pointer */ \ +typedef struct FREQMOD(_s) * FREQMOD(); \ + \ +/* create freqmod object (frequency modulator) */ \ +/* _kf : modulation factor */ \ +FREQMOD() FREQMOD(_create)(float _kf); \ + \ +/* destroy freqmod object */ \ +void FREQMOD(_destroy)(FREQMOD() _q); \ + \ +/* print freqmod object internals */ \ +void FREQMOD(_print)(FREQMOD() _q); \ + \ +/* reset state */ \ +void FREQMOD(_reset)(FREQMOD() _q); \ + \ +/* modulate single sample */ \ +/* _q : frequency modulator object */ \ +/* _m : message signal m(t) */ \ +/* _s : complex baseband signal s(t) */ \ +void FREQMOD(_modulate)(FREQMOD() _q, \ + T _m, \ + TC * _s); \ + \ +/* modulate block of samples */ \ +/* _q : frequency modulator object */ \ +/* _m : message signal m(t), [size: _n x 1] */ \ +/* _n : number of input, output samples */ \ +/* _s : complex baseband signal s(t) [size: _n x 1] */ \ +void FREQMOD(_modulate_block)(FREQMOD() _q, \ + T * _m, \ + unsigned int _n, \ + TC * _s); \ + +// define freqmod APIs +LIQUID_FREQMOD_DEFINE_API(LIQUID_FREQMOD_MANGLE_FLOAT,float,liquid_float_complex) + + + +// +// Analog frequency demodulator +// + +#define LIQUID_FREQDEM_MANGLE_FLOAT(name) LIQUID_CONCAT(freqdem,name) + +// Macro : FREQDEM (analog frequency modulator) +// FREQDEM : name-mangling macro +// T : primitive data type +// TC : primitive data type (complex) +#define LIQUID_FREQDEM_DEFINE_API(FREQDEM,T,TC) \ + \ +/* define struct pointer */ \ +typedef struct FREQDEM(_s) * FREQDEM(); \ + \ +/* create freqdem object (frequency modulator) */ \ +/* _kf : modulation factor */ \ +FREQDEM() FREQDEM(_create)(float _kf); \ + \ +/* destroy freqdem object */ \ +void FREQDEM(_destroy)(FREQDEM() _q); \ + \ +/* print freqdem object internals */ \ +void FREQDEM(_print)(FREQDEM() _q); \ + \ +/* reset state */ \ +void FREQDEM(_reset)(FREQDEM() _q); \ + \ +/* demodulate sample */ \ +/* _q : frequency modulator object */ \ +/* _r : received signal r(t) */ \ +/* _m : output message signal m(t) */ \ +void FREQDEM(_demodulate)(FREQDEM() _q, \ + TC _r, \ + T * _m); \ + \ +/* demodulate block of samples */ \ +/* _q : frequency demodulator object */ \ +/* _r : received signal r(t) [size: _n x 1] */ \ +/* _n : number of input, output samples */ \ +/* _m : message signal m(t), [size: _n x 1] */ \ +void FREQDEM(_demodulate_block)(FREQDEM() _q, \ + TC * _r, \ + unsigned int _n, \ + T * _m); \ + +// define freqdem APIs +LIQUID_FREQDEM_DEFINE_API(LIQUID_FREQDEM_MANGLE_FLOAT,float,liquid_float_complex) + + + +// amplitude modulation types +typedef enum { + LIQUID_AMPMODEM_DSB=0, // double side-band + LIQUID_AMPMODEM_USB, // single side-band (upper) + LIQUID_AMPMODEM_LSB // single side-band (lower) +} liquid_ampmodem_type; + +typedef struct ampmodem_s * ampmodem; + +// create ampmodem object +// _m : modulation index +// _fc : carrier frequency, range: [-0.5,0.5] +// _type : AM type (e.g. LIQUID_AMPMODEM_DSB) +// _suppressed_carrier : carrier suppression flag +ampmodem ampmodem_create(float _m, + float _fc, + liquid_ampmodem_type _type, + int _suppressed_carrier); + +// destroy ampmodem object +void ampmodem_destroy(ampmodem _fm); + +// print ampmodem object internals +void ampmodem_print(ampmodem _fm); + +// reset ampmodem object state +void ampmodem_reset(ampmodem _fm); + +// modulate sample +void ampmodem_modulate(ampmodem _fm, + float _x, + liquid_float_complex *_y); + +// demodulate sample +void ampmodem_demodulate(ampmodem _fm, + liquid_float_complex _y, + float *_x); + + +// +// MODULE : multichannel +// + + +#define FIRPFBCH_NYQUIST 0 +#define FIRPFBCH_ROOTNYQUIST 1 + +#define LIQUID_ANALYZER 0 +#define LIQUID_SYNTHESIZER 1 + + +// +// Finite impulse response polyphase filterbank channelizer +// + +#define FIRPFBCH_MANGLE_CRCF(name) LIQUID_CONCAT(firpfbch_crcf,name) +#define FIRPFBCH_MANGLE_CCCF(name) LIQUID_CONCAT(firpfbch_cccf,name) + +// Macro: +// FIRPFBCH : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_FIRPFBCH_DEFINE_API(FIRPFBCH,TO,TC,TI) \ +typedef struct FIRPFBCH(_s) * FIRPFBCH(); \ + \ +/* create finite impulse response polyphase filter-bank */ \ +/* channelizer object from external coefficients */ \ +/* _type : channelizer type, e.g. LIQUID_ANALYZER */ \ +/* _M : number of channels */ \ +/* _p : number of coefficients for each channel */ \ +/* _h : coefficients [size: _M*_p x 1] */ \ +FIRPFBCH() FIRPFBCH(_create)(int _type, \ + unsigned int _M, \ + unsigned int _p, \ + TC * _h); \ + \ +/* create FIR polyphase filterbank channelizer object with */ \ +/* prototype filter based on windowed Kaiser design */ \ +/* _type : type (LIQUID_ANALYZER | LIQUID_SYNTHESIZER) */ \ +/* _M : number of channels */ \ +/* _m : filter delay (symbols) */ \ +/* _As : stop-band attentuation [dB] */ \ +FIRPFBCH() FIRPFBCH(_create_kaiser)(int _type, \ + unsigned int _M, \ + unsigned int _m, \ + float _As); \ + \ +/* create FIR polyphase filterbank channelizer object with */ \ +/* prototype root-Nyquist filter */ \ +/* _type : type (LIQUID_ANALYZER | LIQUID_SYNTHESIZER) */ \ +/* _M : number of channels */ \ +/* _m : filter delay (symbols) */ \ +/* _beta : filter excess bandwidth factor, in [0,1] */ \ +/* _ftype : filter prototype (rrcos, rkaiser, etc.) */ \ +FIRPFBCH() FIRPFBCH(_create_rnyquist)(int _type, \ + unsigned int _M, \ + unsigned int _m, \ + float _beta, \ + int _ftype); \ + \ +/* destroy firpfbch object */ \ +void FIRPFBCH(_destroy)(FIRPFBCH() _q); \ + \ +/* clear/reset firpfbch internal state */ \ +void FIRPFBCH(_reset)(FIRPFBCH() _q); \ + \ +/* print firpfbch internal parameters to stdout */ \ +void FIRPFBCH(_print)(FIRPFBCH() _q); \ + \ +/* execute filterbank as synthesizer on block of samples */ \ +/* _q : filterbank channelizer object */ \ +/* _x : channelized input, [size: num_channels x 1] */ \ +/* _y : output time series, [size: num_channels x 1] */ \ +void FIRPFBCH(_synthesizer_execute)(FIRPFBCH() _q, \ + TI * _x, \ + TO * _y); \ + \ +/* execute filterbank as analyzer on block of samples */ \ +/* _q : filterbank channelizer object */ \ +/* _x : input time series, [size: num_channels x 1] */ \ +/* _y : channelized output, [size: num_channels x 1] */ \ +void FIRPFBCH(_analyzer_execute)(FIRPFBCH() _q, \ + TI * _x, \ + TO * _y); \ + + +LIQUID_FIRPFBCH_DEFINE_API(FIRPFBCH_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + +LIQUID_FIRPFBCH_DEFINE_API(FIRPFBCH_MANGLE_CCCF, + liquid_float_complex, + liquid_float_complex, + liquid_float_complex) + + +// +// Finite impulse response polyphase filterbank channelizer +// with output rate 2 Fs / M +// + +#define FIRPFBCH2_MANGLE_CRCF(name) LIQUID_CONCAT(firpfbch2_crcf,name) + +// Macro: +// FIRPFBCH2 : name-mangling macro +// TO : output data type +// TC : coefficients data type +// TI : input data type +#define LIQUID_FIRPFBCH2_DEFINE_API(FIRPFBCH2,TO,TC,TI) \ +typedef struct FIRPFBCH2(_s) * FIRPFBCH2(); \ + \ +/* create firpfbch2 object */ \ +/* _type : channelizer type (e.g. LIQUID_ANALYZER) */ \ +/* _M : number of channels (must be even) */ \ +/* _m : prototype filter semi-lenth, length=2*M*m */ \ +/* _h : prototype filter coefficient array */ \ +FIRPFBCH2() FIRPFBCH2(_create)(int _type, \ + unsigned int _M, \ + unsigned int _m, \ + TC * _h); \ + \ +/* create firpfbch2 object using Kaiser window prototype */ \ +/* _type : channelizer type (e.g. LIQUID_ANALYZER) */ \ +/* _M : number of channels (must be even) */ \ +/* _m : prototype filter semi-lenth, length=2*M*m+1 */ \ +/* _As : filter stop-band attenuation [dB] */ \ +FIRPFBCH2() FIRPFBCH2(_create_kaiser)(int _type, \ + unsigned int _M, \ + unsigned int _m, \ + float _As); \ + \ +/* destroy firpfbch2 object, freeing internal memory */ \ +void FIRPFBCH2(_destroy)(FIRPFBCH2() _q); \ + \ +/* reset firpfbch2 object internals */ \ +void FIRPFBCH2(_reset)(FIRPFBCH2() _q); \ + \ +/* print firpfbch2 object internals */ \ +void FIRPFBCH2(_print)(FIRPFBCH2() _q); \ + \ +/* execute filterbank channelizer */ \ +/* LIQUID_ANALYZER: input: M/2, output: M */ \ +/* LIQUID_SYNTHESIZER: input: M, output: M/2 */ \ +/* _x : channelizer input */ \ +/* _y : channelizer output */ \ +void FIRPFBCH2(_execute)(FIRPFBCH2() _q, \ + TI * _x, \ + TO * _y); \ + + +LIQUID_FIRPFBCH2_DEFINE_API(FIRPFBCH2_MANGLE_CRCF, + liquid_float_complex, + float, + liquid_float_complex) + + + +#define OFDMFRAME_SCTYPE_NULL 0 +#define OFDMFRAME_SCTYPE_PILOT 1 +#define OFDMFRAME_SCTYPE_DATA 2 + +// initialize default subcarrier allocation +// _M : number of subcarriers +// _p : output subcarrier allocation array, [size: _M x 1] +void ofdmframe_init_default_sctype(unsigned int _M, + unsigned char * _p); + +// validate subcarrier type (count number of null, pilot, and data +// subcarriers in the allocation) +// _p : subcarrier allocation array, [size: _M x 1] +// _M : number of subcarriers +// _M_null : output number of null subcarriers +// _M_pilot : output number of pilot subcarriers +// _M_data : output number of data subcarriers +void ofdmframe_validate_sctype(unsigned char * _p, + unsigned int _M, + unsigned int * _M_null, + unsigned int * _M_pilot, + unsigned int * _M_data); + +// print subcarrier allocation to screen +// _p : output subcarrier allocation array, [size: _M x 1] +// _M : number of subcarriers +void ofdmframe_print_sctype(unsigned char * _p, + unsigned int _M); + + +// +// OFDM frame (symbol) generator +// +typedef struct ofdmframegen_s * ofdmframegen; + +// create OFDM framing generator object +// _M : number of subcarriers, >10 typical +// _cp_len : cyclic prefix length +// _taper_len : taper length (OFDM symbol overlap) +// _p : subcarrier allocation (null, pilot, data), [size: _M x 1] +ofdmframegen ofdmframegen_create(unsigned int _M, + unsigned int _cp_len, + unsigned int _taper_len, + unsigned char * _p); + +void ofdmframegen_destroy(ofdmframegen _q); + +void ofdmframegen_print(ofdmframegen _q); + +void ofdmframegen_reset(ofdmframegen _q); + +// write first S0 symbol +void ofdmframegen_write_S0a(ofdmframegen _q, + liquid_float_complex *_y); + +// write second S0 symbol +void ofdmframegen_write_S0b(ofdmframegen _q, + liquid_float_complex *_y); + +// write S1 symbol +void ofdmframegen_write_S1(ofdmframegen _q, + liquid_float_complex *_y); + +// write data symbol +void ofdmframegen_writesymbol(ofdmframegen _q, + liquid_float_complex * _x, + liquid_float_complex *_y); + +// write tail +void ofdmframegen_writetail(ofdmframegen _q, + liquid_float_complex * _x); + +// +// OFDM frame (symbol) synchronizer +// +typedef int (*ofdmframesync_callback)(liquid_float_complex * _y, + unsigned char * _p, + unsigned int _M, + void * _userdata); +typedef struct ofdmframesync_s * ofdmframesync; + +// create OFDM framing synchronizer object +// _M : number of subcarriers, >10 typical +// _cp_len : cyclic prefix length +// _taper_len : taper length (OFDM symbol overlap) +// _p : subcarrier allocation (null, pilot, data), [size: _M x 1] +// _callback : user-defined callback function +// _userdata : user-defined data pointer +ofdmframesync ofdmframesync_create(unsigned int _M, + unsigned int _cp_len, + unsigned int _taper_len, + unsigned char * _p, + ofdmframesync_callback _callback, + void * _userdata); +void ofdmframesync_destroy(ofdmframesync _q); +void ofdmframesync_print(ofdmframesync _q); +void ofdmframesync_reset(ofdmframesync _q); +void ofdmframesync_execute(ofdmframesync _q, + liquid_float_complex * _x, + unsigned int _n); + +// query methods +float ofdmframesync_get_rssi(ofdmframesync _q); // received signal strength indication +float ofdmframesync_get_cfo(ofdmframesync _q); // carrier offset estimate + +// debugging +void ofdmframesync_debug_enable(ofdmframesync _q); +void ofdmframesync_debug_disable(ofdmframesync _q); +void ofdmframesync_debug_print(ofdmframesync _q, const char * _filename); + + +// +// MODULE : nco (numerically-controlled oscillator) +// + +// oscillator type +// LIQUID_NCO : numerically-controlled oscillator (fast) +// LIQUID_VCO : "voltage"-controlled oscillator (precise) +typedef enum { + LIQUID_NCO=0, + LIQUID_VCO +} liquid_ncotype; + +#define NCO_MANGLE_FLOAT(name) LIQUID_CONCAT(nco_crcf, name) + +// large macro +// NCO : name-mangling macro +// T : primitive data type +// TC : input/output data type +#define LIQUID_NCO_DEFINE_API(NCO,T,TC) \ +typedef struct NCO(_s) * NCO(); \ + \ +NCO() NCO(_create)(liquid_ncotype _type); \ +void NCO(_destroy)(NCO() _q); \ +void NCO(_print)(NCO() _q); \ + \ +/* set phase/frequency to zero, reset pll filter */ \ +void NCO(_reset)(NCO() _q); \ + \ +/* get/set/adjust internal frequency/phase */ \ +T NCO(_get_frequency)( NCO() _q); \ +void NCO(_set_frequency)( NCO() _q, T _f); \ +void NCO(_adjust_frequency)(NCO() _q, T _df); \ +T NCO(_get_phase)( NCO() _q); \ +void NCO(_set_phase)( NCO() _q, T _phi); \ +void NCO(_adjust_phase)( NCO() _q, T _dphi); \ + \ +/* increment phase by internal phase step (frequency) */ \ +void NCO(_step)(NCO() _q); \ + \ +/* compute trigonometric functions */ \ +T NCO(_sin)(NCO() _q); \ +T NCO(_cos)(NCO() _q); \ +void NCO(_sincos)(NCO() _q, T* _s, T* _c); \ +void NCO(_cexpf)(NCO() _q, TC * _y); \ + \ +/* pll : phase-locked loop */ \ +void NCO(_pll_set_bandwidth)(NCO() _q, T _b); \ +void NCO(_pll_step)(NCO() _q, T _dphi); \ + \ +/* Rotate input sample up by NCO angle (no stepping) */ \ +void NCO(_mix_up)(NCO() _q, TC _x, TC *_y); \ + \ +/* Rotate input sample down by NCO angle (no stepping) */ \ +void NCO(_mix_down)(NCO() _q, TC _x, TC *_y); \ + \ +/* Rotate input vector up by NCO angle (stepping) */ \ +/* _q : nco object */ \ +/* _x : input vector [size: _N x 1] */ \ +/* _y : output vector [size: _N x 1] */ \ +/* _N : vector size */ \ +void NCO(_mix_block_up)(NCO() _q, \ + TC *_x, \ + TC *_y, \ + unsigned int _N); \ + \ +/* Rotate input vector down by NCO angle (stepping) */ \ +/* _q : nco object */ \ +/* _x : input vector [size: _N x 1] */ \ +/* _y : output vector [size: _N x 1] */ \ +/* _N : vector size */ \ +void NCO(_mix_block_down)(NCO() _q, \ + TC *_x, \ + TC *_y, \ + unsigned int _N); \ + +// Define nco APIs +LIQUID_NCO_DEFINE_API(NCO_MANGLE_FLOAT, float, liquid_float_complex) + + +// nco utilities + +// unwrap phase of array (basic) +void liquid_unwrap_phase(float * _theta, unsigned int _n); + +// unwrap phase of array (advanced) +void liquid_unwrap_phase2(float * _theta, unsigned int _n); + + + +// +// MODULE : optimization +// + +// utility function pointer definition +typedef float (*utility_function)(void * _userdata, + float * _v, + unsigned int _n); + +// n-dimensional Rosenbrock utility function (minimum at _v = {1,1,1...} +// _userdata : user-defined data structure (convenience) +// _v : input vector [size: _n x 1] +// _n : input vector size +float liquid_rosenbrock(void * _userdata, + float * _v, + unsigned int _n); + +// n-dimensional inverse Gauss utility function (minimum at _v = {0,0,0...} +// _userdata : user-defined data structure (convenience) +// _v : input vector [size: _n x 1] +// _n : input vector size +float liquid_invgauss(void * _userdata, + float * _v, + unsigned int _n); + +// n-dimensional multimodal utility function (minimum at _v = {0,0,0...} +// _userdata : user-defined data structure (convenience) +// _v : input vector [size: _n x 1] +// _n : input vector size +float liquid_multimodal(void * _userdata, + float * _v, + unsigned int _n); + +// n-dimensional spiral utility function (minimum at _v = {0,0,0...} +// _userdata : user-defined data structure (convenience) +// _v : input vector [size: _n x 1] +// _n : input vector size +float liquid_spiral(void * _userdata, + float * _v, + unsigned int _n); + + +// +// Gradient search +// + +#define LIQUID_OPTIM_MINIMIZE (0) +#define LIQUID_OPTIM_MAXIMIZE (1) + +typedef struct gradsearch_s * gradsearch; + +// Create a gradient search object +// _userdata : user data object pointer +// _v : array of parameters to optimize +// _num_parameters : array length (number of parameters to optimize) +// _u : utility function pointer +// _direction : search direction (e.g. LIQUID_OPTIM_MAXIMIZE) +gradsearch gradsearch_create(void * _userdata, + float * _v, + unsigned int _num_parameters, + utility_function _utility, + int _direction); + +// Destroy a gradsearch object +void gradsearch_destroy(gradsearch _q); + +// Prints current status of search +void gradsearch_print(gradsearch _q); + +// Iterate once +float gradsearch_step(gradsearch _q); + +// Execute the search +float gradsearch_execute(gradsearch _q, + unsigned int _max_iterations, + float _target_utility); + + +// quasi-Newton search +typedef struct qnsearch_s * qnsearch; + +// Create a simple qnsearch object; parameters are specified internally +// _userdata : userdata +// _v : array of parameters to optimize +// _num_parameters : array length +// _get_utility : utility function pointer +// _direction : search direction (e.g. LIQUID_OPTIM_MAXIMIZE) +qnsearch qnsearch_create(void * _userdata, + float * _v, + unsigned int _num_parameters, + utility_function _u, + int _direction); + +// Destroy a qnsearch object +void qnsearch_destroy(qnsearch _g); + +// Prints current status of search +void qnsearch_print(qnsearch _g); + +// Resets internal state +void qnsearch_reset(qnsearch _g); + +// Iterate once +void qnsearch_step(qnsearch _g); + +// Execute the search +float qnsearch_execute(qnsearch _g, + unsigned int _max_iterations, + float _target_utility); + +// +// chromosome (for genetic algorithm search) +// +typedef struct chromosome_s * chromosome; + +// create a chromosome object, variable bits/trait +chromosome chromosome_create(unsigned int * _bits_per_trait, + unsigned int _num_traits); + +// create a chromosome object, all traits same resolution +chromosome chromosome_create_basic(unsigned int _num_traits, + unsigned int _bits_per_trait); + +// create a chromosome object, cloning a parent +chromosome chromosome_create_clone(chromosome _parent); + +// copy existing chromosomes' internal traits (all other internal +// parameters must be equal) +void chromosome_copy(chromosome _parent, chromosome _child); + +// Destroy a chromosome object +void chromosome_destroy(chromosome _c); + +// get number of traits in chromosome +unsigned int chromosome_get_num_traits(chromosome _c); + +// Print chromosome values to screen (binary representation) +void chromosome_print(chromosome _c); + +// Print chromosome values to screen (floating-point representation) +void chromosome_printf(chromosome _c); + +// clear chromosome (set traits to zero) +void chromosome_clear(chromosome _c); + +// initialize chromosome on integer values +void chromosome_init(chromosome _c, + unsigned int * _v); + +// initialize chromosome on floating-point values +void chromosome_initf(chromosome _c, + float * _v); + +// Mutates chromosome _c at _index +void chromosome_mutate(chromosome _c, unsigned int _index); + +// Resulting chromosome _c is a crossover of parents _p1 and _p2 at _threshold +void chromosome_crossover(chromosome _p1, + chromosome _p2, + chromosome _c, + unsigned int _threshold); + +// Initializes chromosome to random value +void chromosome_init_random(chromosome _c); + +// Returns integer representation of chromosome +unsigned int chromosome_value(chromosome _c, + unsigned int _index); + +// Returns floating-point representation of chromosome +float chromosome_valuef(chromosome _c, + unsigned int _index); + +// +// genetic algorithm search +// +typedef struct gasearch_s * gasearch; + +typedef float (*gasearch_utility)(void * _userdata, chromosome _c); + +// Create a simple gasearch object; parameters are specified internally +// _utility : chromosome fitness utility function +// _userdata : user data, void pointer passed to _get_utility() callback +// _parent : initial population parent chromosome, governs precision, etc. +// _minmax : search direction +gasearch gasearch_create(gasearch_utility _u, + void * _userdata, + chromosome _parent, + int _minmax); + +// Create a gasearch object, specifying search parameters +// _utility : chromosome fitness utility function +// _userdata : user data, void pointer passed to _get_utility() callback +// _parent : initial population parent chromosome, governs precision, etc. +// _minmax : search direction +// _population_size : number of chromosomes in population +// _mutation_rate : probability of mutating chromosomes +gasearch gasearch_create_advanced(gasearch_utility _utility, + void * _userdata, + chromosome _parent, + int _minmax, + unsigned int _population_size, + float _mutation_rate); + + +// Destroy a gasearch object +void gasearch_destroy(gasearch _q); + +// print search parameter internals +void gasearch_print(gasearch _q); + +// set mutation rate +void gasearch_set_mutation_rate(gasearch _q, + float _mutation_rate); + +// set population/selection size +// _q : ga search object +// _population_size : new population size (number of chromosomes) +// _selection_size : selection size (number of parents for new generation) +void gasearch_set_population_size(gasearch _q, + unsigned int _population_size, + unsigned int _selection_size); + +// Execute the search +// _q : ga search object +// _max_iterations : maximum number of iterations to run before bailing +// _target_utility : target utility +float gasearch_run(gasearch _q, + unsigned int _max_iterations, + float _target_utility); + +// iterate over one evolution of the search algorithm +void gasearch_evolve(gasearch _q); + +// get optimal chromosome +// _q : ga search object +// _c : output optimal chromosome +// _utility_opt : fitness of _c +void gasearch_getopt(gasearch _q, + chromosome _c, + float * _utility_opt); + +// +// MODULE : quantization +// + +float compress_mulaw(float _x, float _mu); +float expand_mulaw(float _x, float _mu); + +void compress_cf_mulaw(liquid_float_complex _x, float _mu, liquid_float_complex * _y); +void expand_cf_mulaw(liquid_float_complex _y, float _mu, liquid_float_complex * _x); + +//float compress_alaw(float _x, float _a); +//float expand_alaw(float _x, float _a); + +// inline quantizer: 'analog' signal in [-1, 1] +unsigned int quantize_adc(float _x, unsigned int _num_bits); +float quantize_dac(unsigned int _s, unsigned int _num_bits); + +// structured quantizer + +typedef enum { + LIQUID_COMPANDER_NONE=0, + LIQUID_COMPANDER_LINEAR, + LIQUID_COMPANDER_MULAW, + LIQUID_COMPANDER_ALAW +} liquid_compander_type; + +#define QUANTIZER_MANGLE_FLOAT(name) LIQUID_CONCAT(quantizerf, name) +#define QUANTIZER_MANGLE_CFLOAT(name) LIQUID_CONCAT(quantizercf, name) + +// large macro +// QUANTIZER : name-mangling macro +// T : data type +#define LIQUID_QUANTIZER_DEFINE_API(QUANTIZER,T) \ +typedef struct QUANTIZER(_s) * QUANTIZER(); \ +QUANTIZER() QUANTIZER(_create)(liquid_compander_type _ctype, \ + float _range, \ + unsigned int _num_bits); \ +void QUANTIZER(_destroy)(QUANTIZER() _q); \ +void QUANTIZER(_print)(QUANTIZER() _q); \ +void QUANTIZER(_execute_adc)(QUANTIZER() _q, \ + T _x, \ + unsigned int * _sample); \ +void QUANTIZER(_execute_dac)(QUANTIZER() _q, \ + unsigned int _sample, \ + T * _x); + +LIQUID_QUANTIZER_DEFINE_API(QUANTIZER_MANGLE_FLOAT, float) +LIQUID_QUANTIZER_DEFINE_API(QUANTIZER_MANGLE_CFLOAT, liquid_float_complex) + + +// +// MODULE : random (number generators) +// + + +// Uniform random number generator, (0,1] +float randf(); +float randf_pdf(float _x); +float randf_cdf(float _x); + +// Gauss random number generator, N(0,1) +// f(x) = 1/sqrt(2*pi*sigma^2) * exp{-(x-eta)^2/(2*sigma^2)} +// +// where +// eta = mean +// sigma = standard deviation +// +float randnf(); +void awgn(float *_x, float _nstd); +void crandnf(liquid_float_complex *_y); +void cawgn(liquid_float_complex *_x, float _nstd); +float randnf_pdf(float _x, float _eta, float _sig); +float randnf_cdf(float _x, float _eta, float _sig); + +// Exponential +// f(x) = lambda exp{ -lambda x } +// where +// lambda = spread parameter, lambda > 0 +// x >= 0 +float randexpf(float _lambda); +float randexpf_pdf(float _x, float _lambda); +float randexpf_cdf(float _x, float _lambda); + +// Weibull +// f(x) = (a/b) (x/b)^(a-1) exp{ -(x/b)^a } +// where +// a = alpha : shape parameter +// b = beta : scaling parameter +// g = gamma : location (threshold) parameter +// +float randweibf(float _alpha, float _beta, float _gamma); +float randweibf_pdf(float _x, float _a, float _b, float _g); +float randweibf_cdf(float _x, float _a, float _b, float _g); + +// Gamma +// x^(a-1) exp(-x/b) +// f(x) = ------------------- +// Gamma(a) b^a +// where +// a = alpha : shape parameter, a > 0 +// b = beta : scale parameter, b > 0 +// Gamma(z) = regular gamma function +// x >= 0 +float randgammaf(float _alpha, float _beta); +float randgammaf_pdf(float _x, float _alpha, float _beta); +float randgammaf_cdf(float _x, float _alpha, float _beta); + +// Nakagami-m +// f(x) = (2/Gamma(m)) (m/omega)^m x^(2m-1) exp{-(m/omega)x^2} +// where +// m : shape parameter, m >= 0.5 +// omega : spread parameter, omega > 0 +// Gamma(z): regular complete gamma function +// x >= 0 +float randnakmf(float _m, float _omega); +float randnakmf_pdf(float _x, float _m, float _omega); +float randnakmf_cdf(float _x, float _m, float _omega); + +// Rice-K +// f(x) = (x/sigma^2) exp{ -(x^2+s^2)/(2sigma^2) } I0( x s / sigma^2 ) +// where +// s = sqrt( omega*K/(K+1) ) +// sigma = sqrt(0.5 omega/(K+1)) +// and +// K = shape parameter +// omega = spread parameter +// I0 = modified Bessel function of the first kind +// x >= 0 +float randricekf(float _K, float _omega); +float randricekf_cdf(float _x, float _K, float _omega); +float randricekf_pdf(float _x, float _K, float _omega); + + +// Data scrambler : whiten data sequence +void scramble_data(unsigned char * _x, unsigned int _len); +void unscramble_data(unsigned char * _x, unsigned int _len); +void unscramble_data_soft(unsigned char * _x, unsigned int _len); + +// +// MODULE : sequence +// + +// Binary sequence (generic) + +typedef struct bsequence_s * bsequence; + +// Create a binary sequence of a specific length (number of bits) +bsequence bsequence_create(unsigned int num_bits); + +// Free memory in a binary sequence +void bsequence_destroy(bsequence _bs); + +// Clear binary sequence (set to 0's) +void bsequence_clear(bsequence _bs); + +// initialize sequence on external array +void bsequence_init(bsequence _bs, + unsigned char * _v); + +// Print sequence to the screen +void bsequence_print(bsequence _bs); + +// Push bit into to back of a binary sequence +void bsequence_push(bsequence _bs, + unsigned int _bit); + +// circular shift (left) +void bsequence_circshift(bsequence _bs); + +// Correlate two binary sequences together +int bsequence_correlate(bsequence _bs1, bsequence _bs2); + +// compute the binary addition of two bit sequences +void bsequence_add(bsequence _bs1, bsequence _bs2, bsequence _bs3); + +// compute the binary multiplication of two bit sequences +void bsequence_mul(bsequence _bs1, bsequence _bs2, bsequence _bs3); + +// accumulate the 1's in a binary sequence +unsigned int bsequence_accumulate(bsequence _bs); + +// accessor functions +unsigned int bsequence_get_length(bsequence _bs); +unsigned int bsequence_index(bsequence _bs, unsigned int _i); + +// Complementary codes + +// intialize two sequences to complementary codes. sequences must +// be of length at least 8 and a power of 2 (e.g. 8, 16, 32, 64,...) +// _a : sequence 'a' (bsequence object) +// _b : sequence 'b' (bsequence object) +void bsequence_create_ccodes(bsequence _a, + bsequence _b); + + +// M-Sequence + +#define LIQUID_MAX_MSEQUENCE_LENGTH 32767 + +// default m-sequence generators: g (hex) m n g (oct) g (binary) +#define LIQUID_MSEQUENCE_GENPOLY_M2 0x0007 // 2 3 7 111 +#define LIQUID_MSEQUENCE_GENPOLY_M3 0x000B // 3 7 13 1011 +#define LIQUID_MSEQUENCE_GENPOLY_M4 0x0013 // 4 15 23 10011 +#define LIQUID_MSEQUENCE_GENPOLY_M5 0x0025 // 5 31 45 100101 +#define LIQUID_MSEQUENCE_GENPOLY_M6 0x0043 // 6 63 103 1000011 +#define LIQUID_MSEQUENCE_GENPOLY_M7 0x0089 // 7 127 211 10001001 +#define LIQUID_MSEQUENCE_GENPOLY_M8 0x011D // 8 255 435 100101101 +#define LIQUID_MSEQUENCE_GENPOLY_M9 0x0211 // 9 511 1021 1000010001 +#define LIQUID_MSEQUENCE_GENPOLY_M10 0x0409 // 10 1023 2011 10000001001 +#define LIQUID_MSEQUENCE_GENPOLY_M11 0x0805 // 11 2047 4005 100000000101 +#define LIQUID_MSEQUENCE_GENPOLY_M12 0x1053 // 12 4095 10123 1000001010011 +#define LIQUID_MSEQUENCE_GENPOLY_M13 0x201b // 13 8191 20033 10000000011011 +#define LIQUID_MSEQUENCE_GENPOLY_M14 0x402b // 14 16383 40053 100000000101011 +#define LIQUID_MSEQUENCE_GENPOLY_M15 0x8003 // 15 32767 100003 1000000000000011 + +typedef struct msequence_s * msequence; + +// create a maximal-length sequence (m-sequence) object with +// an internal shift register length of _m bits. +// _m : generator polynomial length, sequence length is (2^m)-1 +// _g : generator polynomial, starting with most-significant bit +// _a : initial shift register state, default: 000...001 +msequence msequence_create(unsigned int _m, + unsigned int _g, + unsigned int _a); + +// create a maximal-length sequence (m-sequence) object from a generator polynomial +msequence msequence_create_genpoly(unsigned int _g); + +// creates a default maximal-length sequence +msequence msequence_create_default(unsigned int _m); + +// destroy an msequence object, freeing all internal memory +void msequence_destroy(msequence _m); + +// prints the sequence's internal state to the screen +void msequence_print(msequence _m); + +// advance msequence on shift register, returning output bit +unsigned int msequence_advance(msequence _ms); + +// generate pseudo-random symbol from shift register by +// advancing _bps bits and returning compacted symbol +// _ms : m-sequence object +// _bps : bits per symbol of output +unsigned int msequence_generate_symbol(msequence _ms, + unsigned int _bps); + +// reset msequence shift register to original state, typically '1' +void msequence_reset(msequence _ms); + +// initialize a bsequence object on an msequence object +// _bs : bsequence object +// _ms : msequence object +void bsequence_init_msequence(bsequence _bs, + msequence _ms); + +// get the length of the sequence +unsigned int msequence_get_length(msequence _ms); + +// get the internal state of the sequence +unsigned int msequence_get_state(msequence _ms); + +// set the internal state of the sequence +void msequence_set_state(msequence _ms, + unsigned int _a); + + +// +// MODULE : utility +// + +// pack binary array with symbol(s) +// _src : source array [size: _n x 1] +// _n : input source array length +// _k : bit index to write in _src +// _b : number of bits in input symbol +// _sym_in : input symbol +void liquid_pack_array(unsigned char * _src, + unsigned int _n, + unsigned int _k, + unsigned int _b, + unsigned char _sym_in); + +// unpack symbols from binary array +// _src : source array [size: _n x 1] +// _n : input source array length +// _k : bit index to write in _src +// _b : number of bits in output symbol +// _sym_out : output symbol +void liquid_unpack_array(unsigned char * _src, + unsigned int _n, + unsigned int _k, + unsigned int _b, + unsigned char * _sym_out); + +// pack one-bit symbols into bytes (8-bit symbols) +// _sym_in : input symbols array [size: _sym_in_len x 1] +// _sym_in_len : number of input symbols +// _sym_out : output symbols +// _sym_out_len : number of bytes allocated to output symbols array +// _num_written : number of output symbols actually written +void liquid_pack_bytes(unsigned char * _sym_in, + unsigned int _sym_in_len, + unsigned char * _sym_out, + unsigned int _sym_out_len, + unsigned int * _num_written); + +// unpack 8-bit symbols (full bytes) into one-bit symbols +// _sym_in : input symbols array [size: _sym_in_len x 1] +// _sym_in_len : number of input symbols +// _sym_out : output symbols array +// _sym_out_len : number of bytes allocated to output symbols array +// _num_written : number of output symbols actually written +void liquid_unpack_bytes(unsigned char * _sym_in, + unsigned int _sym_in_len, + unsigned char * _sym_out, + unsigned int _sym_out_len, + unsigned int * _num_written); + +// repack bytes with arbitrary symbol sizes +// _sym_in : input symbols array [size: _sym_in_len x 1] +// _sym_in_bps : number of bits per input symbol +// _sym_in_len : number of input symbols +// _sym_out : output symbols array +// _sym_out_bps : number of bits per output symbol +// _sym_out_len : number of bytes allocated to output symbols array +// _num_written : number of output symbols actually written +void liquid_repack_bytes(unsigned char * _sym_in, + unsigned int _sym_in_bps, + unsigned int _sym_in_len, + unsigned char * _sym_out, + unsigned int _sym_out_bps, + unsigned int _sym_out_len, + unsigned int * _num_written); + +// shift array to the left _b bits, filling in zeros +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bits to shift +void liquid_lbshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + +// shift array to the right _b bits, filling in zeros +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bits to shift +void liquid_rbshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + +// circularly shift array to the left _b bits +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bits to shift +void liquid_lbcircshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + +// circularly shift array to the right _b bits +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bits to shift +void liquid_rbcircshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + + + + +// shift array to the left _b bytes, filling in zeros +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bytes to shift +void liquid_lshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + +// shift array to the right _b bytes, filling in zeros +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bytes to shift +void liquid_rshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + +// circular shift array to the left _b bytes +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bytes to shift +void liquid_lcircshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + +// circular shift array to the right _b bytes +// _src : source address [size: _n x 1] +// _n : input data array size +// _b : number of bytes to shift +void liquid_rcircshift(unsigned char * _src, + unsigned int _n, + unsigned int _b); + +// Count the number of ones in an integer +unsigned int liquid_count_ones(unsigned int _x); + +// count number of ones in an integer, modulo 2 +unsigned int liquid_count_ones_mod2(unsigned int _x); + +// compute bindary dot-product between two integers +unsigned int liquid_bdotprod(unsigned int _x, + unsigned int _y); + +// Count leading zeros in an integer +unsigned int liquid_count_leading_zeros(unsigned int _x); + +// Most-significant bit index +unsigned int liquid_msb_index(unsigned int _x); + +// Print string of bits to stdout +void liquid_print_bitstring(unsigned int _x, + unsigned int _n); + +// reverse byte, word, etc. +unsigned char liquid_reverse_byte( unsigned char _x); +unsigned int liquid_reverse_uint16(unsigned int _x); +unsigned int liquid_reverse_uint24(unsigned int _x); +unsigned int liquid_reverse_uint32(unsigned int _x); + +// +// MODULE : vector +// + +#define VECTOR_MANGLE_RF(name) LIQUID_CONCAT(liquid_vectorf, name) +#define VECTOR_MANGLE_CF(name) LIQUID_CONCAT(liquid_vectorcf,name) + +// large macro +// VECTOR : name-mangling macro +// T : data type +// TP : data type (primitive) +#define LIQUID_VECTOR_DEFINE_API(VECTOR,T,TP) \ + \ +/* initialize vector with scalar: x[i] = c (scalar) */ \ +void VECTOR(_init)(T _c, \ + T * _x, \ + unsigned int _n); \ + \ +/* add each element: z[i] = x[i] + y[i] */ \ +void VECTOR(_add)(T * _x, \ + T * _y, \ + unsigned int _n, \ + T * _z); \ +/* add scalar to each element: y[i] = x[i] + c */ \ +void VECTOR(_addscalar)(T * _x, \ + unsigned int _n, \ + T _c, \ + T * _y); \ + \ +/* multiply each element: z[i] = x[i] * y[i] */ \ +void VECTOR(_mul)(T * _x, \ + T * _y, \ + unsigned int _n, \ + T * _z); \ +/* multiply each element with scalar: y[i] = x[i] * c */ \ +void VECTOR(_mulscalar)(T * _x, \ + unsigned int _n, \ + T _c, \ + T * _y); \ + \ +/* compute complex phase rotation: x[i] = exp{j theta[i]} */ \ +void VECTOR(_cexpj)(TP * _theta, \ + unsigned int _n, \ + T * _x); \ +/* compute angle of each element: theta[i] = arg{ x[i] } */ \ +void VECTOR(_carg)(T * _x, \ + unsigned int _n, \ + TP * _theta); \ +/* compute absolute value of each element: y[i] = |x[i]| */ \ +void VECTOR(_abs)(T * _x, \ + unsigned int _n, \ + TP * _y); \ + \ +/* compute sum of squares: sum{ |x|^2 } */ \ +TP VECTOR(_sumsq)(T * _x, \ + unsigned int _n); \ + \ +/* compute l-2 norm: sqrt{ sum{ |x|^2 } } */ \ +TP VECTOR(_norm)(T * _x, \ + unsigned int _n); \ + \ +/* compute l-p norm: { sum{ |x|^p } }^(1/p) */ \ +TP VECTOR(_pnorm)(T * _x, \ + unsigned int _n, \ + TP _p); \ + \ +/* scale vector elements by l-2 norm: y[i] = x[i]/norm(x) */ \ +void VECTOR(_normalize)(T * _x, \ + unsigned int _n, \ + T * _y); \ + +LIQUID_VECTOR_DEFINE_API(VECTOR_MANGLE_RF, float, float); +LIQUID_VECTOR_DEFINE_API(VECTOR_MANGLE_CF, liquid_float_complex, float); + +// +// mixed types +// +#if 0 +void liquid_vectorf_add(float * _a, + float * _b, + unsigned int _n, + float * _c); +#endif + +#ifdef __cplusplus +} //extern "C" +#endif // __cplusplus + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + +#endif // __LIQUID_H__ + diff --git a/external/liquid-dsp/lib/libliquid.a b/external/liquid-dsp/lib/libliquid.a new file mode 100644 index 0000000..473d57d Binary files /dev/null and b/external/liquid-dsp/lib/libliquid.a differ diff --git a/external/liquid-dsp/lib/libliquid.def b/external/liquid-dsp/lib/libliquid.def new file mode 100644 index 0000000..6df6363 --- /dev/null +++ b/external/liquid-dsp/lib/libliquid.def @@ -0,0 +1,1871 @@ +EXPORTS + agc_crcf_create @1 + agc_crcf_destroy @2 + agc_crcf_execute @3 + agc_crcf_execute_block @4 + agc_crcf_get_bandwidth @5 + agc_crcf_get_gain @6 + agc_crcf_get_rssi @7 + agc_crcf_get_signal_level @8 + agc_crcf_init @9 + agc_crcf_lock @10 + agc_crcf_print @11 + agc_crcf_reset @12 + agc_crcf_set_bandwidth @13 + agc_crcf_set_gain @14 + agc_crcf_set_rssi @15 + agc_crcf_set_signal_level @16 + agc_crcf_unlock @17 + agc_rrrf_create @18 + agc_rrrf_destroy @19 + agc_rrrf_execute @20 + agc_rrrf_execute_block @21 + agc_rrrf_get_bandwidth @22 + agc_rrrf_get_gain @23 + agc_rrrf_get_rssi @24 + agc_rrrf_get_signal_level @25 + agc_rrrf_init @26 + agc_rrrf_lock @27 + agc_rrrf_print @28 + agc_rrrf_reset @29 + agc_rrrf_set_bandwidth @30 + agc_rrrf_set_gain @31 + agc_rrrf_set_rssi @32 + agc_rrrf_set_signal_level @33 + agc_rrrf_unlock @34 + ampmodem_create @35 + ampmodem_debug_print @36 + ampmodem_demodulate @37 + ampmodem_destroy @38 + ampmodem_modulate @39 + ampmodem_print @40 + ampmodem_reset @41 + apsk128_map @42 DATA + apsk128_num_levels @43 DATA + apsk128_p @44 DATA + apsk128_phi @45 DATA + apsk128_r @46 DATA + apsk128_r_slicer @47 DATA + apsk16_map @48 DATA + apsk16_num_levels @49 DATA + apsk16_p @50 DATA + apsk16_phi @51 DATA + apsk16_r @52 DATA + apsk16_r_slicer @53 DATA + apsk256_map @54 DATA + apsk256_num_levels @55 DATA + apsk256_p @56 DATA + apsk256_phi @57 DATA + apsk256_r @58 DATA + apsk256_r_slicer @59 DATA + apsk32_map @60 DATA + apsk32_num_levels @61 DATA + apsk32_p @62 DATA + apsk32_phi @63 DATA + apsk32_r @64 DATA + apsk32_r_slicer @65 DATA + apsk4_map @66 DATA + apsk4_num_levels @67 DATA + apsk4_p @68 DATA + apsk4_phi @69 DATA + apsk4_r @70 DATA + apsk4_r_slicer @71 DATA + apsk64_map @72 DATA + apsk64_num_levels @73 DATA + apsk64_p @74 DATA + apsk64_phi @75 DATA + apsk64_r @76 DATA + apsk64_r_slicer @77 DATA + apsk8_map @78 DATA + apsk8_num_levels @79 DATA + apsk8_p @80 DATA + apsk8_phi @81 DATA + apsk8_r @82 DATA + apsk8_r_slicer @83 DATA + asgram_create @84 + asgram_destroy @85 + asgram_execute @86 + asgram_push @87 + asgram_reset @88 + asgram_set_scale @89 + autocorr_cccf_create @90 + autocorr_cccf_destroy @91 + autocorr_cccf_execute @92 + autocorr_cccf_execute_block @93 + autocorr_cccf_get_energy @94 + autocorr_cccf_print @95 + autocorr_cccf_push @96 + autocorr_cccf_reset @97 + autocorr_rrrf_create @98 + autocorr_rrrf_destroy @99 + autocorr_rrrf_execute @100 + autocorr_rrrf_execute_block @101 + autocorr_rrrf_get_energy @102 + autocorr_rrrf_print @103 + autocorr_rrrf_push @104 + autocorr_rrrf_reset @105 + awgn @106 + bessel_azpkf @107 + bilinear_zpkf @108 + blackmanharris @109 + bpacketgen_assemble_header @110 + bpacketgen_assemble_pnsequence @111 + bpacketgen_compute_packet_len @112 + bpacketgen_create @113 + bpacketgen_destroy @114 + bpacketgen_encode @115 + bpacketgen_get_packet_len @116 + bpacketgen_print @117 + bpacketgen_recreate @118 + bpacketsync_assemble_pnsequence @119 + bpacketsync_create @120 + bpacketsync_decode_header @121 + bpacketsync_decode_payload @122 + bpacketsync_destroy @123 + bpacketsync_execute @124 + bpacketsync_execute_bit @125 + bpacketsync_execute_byte @126 + bpacketsync_execute_rxheader @127 + bpacketsync_execute_rxpayload @128 + bpacketsync_execute_seekpn @129 + bpacketsync_execute_sym @130 + bpacketsync_print @131 + bpacketsync_reconfig @132 + bpacketsync_reset @133 + bpresync_cccf_correlate @134 + bpresync_cccf_correlatex @135 + bpresync_cccf_create @136 + bpresync_cccf_destroy @137 + bpresync_cccf_print @138 + bpresync_cccf_push @139 + bpresync_cccf_reset @140 + bsequence_accumulate @141 + bsequence_add @142 + bsequence_circshift @143 + bsequence_clear @144 + bsequence_correlate @145 + bsequence_create @146 + bsequence_create_ccodes @147 + bsequence_destroy @148 + bsequence_get_length @149 + bsequence_index @150 + bsequence_init @151 + bsequence_init_msequence @152 + bsequence_mul @153 + bsequence_print @154 + bsequence_push @155 + bsync_cccf_correlate @156 + bsync_cccf_create @157 + bsync_cccf_create_msequence @158 + bsync_cccf_destroy @159 + bsync_cccf_print @160 + bsync_crcf_correlate @161 + bsync_crcf_create @162 + bsync_crcf_create_msequence @163 + bsync_crcf_destroy @164 + bsync_crcf_print @165 + bsync_rrrf_correlate @166 + bsync_rrrf_create @167 + bsync_rrrf_create_msequence @168 + bsync_rrrf_destroy @169 + bsync_rrrf_print @170 + butter_azpkf @171 + cawgn @172 + cbuffercf_clear @173 + cbuffercf_create @174 + cbuffercf_create_max @175 + cbuffercf_debug_print @176 + cbuffercf_destroy @177 + cbuffercf_is_full @178 + cbuffercf_linearize @179 + cbuffercf_max_read @180 + cbuffercf_max_size @181 + cbuffercf_pop @182 + cbuffercf_print @183 + cbuffercf_push @184 + cbuffercf_read @185 + cbuffercf_release @186 + cbuffercf_size @187 + cbuffercf_space_available @188 + cbuffercf_write @189 + cbufferf_clear @190 + cbufferf_create @191 + cbufferf_create_max @192 + cbufferf_debug_print @193 + cbufferf_destroy @194 + cbufferf_is_full @195 + cbufferf_linearize @196 + cbufferf_max_read @197 + cbufferf_max_size @198 + cbufferf_pop @199 + cbufferf_print @200 + cbufferf_push @201 + cbufferf_read @202 + cbufferf_release @203 + cbufferf_size @204 + cbufferf_space_available @205 + cbufferf_write @206 + cheby1_azpkf @207 + cheby2_azpkf @208 + checksum_generate_key @209 + chromosome_clear @210 + chromosome_copy @211 + chromosome_create @212 + chromosome_create_basic @213 + chromosome_create_clone @214 + chromosome_crossover @215 + chromosome_destroy @216 + chromosome_get_num_traits @217 + chromosome_init @218 + chromosome_init_random @219 + chromosome_initf @220 + chromosome_mutate @221 + chromosome_print @222 + chromosome_printf @223 + chromosome_value @224 + chromosome_valuef @225 + compress_cf_mulaw @226 + compress_mulaw @227 + count_bit_errors @228 + count_bit_errors_array @229 + crandnf @230 + crc16_generate_key @231 + crc24_generate_key @232 + crc32_generate_key @233 + crc8_generate_key @234 + crc_generate_key @235 + crc_get_length @236 + crc_scheme_str @237 DATA + crc_validate_message @238 + cvsd_create @239 + cvsd_decode @240 + cvsd_decode8 @241 + cvsd_destroy @242 + cvsd_encode @243 + cvsd_encode8 @244 + cvsd_print @245 + detector_cccf_compute_dotprods @246 + detector_cccf_correlate @247 + detector_cccf_create @248 + detector_cccf_debug_print @249 + detector_cccf_destroy @250 + detector_cccf_estimate_offsets @251 + detector_cccf_print @252 + detector_cccf_reset @253 + detector_cccf_update_sumsq @254 + dotprod_cccf_create @255 + dotprod_cccf_destroy @256 + dotprod_cccf_execute @257 + dotprod_cccf_print @258 + dotprod_cccf_recreate @259 + dotprod_cccf_run @260 + dotprod_cccf_run4 @261 + dotprod_crcf_create @262 + dotprod_crcf_destroy @263 + dotprod_crcf_execute @264 + dotprod_crcf_print @265 + dotprod_crcf_recreate @266 + dotprod_crcf_run @267 + dotprod_crcf_run4 @268 + dotprod_rrrf_create @269 + dotprod_rrrf_destroy @270 + dotprod_rrrf_execute @271 + dotprod_rrrf_print @272 + dotprod_rrrf_recreate @273 + dotprod_rrrf_run @274 + dotprod_rrrf_run4 @275 + ellip_acdf @276 + ellip_asnf @277 + ellip_azpkf @278 + ellip_cdf @279 + ellip_snf @280 + ellipdegf @281 + ellipkf @282 + eqlms_cccf_create @283 + eqlms_cccf_create_rnyquist @284 + eqlms_cccf_destroy @285 + eqlms_cccf_execute @286 + eqlms_cccf_get_bw @287 + eqlms_cccf_get_weights @288 + eqlms_cccf_print @289 + eqlms_cccf_push @290 + eqlms_cccf_recreate @291 + eqlms_cccf_reset @292 + eqlms_cccf_set_bw @293 + eqlms_cccf_step @294 + eqlms_cccf_train @295 + eqlms_cccf_update_sumsq @296 + eqlms_rrrf_create @297 + eqlms_rrrf_create_rnyquist @298 + eqlms_rrrf_destroy @299 + eqlms_rrrf_execute @300 + eqlms_rrrf_get_bw @301 + eqlms_rrrf_get_weights @302 + eqlms_rrrf_print @303 + eqlms_rrrf_push @304 + eqlms_rrrf_recreate @305 + eqlms_rrrf_reset @306 + eqlms_rrrf_set_bw @307 + eqlms_rrrf_step @308 + eqlms_rrrf_train @309 + eqlms_rrrf_update_sumsq @310 + eqrls_cccf_create @311 + eqrls_cccf_destroy @312 + eqrls_cccf_execute @313 + eqrls_cccf_get_bw @314 + eqrls_cccf_get_weights @315 + eqrls_cccf_print @316 + eqrls_cccf_push @317 + eqrls_cccf_recreate @318 + eqrls_cccf_reset @319 + eqrls_cccf_set_bw @320 + eqrls_cccf_step @321 + eqrls_cccf_train @322 + eqrls_rrrf_create @323 + eqrls_rrrf_destroy @324 + eqrls_rrrf_execute @325 + eqrls_rrrf_get_bw @326 + eqrls_rrrf_get_weights @327 + eqrls_rrrf_print @328 + eqrls_rrrf_push @329 + eqrls_rrrf_recreate @330 + eqrls_rrrf_reset @331 + eqrls_rrrf_set_bw @332 + eqrls_rrrf_step @333 + eqrls_rrrf_train @334 + estimate_req_filter_As @335 + estimate_req_filter_df @336 + estimate_req_filter_len @337 + estimate_req_filter_len_Herrmann @338 + estimate_req_filter_len_Kaiser @339 + expand_cf_mulaw @340 + expand_mulaw @341 + fec_block_get_enc_msg_len @342 + fec_conv27_poly @343 DATA + fec_conv27p23_matrix @344 DATA + fec_conv27p34_matrix @345 DATA + fec_conv27p45_matrix @346 DATA + fec_conv27p56_matrix @347 DATA + fec_conv27p67_matrix @348 DATA + fec_conv27p78_matrix @349 DATA + fec_conv29_poly @350 DATA + fec_conv29p23_matrix @351 DATA + fec_conv29p34_matrix @352 DATA + fec_conv29p45_matrix @353 DATA + fec_conv29p56_matrix @354 DATA + fec_conv29p67_matrix @355 DATA + fec_conv29p78_matrix @356 DATA + fec_conv39_poly @357 DATA + fec_conv615_poly @358 DATA + fec_conv_create @359 + fec_conv_destroy @360 + fec_conv_get_enc_msg_len @361 + fec_conv_punctured_create @362 + fec_conv_punctured_decode @363 + fec_conv_punctured_destroy @364 + fec_conv_punctured_encode @365 + fec_create @366 + fec_decode @367 + fec_decode_soft @368 + fec_destroy @369 + fec_encode @370 + fec_get_enc_msg_length @371 + fec_get_rate @372 + fec_golay2412_create @373 + fec_golay2412_decode @374 + fec_golay2412_decode_symbol @375 + fec_golay2412_destroy @376 + fec_golay2412_encode @377 + fec_golay2412_encode_symbol @378 + fec_hamming128_create @379 + fec_hamming128_decode @380 + fec_hamming128_decode_soft @381 + fec_hamming128_decode_symbol @382 + fec_hamming128_destroy @383 + fec_hamming128_encode @384 + fec_hamming128_encode_symbol @385 + fec_hamming1511_decode_symbol @386 + fec_hamming1511_encode_symbol @387 + fec_hamming3126_decode_symbol @388 + fec_hamming3126_encode_symbol @389 + fec_hamming74_create @390 + fec_hamming74_decode @391 + fec_hamming74_decode_soft @392 + fec_hamming74_destroy @393 + fec_hamming74_encode @394 + fec_hamming84_create @395 + fec_hamming84_decode @396 + fec_hamming84_decode_soft @397 + fec_hamming84_destroy @398 + fec_hamming84_encode @399 + fec_pass_create @400 + fec_pass_decode @401 + fec_pass_destroy @402 + fec_pass_encode @403 + fec_pass_print @404 + fec_print @405 + fec_recreate @406 + fec_rep3_create @407 + fec_rep3_decode @408 + fec_rep3_decode_soft @409 + fec_rep3_destroy @410 + fec_rep3_encode @411 + fec_rep3_print @412 + fec_rep5_create @413 + fec_rep5_decode @414 + fec_rep5_decode_soft @415 + fec_rep5_destroy @416 + fec_rep5_encode @417 + fec_rep5_print @418 + fec_rs_create @419 + fec_rs_decode @420 + fec_rs_destroy @421 + fec_rs_encode @422 + fec_rs_get_enc_msg_len @423 + fec_scheme_is_convolutional @424 + fec_scheme_is_hamming @425 + fec_scheme_is_punctured @426 + fec_scheme_is_reedsolomon @427 + fec_scheme_is_repeat @428 + fec_scheme_str @429 DATA + fec_secded2216_compute_parity @430 + fec_secded2216_compute_syndrome @431 + fec_secded2216_create @432 + fec_secded2216_decode @433 + fec_secded2216_decode_symbol @434 + fec_secded2216_destroy @435 + fec_secded2216_encode @436 + fec_secded2216_encode_symbol @437 + fec_secded2216_estimate_ehat @438 + fec_secded3932_compute_parity @439 + fec_secded3932_compute_syndrome @440 + fec_secded3932_create @441 + fec_secded3932_decode @442 + fec_secded3932_decode_symbol @443 + fec_secded3932_destroy @444 + fec_secded3932_encode @445 + fec_secded3932_encode_symbol @446 + fec_secded3932_estimate_ehat @447 + fec_secded7264_compute_parity @448 + fec_secded7264_compute_syndrome @449 + fec_secded7264_create @450 + fec_secded7264_decode @451 + fec_secded7264_decode_symbol @452 + fec_secded7264_destroy @453 + fec_secded7264_encode @454 + fec_secded7264_encode_symbol @455 + fec_secded7264_estimate_ehat @456 + fec_sumproduct @457 + fec_sumproduct_step @458 + fecsoft_hamming128_decode @459 + fecsoft_hamming128_decode_n3 @460 + fecsoft_hamming128_n3 @461 DATA + fecsoft_hamming74_decode @462 + fecsoft_hamming84_decode @463 + fft_create_plan @464 + fft_create_plan_dft @465 + fft_create_plan_mixed_radix @466 + fft_create_plan_r2r_1d @467 + fft_create_plan_rader @468 + fft_create_plan_rader2 @469 + fft_create_plan_radix2 @470 + fft_destroy_plan @471 + fft_destroy_plan_dft @472 + fft_destroy_plan_mixed_radix @473 + fft_destroy_plan_r2r_1d @474 + fft_destroy_plan_rader @475 + fft_destroy_plan_rader2 @476 + fft_destroy_plan_radix2 @477 + fft_estimate_mixed_radix @478 + fft_execute @479 + fft_execute_REDFT00 @480 + fft_execute_REDFT01 @481 + fft_execute_REDFT10 @482 + fft_execute_REDFT11 @483 + fft_execute_RODFT00 @484 + fft_execute_RODFT01 @485 + fft_execute_RODFT10 @486 + fft_execute_RODFT11 @487 + fft_execute_dft @488 + fft_execute_dft_16 @489 + fft_execute_dft_2 @490 + fft_execute_dft_3 @491 + fft_execute_dft_4 @492 + fft_execute_dft_5 @493 + fft_execute_dft_6 @494 + fft_execute_dft_7 @495 + fft_execute_dft_8 @496 + fft_execute_mixed_radix @497 + fft_execute_rader @498 + fft_execute_rader2 @499 + fft_execute_radix2 @500 + fft_is_radix2 @501 + fft_print_plan @502 + fft_print_plan_r2r_1d @503 + fft_print_plan_recursive @504 + fft_r2r_1d_run @505 + fft_reverse_index @506 + fft_run @507 + fft_shift @508 + fftfilt_cccf_create @509 + fftfilt_cccf_destroy @510 + fftfilt_cccf_execute @511 + fftfilt_cccf_get_length @512 + fftfilt_cccf_print @513 + fftfilt_cccf_reset @514 + fftfilt_cccf_set_scale @515 + fftfilt_crcf_create @516 + fftfilt_crcf_destroy @517 + fftfilt_crcf_execute @518 + fftfilt_crcf_get_length @519 + fftfilt_crcf_print @520 + fftfilt_crcf_reset @521 + fftfilt_crcf_set_scale @522 + fftfilt_rrrf_create @523 + fftfilt_rrrf_destroy @524 + fftfilt_rrrf_execute @525 + fftfilt_rrrf_get_length @526 + fftfilt_rrrf_print @527 + fftfilt_rrrf_reset @528 + fftfilt_rrrf_set_scale @529 + fir_group_delay @530 + firdecim_cccf_clear @531 + firdecim_cccf_create @532 + firdecim_cccf_create_prototype @533 + firdecim_cccf_create_rnyquist @534 + firdecim_cccf_destroy @535 + firdecim_cccf_execute @536 + firdecim_cccf_execute_block @537 + firdecim_cccf_print @538 + firdecim_crcf_clear @539 + firdecim_crcf_create @540 + firdecim_crcf_create_prototype @541 + firdecim_crcf_create_rnyquist @542 + firdecim_crcf_destroy @543 + firdecim_crcf_execute @544 + firdecim_crcf_execute_block @545 + firdecim_crcf_print @546 + firdecim_rrrf_clear @547 + firdecim_rrrf_create @548 + firdecim_rrrf_create_prototype @549 + firdecim_rrrf_create_rnyquist @550 + firdecim_rrrf_destroy @551 + firdecim_rrrf_execute @552 + firdecim_rrrf_execute_block @553 + firdecim_rrrf_print @554 + firdespm_compute_error @555 + firdespm_compute_interp @556 + firdespm_compute_taps @557 + firdespm_create @558 + firdespm_destroy @559 + firdespm_execute @560 + firdespm_iext_search @561 + firdespm_init_grid @562 + firdespm_is_search_complete @563 + firdespm_print @564 + firdespm_run @565 + firfarrow_crcf_create @566 + firfarrow_crcf_destroy @567 + firfarrow_crcf_execute @568 + firfarrow_crcf_execute_block @569 + firfarrow_crcf_freqresponse @570 + firfarrow_crcf_genpoly @571 + firfarrow_crcf_get_coefficients @572 + firfarrow_crcf_get_length @573 + firfarrow_crcf_groupdelay @574 + firfarrow_crcf_print @575 + firfarrow_crcf_push @576 + firfarrow_crcf_reset @577 + firfarrow_crcf_set_delay @578 + firfarrow_rrrf_create @579 + firfarrow_rrrf_destroy @580 + firfarrow_rrrf_execute @581 + firfarrow_rrrf_execute_block @582 + firfarrow_rrrf_freqresponse @583 + firfarrow_rrrf_genpoly @584 + firfarrow_rrrf_get_coefficients @585 + firfarrow_rrrf_get_length @586 + firfarrow_rrrf_groupdelay @587 + firfarrow_rrrf_print @588 + firfarrow_rrrf_push @589 + firfarrow_rrrf_reset @590 + firfarrow_rrrf_set_delay @591 + firfilt_cccf_create @592 + firfilt_cccf_create_kaiser @593 + firfilt_cccf_create_rnyquist @594 + firfilt_cccf_destroy @595 + firfilt_cccf_execute @596 + firfilt_cccf_execute_block @597 + firfilt_cccf_freqresponse @598 + firfilt_cccf_get_length @599 + firfilt_cccf_groupdelay @600 + firfilt_cccf_print @601 + firfilt_cccf_push @602 + firfilt_cccf_recreate @603 + firfilt_cccf_reset @604 + firfilt_cccf_set_scale @605 + firfilt_crcf_create @606 + firfilt_crcf_create_kaiser @607 + firfilt_crcf_create_rnyquist @608 + firfilt_crcf_destroy @609 + firfilt_crcf_execute @610 + firfilt_crcf_execute_block @611 + firfilt_crcf_freqresponse @612 + firfilt_crcf_get_length @613 + firfilt_crcf_groupdelay @614 + firfilt_crcf_print @615 + firfilt_crcf_push @616 + firfilt_crcf_recreate @617 + firfilt_crcf_reset @618 + firfilt_crcf_set_scale @619 + firfilt_rrrf_create @620 + firfilt_rrrf_create_kaiser @621 + firfilt_rrrf_create_rnyquist @622 + firfilt_rrrf_destroy @623 + firfilt_rrrf_execute @624 + firfilt_rrrf_execute_block @625 + firfilt_rrrf_freqresponse @626 + firfilt_rrrf_get_length @627 + firfilt_rrrf_groupdelay @628 + firfilt_rrrf_print @629 + firfilt_rrrf_push @630 + firfilt_rrrf_recreate @631 + firfilt_rrrf_reset @632 + firfilt_rrrf_set_scale @633 + firhilbf_c2r_execute @634 + firhilbf_create @635 + firhilbf_decim_execute @636 + firhilbf_destroy @637 + firhilbf_interp_execute @638 + firhilbf_print @639 + firhilbf_r2c_execute @640 + firhilbf_reset @641 + firinterp_cccf_create @642 + firinterp_cccf_create_nyquist @643 + firinterp_cccf_create_prototype @644 + firinterp_cccf_create_rnyquist @645 + firinterp_cccf_destroy @646 + firinterp_cccf_execute @647 + firinterp_cccf_execute_block @648 + firinterp_cccf_print @649 + firinterp_cccf_reset @650 + firinterp_crcf_create @651 + firinterp_crcf_create_nyquist @652 + firinterp_crcf_create_prototype @653 + firinterp_crcf_create_rnyquist @654 + firinterp_crcf_destroy @655 + firinterp_crcf_execute @656 + firinterp_crcf_execute_block @657 + firinterp_crcf_print @658 + firinterp_crcf_reset @659 + firinterp_rrrf_create @660 + firinterp_rrrf_create_nyquist @661 + firinterp_rrrf_create_prototype @662 + firinterp_rrrf_create_rnyquist @663 + firinterp_rrrf_destroy @664 + firinterp_rrrf_execute @665 + firinterp_rrrf_execute_block @666 + firinterp_rrrf_print @667 + firinterp_rrrf_reset @668 + firpfb_cccf_create @669 + firpfb_cccf_create_drnyquist @670 + firpfb_cccf_create_rnyquist @671 + firpfb_cccf_destroy @672 + firpfb_cccf_execute @673 + firpfb_cccf_print @674 + firpfb_cccf_push @675 + firpfb_cccf_recreate @676 + firpfb_cccf_reset @677 + firpfb_crcf_create @678 + firpfb_crcf_create_drnyquist @679 + firpfb_crcf_create_rnyquist @680 + firpfb_crcf_destroy @681 + firpfb_crcf_execute @682 + firpfb_crcf_print @683 + firpfb_crcf_push @684 + firpfb_crcf_recreate @685 + firpfb_crcf_reset @686 + firpfb_rrrf_create @687 + firpfb_rrrf_create_drnyquist @688 + firpfb_rrrf_create_rnyquist @689 + firpfb_rrrf_destroy @690 + firpfb_rrrf_execute @691 + firpfb_rrrf_print @692 + firpfb_rrrf_push @693 + firpfb_rrrf_recreate @694 + firpfb_rrrf_reset @695 + firpfbch2_crcf_create @696 + firpfbch2_crcf_create_kaiser @697 + firpfbch2_crcf_destroy @698 + firpfbch2_crcf_execute @699 + firpfbch2_crcf_execute_analyzer @700 + firpfbch2_crcf_execute_synthesizer @701 + firpfbch2_crcf_print @702 + firpfbch2_crcf_reset @703 + firpfbch_cccf_analyzer_execute @704 + firpfbch_cccf_analyzer_push @705 + firpfbch_cccf_analyzer_run @706 + firpfbch_cccf_create @707 + firpfbch_cccf_create_kaiser @708 + firpfbch_cccf_create_rnyquist @709 + firpfbch_cccf_destroy @710 + firpfbch_cccf_print @711 + firpfbch_cccf_reset @712 + firpfbch_cccf_synthesizer_execute @713 + firpfbch_crcf_analyzer_execute @714 + firpfbch_crcf_analyzer_push @715 + firpfbch_crcf_analyzer_run @716 + firpfbch_crcf_create @717 + firpfbch_crcf_create_kaiser @718 + firpfbch_crcf_create_rnyquist @719 + firpfbch_crcf_destroy @720 + firpfbch_crcf_print @721 + firpfbch_crcf_reset @722 + firpfbch_crcf_synthesizer_execute @723 + flexframegen_assemble @724 + flexframegen_create @725 + flexframegen_destroy @726 + flexframegen_encode_header @727 + flexframegen_getframelen @728 + flexframegen_getprops @729 + flexframegen_is_assembled @730 + flexframegen_modulate_header @731 + flexframegen_modulate_payload @732 + flexframegen_print @733 + flexframegen_reconfigure @734 + flexframegen_reset @735 + flexframegen_setprops @736 + flexframegen_write_header @737 + flexframegen_write_payload @738 + flexframegen_write_preamble @739 + flexframegen_write_samples @740 + flexframegen_write_tail @741 + flexframegenprops_init_default @742 + flexframesync_create @743 + flexframesync_debug_disable @744 + flexframesync_debug_enable @745 + flexframesync_debug_print @746 + flexframesync_decode_header @747 + flexframesync_decode_payload @748 + flexframesync_destroy @749 + flexframesync_execute @750 + flexframesync_execute_rxheader @751 + flexframesync_execute_rxpayload @752 + flexframesync_execute_rxpn @753 + flexframesync_execute_seekpn @754 + flexframesync_print @755 + flexframesync_pushpn @756 + flexframesync_reset @757 + flexframesync_syncpn @758 + flexframesync_update_symsync @759 + fpoly_bessel @760 + fpoly_bessel_roots @761 + fpoly_bessel_roots_orchard @762 + fpoly_bessel_roots_orchard_recursion @763 + framegen64_byte_to_syms @764 + framegen64_create @765 + framegen64_destroy @766 + framegen64_execute @767 + framegen64_print @768 + framesync64_create @769 + framesync64_debug_disable @770 + framesync64_debug_enable @771 + framesync64_debug_print @772 + framesync64_decode_payload @773 + framesync64_destroy @774 + framesync64_execute @775 + framesync64_execute_rxpayload @776 + framesync64_execute_rxpreamble @777 + framesync64_execute_seekpn @778 + framesync64_print @779 + framesync64_pushpn @780 + framesync64_reset @781 + framesync64_syncpn @782 + framesync64_update_symsync @783 + framesyncstats_default @784 DATA + framesyncstats_init_default @785 + framesyncstats_print @786 + freqdem_create @787 + freqdem_demodulate @788 + freqdem_demodulate_block @789 + freqdem_destroy @790 + freqdem_print @791 + freqdem_reset @792 + freqmod_create @793 + freqmod_destroy @794 + freqmod_modulate @795 + freqmod_modulate_block @796 + freqmod_print @797 + freqmod_reset @798 + gasearch_create @799 + gasearch_create_advanced @800 + gasearch_crossover @801 + gasearch_destroy @802 + gasearch_evaluate @803 + gasearch_evolve @804 + gasearch_getopt @805 + gasearch_mutate @806 + gasearch_print @807 + gasearch_rank @808 + gasearch_run @809 + gasearch_set_mutation_rate @810 + gasearch_set_population_size @811 + gmskdem_create @812 + gmskdem_debug_print @813 + gmskdem_demodulate @814 + gmskdem_destroy @815 + gmskdem_print @816 + gmskdem_reset @817 + gmskdem_set_eq_bw @818 + gmskframegen_assemble @819 + gmskframegen_create @820 + gmskframegen_destroy @821 + gmskframegen_encode_header @822 + gmskframegen_getframelen @823 + gmskframegen_print @824 + gmskframegen_reset @825 + gmskframegen_write_header @826 + gmskframegen_write_payload @827 + gmskframegen_write_preamble @828 + gmskframegen_write_samples @829 + gmskframegen_write_tail @830 + gmskframesync_create @831 + gmskframesync_debug_disable @832 + gmskframesync_debug_enable @833 + gmskframesync_debug_print @834 + gmskframesync_decode_header @835 + gmskframesync_destroy @836 + gmskframesync_execute @837 + gmskframesync_execute_detectframe @838 + gmskframesync_execute_rxheader @839 + gmskframesync_execute_rxpayload @840 + gmskframesync_execute_rxpreamble @841 + gmskframesync_print @842 + gmskframesync_pushpn @843 + gmskframesync_reset @844 + gmskframesync_syncpn @845 + gmskframesync_update_fi @846 + gmskframesync_update_symsync @847 + gmskmod_create @848 + gmskmod_destroy @849 + gmskmod_modulate @850 + gmskmod_print @851 + gmskmod_reset @852 + golay2412_Gt @853 DATA + golay2412_H @854 DATA + golay2412_P @855 DATA + golay2412_matrix_mul @856 + golay2412_parity_search @857 + gradsearch_create @858 + gradsearch_destroy @859 + gradsearch_execute @860 + gradsearch_gradient @861 + gradsearch_linesearch @862 + gradsearch_norm @863 + gradsearch_print @864 + gradsearch_step @865 + gray_decode @866 + gray_encode @867 + hamming @868 + hamming128_enc_gentab @869 DATA + hamming74_dec_gentab @870 DATA + hamming74_enc_gentab @871 DATA + hamming84_dec_gentab @872 DATA + hamming84_enc_gentab @873 DATA + hann @874 + icrandnf @875 + iir_group_delay @876 + iirdecim_cccf_create @877 + iirdecim_cccf_create_prototype @878 + iirdecim_cccf_destroy @879 + iirdecim_cccf_execute @880 + iirdecim_cccf_execute_block @881 + iirdecim_cccf_groupdelay @882 + iirdecim_cccf_print @883 + iirdecim_cccf_reset @884 + iirdecim_crcf_create @885 + iirdecim_crcf_create_prototype @886 + iirdecim_crcf_destroy @887 + iirdecim_crcf_execute @888 + iirdecim_crcf_execute_block @889 + iirdecim_crcf_groupdelay @890 + iirdecim_crcf_print @891 + iirdecim_crcf_reset @892 + iirdecim_rrrf_create @893 + iirdecim_rrrf_create_prototype @894 + iirdecim_rrrf_destroy @895 + iirdecim_rrrf_execute @896 + iirdecim_rrrf_execute_block @897 + iirdecim_rrrf_groupdelay @898 + iirdecim_rrrf_print @899 + iirdecim_rrrf_reset @900 + iirdes_dzpk2sosf @901 + iirdes_dzpk2tff @902 + iirdes_dzpk_lp2bp @903 + iirdes_dzpk_lp2hp @904 + iirdes_freqprewarp @905 + iirdes_isstable @906 + iirdes_pll_active_PI @907 + iirdes_pll_active_lag @908 + iirfilt_cccf_create @909 + iirfilt_cccf_create_dc_blocker @910 + iirfilt_cccf_create_differentiator @911 + iirfilt_cccf_create_integrator @912 + iirfilt_cccf_create_pll @913 + iirfilt_cccf_create_prototype @914 + iirfilt_cccf_create_sos @915 + iirfilt_cccf_destroy @916 + iirfilt_cccf_execute @917 + iirfilt_cccf_execute_block @918 + iirfilt_cccf_execute_norm @919 + iirfilt_cccf_execute_sos @920 + iirfilt_cccf_freqresponse @921 + iirfilt_cccf_get_length @922 + iirfilt_cccf_groupdelay @923 + iirfilt_cccf_print @924 + iirfilt_cccf_reset @925 + iirfilt_crcf_create @926 + iirfilt_crcf_create_dc_blocker @927 + iirfilt_crcf_create_differentiator @928 + iirfilt_crcf_create_integrator @929 + iirfilt_crcf_create_pll @930 + iirfilt_crcf_create_prototype @931 + iirfilt_crcf_create_sos @932 + iirfilt_crcf_destroy @933 + iirfilt_crcf_execute @934 + iirfilt_crcf_execute_block @935 + iirfilt_crcf_execute_norm @936 + iirfilt_crcf_execute_sos @937 + iirfilt_crcf_freqresponse @938 + iirfilt_crcf_get_length @939 + iirfilt_crcf_groupdelay @940 + iirfilt_crcf_print @941 + iirfilt_crcf_reset @942 + iirfilt_rrrf_create @943 + iirfilt_rrrf_create_dc_blocker @944 + iirfilt_rrrf_create_differentiator @945 + iirfilt_rrrf_create_integrator @946 + iirfilt_rrrf_create_pll @947 + iirfilt_rrrf_create_prototype @948 + iirfilt_rrrf_create_sos @949 + iirfilt_rrrf_destroy @950 + iirfilt_rrrf_execute @951 + iirfilt_rrrf_execute_block @952 + iirfilt_rrrf_execute_norm @953 + iirfilt_rrrf_execute_sos @954 + iirfilt_rrrf_freqresponse @955 + iirfilt_rrrf_get_length @956 + iirfilt_rrrf_groupdelay @957 + iirfilt_rrrf_print @958 + iirfilt_rrrf_reset @959 + iirfiltsos_cccf_create @960 + iirfiltsos_cccf_destroy @961 + iirfiltsos_cccf_execute @962 + iirfiltsos_cccf_execute_df1 @963 + iirfiltsos_cccf_execute_df2 @964 + iirfiltsos_cccf_groupdelay @965 + iirfiltsos_cccf_print @966 + iirfiltsos_cccf_reset @967 + iirfiltsos_cccf_set_coefficients @968 + iirfiltsos_crcf_create @969 + iirfiltsos_crcf_destroy @970 + iirfiltsos_crcf_execute @971 + iirfiltsos_crcf_execute_df1 @972 + iirfiltsos_crcf_execute_df2 @973 + iirfiltsos_crcf_groupdelay @974 + iirfiltsos_crcf_print @975 + iirfiltsos_crcf_reset @976 + iirfiltsos_crcf_set_coefficients @977 + iirfiltsos_rrrf_create @978 + iirfiltsos_rrrf_destroy @979 + iirfiltsos_rrrf_execute @980 + iirfiltsos_rrrf_execute_df1 @981 + iirfiltsos_rrrf_execute_df2 @982 + iirfiltsos_rrrf_groupdelay @983 + iirfiltsos_rrrf_print @984 + iirfiltsos_rrrf_reset @985 + iirfiltsos_rrrf_set_coefficients @986 + iirinterp_cccf_create @987 + iirinterp_cccf_create_prototype @988 + iirinterp_cccf_destroy @989 + iirinterp_cccf_execute @990 + iirinterp_cccf_execute_block @991 + iirinterp_cccf_groupdelay @992 + iirinterp_cccf_print @993 + iirinterp_cccf_reset @994 + iirinterp_crcf_create @995 + iirinterp_crcf_create_prototype @996 + iirinterp_crcf_destroy @997 + iirinterp_crcf_execute @998 + iirinterp_crcf_execute_block @999 + iirinterp_crcf_groupdelay @1000 + iirinterp_crcf_print @1001 + iirinterp_crcf_reset @1002 + iirinterp_rrrf_create @1003 + iirinterp_rrrf_create_prototype @1004 + iirinterp_rrrf_destroy @1005 + iirinterp_rrrf_execute @1006 + iirinterp_rrrf_execute_block @1007 + iirinterp_rrrf_groupdelay @1008 + iirinterp_rrrf_print @1009 + iirinterp_rrrf_reset @1010 + interleaver_create @1011 + interleaver_decode @1012 + interleaver_decode_soft @1013 + interleaver_destroy @1014 + interleaver_encode @1015 + interleaver_encode_soft @1016 + interleaver_permute @1017 + interleaver_permute_mask @1018 + interleaver_permute_mask_soft @1019 + interleaver_permute_soft @1020 + interleaver_print @1021 + interleaver_set_depth @1022 + kaiser @1023 + kaiser_beta_As @1024 + landenf @1025 + liquid_MarcumQ1f @1026 + liquid_MarcumQf @1027 + liquid_Qf @1028 + liquid_apsk128 @1029 DATA + liquid_apsk16 @1030 DATA + liquid_apsk256 @1031 DATA + liquid_apsk32 @1032 DATA + liquid_apsk4 @1033 DATA + liquid_apsk64 @1034 DATA + liquid_apsk8 @1035 DATA + liquid_asechf @1036 + liquid_bdotprod @1037 + liquid_besseli0f @1038 + liquid_besselif @1039 + liquid_besselj0f @1040 + liquid_besseljf @1041 + liquid_c_leading_zeros @1042 DATA + liquid_c_ones @1043 DATA + liquid_c_ones_mod2 @1044 DATA + liquid_cacosf @1045 + liquid_cargf_approx @1046 + liquid_casinf @1047 + liquid_catanf @1048 + liquid_cexpf @1049 + liquid_clogf @1050 + liquid_cosf @1051 + liquid_count_leading_zeros @1052 + liquid_count_ones @1053 + liquid_count_ones_mod2 @1054 + liquid_cplxpair @1055 + liquid_cplxpair_cleanup @1056 + liquid_csqrtf @1057 + liquid_expf @1058 + liquid_factor @1059 + liquid_factorialf @1060 + liquid_fft_estimate_method @1061 + liquid_filter_autocorr @1062 + liquid_filter_crosscorr @1063 + liquid_filter_energy @1064 + liquid_filter_isi @1065 + liquid_firdes_arkaiser @1066 + liquid_firdes_doppler @1067 + liquid_firdes_farcsech @1068 + liquid_firdes_farcsech_freqresponse @1069 + liquid_firdes_fexp @1070 + liquid_firdes_fexp_freqresponse @1071 + liquid_firdes_fnyquist @1072 + liquid_firdes_fsech @1073 + liquid_firdes_fsech_freqresponse @1074 + liquid_firdes_gmskrx @1075 + liquid_firdes_gmsktx @1076 + liquid_firdes_hM3 @1077 + liquid_firdes_kaiser @1078 + liquid_firdes_nyquist @1079 + liquid_firdes_rcos @1080 + liquid_firdes_rfarcsech @1081 + liquid_firdes_rfexp @1082 + liquid_firdes_rfsech @1083 + liquid_firdes_rkaiser @1084 + liquid_firdes_rkaiser_bisection @1085 + liquid_firdes_rkaiser_internal_isi @1086 + liquid_firdes_rkaiser_quadratic @1087 + liquid_firdes_rnyquist @1088 + liquid_firdes_rrcos @1089 + liquid_gammaf @1090 + liquid_getopt_str2crc @1091 + liquid_getopt_str2fec @1092 + liquid_getopt_str2firfilt @1093 + liquid_getopt_str2mod @1094 + liquid_iirdes @1095 + liquid_invgauss @1096 + liquid_is_prime @1097 + liquid_kbd @1098 + liquid_kbd_window @1099 + liquid_lbcircshift @1100 + liquid_lbshift @1101 + liquid_lcircshift @1102 + liquid_levinson @1103 + liquid_libversion @1104 + liquid_libversion_number @1105 + liquid_lnbesselif @1106 + liquid_lngammaf @1107 + liquid_lnlowergammaf @1108 + liquid_lnuppergammaf @1109 + liquid_logf @1110 + liquid_lowergammaf @1111 + liquid_lpc @1112 + liquid_lshift @1113 + liquid_modem_is_apsk @1114 + liquid_modem_is_ask @1115 + liquid_modem_is_dpsk @1116 + liquid_modem_is_psk @1117 + liquid_modem_is_qam @1118 + liquid_modpow @1119 + liquid_msb_index @1120 + liquid_multimodal @1121 + liquid_nchoosek @1122 + liquid_nextpow2 @1123 + liquid_pack_array @1124 + liquid_pack_bytes @1125 + liquid_pack_soft_bits @1126 + liquid_primitive_root @1127 + liquid_primitive_root_prime @1128 + liquid_print_bitstring @1129 + liquid_print_crc_schemes @1130 + liquid_print_fec_schemes @1131 + liquid_print_modulation_schemes @1132 + liquid_rbcircshift @1133 + liquid_rbshift @1134 + liquid_rcircshift @1135 + liquid_repack_bytes @1136 + liquid_reverse_byte @1137 + liquid_reverse_byte_gentab @1138 DATA + liquid_reverse_uint16 @1139 + liquid_reverse_uint24 @1140 + liquid_reverse_uint32 @1141 + liquid_rosenbrock @1142 + liquid_rshift @1143 + liquid_sincosf @1144 + liquid_sinf @1145 + liquid_spiral @1146 + liquid_sumsqcf @1147 + liquid_sumsqf @1148 + liquid_tanf @1149 + liquid_totient @1150 + liquid_unique_factor @1151 + liquid_unpack_array @1152 + liquid_unpack_bytes @1153 + liquid_unpack_soft_bits @1154 + liquid_unwrap_phase @1155 + liquid_unwrap_phase2 @1156 + liquid_uppergammaf @1157 + liquid_vectorcf_abs @1158 + liquid_vectorcf_add @1159 + liquid_vectorcf_addscalar @1160 + liquid_vectorcf_carg @1161 + liquid_vectorcf_cexpj @1162 + liquid_vectorcf_mul @1163 + liquid_vectorcf_mulscalar @1164 + liquid_vectorcf_norm @1165 + liquid_vectorcf_normalize @1166 + liquid_vectorf_abs @1167 + liquid_vectorf_add @1168 + liquid_vectorf_addscalar @1169 + liquid_vectorf_carg @1170 + liquid_vectorf_cexpj @1171 + liquid_vectorf_mul @1172 + liquid_vectorf_mulscalar @1173 + liquid_vectorf_norm @1174 + liquid_vectorf_normalize @1175 + liquid_version @1176 DATA + matrix_add @1177 + matrix_aug @1178 + matrix_cgsolve @1179 + matrix_chol @1180 + matrix_det @1181 + matrix_det2x2 @1182 + matrix_div @1183 + matrix_eye @1184 + matrix_gjelim @1185 + matrix_gramschmidt @1186 + matrix_hermitian @1187 + matrix_hermitian_mul @1188 + matrix_inv @1189 + matrix_linsolve @1190 + matrix_ludecomp_crout @1191 + matrix_ludecomp_doolittle @1192 + matrix_mul @1193 + matrix_mul_hermitian @1194 + matrix_mul_transpose @1195 + matrix_ones @1196 + matrix_pdiv @1197 + matrix_pivot @1198 + matrix_pmul @1199 + matrix_print @1200 + matrix_proj @1201 + matrix_qrdecomp_gramschmidt @1202 + matrix_sub @1203 + matrix_swaprows @1204 + matrix_trans @1205 + matrix_transpose_mul @1206 + matrix_zeros @1207 + matrixc_add @1208 + matrixc_aug @1209 + matrixc_cgsolve @1210 + matrixc_chol @1211 + matrixc_det @1212 + matrixc_det2x2 @1213 + matrixc_div @1214 + matrixc_eye @1215 + matrixc_gjelim @1216 + matrixc_gramschmidt @1217 + matrixc_hermitian @1218 + matrixc_hermitian_mul @1219 + matrixc_inv @1220 + matrixc_linsolve @1221 + matrixc_ludecomp_crout @1222 + matrixc_ludecomp_doolittle @1223 + matrixc_mul @1224 + matrixc_mul_hermitian @1225 + matrixc_mul_transpose @1226 + matrixc_ones @1227 + matrixc_pdiv @1228 + matrixc_pivot @1229 + matrixc_pmul @1230 + matrixc_print @1231 + matrixc_proj @1232 + matrixc_qrdecomp_gramschmidt @1233 + matrixc_sub @1234 + matrixc_swaprows @1235 + matrixc_trans @1236 + matrixc_transpose_mul @1237 + matrixc_zeros @1238 + matrixcf_add @1239 + matrixcf_aug @1240 + matrixcf_cgsolve @1241 + matrixcf_chol @1242 + matrixcf_det @1243 + matrixcf_det2x2 @1244 + matrixcf_div @1245 + matrixcf_eye @1246 + matrixcf_gjelim @1247 + matrixcf_gramschmidt @1248 + matrixcf_hermitian @1249 + matrixcf_hermitian_mul @1250 + matrixcf_inv @1251 + matrixcf_linsolve @1252 + matrixcf_ludecomp_crout @1253 + matrixcf_ludecomp_doolittle @1254 + matrixcf_mul @1255 + matrixcf_mul_hermitian @1256 + matrixcf_mul_transpose @1257 + matrixcf_ones @1258 + matrixcf_pdiv @1259 + matrixcf_pivot @1260 + matrixcf_pmul @1261 + matrixcf_print @1262 + matrixcf_proj @1263 + matrixcf_qrdecomp_gramschmidt @1264 + matrixcf_sub @1265 + matrixcf_swaprows @1266 + matrixcf_trans @1267 + matrixcf_transpose_mul @1268 + matrixcf_zeros @1269 + matrixf_add @1270 + matrixf_aug @1271 + matrixf_cgsolve @1272 + matrixf_chol @1273 + matrixf_det @1274 + matrixf_det2x2 @1275 + matrixf_div @1276 + matrixf_eye @1277 + matrixf_gjelim @1278 + matrixf_gramschmidt @1279 + matrixf_hermitian @1280 + matrixf_hermitian_mul @1281 + matrixf_inv @1282 + matrixf_linsolve @1283 + matrixf_ludecomp_crout @1284 + matrixf_ludecomp_doolittle @1285 + matrixf_mul @1286 + matrixf_mul_hermitian @1287 + matrixf_mul_transpose @1288 + matrixf_ones @1289 + matrixf_pdiv @1290 + matrixf_pivot @1291 + matrixf_pmul @1292 + matrixf_print @1293 + matrixf_proj @1294 + matrixf_qrdecomp_gramschmidt @1295 + matrixf_sub @1296 + matrixf_swaprows @1297 + matrixf_trans @1298 + matrixf_transpose_mul @1299 + matrixf_zeros @1300 + modem_arb128opt @1301 DATA + modem_arb16opt @1302 DATA + modem_arb256opt @1303 DATA + modem_arb32opt @1304 DATA + modem_arb64opt @1305 DATA + modem_arb_V29 @1306 DATA + modem_arb_balance_iq @1307 + modem_arb_init @1308 + modem_arb_init_file @1309 + modem_arb_scale @1310 + modem_arb_sqam128 @1311 DATA + modem_arb_sqam32 @1312 DATA + modem_arb_vt64 @1313 DATA + modem_create @1314 + modem_create_V29 @1315 + modem_create_apsk @1316 + modem_create_arb @1317 + modem_create_arb128opt @1318 + modem_create_arb16opt @1319 + modem_create_arb256opt @1320 + modem_create_arb32opt @1321 + modem_create_arb64opt @1322 + modem_create_arb64vt @1323 + modem_create_arbitrary @1324 + modem_create_ask @1325 + modem_create_bpsk @1326 + modem_create_dpsk @1327 + modem_create_ook @1328 + modem_create_psk @1329 + modem_create_qam @1330 + modem_create_qpsk @1331 + modem_create_sqam128 @1332 + modem_create_sqam32 @1333 + modem_demodsoft_gentab @1334 + modem_demodulate @1335 + modem_demodulate_apsk @1336 + modem_demodulate_arb @1337 + modem_demodulate_ask @1338 + modem_demodulate_bpsk @1339 + modem_demodulate_dpsk @1340 + modem_demodulate_linear_array @1341 + modem_demodulate_linear_array_ref @1342 + modem_demodulate_ook @1343 + modem_demodulate_psk @1344 + modem_demodulate_qam @1345 + modem_demodulate_qpsk @1346 + modem_demodulate_soft @1347 + modem_demodulate_soft_arb @1348 + modem_demodulate_soft_bpsk @1349 + modem_demodulate_soft_qpsk @1350 + modem_demodulate_soft_table @1351 + modem_demodulate_sqam128 @1352 + modem_demodulate_sqam32 @1353 + modem_destroy @1354 + modem_gen_rand_sym @1355 + modem_get_bps @1356 + modem_get_demodulator_evm @1357 + modem_get_demodulator_phase_error @1358 + modem_get_demodulator_sample @1359 + modem_init @1360 + modem_init_map @1361 + modem_modulate @1362 + modem_modulate_apsk @1363 + modem_modulate_arb @1364 + modem_modulate_ask @1365 + modem_modulate_bpsk @1366 + modem_modulate_dpsk @1367 + modem_modulate_map @1368 + modem_modulate_ook @1369 + modem_modulate_psk @1370 + modem_modulate_qam @1371 + modem_modulate_qpsk @1372 + modem_modulate_sqam128 @1373 + modem_modulate_sqam32 @1374 + modem_print @1375 + modem_recreate @1376 + modem_reset @1377 + modulation_types @1378 DATA + msequence_advance @1379 + msequence_create @1380 + msequence_create_default @1381 + msequence_create_genpoly @1382 + msequence_default @1383 DATA + msequence_destroy @1384 + msequence_generate_symbol @1385 + msequence_get_length @1386 + msequence_get_state @1387 + msequence_print @1388 + msequence_reset @1389 + msequence_set_state @1390 + msresamp2_cccf_create @1391 + msresamp2_cccf_decim_execute @1392 + msresamp2_cccf_destroy @1393 + msresamp2_cccf_execute @1394 + msresamp2_cccf_get_delay @1395 + msresamp2_cccf_interp_execute @1396 + msresamp2_cccf_print @1397 + msresamp2_cccf_reset @1398 + msresamp2_crcf_create @1399 + msresamp2_crcf_decim_execute @1400 + msresamp2_crcf_destroy @1401 + msresamp2_crcf_execute @1402 + msresamp2_crcf_get_delay @1403 + msresamp2_crcf_interp_execute @1404 + msresamp2_crcf_print @1405 + msresamp2_crcf_reset @1406 + msresamp2_rrrf_create @1407 + msresamp2_rrrf_decim_execute @1408 + msresamp2_rrrf_destroy @1409 + msresamp2_rrrf_execute @1410 + msresamp2_rrrf_get_delay @1411 + msresamp2_rrrf_interp_execute @1412 + msresamp2_rrrf_print @1413 + msresamp2_rrrf_reset @1414 + msresamp_cccf_create @1415 + msresamp_cccf_decim_execute @1416 + msresamp_cccf_destroy @1417 + msresamp_cccf_execute @1418 + msresamp_cccf_get_delay @1419 + msresamp_cccf_interp_execute @1420 + msresamp_cccf_print @1421 + msresamp_cccf_reset @1422 + msresamp_crcf_create @1423 + msresamp_crcf_decim_execute @1424 + msresamp_crcf_destroy @1425 + msresamp_crcf_execute @1426 + msresamp_crcf_get_delay @1427 + msresamp_crcf_interp_execute @1428 + msresamp_crcf_print @1429 + msresamp_crcf_reset @1430 + msresamp_rrrf_create @1431 + msresamp_rrrf_decim_execute @1432 + msresamp_rrrf_destroy @1433 + msresamp_rrrf_execute @1434 + msresamp_rrrf_get_delay @1435 + msresamp_rrrf_interp_execute @1436 + msresamp_rrrf_print @1437 + msresamp_rrrf_reset @1438 + nco_crcf_adjust_frequency @1439 + nco_crcf_adjust_phase @1440 + nco_crcf_cexpf @1441 + nco_crcf_compute_sincos_nco @1442 + nco_crcf_compute_sincos_vco @1443 + nco_crcf_constrain_frequency @1444 + nco_crcf_constrain_phase @1445 + nco_crcf_cos @1446 + nco_crcf_create @1447 + nco_crcf_destroy @1448 + nco_crcf_get_frequency @1449 + nco_crcf_get_phase @1450 + nco_crcf_mix_block_down @1451 + nco_crcf_mix_block_up @1452 + nco_crcf_mix_down @1453 + nco_crcf_mix_up @1454 + nco_crcf_pll_reset @1455 + nco_crcf_pll_set_bandwidth @1456 + nco_crcf_pll_step @1457 + nco_crcf_reset @1458 + nco_crcf_set_frequency @1459 + nco_crcf_set_phase @1460 + nco_crcf_sin @1461 + nco_crcf_sincos @1462 + nco_crcf_step @1463 + ofdmflexframegen_assemble @1464 + ofdmflexframegen_create @1465 + ofdmflexframegen_destroy @1466 + ofdmflexframegen_encode_header @1467 + ofdmflexframegen_getframelen @1468 + ofdmflexframegen_getprops @1469 + ofdmflexframegen_is_assembled @1470 + ofdmflexframegen_modulate_header @1471 + ofdmflexframegen_print @1472 + ofdmflexframegen_reconfigure @1473 + ofdmflexframegen_reset @1474 + ofdmflexframegen_setprops @1475 + ofdmflexframegen_write_S0a @1476 + ofdmflexframegen_write_S0b @1477 + ofdmflexframegen_write_S1 @1478 + ofdmflexframegen_write_header @1479 + ofdmflexframegen_write_payload @1480 + ofdmflexframegen_writesymbol @1481 + ofdmflexframegenprops_init_default @1482 + ofdmflexframesync_create @1483 + ofdmflexframesync_debug_disable @1484 + ofdmflexframesync_debug_enable @1485 + ofdmflexframesync_debug_print @1486 + ofdmflexframesync_decode_header @1487 + ofdmflexframesync_destroy @1488 + ofdmflexframesync_execute @1489 + ofdmflexframesync_get_cfo @1490 + ofdmflexframesync_get_rssi @1491 + ofdmflexframesync_internal_callback @1492 + ofdmflexframesync_print @1493 + ofdmflexframesync_reset @1494 + ofdmflexframesync_rxheader @1495 + ofdmflexframesync_rxpayload @1496 + ofdmframe_init_S0 @1497 + ofdmframe_init_S1 @1498 + ofdmframe_init_default_sctype @1499 + ofdmframe_print_sctype @1500 + ofdmframe_validate_sctype @1501 + ofdmframegen_create @1502 + ofdmframegen_destroy @1503 + ofdmframegen_gensymbol @1504 + ofdmframegen_print @1505 + ofdmframegen_reset @1506 + ofdmframegen_write_S0a @1507 + ofdmframegen_write_S0b @1508 + ofdmframegen_write_S1 @1509 + ofdmframegen_writesymbol @1510 + ofdmframegen_writetail @1511 + ofdmframesync_S0_metrics @1512 + ofdmframesync_create @1513 + ofdmframesync_debug_disable @1514 + ofdmframesync_debug_enable @1515 + ofdmframesync_debug_print @1516 + ofdmframesync_destroy @1517 + ofdmframesync_estimate_eqgain @1518 + ofdmframesync_estimate_eqgain_poly @1519 + ofdmframesync_estimate_gain_S0 @1520 + ofdmframesync_estimate_gain_S1 @1521 + ofdmframesync_execute @1522 + ofdmframesync_execute_S0a @1523 + ofdmframesync_execute_S0b @1524 + ofdmframesync_execute_S1 @1525 + ofdmframesync_execute_rxsymbols @1526 + ofdmframesync_execute_seekplcp @1527 + ofdmframesync_get_cfo @1528 + ofdmframesync_get_rssi @1529 + ofdmframesync_print @1530 + ofdmframesync_reset @1531 + ofdmframesync_rxsymbol @1532 + optim_sort @1533 + optim_threshold_switch @1534 + packetizer_compute_dec_msg_len @1535 + packetizer_compute_enc_msg_len @1536 + packetizer_create @1537 + packetizer_decode @1538 + packetizer_decode_soft @1539 + packetizer_destroy @1540 + packetizer_encode @1541 + packetizer_get_dec_msg_len @1542 + packetizer_get_enc_msg_len @1543 + packetizer_print @1544 + packetizer_realloc_buffers @1545 + packetizer_recreate @1546 + packetizer_set_scheme @1547 + poly_expandbinomial @1548 + poly_expandbinomial_pm @1549 + poly_expandroots @1550 + poly_expandroots2 @1551 + poly_findroots @1552 + poly_findroots_bairstow @1553 + poly_findroots_bairstow_recursion @1554 + poly_findroots_durandkerner @1555 + poly_fit @1556 + poly_fit_lagrange @1557 + poly_fit_lagrange_barycentric @1558 + poly_interp_lagrange @1559 + poly_mul @1560 + poly_val @1561 + poly_val_lagrange_barycentric @1562 + polyc_expandbinomial @1563 + polyc_expandbinomial_pm @1564 + polyc_expandroots @1565 + polyc_expandroots2 @1566 + polyc_findroots @1567 + polyc_findroots_bairstow @1568 + polyc_findroots_bairstow_recursion @1569 + polyc_findroots_durandkerner @1570 + polyc_fit @1571 + polyc_fit_lagrange @1572 + polyc_fit_lagrange_barycentric @1573 + polyc_interp_lagrange @1574 + polyc_mul @1575 + polyc_val @1576 + polyc_val_lagrange_barycentric @1577 + polycf_expandbinomial @1578 + polycf_expandbinomial_pm @1579 + polycf_expandroots @1580 + polycf_expandroots2 @1581 + polycf_findroots @1582 + polycf_findroots_bairstow @1583 + polycf_findroots_bairstow_recursion @1584 + polycf_findroots_durandkerner @1585 + polycf_fit @1586 + polycf_fit_lagrange @1587 + polycf_fit_lagrange_barycentric @1588 + polycf_interp_lagrange @1589 + polycf_mul @1590 + polycf_val @1591 + polycf_val_lagrange_barycentric @1592 + polyf_expandbinomial @1593 + polyf_expandbinomial_pm @1594 + polyf_expandroots @1595 + polyf_expandroots2 @1596 + polyf_findroots @1597 + polyf_findroots_bairstow @1598 + polyf_findroots_bairstow_recursion @1599 + polyf_findroots_durandkerner @1600 + polyf_fit @1601 + polyf_fit_lagrange @1602 + polyf_fit_lagrange_barycentric @1603 + polyf_interp_lagrange @1604 + polyf_mul @1605 + polyf_val @1606 + polyf_val_lagrange_barycentric @1607 + presync_cccf_correlate @1608 + presync_cccf_correlatex @1609 + presync_cccf_create @1610 + presync_cccf_destroy @1611 + presync_cccf_print @1612 + presync_cccf_push @1613 + presync_cccf_reset @1614 + qnsearch_compute_Hessian @1615 + qnsearch_compute_gradient @1616 + qnsearch_create @1617 + qnsearch_destroy @1618 + qnsearch_normalize_gradient @1619 + qnsearch_print @1620 + qnsearch_reset @1621 + qnsearch_run @1622 + qnsearch_step @1623 + quantize_adc @1624 + quantize_dac @1625 + quantizercf_create @1626 + quantizercf_destroy @1627 + quantizercf_execute_adc @1628 + quantizercf_execute_dac @1629 + quantizercf_print @1630 + quantizerf_create @1631 + quantizerf_destroy @1632 + quantizerf_execute_adc @1633 + quantizerf_execute_dac @1634 + quantizerf_print @1635 + randexpf @1636 + randexpf_cdf @1637 + randexpf_pdf @1638 + randf @1639 + randf_cdf @1640 + randf_pdf @1641 + randgammaf @1642 + randgammaf_cdf @1643 + randgammaf_delta @1644 + randgammaf_pdf @1645 + randnakmf @1646 + randnakmf_cdf @1647 + randnakmf_pdf @1648 + randnf @1649 + randnf_cdf @1650 + randnf_pdf @1651 + randricekf @1652 + randricekf_cdf @1653 + randricekf_pdf @1654 + randweibf @1655 + randweibf_cdf @1656 + randweibf_pdf @1657 + resamp2_cccf_analyzer_execute @1658 + resamp2_cccf_clear @1659 + resamp2_cccf_create @1660 + resamp2_cccf_decim_execute @1661 + resamp2_cccf_destroy @1662 + resamp2_cccf_filter_execute @1663 + resamp2_cccf_get_delay @1664 + resamp2_cccf_interp_execute @1665 + resamp2_cccf_print @1666 + resamp2_cccf_recreate @1667 + resamp2_cccf_synthesizer_execute @1668 + resamp2_crcf_analyzer_execute @1669 + resamp2_crcf_clear @1670 + resamp2_crcf_create @1671 + resamp2_crcf_decim_execute @1672 + resamp2_crcf_destroy @1673 + resamp2_crcf_filter_execute @1674 + resamp2_crcf_get_delay @1675 + resamp2_crcf_interp_execute @1676 + resamp2_crcf_print @1677 + resamp2_crcf_recreate @1678 + resamp2_crcf_synthesizer_execute @1679 + resamp2_rrrf_analyzer_execute @1680 + resamp2_rrrf_clear @1681 + resamp2_rrrf_create @1682 + resamp2_rrrf_decim_execute @1683 + resamp2_rrrf_destroy @1684 + resamp2_rrrf_filter_execute @1685 + resamp2_rrrf_get_delay @1686 + resamp2_rrrf_interp_execute @1687 + resamp2_rrrf_print @1688 + resamp2_rrrf_recreate @1689 + resamp2_rrrf_synthesizer_execute @1690 + resamp_cccf_create @1691 + resamp_cccf_destroy @1692 + resamp_cccf_execute @1693 + resamp_cccf_execute_block @1694 + resamp_cccf_get_delay @1695 + resamp_cccf_print @1696 + resamp_cccf_reset @1697 + resamp_cccf_setrate @1698 + resamp_cccf_update_timing_state @1699 + resamp_crcf_create @1700 + resamp_crcf_destroy @1701 + resamp_crcf_execute @1702 + resamp_crcf_execute_block @1703 + resamp_crcf_get_delay @1704 + resamp_crcf_print @1705 + resamp_crcf_reset @1706 + resamp_crcf_setrate @1707 + resamp_crcf_update_timing_state @1708 + resamp_rrrf_create @1709 + resamp_rrrf_destroy @1710 + resamp_rrrf_execute @1711 + resamp_rrrf_execute_block @1712 + resamp_rrrf_get_delay @1713 + resamp_rrrf_print @1714 + resamp_rrrf_reset @1715 + resamp_rrrf_setrate @1716 + resamp_rrrf_update_timing_state @1717 + rkaiser_approximate_rho @1718 + scramble_data @1719 + secded2216_P @1720 DATA + secded2216_syndrome_w1 @1721 DATA + secded3932_P @1722 DATA + secded3932_syndrome_w1 @1723 DATA + secded7264_P @1724 DATA + secded7264_syndrome_w1 @1725 DATA + sincf @1726 + smatrix_indexsearch @1727 + smatrixb_clear @1728 + smatrixb_create @1729 + smatrixb_create_array @1730 + smatrixb_delete @1731 + smatrixb_destroy @1732 + smatrixb_eye @1733 + smatrixb_get @1734 + smatrixb_insert @1735 + smatrixb_isset @1736 + smatrixb_mul @1737 + smatrixb_mulf @1738 + smatrixb_print @1739 + smatrixb_print_expanded @1740 + smatrixb_reset @1741 + smatrixb_reset_max_mlist @1742 + smatrixb_reset_max_nlist @1743 + smatrixb_set @1744 + smatrixb_size @1745 + smatrixb_vmul @1746 + smatrixb_vmulf @1747 + smatrixf_clear @1748 + smatrixf_create @1749 + smatrixf_create_array @1750 + smatrixf_delete @1751 + smatrixf_destroy @1752 + smatrixf_eye @1753 + smatrixf_get @1754 + smatrixf_insert @1755 + smatrixf_isset @1756 + smatrixf_mul @1757 + smatrixf_print @1758 + smatrixf_print_expanded @1759 + smatrixf_reset @1760 + smatrixf_reset_max_mlist @1761 + smatrixf_reset_max_nlist @1762 + smatrixf_set @1763 + smatrixf_size @1764 + smatrixf_vmul @1765 + smatrixi_clear @1766 + smatrixi_create @1767 + smatrixi_create_array @1768 + smatrixi_delete @1769 + smatrixi_destroy @1770 + smatrixi_eye @1771 + smatrixi_get @1772 + smatrixi_insert @1773 + smatrixi_isset @1774 + smatrixi_mul @1775 + smatrixi_print @1776 + smatrixi_print_expanded @1777 + smatrixi_reset @1778 + smatrixi_reset_max_mlist @1779 + smatrixi_reset_max_nlist @1780 + smatrixi_set @1781 + smatrixi_size @1782 + smatrixi_vmul @1783 + spgramcf_accumulate_psd @1784 + spgramcf_create @1785 + spgramcf_create_kaiser @1786 + spgramcf_destroy @1787 + spgramcf_estimate_psd @1788 + spgramcf_execute @1789 + spgramcf_push @1790 + spgramcf_reset @1791 + spgramcf_write_accumulation @1792 + spgramf_accumulate_psd @1793 + spgramf_create @1794 + spgramf_create_kaiser @1795 + spgramf_destroy @1796 + spgramf_estimate_psd @1797 + spgramf_execute @1798 + spgramf_push @1799 + spgramf_reset @1800 + spgramf_write_accumulation @1801 + sumproduct_phi @1802 + symsync_crcf_advance_internal_loop @1803 + symsync_crcf_create @1804 + symsync_crcf_create_kaiser @1805 + symsync_crcf_create_rnyquist @1806 + symsync_crcf_destroy @1807 + symsync_crcf_execute @1808 + symsync_crcf_get_tau @1809 + symsync_crcf_lock @1810 + symsync_crcf_output_debug_file @1811 + symsync_crcf_print @1812 + symsync_crcf_reset @1813 + symsync_crcf_set_lf_bw @1814 + symsync_crcf_set_output_rate @1815 + symsync_crcf_setrate @1816 + symsync_crcf_step @1817 + symsync_crcf_unlock @1818 + symsync_rrrf_advance_internal_loop @1819 + symsync_rrrf_create @1820 + symsync_rrrf_create_kaiser @1821 + symsync_rrrf_create_rnyquist @1822 + symsync_rrrf_destroy @1823 + symsync_rrrf_execute @1824 + symsync_rrrf_get_tau @1825 + symsync_rrrf_lock @1826 + symsync_rrrf_output_debug_file @1827 + symsync_rrrf_print @1828 + symsync_rrrf_reset @1829 + symsync_rrrf_set_lf_bw @1830 + symsync_rrrf_set_output_rate @1831 + symsync_rrrf_setrate @1832 + symsync_rrrf_step @1833 + symsync_rrrf_unlock @1834 + unscramble_data @1835 + unscramble_data_soft @1836 + wdelaycf_clear @1837 + wdelaycf_create @1838 + wdelaycf_destroy @1839 + wdelaycf_print @1840 + wdelaycf_push @1841 + wdelaycf_read @1842 + wdelaycf_recreate @1843 + wdelayf_clear @1844 + wdelayf_create @1845 + wdelayf_destroy @1846 + wdelayf_print @1847 + wdelayf_push @1848 + wdelayf_read @1849 + wdelayf_recreate @1850 + windowcf_clear @1851 + windowcf_create @1852 + windowcf_debug_print @1853 + windowcf_destroy @1854 + windowcf_index @1855 + windowcf_print @1856 + windowcf_push @1857 + windowcf_read @1858 + windowcf_recreate @1859 + windowcf_write @1860 + windowf_clear @1861 + windowf_create @1862 + windowf_debug_print @1863 + windowf_destroy @1864 + windowf_index @1865 + windowf_print @1866 + windowf_push @1867 + windowf_read @1868 + windowf_recreate @1869 + windowf_write @1870 diff --git a/external/liquid-dsp/lib/libliquid.dll b/external/liquid-dsp/lib/libliquid.dll new file mode 100644 index 0000000..84dbf2d Binary files /dev/null and b/external/liquid-dsp/lib/libliquid.dll differ diff --git a/external/portaudio/LICENSE.txt b/external/portaudio/LICENSE.txt new file mode 100644 index 0000000..e0ac4e8 --- /dev/null +++ b/external/portaudio/LICENSE.txt @@ -0,0 +1,81 @@ +Portable header file to contain: +>>>>> +/* + * PortAudio Portable Real-Time Audio Library + * PortAudio API Header File + * Latest version available at: http://www.portaudio.com + * + * Copyright (c) 1999-2006 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ +<<<<< + + +Implementation files to contain: +>>>>> +/* + * PortAudio Portable Real-Time Audio Library + * Latest version at: http://www.portaudio.com + * Implementation + * Copyright (c) 1999-2000 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ +<<<<< \ No newline at end of file diff --git a/external/portaudio/include/pa_allocation.h b/external/portaudio/include/pa_allocation.h new file mode 100644 index 0000000..811dd72 --- /dev/null +++ b/external/portaudio/include/pa_allocation.h @@ -0,0 +1,104 @@ +#ifndef PA_ALLOCATION_H +#define PA_ALLOCATION_H +/* + * $Id: pa_allocation.h 1339 2008-02-15 07:50:33Z rossb $ + * Portable Audio I/O Library allocation context header + * memory allocation context for tracking allocation groups + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2008 Ross Bencina, Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Allocation Group prototypes. An Allocation Group makes it easy to + allocate multiple blocks of memory and free them all at once. + + An allocation group is useful for keeping track of multiple blocks + of memory which are allocated at the same time (such as during initialization) + and need to be deallocated at the same time. The allocation group maintains + a list of allocated blocks, and can free all allocations at once. This + can be usefull for cleaning up after a partially initialized object fails. + + The allocation group implementation is built on top of the lower + level allocation functions defined in pa_util.h +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +typedef struct +{ + long linkCount; + struct PaUtilAllocationGroupLink *linkBlocks; + struct PaUtilAllocationGroupLink *spareLinks; + struct PaUtilAllocationGroupLink *allocations; +}PaUtilAllocationGroup; + + + +/** Create an allocation group. +*/ +PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void ); + +/** Destroy an allocation group, but not the memory allocated through the group. +*/ +void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group ); + +/** Allocate a block of memory though an allocation group. +*/ +void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size ); + +/** Free a block of memory that was previously allocated though an allocation + group. Calling this function is a relatively time consuming operation. + Under normal circumstances clients should call PaUtil_FreeAllAllocations to + free all allocated blocks simultaneously. + @see PaUtil_FreeAllAllocations +*/ +void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer ); + +/** Free all blocks of memory which have been allocated through the allocation + group. This function doesn't destroy the group itself. +*/ +void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group ); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_ALLOCATION_H */ diff --git a/external/portaudio/include/pa_asio.h b/external/portaudio/include/pa_asio.h new file mode 100644 index 0000000..8f4624e --- /dev/null +++ b/external/portaudio/include/pa_asio.h @@ -0,0 +1,150 @@ +#ifndef PA_ASIO_H +#define PA_ASIO_H +/* + * $Id: pa_asio.h 1667 2011-05-02 15:49:20Z rossb $ + * PortAudio Portable Real-Time Audio Library + * ASIO specific extensions + * + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + + +/** @file + @ingroup public_header + @brief ASIO-specific PortAudio API extension header file. +*/ + +#include "portaudio.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/** Retrieve legal native buffer sizes for the specificed device, in sample frames. + + @param device The global index of the device about which the query is being made. + @param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value. + @param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value. + @param preferredBufferSizeFrames A pointer to the location which will receive the preferred buffer size value. + @param granularity A pointer to the location which will receive the "granularity". This value determines + the step size used to compute the legal values between minBufferSizeFrames and maxBufferSizeFrames. + If granularity is -1 then available buffer size values are powers of two. + + @see ASIOGetBufferSize in the ASIO SDK. + + @note: this function used to be called PaAsio_GetAvailableLatencyValues. There is a + #define that maps PaAsio_GetAvailableLatencyValues to this function for backwards compatibility. +*/ +PaError PaAsio_GetAvailableBufferSizes( PaDeviceIndex device, + long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity ); + + +/** Backwards compatibility alias for PaAsio_GetAvailableBufferSizes + + @see PaAsio_GetAvailableBufferSizes +*/ +#define PaAsio_GetAvailableLatencyValues PaAsio_GetAvailableBufferSizes + + +/** Display the ASIO control panel for the specified device. + + @param device The global index of the device whose control panel is to be displayed. + @param systemSpecific On Windows, the calling application's main window handle, + on Macintosh this value should be zero. +*/ +PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific ); + + + + +/** Retrieve a pointer to a string containing the name of the specified + input channel. The string is valid until Pa_Terminate is called. + + The string will be no longer than 32 characters including the null terminator. +*/ +PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, + const char** channelName ); + + +/** Retrieve a pointer to a string containing the name of the specified + input channel. The string is valid until Pa_Terminate is called. + + The string will be no longer than 32 characters including the null terminator. +*/ +PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, + const char** channelName ); + + +/** Set the sample rate of an open paASIO stream. + + @param stream The stream to operate on. + @param sampleRate The new sample rate. + + Note that this function may fail if the stream is alredy running and the + ASIO driver does not support switching the sample rate of a running stream. + + Returns paIncompatibleStreamHostApi if stream is not a paASIO stream. +*/ +PaError PaAsio_SetStreamSampleRate( PaStream* stream, double sampleRate ); + + +#define paAsioUseChannelSelectors (0x01) + +typedef struct PaAsioStreamInfo{ + unsigned long size; /**< sizeof(PaAsioStreamInfo) */ + PaHostApiTypeId hostApiType; /**< paASIO */ + unsigned long version; /**< 1 */ + + unsigned long flags; + + /* Support for opening only specific channels of an ASIO device. + If the paAsioUseChannelSelectors flag is set, channelSelectors is a + pointer to an array of integers specifying the device channels to use. + When used, the length of the channelSelectors array must match the + corresponding channelCount parameter to Pa_OpenStream() otherwise a + crash may result. + The values in the selectors array must specify channels within the + range of supported channels for the device or paInvalidChannelCount will + result. + */ + int *channelSelectors; +}PaAsioStreamInfo; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_ASIO_H */ diff --git a/external/portaudio/include/pa_converters.h b/external/portaudio/include/pa_converters.h new file mode 100644 index 0000000..7ddfcaa --- /dev/null +++ b/external/portaudio/include/pa_converters.h @@ -0,0 +1,263 @@ +#ifndef PA_CONVERTERS_H +#define PA_CONVERTERS_H +/* + * $Id: pa_converters.h 1097 2006-08-26 08:27:53Z rossb $ + * Portable Audio I/O Library sample conversion mechanism + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2002 Phil Burk, Ross Bencina + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Conversion functions used to convert buffers of samples from one + format to another. +*/ + + +#include "portaudio.h" /* for PaSampleFormat */ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +struct PaUtilTriangularDitherGenerator; + + +/** Choose an available sample format which is most appropriate for + representing the requested format. If the requested format is not available + higher quality formats are considered before lower quality formates. + @param availableFormats A variable containing the logical OR of all available + formats. + @param format The desired format. + @return The most appropriate available format for representing the requested + format. +*/ +PaSampleFormat PaUtil_SelectClosestAvailableFormat( + PaSampleFormat availableFormats, PaSampleFormat format ); + + +/* high level conversions functions for use by implementations */ + + +/** The generic sample converter prototype. Sample converters convert count + samples from sourceBuffer to destinationBuffer. The actual type of the data + pointed to by these parameters varys for different converter functions. + @param destinationBuffer A pointer to the first sample of the destination. + @param destinationStride An offset between successive destination samples + expressed in samples (not bytes.) It may be negative. + @param sourceBuffer A pointer to the first sample of the source. + @param sourceStride An offset between successive source samples + expressed in samples (not bytes.) It may be negative. + @param count The number of samples to convert. + @param ditherState State information used to calculate dither. Converters + that do not perform dithering will ignore this parameter, in which case + NULL or invalid dither state may be passed. +*/ +typedef void PaUtilConverter( + void *destinationBuffer, signed int destinationStride, + void *sourceBuffer, signed int sourceStride, + unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ); + + +/** Find a sample converter function for the given source and destinations + formats and flags (clip and dither.) + @return + A pointer to a PaUtilConverter which will perform the requested + conversion, or NULL if the given format conversion is not supported. + For conversions where clipping or dithering is not necessary, the + clip and dither flags are ignored and a non-clipping or dithering + version is returned. + If the source and destination formats are the same, a function which + copies data of the appropriate size will be returned. +*/ +PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat, + PaSampleFormat destinationFormat, PaStreamFlags flags ); + + +/** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to + destinationBuffer. The actual type of the data pointed to varys for + different zeroer functions. + @param destinationBuffer A pointer to the first sample of the destination. + @param destinationStride An offset between successive destination samples + expressed in samples (not bytes.) It may be negative. + @param count The number of samples to zero. +*/ +typedef void PaUtilZeroer( + void *destinationBuffer, signed int destinationStride, unsigned int count ); + + +/** Find a buffer zeroer function for the given destination format. + @return + A pointer to a PaUtilZeroer which will perform the requested + zeroing. +*/ +PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat ); + +/*----------------------------------------------------------------------------*/ +/* low level functions and data structures which may be used for + substituting conversion functions */ + + +/** The type used to store all sample conversion functions. + @see paConverters; +*/ +typedef struct{ + PaUtilConverter *Float32_To_Int32; + PaUtilConverter *Float32_To_Int32_Dither; + PaUtilConverter *Float32_To_Int32_Clip; + PaUtilConverter *Float32_To_Int32_DitherClip; + + PaUtilConverter *Float32_To_Int24; + PaUtilConverter *Float32_To_Int24_Dither; + PaUtilConverter *Float32_To_Int24_Clip; + PaUtilConverter *Float32_To_Int24_DitherClip; + + PaUtilConverter *Float32_To_Int16; + PaUtilConverter *Float32_To_Int16_Dither; + PaUtilConverter *Float32_To_Int16_Clip; + PaUtilConverter *Float32_To_Int16_DitherClip; + + PaUtilConverter *Float32_To_Int8; + PaUtilConverter *Float32_To_Int8_Dither; + PaUtilConverter *Float32_To_Int8_Clip; + PaUtilConverter *Float32_To_Int8_DitherClip; + + PaUtilConverter *Float32_To_UInt8; + PaUtilConverter *Float32_To_UInt8_Dither; + PaUtilConverter *Float32_To_UInt8_Clip; + PaUtilConverter *Float32_To_UInt8_DitherClip; + + PaUtilConverter *Int32_To_Float32; + PaUtilConverter *Int32_To_Int24; + PaUtilConverter *Int32_To_Int24_Dither; + PaUtilConverter *Int32_To_Int16; + PaUtilConverter *Int32_To_Int16_Dither; + PaUtilConverter *Int32_To_Int8; + PaUtilConverter *Int32_To_Int8_Dither; + PaUtilConverter *Int32_To_UInt8; + PaUtilConverter *Int32_To_UInt8_Dither; + + PaUtilConverter *Int24_To_Float32; + PaUtilConverter *Int24_To_Int32; + PaUtilConverter *Int24_To_Int16; + PaUtilConverter *Int24_To_Int16_Dither; + PaUtilConverter *Int24_To_Int8; + PaUtilConverter *Int24_To_Int8_Dither; + PaUtilConverter *Int24_To_UInt8; + PaUtilConverter *Int24_To_UInt8_Dither; + + PaUtilConverter *Int16_To_Float32; + PaUtilConverter *Int16_To_Int32; + PaUtilConverter *Int16_To_Int24; + PaUtilConverter *Int16_To_Int8; + PaUtilConverter *Int16_To_Int8_Dither; + PaUtilConverter *Int16_To_UInt8; + PaUtilConverter *Int16_To_UInt8_Dither; + + PaUtilConverter *Int8_To_Float32; + PaUtilConverter *Int8_To_Int32; + PaUtilConverter *Int8_To_Int24; + PaUtilConverter *Int8_To_Int16; + PaUtilConverter *Int8_To_UInt8; + + PaUtilConverter *UInt8_To_Float32; + PaUtilConverter *UInt8_To_Int32; + PaUtilConverter *UInt8_To_Int24; + PaUtilConverter *UInt8_To_Int16; + PaUtilConverter *UInt8_To_Int8; + + PaUtilConverter *Copy_8_To_8; /* copy without any conversion */ + PaUtilConverter *Copy_16_To_16; /* copy without any conversion */ + PaUtilConverter *Copy_24_To_24; /* copy without any conversion */ + PaUtilConverter *Copy_32_To_32; /* copy without any conversion */ +} PaUtilConverterTable; + + +/** A table of pointers to all required converter functions. + PaUtil_SelectConverter() uses this table to lookup the appropriate + conversion functions. The fields of this structure are initialized + with default conversion functions. Fields may be NULL, indicating that + no conversion function is available. User code may substitue optimised + conversion functions by assigning different function pointers to + these fields. + + @note + If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined, + PortAudio's standard converters will not be compiled, and all fields + of this structure will be initialized to NULL. In such cases, users + should supply their own conversion functions if the require PortAudio + to open a stream that requires sample conversion. + + @see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter +*/ +extern PaUtilConverterTable paConverters; + + +/** The type used to store all buffer zeroing functions. + @see paZeroers; +*/ +typedef struct{ + PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */ + PaUtilZeroer *Zero8; + PaUtilZeroer *Zero16; + PaUtilZeroer *Zero24; + PaUtilZeroer *Zero32; +} PaUtilZeroerTable; + + +/** A table of pointers to all required zeroer functions. + PaUtil_SelectZeroer() uses this table to lookup the appropriate + conversion functions. The fields of this structure are initialized + with default conversion functions. User code may substitue optimised + conversion functions by assigning different function pointers to + these fields. + + @note + If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined, + PortAudio's standard zeroers will not be compiled, and all fields + of this structure will be initialized to NULL. In such cases, users + should supply their own zeroing functions for the sample sizes which + they intend to use. + + @see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer +*/ +extern PaUtilZeroerTable paZeroers; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_CONVERTERS_H */ diff --git a/external/portaudio/include/pa_cpuload.h b/external/portaudio/include/pa_cpuload.h new file mode 100644 index 0000000..4a59443 --- /dev/null +++ b/external/portaudio/include/pa_cpuload.h @@ -0,0 +1,72 @@ +#ifndef PA_CPULOAD_H +#define PA_CPULOAD_H +/* + * $Id: pa_cpuload.h 1097 2006-08-26 08:27:53Z rossb $ + * Portable Audio I/O Library CPU Load measurement functions + * Portable CPU load measurement facility. + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 2002 Ross Bencina + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Functions to assist in measuring the CPU utilization of a callback + stream. Used to implement the Pa_GetStreamCpuLoad() function. +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +typedef struct { + double samplingPeriod; + double measurementStartTime; + double averageLoad; +} PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */ + +void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate ); +void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer ); +void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed ); +void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer ); +double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_CPULOAD_H */ diff --git a/external/portaudio/include/pa_debugprint.h b/external/portaudio/include/pa_debugprint.h new file mode 100644 index 0000000..5fba766 --- /dev/null +++ b/external/portaudio/include/pa_debugprint.h @@ -0,0 +1,149 @@ +#ifndef PA_LOG_H +#define PA_LOG_H +/* + * Log file redirector function + * Copyright (c) 1999-2006 Ross Bencina, Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + + +void PaUtil_DebugPrint( const char *format, ... ); + + +/* + The basic format for log messages is described below. If you need to + add any log messages, please follow this format. + + Function entry (void function): + + "FunctionName called.\n" + + Function entry (non void function): + + "FunctionName called:\n" + "\tParam1Type param1: param1Value\n" + "\tParam2Type param2: param2Value\n" (etc...) + + + Function exit (no return value): + + "FunctionName returned.\n" + + Function exit (simple return value): + + "FunctionName returned:\n" + "\tReturnType: returnValue\n" + + If the return type is an error code, the error text is displayed in () + + If the return type is not an error code, but has taken a special value + because an error occurred, then the reason for the error is shown in [] + + If the return type is a struct ptr, the struct is dumped. + + See the code below for examples +*/ + +/** PA_DEBUG() provides a simple debug message printing facility. The macro + passes it's argument to a printf-like function called PaUtil_DebugPrint() + which prints to stderr and always flushes the stream after printing. + Because preprocessor macros cannot directly accept variable length argument + lists, calls to the macro must include an additional set of parenthesis, eg: + PA_DEBUG(("errorno: %d", 1001 )); +*/ + + +#ifdef PA_ENABLE_DEBUG_OUTPUT +#define PA_DEBUG(x) PaUtil_DebugPrint x ; +#else +#define PA_DEBUG(x) +#endif + + +#ifdef PA_LOG_API_CALLS +#define PA_LOGAPI(x) PaUtil_DebugPrint x + +#define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" ) + +#define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" ) + +#define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" ) + +#define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \ + PaUtil_DebugPrint( functionName " returned:\n" ); \ + PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) + +#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \ + PaUtil_DebugPrint( functionName " returned:\n" ); \ + PaUtil_DebugPrint("\t" resultFormatString "\n", result ) + +#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \ + PaUtil_DebugPrint( functionName " returned:\n" ); \ + if( result > 0 ) \ + PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \ + else \ + PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) +#else +#define PA_LOGAPI(x) +#define PA_LOGAPI_ENTER(functionName) +#define PA_LOGAPI_ENTER_PARAMS(functionName) +#define PA_LOGAPI_EXIT(functionName) +#define PA_LOGAPI_EXIT_PAERROR( functionName, result ) +#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) +#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) +#endif + + +typedef void (*PaUtilLogCallback ) (const char *log); + +/** + Install user provided log function +*/ +void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_LOG_H */ diff --git a/external/portaudio/include/pa_dither.h b/external/portaudio/include/pa_dither.h new file mode 100644 index 0000000..a5131b2 --- /dev/null +++ b/external/portaudio/include/pa_dither.h @@ -0,0 +1,106 @@ +#ifndef PA_DITHER_H +#define PA_DITHER_H +/* + * $Id: pa_dither.h 1418 2009-10-12 21:00:53Z philburk $ + * Portable Audio I/O Library triangular dither generator + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2002 Phil Burk, Ross Bencina + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Functions for generating dither noise +*/ + +#include "pa_types.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Note that the linear congruential algorithm requires 32 bit integers + * because it uses arithmetic overflow. So use PaUint32 instead of + * unsigned long so it will work on 64 bit systems. + */ + +/** @brief State needed to generate a dither signal */ +typedef struct PaUtilTriangularDitherGenerator{ + PaUint32 previous; + PaUint32 randSeed1; + PaUint32 randSeed2; +} PaUtilTriangularDitherGenerator; + + +/** @brief Initialize dither state */ +void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState ); + + +/** + @brief Calculate 2 LSB dither signal with a triangular distribution. + Ranged for adding to a 1 bit right-shifted 32 bit integer + prior to >>15. eg: +
+    signed long in = *
+    signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
+    signed short out = (signed short)(((in>>1) + dither) >> 15);
+
+ @return + A signed 32-bit integer with a range of +32767 to -32768 +*/ +PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); + + +/** + @brief Calculate 2 LSB dither signal with a triangular distribution. + Ranged for adding to a pre-scaled float. +
+    float in = *
+    float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
+    // use smaller scaler to prevent overflow when we add the dither
+    signed short out = (signed short)(in*(32766.0f) + dither );
+
+ @return + A float with a range of -2.0 to +1.99999. +*/ +float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_DITHER_H */ diff --git a/external/portaudio/include/pa_endianness.h b/external/portaudio/include/pa_endianness.h new file mode 100644 index 0000000..84e904c --- /dev/null +++ b/external/portaudio/include/pa_endianness.h @@ -0,0 +1,145 @@ +#ifndef PA_ENDIANNESS_H +#define PA_ENDIANNESS_H +/* + * $Id: pa_endianness.h 1324 2008-01-27 02:03:30Z bjornroche $ + * Portable Audio I/O Library current platform endianness macros + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2002 Phil Burk, Ross Bencina + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Configure endianness symbols for the target processor. + + Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols + to be defined. The one that is defined reflects the endianness of the target + platform and may be used to implement conditional compilation of byte-order + dependent code. + + If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt + is made to override that setting. This may be useful if you have a better way + of determining the platform's endianness. The autoconf mechanism uses this for + example. + + A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time + and runtime endiannes and raise an assertion if they don't match. +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* If this is an apple, we need to do detect endianness this way */ +#if defined(__APPLE__) + /* we need to do some endian detection that is sensitive to harware arch */ + #if defined(__LITTLE_ENDIAN__) + #if !defined( PA_LITTLE_ENDIAN ) + #define PA_LITTLE_ENDIAN + #endif + #if defined( PA_BIG_ENDIAN ) + #undef PA_BIG_ENDIAN + #endif + #else + #if !defined( PA_BIG_ENDIAN ) + #define PA_BIG_ENDIAN + #endif + #if defined( PA_LITTLE_ENDIAN ) + #undef PA_LITTLE_ENDIAN + #endif + #endif +#else + /* this is not an apple, so first check the existing defines, and, failing that, + detect well-known architechtures. */ + + #if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN) + /* endianness define has been set externally, such as by autoconf */ + + #if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN) + #error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please + #endif + + #else + /* endianness define has not been set externally */ + + /* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */ + + #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) + #define PA_LITTLE_ENDIAN /* win32, assume intel byte order */ + #else + #define PA_BIG_ENDIAN + #endif + #endif + + #if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN) + /* + If the following error is raised, you either need to modify the code above + to automatically determine the endianness from other symbols defined on your + platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally. + */ + #error pa_endianness.h was unable to automatically determine the endianness of the target platform + #endif + +#endif + + +/* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness, + and raises an assertion if they don't match. must be included in + the context in which this macro is used. +*/ +#if defined(NDEBUG) + #define PA_VALIDATE_ENDIANNESS +#else + #if defined(PA_LITTLE_ENDIAN) + #define PA_VALIDATE_ENDIANNESS \ + { \ + const long nativeOne = 1; \ + assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \ + } + #elif defined(PA_BIG_ENDIAN) + #define PA_VALIDATE_ENDIANNESS \ + { \ + const long nativeOne = 1; \ + assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \ + } + #endif +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_ENDIANNESS_H */ diff --git a/external/portaudio/include/pa_hostapi.h b/external/portaudio/include/pa_hostapi.h new file mode 100644 index 0000000..d38b8fe --- /dev/null +++ b/external/portaudio/include/pa_hostapi.h @@ -0,0 +1,362 @@ +#ifndef PA_HOSTAPI_H +#define PA_HOSTAPI_H +/* + * $Id: pa_hostapi.h 1880 2012-12-04 18:39:48Z rbencina $ + * Portable Audio I/O Library + * host api representation + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2008 Ross Bencina, Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Interfaces and representation structures used by pa_front.c + to manage and communicate with host API implementations. +*/ + +#include "portaudio.h" + +/** +The PA_NO_* host API macros are now deprecated in favor of PA_USE_* macros. +PA_USE_* indicates whether a particular host API will be initialized by PortAudio. +An undefined or 0 value indicates that the host API will not be used. A value of 1 +indicates that the host API will be used. PA_USE_* macros should be left undefined +or defined to either 0 or 1. + +The code below ensures that PA_USE_* macros are always defined and have value +0 or 1. Undefined symbols are defaulted to 0. Symbols that are neither 0 nor 1 +are defaulted to 1. +*/ + +#ifndef PA_USE_SKELETON +#define PA_USE_SKELETON 0 +#elif (PA_USE_SKELETON != 0) && (PA_USE_SKELETON != 1) +#undef PA_USE_SKELETON +#define PA_USE_SKELETON 1 +#endif + +#if defined(PA_NO_ASIO) || defined(PA_NO_DS) || defined(PA_NO_WMME) || defined(PA_NO_WASAPI) || defined(PA_NO_WDMKS) +#error "Portaudio: PA_NO_ is no longer supported, please remove definition and use PA_USE_ instead" +#endif + +#ifndef PA_USE_ASIO +#define PA_USE_ASIO 0 +#elif (PA_USE_ASIO != 0) && (PA_USE_ASIO != 1) +#undef PA_USE_ASIO +#define PA_USE_ASIO 1 +#endif + +#ifndef PA_USE_DS +#define PA_USE_DS 0 +#elif (PA_USE_DS != 0) && (PA_USE_DS != 1) +#undef PA_USE_DS +#define PA_USE_DS 1 +#endif + +#ifndef PA_USE_WMME +#define PA_USE_WMME 0 +#elif (PA_USE_WMME != 0) && (PA_USE_WMME != 1) +#undef PA_USE_WMME +#define PA_USE_WMME 1 +#endif + +#ifndef PA_USE_WASAPI +#define PA_USE_WASAPI 0 +#elif (PA_USE_WASAPI != 0) && (PA_USE_WASAPI != 1) +#undef PA_USE_WASAPI +#define PA_USE_WASAPI 1 +#endif + +#ifndef PA_USE_WDMKS +#define PA_USE_WDMKS 0 +#elif (PA_USE_WDMKS != 0) && (PA_USE_WDMKS != 1) +#undef PA_USE_WDMKS +#define PA_USE_WDMKS 1 +#endif + +/* Set default values for Unix based APIs. */ +#if defined(PA_NO_OSS) || defined(PA_NO_ALSA) || defined(PA_NO_JACK) || defined(PA_NO_COREAUDIO) || defined(PA_NO_SGI) || defined(PA_NO_ASIHPI) +#error "Portaudio: PA_NO_ is no longer supported, please remove definition and use PA_USE_ instead" +#endif + +#ifndef PA_USE_OSS +#define PA_USE_OSS 0 +#elif (PA_USE_OSS != 0) && (PA_USE_OSS != 1) +#undef PA_USE_OSS +#define PA_USE_OSS 1 +#endif + +#ifndef PA_USE_ALSA +#define PA_USE_ALSA 0 +#elif (PA_USE_ALSA != 0) && (PA_USE_ALSA != 1) +#undef PA_USE_ALSA +#define PA_USE_ALSA 1 +#endif + +#ifndef PA_USE_JACK +#define PA_USE_JACK 0 +#elif (PA_USE_JACK != 0) && (PA_USE_JACK != 1) +#undef PA_USE_JACK +#define PA_USE_JACK 1 +#endif + +#ifndef PA_USE_SGI +#define PA_USE_SGI 0 +#elif (PA_USE_SGI != 0) && (PA_USE_SGI != 1) +#undef PA_USE_SGI +#define PA_USE_SGI 1 +#endif + +#ifndef PA_USE_COREAUDIO +#define PA_USE_COREAUDIO 0 +#elif (PA_USE_COREAUDIO != 0) && (PA_USE_COREAUDIO != 1) +#undef PA_USE_COREAUDIO +#define PA_USE_COREAUDIO 1 +#endif + +#ifndef PA_USE_ASIHPI +#define PA_USE_ASIHPI 0 +#elif (PA_USE_ASIHPI != 0) && (PA_USE_ASIHPI != 1) +#undef PA_USE_ASIHPI +#define PA_USE_ASIHPI 1 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/** **FOR THE USE OF pa_front.c ONLY** + Do NOT use fields in this structure, they my change at any time. + Use functions defined in pa_util.h if you think you need functionality + which can be derived from here. +*/ +typedef struct PaUtilPrivatePaFrontHostApiInfo { + + + unsigned long baseDeviceIndex; +}PaUtilPrivatePaFrontHostApiInfo; + + +/** The common header for all data structures whose pointers are passed through + the hostApiSpecificStreamInfo field of the PaStreamParameters structure. + Note that in order to keep the public PortAudio interface clean, this structure + is not used explicitly when declaring hostApiSpecificStreamInfo data structures. + However, some code in pa_front depends on the first 3 members being equivalent + with this structure. + @see PaStreamParameters +*/ +typedef struct PaUtilHostApiSpecificStreamInfoHeader +{ + unsigned long size; /**< size of whole structure including this header */ + PaHostApiTypeId hostApiType; /**< host API for which this data is intended */ + unsigned long version; /**< structure version */ +} PaUtilHostApiSpecificStreamInfoHeader; + + + +/** A structure representing the interface to a host API. Contains both + concrete data and pointers to functions which implement the interface. +*/ +typedef struct PaUtilHostApiRepresentation { + PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo; + + /** The host api implementation should populate the info field. In the + case of info.defaultInputDevice and info.defaultOutputDevice the + values stored should be 0 based indices within the host api's own + device index range (0 to deviceCount). These values will be converted + to global device indices by pa_front after PaUtilHostApiInitializer() + returns. + */ + PaHostApiInfo info; + + PaDeviceInfo** deviceInfos; + + /** + (*Terminate)() is guaranteed to be called with a valid + parameter, which was previously returned from the same implementation's + initializer. + */ + void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi ); + + /** + The inputParameters and outputParameters pointers should not be saved + as they will not remain valid after OpenStream is called. + + + The following guarantees are made about parameters to (*OpenStream)(): + + [NOTE: the following list up to *END PA FRONT VALIDATIONS* should be + kept in sync with the one for ValidateOpenStreamParameters and + Pa_OpenStream in pa_front.c] + + PaHostApiRepresentation *hostApi + - is valid for this implementation + + PaStream** stream + - is non-null + + - at least one of inputParameters & outputParmeters is valid (not NULL) + + - if inputParameters & outputParmeters are both valid, that + inputParameters->device & outputParmeters->device both use the same host api + + PaDeviceIndex inputParameters->device + - is within range (0 to Pa_CountDevices-1) Or: + - is paUseHostApiSpecificDeviceSpecification and + inputParameters->hostApiSpecificStreamInfo is non-NULL and refers + to a valid host api + + int inputParameters->numChannels + - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0 + - upper bound is NOT validated against device capabilities + + PaSampleFormat inputParameters->sampleFormat + - is one of the sample formats defined in portaudio.h + + void *inputParameters->hostApiSpecificStreamInfo + - if supplied its hostApi field matches the input device's host Api + + PaDeviceIndex outputParmeters->device + - is within range (0 to Pa_CountDevices-1) + + int outputParmeters->numChannels + - if inputDevice is valid, numInputChannels is > 0 + - upper bound is NOT validated against device capabilities + + PaSampleFormat outputParmeters->sampleFormat + - is one of the sample formats defined in portaudio.h + + void *outputParmeters->hostApiSpecificStreamInfo + - if supplied its hostApi field matches the output device's host Api + + double sampleRate + - is not an 'absurd' rate (less than 1000. or greater than 384000.) + - sampleRate is NOT validated against device capabilities + + PaStreamFlags streamFlags + - unused platform neutral flags are zero + - paNeverDropInput is only used for full-duplex callback streams + with variable buffer size (paFramesPerBufferUnspecified) + + [*END PA FRONT VALIDATIONS*] + + + The following validations MUST be performed by (*OpenStream)(): + + - check that input device can support numInputChannels + + - check that input device can support inputSampleFormat, or that + we have the capability to convert from outputSampleFormat to + a native format + + - if inputStreamInfo is supplied, validate its contents, + or return an error if no inputStreamInfo is expected + + - check that output device can support numOutputChannels + + - check that output device can support outputSampleFormat, or that + we have the capability to convert from outputSampleFormat to + a native format + + - if outputStreamInfo is supplied, validate its contents, + or return an error if no outputStreamInfo is expected + + - if a full duplex stream is requested, check that the combination + of input and output parameters is supported + + - check that the device supports sampleRate + + - alter sampleRate to a close allowable rate if necessary + + - validate inputLatency and outputLatency + + - validate any platform specific flags, if flags are supplied they + must be valid. + */ + PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi, + PaStream** stream, + const PaStreamParameters *inputParameters, + const PaStreamParameters *outputParameters, + double sampleRate, + unsigned long framesPerCallback, + PaStreamFlags streamFlags, + PaStreamCallback *streamCallback, + void *userData ); + + + PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi, + const PaStreamParameters *inputParameters, + const PaStreamParameters *outputParameters, + double sampleRate ); +} PaUtilHostApiRepresentation; + + +/** Prototype for the initialization function which must be implemented by every + host API. + + This function should only return an error other than paNoError if it encounters + an unexpected and fatal error (memory allocation error for example). In general, + there may be conditions under which it returns a NULL interface pointer and also + returns paNoError. For example, if the ASIO implementation detects that ASIO is + not installed, it should return a NULL interface, and paNoError. + + @see paHostApiInitializers +*/ +typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex ); + + +/** paHostApiInitializers is a NULL-terminated array of host API initialization + functions. These functions are called by pa_front.c to initialize the host APIs + when the client calls Pa_Initialize(). + + The initialization functions are invoked in order. + + The first successfully initialized host API that has a default input *or* output + device is used as the default PortAudio host API. This is based on the logic that + there is only one default host API, and it must contain the default input and output + devices (if defined). + + There is a platform specific file that defines paHostApiInitializers for that + platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example. +*/ +extern PaUtilHostApiInitializer *paHostApiInitializers[]; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_HOSTAPI_H */ diff --git a/external/portaudio/include/pa_jack.h b/external/portaudio/include/pa_jack.h new file mode 100644 index 0000000..99ef833 --- /dev/null +++ b/external/portaudio/include/pa_jack.h @@ -0,0 +1,77 @@ +#ifndef PA_JACK_H +#define PA_JACK_H + +/* + * $Id: + * PortAudio Portable Real-Time Audio Library + * JACK-specific extensions + * + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + * @ingroup public_header + * @brief JACK-specific PortAudio API extension header file. + */ + +#include "portaudio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Set the JACK client name. + * + * During Pa_Initialize, When PA JACK connects as a client of the JACK server, it requests a certain + * name, which is for instance prepended to port names. By default this name is "PortAudio". The + * JACK server may append a suffix to the client name, in order to avoid clashes among clients that + * try to connect with the same name (e.g., different PA JACK clients). + * + * This function must be called before Pa_Initialize, otherwise it won't have any effect. Note that + * the string is not copied, but instead referenced directly, so it must not be freed for as long as + * PA might need it. + * @sa PaJack_GetClientName + */ +PaError PaJack_SetClientName( const char* name ); + +/** Get the JACK client name used by PA JACK. + * + * The caller is responsible for freeing the returned pointer. + */ +PaError PaJack_GetClientName(const char** clientName); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/portaudio/include/pa_linux_alsa.h b/external/portaudio/include/pa_linux_alsa.h new file mode 100644 index 0000000..21627bd --- /dev/null +++ b/external/portaudio/include/pa_linux_alsa.h @@ -0,0 +1,107 @@ +#ifndef PA_LINUX_ALSA_H +#define PA_LINUX_ALSA_H + +/* + * $Id: pa_linux_alsa.h 1597 2011-02-11 00:15:51Z dmitrykos $ + * PortAudio Portable Real-Time Audio Library + * ALSA-specific extensions + * + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + * @ingroup public_header + * @brief ALSA-specific PortAudio API extension header file. + */ + +#include "portaudio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PaAlsaStreamInfo +{ + unsigned long size; + PaHostApiTypeId hostApiType; + unsigned long version; + + const char *deviceString; +} +PaAlsaStreamInfo; + +/** Initialize host API specific structure, call this before setting relevant attributes. */ +void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info ); + +/** Instruct whether to enable real-time priority when starting the audio thread. + * + * If this is turned on by the stream is started, the audio callback thread will be created + * with the FIFO scheduling policy, which is suitable for realtime operation. + **/ +void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable ); + +#if 0 +void PaAlsa_EnableWatchdog( PaStream *s, int enable ); +#endif + +/** Get the ALSA-lib card index of this stream's input device. */ +PaError PaAlsa_GetStreamInputCard( PaStream *s, int *card ); + +/** Get the ALSA-lib card index of this stream's output device. */ +PaError PaAlsa_GetStreamOutputCard( PaStream *s, int *card ); + +/** Set the number of periods (buffer fragments) to configure devices with. + * + * By default the number of periods is 4, this is the lowest number of periods that works well on + * the author's soundcard. + * @param numPeriods The number of periods. + */ +PaError PaAlsa_SetNumPeriods( int numPeriods ); + +/** Set the maximum number of times to retry opening busy device (sleeping for a + * short interval inbetween). + */ +PaError PaAlsa_SetRetriesBusy( int retries ); + +/** Set the path and name of ALSA library file if PortAudio is configured to load it dynamically (see + * PA_ALSA_DYNAMIC). This setting will overwrite the default name set by PA_ALSA_PATHNAME define. + * @param pathName Full path with filename. Only filename can be used, but dlopen() will lookup default + * searchable directories (/usr/lib;/usr/local/lib) then. + */ +void PaAlsa_SetLibraryPathName( const char *pathName ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/portaudio/include/pa_mac_core.h b/external/portaudio/include/pa_mac_core.h new file mode 100644 index 0000000..83e40a6 --- /dev/null +++ b/external/portaudio/include/pa_mac_core.h @@ -0,0 +1,191 @@ +#ifndef PA_MAC_CORE_H +#define PA_MAC_CORE_H +/* + * PortAudio Portable Real-Time Audio Library + * Macintosh Core Audio specific extensions + * portaudio.h should be included before this file. + * + * Copyright (c) 2005-2006 Bjorn Roche + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + * @ingroup public_header + * @brief CoreAudio-specific PortAudio API extension header file. + */ + +#include "portaudio.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * A pointer to a paMacCoreStreamInfo may be passed as + * the hostApiSpecificStreamInfo in the PaStreamParameters struct + * when opening a stream or querying the format. Use NULL, for the + * defaults. Note that for duplex streams, flags for input and output + * should be the same or behaviour is undefined. + */ +typedef struct +{ + unsigned long size; /**size of whole structure including this header */ + PaHostApiTypeId hostApiType; /**host API for which this data is intended */ + unsigned long version; /**structure version */ + unsigned long flags; /** flags to modify behaviour */ + SInt32 const * channelMap; /** Channel map for HAL channel mapping , if not needed, use NULL;*/ + unsigned long channelMapSize; /** Channel map size for HAL channel mapping , if not needed, use 0;*/ +} PaMacCoreStreamInfo; + +/** + * Functions + */ + + +/** Use this function to initialize a paMacCoreStreamInfo struct + * using the requested flags. Note that channel mapping is turned + * off after a call to this function. + * @param data The datastructure to initialize + * @param flags The flags to initialize the datastructure with. +*/ +void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, unsigned long flags ); + +/** call this after pa_SetupMacCoreStreamInfo to use channel mapping as described in notes.txt. + * @param data The stream info structure to assign a channel mapping to + * @param channelMap The channel map array, as described in notes.txt. This array pointer will be used directly (ie the underlying data will not be copied), so the caller should not free the array until after the stream has been opened. + * @param channelMapSize The size of the channel map array. + */ +void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, unsigned long channelMapSize ); + +/** + * Retrieve the AudioDeviceID of the input device assigned to an open stream + * + * @param s The stream to query. + * + * @return A valid AudioDeviceID, or NULL if an error occurred. + */ +AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s ); + +/** + * Retrieve the AudioDeviceID of the output device assigned to an open stream + * + * @param s The stream to query. + * + * @return A valid AudioDeviceID, or NULL if an error occurred. + */ +AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s ); + +/** + * Returns a statically allocated string with the device's name + * for the given channel. NULL will be returned on failure. + * + * This function's implemenation is not complete! + * + * @param device The PortAudio device index. + * @param channel The channel number who's name is requested. + * @return a statically allocated string with the name of the device. + * Because this string is statically allocated, it must be + * coppied if it is to be saved and used by the user after + * another call to this function. + * + */ +const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ); + + +/** Retrieve the range of legal native buffer sizes for the specificed device, in sample frames. + + @param device The global index of the PortAudio device about which the query is being made. + @param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value. + @param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value. + + @see kAudioDevicePropertyBufferFrameSizeRange in the CoreAudio SDK. + */ +PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device, + long *minBufferSizeFrames, long *maxBufferSizeFrames ); + + +/** + * Flags + */ + +/** + * The following flags alter the behaviour of PA on the mac platform. + * they can be ORed together. These should work both for opening and + * checking a device. + */ + +/** Allows PortAudio to change things like the device's frame size, + * which allows for much lower latency, but might disrupt the device + * if other programs are using it, even when you are just Querying + * the device. */ +#define paMacCoreChangeDeviceParameters (0x01) + +/** In combination with the above flag, + * causes the stream opening to fail, unless the exact sample rates + * are supported by the device. */ +#define paMacCoreFailIfConversionRequired (0x02) + +/** These flags set the SR conversion quality, if required. The wierd ordering + * allows Maximum Quality to be the default.*/ +#define paMacCoreConversionQualityMin (0x0100) +#define paMacCoreConversionQualityMedium (0x0200) +#define paMacCoreConversionQualityLow (0x0300) +#define paMacCoreConversionQualityHigh (0x0400) +#define paMacCoreConversionQualityMax (0x0000) + +/** + * Here are some "preset" combinations of flags (above) to get to some + * common configurations. THIS IS OVERKILL, but if more flags are added + * it won't be. + */ + +/**This is the default setting: do as much sample rate conversion as possible + * and as little mucking with the device as possible. */ +#define paMacCorePlayNice (0x00) +/**This setting is tuned for pro audio apps. It allows SR conversion on input + and output, but it tries to set the appropriate SR on the device.*/ +#define paMacCorePro (0x01) +/**This is a setting to minimize CPU usage and still play nice.*/ +#define paMacCoreMinimizeCPUButPlayNice (0x0100) +/**This is a setting to minimize CPU usage, even if that means interrupting the device. */ +#define paMacCoreMinimizeCPU (0x0101) + + +#ifdef __cplusplus +} +#endif /** __cplusplus */ + +#endif /** PA_MAC_CORE_H */ diff --git a/external/portaudio/include/pa_memorybarrier.h b/external/portaudio/include/pa_memorybarrier.h new file mode 100644 index 0000000..2879ce3 --- /dev/null +++ b/external/portaudio/include/pa_memorybarrier.h @@ -0,0 +1,128 @@ +/* + * $Id: pa_memorybarrier.h 1240 2007-07-17 13:05:07Z bjornroche $ + * Portable Audio I/O Library + * Memory barrier utilities + * + * Author: Bjorn Roche, XO Audio, LLC + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** + @file pa_memorybarrier.h + @ingroup common_src +*/ + +/**************** + * Some memory barrier primitives based on the system. + * right now only OS X, FreeBSD, and Linux are supported. In addition to providing + * memory barriers, these functions should ensure that data cached in registers + * is written out to cache where it can be snooped by other CPUs. (ie, the volatile + * keyword should not be required) + * + * the primitives that must be defined are: + * + * PaUtil_FullMemoryBarrier() + * PaUtil_ReadMemoryBarrier() + * PaUtil_WriteMemoryBarrier() + * + ****************/ + +#if defined(__APPLE__) +# include + /* Here are the memory barrier functions. Mac OS X only provides + full memory barriers, so the three types of barriers are the same, + however, these barriers are superior to compiler-based ones. */ +# define PaUtil_FullMemoryBarrier() OSMemoryBarrier() +# define PaUtil_ReadMemoryBarrier() OSMemoryBarrier() +# define PaUtil_WriteMemoryBarrier() OSMemoryBarrier() +#elif defined(__GNUC__) + /* GCC >= 4.1 has built-in intrinsics. We'll use those */ +# if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) +# define PaUtil_FullMemoryBarrier() __sync_synchronize() +# define PaUtil_ReadMemoryBarrier() __sync_synchronize() +# define PaUtil_WriteMemoryBarrier() __sync_synchronize() + /* as a fallback, GCC understands volatile asm and "memory" to mean it + * should not reorder memory read/writes */ + /* Note that it is not clear that any compiler actually defines __PPC__, + * it can probably removed safely. */ +# elif defined( __ppc__ ) || defined( __powerpc__) || defined( __PPC__ ) +# define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory") +# define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory") +# define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory") +# elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \ + defined( __i686__ ) || defined( __x86_64__ ) +# define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory") +# define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory") +# define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory") +# else +# ifdef ALLOW_SMP_DANGERS +# warning Memory barriers not defined on this system or system unknown +# warning For SMP safety, you should fix this. +# define PaUtil_FullMemoryBarrier() +# define PaUtil_ReadMemoryBarrier() +# define PaUtil_WriteMemoryBarrier() +# else +# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. +# endif +# endif +#elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE) +# include +# pragma intrinsic(_ReadWriteBarrier) +# pragma intrinsic(_ReadBarrier) +# pragma intrinsic(_WriteBarrier) +/* note that MSVC intrinsics _ReadWriteBarrier(), _ReadBarrier(), _WriteBarrier() are just compiler barriers *not* memory barriers */ +# define PaUtil_FullMemoryBarrier() _ReadWriteBarrier() +# define PaUtil_ReadMemoryBarrier() _ReadBarrier() +# define PaUtil_WriteMemoryBarrier() _WriteBarrier() +#elif defined(_WIN32_WCE) +# define PaUtil_FullMemoryBarrier() +# define PaUtil_ReadMemoryBarrier() +# define PaUtil_WriteMemoryBarrier() +#elif defined(_MSC_VER) || defined(__BORLANDC__) +# define PaUtil_FullMemoryBarrier() _asm { lock add [esp], 0 } +# define PaUtil_ReadMemoryBarrier() _asm { lock add [esp], 0 } +# define PaUtil_WriteMemoryBarrier() _asm { lock add [esp], 0 } +#else +# ifdef ALLOW_SMP_DANGERS +# warning Memory barriers not defined on this system or system unknown +# warning For SMP safety, you should fix this. +# define PaUtil_FullMemoryBarrier() +# define PaUtil_ReadMemoryBarrier() +# define PaUtil_WriteMemoryBarrier() +# else +# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. +# endif +#endif diff --git a/external/portaudio/include/pa_process.h b/external/portaudio/include/pa_process.h new file mode 100644 index 0000000..4d5f56a --- /dev/null +++ b/external/portaudio/include/pa_process.h @@ -0,0 +1,754 @@ +#ifndef PA_PROCESS_H +#define PA_PROCESS_H +/* + * $Id: pa_process.h 1668 2011-05-02 17:07:11Z rossb $ + * Portable Audio I/O Library callback buffer processing adapters + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2002 Phil Burk, Ross Bencina + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Buffer Processor prototypes. A Buffer Processor performs buffer length + adaption, coordinates sample format conversion, and interleaves/deinterleaves + channels. + +

Overview

+ + The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio + data from host buffers to user buffers and back again. Where required, the + buffer processor takes care of converting between host and user sample formats, + interleaving and deinterleaving multichannel buffers, and adapting between host + and user buffers with different lengths. The buffer processor may be used with + full and half duplex streams, for both callback streams and blocking read/write + streams. + + One of the important capabilities provided by the buffer processor is + the ability to adapt between user and host buffer sizes of different lengths + with minimum latency. Although this task is relatively easy to perform when + the host buffer size is an integer multiple of the user buffer size, the + problem is more complicated when this is not the case - especially for + full-duplex callback streams. Where necessary the adaption is implemented by + internally buffering some input and/or output data. The buffer adation + algorithm used by the buffer processor was originally implemented by + Stephan Letz for the ASIO version of PortAudio, and is described in his + Callback_adaption_.pdf which is included in the distribution. + + The buffer processor performs sample conversion using the functions provided + by pa_converters.c. + + The following sections provide an overview of how to use the buffer processor. + Interested readers are advised to consult the host API implementations for + examples of buffer processor usage. + + +

Initialization, resetting and termination

+ + When a stream is opened, the buffer processor should be initialized using + PaUtil_InitializeBufferProcessor. This function initializes internal state + and allocates temporary buffers as neccesary according to the supplied + configuration parameters. Some of the parameters correspond to those requested + by the user in their call to Pa_OpenStream(), others reflect the requirements + of the host API implementation - they indicate host buffer sizes, formats, + and the type of buffering which the Host API uses. The buffer processor should + be initialized for callback streams and blocking read/write streams. + + Call PaUtil_ResetBufferProcessor to clear any sample data which is present + in the buffer processor before starting to use it (for example when + Pa_StartStream is called). + + When the buffer processor is no longer used call + PaUtil_TerminateBufferProcessor. + + +

Using the buffer processor for a callback stream

+ + The buffer processor's role in a callback stream is to take host input buffers + process them with the stream callback, and fill host output buffers. For a + full duplex stream, the buffer processor handles input and output simultaneously + due to the requirements of the minimum-latency buffer adation algorithm. + + When a host buffer becomes available, the implementation should call + the buffer processor to process the buffer. The buffer processor calls the + stream callback to consume and/or produce audio data as necessary. The buffer + processor will convert sample formats, interleave/deinterleave channels, + and slice or chunk the data to the appropriate buffer lengths according to + the requirements of the stream callback and the host API. + + To process a host buffer (or a pair of host buffers for a full-duplex stream) + use the following calling sequence: + + -# Call PaUtil_BeginBufferProcessing + -# For a stream which takes input: + - Call PaUtil_SetInputFrameCount with the number of frames in the host input + buffer. + - Call one of the following functions one or more times to tell the + buffer processor about the host input buffer(s): PaUtil_SetInputChannel, + PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. + Which function you call will depend on whether the host buffer(s) are + interleaved or not. + - If the available host data is split accross two buffers (for example a + data range at the end of a circular buffer and another range at the + beginning of the circular buffer), also call + PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel, + PaUtil_Set2ndInterleavedInputChannels, + PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer + processor about the second buffer. + -# For a stream which generates output: + - Call PaUtil_SetOutputFrameCount with the number of frames in the host + output buffer. + - Call one of the following functions one or more times to tell the + buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, + PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. + Which function you call will depend on whether the host buffer(s) are + interleaved or not. + - If the available host output buffer space is split accross two buffers + (for example a data range at the end of a circular buffer and another + range at the beginning of the circular buffer), call + PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel, + PaUtil_Set2ndInterleavedOutputChannels, + PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer + processor about the second buffer. + -# Call PaUtil_EndBufferProcessing, this function performs the actual data + conversion and processing. + + +

Using the buffer processor for a blocking read/write stream

+ + Blocking read/write streams use the buffer processor to convert and copy user + output data to a host buffer, and to convert and copy host input data to + the user's buffer. The buffer processor does not perform any buffer adaption. + When using the buffer processor in a blocking read/write stream the input and + output conversion are performed separately by the PaUtil_CopyInput and + PaUtil_CopyOutput functions. + + To copy data from a host input buffer to the buffer(s) which the user supplies + to Pa_ReadStream, use the following calling sequence. + + - Repeat the following three steps until the user buffer(s) have been filled + with samples from the host input buffers: + -# Call PaUtil_SetInputFrameCount with the number of frames in the host + input buffer. + -# Call one of the following functions one or more times to tell the + buffer processor about the host input buffer(s): PaUtil_SetInputChannel, + PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. + Which function you call will depend on whether the host buffer(s) are + interleaved or not. + -# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the + array of buffer pointers for a non-interleaved stream) passed to + Pa_ReadStream, along with the number of frames in the user buffer(s). + Be careful to pass a copy of the user buffer pointers to + PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to + the start of the next region to copy. + - PaUtil_CopyInput will not copy more data than is available in the + host buffer(s), so the above steps need to be repeated until the user + buffer(s) are full. + + + To copy data to the host output buffer from the user buffers(s) supplied + to Pa_WriteStream use the following calling sequence. + + - Repeat the following three steps until all frames from the user buffer(s) + have been copied to the host API: + -# Call PaUtil_SetOutputFrameCount with the number of frames in the host + output buffer. + -# Call one of the following functions one or more times to tell the + buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, + PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. + Which function you call will depend on whether the host buffer(s) are + interleaved or not. + -# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the + array of buffer pointers for a non-interleaved stream) passed to + Pa_WriteStream, along with the number of frames in the user buffer(s). + Be careful to pass a copy of the user buffer pointers to + PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to + the start of the next region to copy. + - PaUtil_CopyOutput will not copy more data than fits in the host buffer(s), + so the above steps need to be repeated until all user data is copied. +*/ + + +#include "portaudio.h" +#include "pa_converters.h" +#include "pa_dither.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type + of buffering that the host API uses. + + The mode used depends on whether the host API or the implementation manages + the buffers, and how these buffers are used (scatter gather, circular buffer). +*/ +typedef enum { +/** The host buffer size is a fixed known size. */ + paUtilFixedHostBufferSize, + +/** The host buffer size may vary, but has a known maximum size. */ + paUtilBoundedHostBufferSize, + +/** Nothing is known about the host buffer size. */ + paUtilUnknownHostBufferSize, + +/** The host buffer size varies, and the client does not require the buffer + processor to consume all of the input and fill all of the output buffer. This + is useful when the implementation has access to the host API's circular buffer + and only needs to consume/fill some of it, not necessarily all of it, with each + call to the buffer processor. This is the only mode where + PaUtil_EndBufferProcessing() may not consume the whole buffer. +*/ + paUtilVariableHostBufferSizePartialUsageAllowed +}PaUtilHostBufferSizeMode; + + +/** @brief An auxilliary data structure used internally by the buffer processor + to represent host input and output buffers. */ +typedef struct PaUtilChannelDescriptor{ + void *data; + unsigned int stride; /**< stride in samples, not bytes */ +}PaUtilChannelDescriptor; + + +/** @brief The main buffer processor data structure. + + Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor + and terminate it with PaUtil_TerminateBufferProcessor. +*/ +typedef struct { + unsigned long framesPerUserBuffer; + unsigned long framesPerHostBuffer; + + PaUtilHostBufferSizeMode hostBufferSizeMode; + int useNonAdaptingProcess; + int userOutputSampleFormatIsEqualToHost; + int userInputSampleFormatIsEqualToHost; + unsigned long framesPerTempBuffer; + + unsigned int inputChannelCount; + unsigned int bytesPerHostInputSample; + unsigned int bytesPerUserInputSample; + int userInputIsInterleaved; + PaUtilConverter *inputConverter; + PaUtilZeroer *inputZeroer; + + unsigned int outputChannelCount; + unsigned int bytesPerHostOutputSample; + unsigned int bytesPerUserOutputSample; + int userOutputIsInterleaved; + PaUtilConverter *outputConverter; + PaUtilZeroer *outputZeroer; + + unsigned long initialFramesInTempInputBuffer; + unsigned long initialFramesInTempOutputBuffer; + + void *tempInputBuffer; /**< used for slips, block adaption, and conversion. */ + void **tempInputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */ + unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ + + void *tempOutputBuffer; /**< used for slips, block adaption, and conversion. */ + void **tempOutputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */ + unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ + + PaStreamCallbackTimeInfo *timeInfo; + + PaStreamCallbackFlags callbackStatusFlags; + + int hostInputIsInterleaved; + unsigned long hostInputFrameCount[2]; + PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors. + pointers are NULL for half-duplex output processing. + hostInputChannels[i].data is NULL when the caller + calls PaUtil_SetNoInput() + */ + int hostOutputIsInterleaved; + unsigned long hostOutputFrameCount[2]; + PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors. + pointers are NULL for half-duplex input processing. + hostOutputChannels[i].data is NULL when the caller + calls PaUtil_SetNoOutput() + */ + + PaUtilTriangularDitherGenerator ditherGenerator; + + double samplePeriod; + + PaStreamCallback *streamCallback; + void *userData; +} PaUtilBufferProcessor; + + +/** @name Initialization, termination, resetting and info */ +/*@{*/ + +/** Initialize a buffer processor's representation stored in a + PaUtilBufferProcessor structure. Be sure to call + PaUtil_TerminateBufferProcessor after finishing with a buffer processor. + + @param bufferProcessor The buffer processor structure to initialize. + + @param inputChannelCount The number of input channels as passed to + Pa_OpenStream or 0 for an output-only stream. + + @param userInputSampleFormat Format of user input samples, as passed to + Pa_OpenStream. This parameter is ignored for ouput-only streams. + + @param hostInputSampleFormat Format of host input samples. This parameter is + ignored for output-only streams. See note about host buffer interleave below. + + @param outputChannelCount The number of output channels as passed to + Pa_OpenStream or 0 for an input-only stream. + + @param userOutputSampleFormat Format of user output samples, as passed to + Pa_OpenStream. This parameter is ignored for input-only streams. + + @param hostOutputSampleFormat Format of host output samples. This parameter is + ignored for input-only streams. See note about host buffer interleave below. + + @param sampleRate Sample rate of the stream. The more accurate this is the + better - it is used for updating time stamps when adapting buffers. + + @param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is + used for selecting special sample conversion options such as clipping and + dithering. + + @param framesPerUserBuffer Number of frames per user buffer, as requested + by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be + zero to indicate that the user will accept any (and varying) buffer sizes. + + @param framesPerHostBuffer Specifies the number of frames per host buffer + for the fixed buffer size mode, and the maximum number of frames + per host buffer for the bounded host buffer size mode. It is ignored for + the other modes. + + @param hostBufferSizeMode A mode flag indicating the size variability of + host buffers that will be passed to the buffer processor. See + PaUtilHostBufferSizeMode for further details. + + @param streamCallback The user stream callback passed to Pa_OpenStream. + + @param userData The user data field passed to Pa_OpenStream. + + @note The interleave flag is ignored for host buffer formats. Host + interleave is determined by the use of different SetInput and SetOutput + functions. + + @return An error code indicating whether the initialization was successful. + If the error code is not PaNoError, the buffer processor was not initialized + and should not be used. + + @see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor +*/ +PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor, + int inputChannelCount, PaSampleFormat userInputSampleFormat, + PaSampleFormat hostInputSampleFormat, + int outputChannelCount, PaSampleFormat userOutputSampleFormat, + PaSampleFormat hostOutputSampleFormat, + double sampleRate, + PaStreamFlags streamFlags, + unsigned long framesPerUserBuffer, /* 0 indicates don't care */ + unsigned long framesPerHostBuffer, + PaUtilHostBufferSizeMode hostBufferSizeMode, + PaStreamCallback *streamCallback, void *userData ); + + +/** Terminate a buffer processor's representation. Deallocates any temporary + buffers allocated by PaUtil_InitializeBufferProcessor. + + @param bufferProcessor The buffer processor structure to terminate. + + @see PaUtil_InitializeBufferProcessor. +*/ +void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); + + +/** Clear any internally buffered data. If you call + PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you + call PaUtil_ResetBufferProcessor in your StartStream call. + + @param bufferProcessor The buffer processor to reset. +*/ +void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); + + +/** Retrieve the input latency of a buffer processor, in frames. + + @param bufferProcessor The buffer processor examine. + + @return The input latency introduced by the buffer processor, in frames. + + @see PaUtil_GetBufferProcessorOutputLatencyFrames +*/ +unsigned long PaUtil_GetBufferProcessorInputLatencyFrames( PaUtilBufferProcessor* bufferProcessor ); + +/** Retrieve the output latency of a buffer processor, in frames. + + @param bufferProcessor The buffer processor examine. + + @return The output latency introduced by the buffer processor, in frames. + + @see PaUtil_GetBufferProcessorInputLatencyFrames +*/ +unsigned long PaUtil_GetBufferProcessorOutputLatencyFrames( PaUtilBufferProcessor* bufferProcessor ); + +/*@}*/ + + +/** @name Host buffer pointer configuration + + Functions to set host input and output buffers, used by both callback streams + and blocking read/write streams. +*/ +/*@{*/ + + +/** Set the number of frames in the input host buffer(s) specified by the + PaUtil_Set*InputChannel functions. + + @param bufferProcessor The buffer processor. + + @param frameCount The number of host input frames. A 0 frameCount indicates to + use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. + + @see PaUtil_SetNoInput, PaUtil_SetInputChannel, + PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel +*/ +void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor, + unsigned long frameCount ); + + +/** Indicate that no input is avalable. This function should be used when + priming the output of a full-duplex stream opened with the + paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary + to call this or any othe PaUtil_Set*Input* functions for ouput-only streams. + + @param bufferProcessor The buffer processor. +*/ +void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor ); + + +/** Provide the buffer processor with a pointer to a host input channel. + + @param bufferProcessor The buffer processor. + @param channel The channel number. + @param data The buffer. + @param stride The stride from one sample to the next, in samples. For + interleaved host buffers, the stride will usually be the same as the number of + channels in the buffer. +*/ +void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data, unsigned int stride ); + + +/** Provide the buffer processor with a pointer to an number of interleaved + host input channels. + + @param bufferProcessor The buffer processor. + @param firstChannel The first channel number. + @param data The buffer. + @param channelCount The number of interleaved channels in the buffer. If + channelCount is zero, the number of channels specified to + PaUtil_InitializeBufferProcessor will be used. +*/ +void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, + unsigned int firstChannel, void *data, unsigned int channelCount ); + + +/** Provide the buffer processor with a pointer to one non-interleaved host + output channel. + + @param bufferProcessor The buffer processor. + @param channel The channel number. + @param data The buffer. +*/ +void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data ); + + +/** Use for the second buffer half when the input buffer is split in two halves. + @see PaUtil_SetInputFrameCount +*/ +void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor, + unsigned long frameCount ); + +/** Use for the second buffer half when the input buffer is split in two halves. + @see PaUtil_SetInputChannel +*/ +void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data, unsigned int stride ); + +/** Use for the second buffer half when the input buffer is split in two halves. + @see PaUtil_SetInterleavedInputChannels +*/ +void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, + unsigned int firstChannel, void *data, unsigned int channelCount ); + +/** Use for the second buffer half when the input buffer is split in two halves. + @see PaUtil_SetNonInterleavedInputChannel +*/ +void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data ); + + +/** Set the number of frames in the output host buffer(s) specified by the + PaUtil_Set*OutputChannel functions. + + @param bufferProcessor The buffer processor. + + @param frameCount The number of host output frames. A 0 frameCount indicates to + use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. + + @see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, + PaUtil_SetNonInterleavedOutputChannel +*/ +void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, + unsigned long frameCount ); + + +/** Indicate that the output will be discarded. This function should be used + when implementing the paNeverDropInput mode for full duplex streams. + + @param bufferProcessor The buffer processor. +*/ +void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor ); + + +/** Provide the buffer processor with a pointer to a host output channel. + + @param bufferProcessor The buffer processor. + @param channel The channel number. + @param data The buffer. + @param stride The stride from one sample to the next, in samples. For + interleaved host buffers, the stride will usually be the same as the number of + channels in the buffer. +*/ +void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data, unsigned int stride ); + + +/** Provide the buffer processor with a pointer to a number of interleaved + host output channels. + + @param bufferProcessor The buffer processor. + @param firstChannel The first channel number. + @param data The buffer. + @param channelCount The number of interleaved channels in the buffer. If + channelCount is zero, the number of channels specified to + PaUtil_InitializeBufferProcessor will be used. +*/ +void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, + unsigned int firstChannel, void *data, unsigned int channelCount ); + + +/** Provide the buffer processor with a pointer to one non-interleaved host + output channel. + + @param bufferProcessor The buffer processor. + @param channel The channel number. + @param data The buffer. +*/ +void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data ); + + +/** Use for the second buffer half when the output buffer is split in two halves. + @see PaUtil_SetOutputFrameCount +*/ +void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, + unsigned long frameCount ); + +/** Use for the second buffer half when the output buffer is split in two halves. + @see PaUtil_SetOutputChannel +*/ +void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data, unsigned int stride ); + +/** Use for the second buffer half when the output buffer is split in two halves. + @see PaUtil_SetInterleavedOutputChannels +*/ +void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, + unsigned int firstChannel, void *data, unsigned int channelCount ); + +/** Use for the second buffer half when the output buffer is split in two halves. + @see PaUtil_SetNonInterleavedOutputChannel +*/ +void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, + unsigned int channel, void *data ); + +/*@}*/ + + +/** @name Buffer processing functions for callback streams +*/ +/*@{*/ + +/** Commence processing a host buffer (or a pair of host buffers in the + full-duplex case) for a callback stream. + + @param bufferProcessor The buffer processor. + + @param timeInfo Timing information for the first sample of the host + buffer(s). This information may be adjusted when buffer adaption is being + performed. + + @param callbackStatusFlags Flags indicating whether underruns and overruns + have occurred since the last time the buffer processor was called. +*/ +void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor, + PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags ); + + +/** Finish processing a host buffer (or a pair of host buffers in the + full-duplex case) for a callback stream. + + @param bufferProcessor The buffer processor. + + @param callbackResult On input, indicates a previous callback result, and on + exit, the result of the user stream callback, if it is called. + On entry callbackResult should contain one of { paContinue, paComplete, or + paAbort}. If paComplete is passed, the stream callback will not be called + but any audio that was generated by previous stream callbacks will be copied + to the output buffer(s). You can check whether the buffer processor's internal + buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty. + + If the stream callback is called its result is stored in *callbackResult. If + the stream callback returns paComplete or paAbort, all output buffers will be + full of valid data - some of which may be zeros to acount for data that + wasn't generated by the terminating callback. + + @return The number of frames processed. This usually corresponds to the + number of frames specified by the PaUtil_Set*FrameCount functions, exept in + the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a + smaller value may be returned. +*/ +unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor, + int *callbackResult ); + + +/** Determine whether any callback generated output remains in the bufffer + processor's internal buffers. This method may be used to determine when to + continue calling PaUtil_EndBufferProcessing() after the callback has returned + a callbackResult of paComplete. + + @param bufferProcessor The buffer processor. + + @return Returns non-zero when callback generated output remains in the internal + buffer and zero (0) when there internal buffer contains no callback generated + data. +*/ +int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor ); + +/*@}*/ + + +/** @name Buffer processing functions for blocking read/write streams +*/ +/*@{*/ + +/** Copy samples from host input channels set up by the PaUtil_Set*InputChannels + functions to a user supplied buffer. This function is intended for use with + blocking read/write streams. Copies the minimum of the number of + user frames (specified by the frameCount parameter) and the number of available + host frames (specified in a previous call to SetInputFrameCount()). + + @param bufferProcessor The buffer processor. + + @param buffer A pointer to the user buffer pointer, or a pointer to a pointer + to an array of user buffer pointers for a non-interleaved stream. It is + important that this parameter points to a copy of the user buffer pointers, + not to the actual user buffer pointers, because this function updates the + pointers before returning. + + @param frameCount The number of frames of data in the buffer(s) pointed to by + the buffer parameter. + + @return The number of frames copied. The buffer pointer(s) pointed to by the + buffer parameter are advanced to point to the frame(s) following the last one + filled. +*/ +unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor, + void **buffer, unsigned long frameCount ); + + +/* Copy samples from a user supplied buffer to host output channels set up by + the PaUtil_Set*OutputChannels functions. This function is intended for use with + blocking read/write streams. Copies the minimum of the number of + user frames (specified by the frameCount parameter) and the number of + host frames (specified in a previous call to SetOutputFrameCount()). + + @param bufferProcessor The buffer processor. + + @param buffer A pointer to the user buffer pointer, or a pointer to a pointer + to an array of user buffer pointers for a non-interleaved stream. It is + important that this parameter points to a copy of the user buffer pointers, + not to the actual user buffer pointers, because this function updates the + pointers before returning. + + @param frameCount The number of frames of data in the buffer(s) pointed to by + the buffer parameter. + + @return The number of frames copied. The buffer pointer(s) pointed to by the + buffer parameter are advanced to point to the frame(s) following the last one + copied. +*/ +unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor, + const void ** buffer, unsigned long frameCount ); + + +/* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels + functions. This function is useful for flushing streams. + Zeros the minimum of frameCount and the number of host frames specified in a + previous call to SetOutputFrameCount(). + + @param bufferProcessor The buffer processor. + + @param frameCount The maximum number of frames to zero. + + @return The number of frames zeroed. +*/ +unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor, + unsigned long frameCount ); + + +/*@}*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_PROCESS_H */ diff --git a/external/portaudio/include/pa_ringbuffer.h b/external/portaudio/include/pa_ringbuffer.h new file mode 100644 index 0000000..0cab3a5 --- /dev/null +++ b/external/portaudio/include/pa_ringbuffer.h @@ -0,0 +1,236 @@ +#ifndef PA_RINGBUFFER_H +#define PA_RINGBUFFER_H +/* + * $Id: pa_ringbuffer.h 1873 2012-10-07 19:00:11Z philburk $ + * Portable Audio I/O Library + * Ring Buffer utility. + * + * Author: Phil Burk, http://www.softsynth.com + * modified for SMP safety on OS X by Bjorn Roche. + * also allowed for const where possible. + * modified for multiple-byte-sized data elements by Sven Fischer + * + * Note that this is safe only for a single-thread reader + * and a single-thread writer. + * + * This program is distributed with the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + @brief Single-reader single-writer lock-free ring buffer + + PaUtilRingBuffer is a ring buffer used to transport samples between + different execution contexts (threads, OS callbacks, interrupt handlers) + without requiring the use of any locks. This only works when there is + a single reader and a single writer (ie. one thread or callback writes + to the ring buffer, another thread or callback reads from it). + + The PaUtilRingBuffer structure manages a ring buffer containing N + elements, where N must be a power of two. An element may be any size + (specified in bytes). + + The memory area used to store the buffer elements must be allocated by + the client prior to calling PaUtil_InitializeRingBuffer() and must outlive + the use of the ring buffer. + + @note The ring buffer functions are not normally exposed in the PortAudio libraries. + If you want to call them then you will need to add pa_ringbuffer.c to your application source code. +*/ + +#if defined(__APPLE__) +#include +typedef int32_t ring_buffer_size_t; +#elif defined( __GNUC__ ) +typedef long ring_buffer_size_t; +#elif (_MSC_VER >= 1400) +typedef long ring_buffer_size_t; +#elif defined(_MSC_VER) || defined(__BORLANDC__) +typedef long ring_buffer_size_t; +#else +typedef long ring_buffer_size_t; +#endif + + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct PaUtilRingBuffer +{ + ring_buffer_size_t bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ + volatile ring_buffer_size_t writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */ + volatile ring_buffer_size_t readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */ + ring_buffer_size_t bigMask; /**< Used for wrapping indices with extra bit to distinguish full/empty. */ + ring_buffer_size_t smallMask; /**< Used for fitting indices to buffer. */ + ring_buffer_size_t elementSizeBytes; /**< Number of bytes per element. */ + char *buffer; /**< Pointer to the buffer containing the actual data. */ +}PaUtilRingBuffer; + +/** Initialize Ring Buffer to empty state ready to have elements written to it. + + @param rbuf The ring buffer. + + @param elementSizeBytes The size of a single data element in bytes. + + @param elementCount The number of elements in the buffer (must be a power of 2). + + @param dataPtr A pointer to a previously allocated area where the data + will be maintained. It must be elementCount*elementSizeBytes long. + + @return -1 if elementCount is not a power of 2, otherwise 0. +*/ +ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr ); + +/** Reset buffer to empty. Should only be called when buffer is NOT being read or written. + + @param rbuf The ring buffer. +*/ +void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ); + +/** Retrieve the number of elements available in the ring buffer for writing. + + @param rbuf The ring buffer. + + @return The number of elements available for writing. +*/ +ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf ); + +/** Retrieve the number of elements available in the ring buffer for reading. + + @param rbuf The ring buffer. + + @return The number of elements available for reading. +*/ +ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf ); + +/** Write data to the ring buffer. + + @param rbuf The ring buffer. + + @param data The address of new data to write to the buffer. + + @param elementCount The number of elements to be written. + + @return The number of elements written. +*/ +ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount ); + +/** Read data from the ring buffer. + + @param rbuf The ring buffer. + + @param data The address where the data should be stored. + + @param elementCount The number of elements to be read. + + @return The number of elements read. +*/ +ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount ); + +/** Get address of region(s) to which we can write data. + + @param rbuf The ring buffer. + + @param elementCount The number of elements desired. + + @param dataPtr1 The address where the first (or only) region pointer will be + stored. + + @param sizePtr1 The address where the first (or only) region length will be + stored. + + @param dataPtr2 The address where the second region pointer will be stored if + the first region is too small to satisfy elementCount. + + @param sizePtr2 The address where the second region length will be stored if + the first region is too small to satisfy elementCount. + + @return The room available to be written or elementCount, whichever is smaller. +*/ +ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, + void **dataPtr1, ring_buffer_size_t *sizePtr1, + void **dataPtr2, ring_buffer_size_t *sizePtr2 ); + +/** Advance the write index to the next location to be written. + + @param rbuf The ring buffer. + + @param elementCount The number of elements to advance. + + @return The new position. +*/ +ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ); + +/** Get address of region(s) from which we can read data. + + @param rbuf The ring buffer. + + @param elementCount The number of elements desired. + + @param dataPtr1 The address where the first (or only) region pointer will be + stored. + + @param sizePtr1 The address where the first (or only) region length will be + stored. + + @param dataPtr2 The address where the second region pointer will be stored if + the first region is too small to satisfy elementCount. + + @param sizePtr2 The address where the second region length will be stored if + the first region is too small to satisfy elementCount. + + @return The number of elements available for reading. +*/ +ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, + void **dataPtr1, ring_buffer_size_t *sizePtr1, + void **dataPtr2, ring_buffer_size_t *sizePtr2 ); + +/** Advance the read index to the next location to be read. + + @param rbuf The ring buffer. + + @param elementCount The number of elements to advance. + + @return The new position. +*/ +ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_RINGBUFFER_H */ diff --git a/external/portaudio/include/pa_stream.h b/external/portaudio/include/pa_stream.h new file mode 100644 index 0000000..8d707b7 --- /dev/null +++ b/external/portaudio/include/pa_stream.h @@ -0,0 +1,205 @@ +#ifndef PA_STREAM_H +#define PA_STREAM_H +/* + * $Id: pa_stream.h 1339 2008-02-15 07:50:33Z rossb $ + * Portable Audio I/O Library + * stream interface + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2008 Ross Bencina, Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Stream interfaces, representation structures and helper functions + used to interface between pa_front.c host API implementations. +*/ + + +#include "portaudio.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +#define PA_STREAM_MAGIC (0x18273645) + + +/** A structure representing an (abstract) interface to a host API. Contains + pointers to functions which implement the interface. + + All PaStreamInterface functions are guaranteed to be called with a non-null, + valid stream parameter. +*/ +typedef struct { + PaError (*Close)( PaStream* stream ); + PaError (*Start)( PaStream *stream ); + PaError (*Stop)( PaStream *stream ); + PaError (*Abort)( PaStream *stream ); + PaError (*IsStopped)( PaStream *stream ); + PaError (*IsActive)( PaStream *stream ); + PaTime (*GetTime)( PaStream *stream ); + double (*GetCpuLoad)( PaStream* stream ); + PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ); + PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ); + signed long (*GetReadAvailable)( PaStream* stream ); + signed long (*GetWriteAvailable)( PaStream* stream ); +} PaUtilStreamInterface; + + +/** Initialize the fields of a PaUtilStreamInterface structure. +*/ +void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface, + PaError (*Close)( PaStream* ), + PaError (*Start)( PaStream* ), + PaError (*Stop)( PaStream* ), + PaError (*Abort)( PaStream* ), + PaError (*IsStopped)( PaStream* ), + PaError (*IsActive)( PaStream* ), + PaTime (*GetTime)( PaStream* ), + double (*GetCpuLoad)( PaStream* ), + PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ), + PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ), + signed long (*GetReadAvailable)( PaStream* stream ), + signed long (*GetWriteAvailable)( PaStream* stream ) ); + + +/** Dummy Read function for use in interfaces to a callback based streams. + Pass to the Read parameter of PaUtil_InitializeStreamInterface. + @return An error code indicating that the function has no effect + because the stream is a callback stream. +*/ +PaError PaUtil_DummyRead( PaStream* stream, + void *buffer, + unsigned long frames ); + + +/** Dummy Write function for use in an interfaces to callback based streams. + Pass to the Write parameter of PaUtil_InitializeStreamInterface. + @return An error code indicating that the function has no effect + because the stream is a callback stream. +*/ +PaError PaUtil_DummyWrite( PaStream* stream, + const void *buffer, + unsigned long frames ); + + +/** Dummy GetReadAvailable function for use in interfaces to callback based + streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface. + @return An error code indicating that the function has no effect + because the stream is a callback stream. +*/ +signed long PaUtil_DummyGetReadAvailable( PaStream* stream ); + + +/** Dummy GetWriteAvailable function for use in interfaces to callback based + streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface. + @return An error code indicating that the function has no effect + because the stream is a callback stream. +*/ +signed long PaUtil_DummyGetWriteAvailable( PaStream* stream ); + + + +/** Dummy GetCpuLoad function for use in an interface to a read/write stream. + Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface. + @return Returns 0. +*/ +double PaUtil_DummyGetCpuLoad( PaStream* stream ); + + +/** Non host specific data for a stream. This data is used by pa_front to + forward to the appropriate functions in the streamInterface structure. +*/ +typedef struct PaUtilStreamRepresentation { + unsigned long magic; /**< set to PA_STREAM_MAGIC */ + struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */ + PaUtilStreamInterface *streamInterface; + PaStreamCallback *streamCallback; + PaStreamFinishedCallback *streamFinishedCallback; + void *userData; + PaStreamInfo streamInfo; +} PaUtilStreamRepresentation; + + +/** Initialize a PaUtilStreamRepresentation structure. + + @see PaUtil_InitializeStreamRepresentation +*/ +void PaUtil_InitializeStreamRepresentation( + PaUtilStreamRepresentation *streamRepresentation, + PaUtilStreamInterface *streamInterface, + PaStreamCallback *streamCallback, + void *userData ); + + +/** Clean up a PaUtilStreamRepresentation structure previously initialized + by a call to PaUtil_InitializeStreamRepresentation. + + @see PaUtil_InitializeStreamRepresentation +*/ +void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ); + + +/** Check that the stream pointer is valid. + + @return Returns paNoError if the stream pointer appears to be OK, otherwise + returns an error indicating the cause of failure. +*/ +PaError PaUtil_ValidateStreamPointer( PaStream *stream ); + + +/** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation. + + @see PaUtilStreamRepresentation +*/ +#define PA_STREAM_REP( stream )\ + ((PaUtilStreamRepresentation*) (stream) ) + + +/** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface. + + @see PaUtilStreamRepresentation, PaUtilStreamInterface +*/ +#define PA_STREAM_INTERFACE( stream )\ + PA_STREAM_REP( (stream) )->streamInterface + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_STREAM_H */ diff --git a/external/portaudio/include/pa_trace.h b/external/portaudio/include/pa_trace.h new file mode 100644 index 0000000..612dbf3 --- /dev/null +++ b/external/portaudio/include/pa_trace.h @@ -0,0 +1,117 @@ +#ifndef PA_TRACE_H +#define PA_TRACE_H +/* + * $Id: pa_trace.h 1812 2012-02-14 09:32:57Z robiwan $ + * Portable Audio I/O Library Trace Facility + * Store trace information in real-time for later printing. + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2000 Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Real-time safe event trace logging facility for debugging. + + Allows data to be logged to a fixed size trace buffer in a real-time + execution context (such as at interrupt time). Each log entry consists + of a message comprising a string pointer and an int. The trace buffer + may be dumped to stdout later. + + This facility is only active if PA_TRACE_REALTIME_EVENTS is set to 1, + otherwise the trace functions expand to no-ops. + + @fn PaUtil_ResetTraceMessages + @brief Clear the trace buffer. + + @fn PaUtil_AddTraceMessage + @brief Add a message to the trace buffer. A message consists of string and an int. + @param msg The string pointer must remain valid until PaUtil_DumpTraceMessages + is called. As a result, usually only string literals should be passed as + the msg parameter. + + @fn PaUtil_DumpTraceMessages + @brief Print all messages in the trace buffer to stdout and clear the trace buffer. +*/ + +#ifndef PA_TRACE_REALTIME_EVENTS +#define PA_TRACE_REALTIME_EVENTS (0) /**< Set to 1 to enable logging using the trace functions defined below */ +#endif + +#ifndef PA_MAX_TRACE_RECORDS +#define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */ +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +#if PA_TRACE_REALTIME_EVENTS + +void PaUtil_ResetTraceMessages(); +void PaUtil_AddTraceMessage( const char *msg, int data ); +void PaUtil_DumpTraceMessages(); + +/* Alternative interface */ + +typedef void* LogHandle; + +int PaUtil_InitializeHighSpeedLog(LogHandle* phLog, unsigned maxSizeInBytes); +void PaUtil_ResetHighSpeedLogTimeRef(LogHandle hLog); +int PaUtil_AddHighSpeedLogMessage(LogHandle hLog, const char* fmt, ...); +void PaUtil_DumpHighSpeedLog(LogHandle hLog, const char* fileName); +void PaUtil_DiscardHighSpeedLog(LogHandle hLog); + +#else + +#define PaUtil_ResetTraceMessages() /* noop */ +#define PaUtil_AddTraceMessage(msg,data) /* noop */ +#define PaUtil_DumpTraceMessages() /* noop */ + +#define PaUtil_InitializeHighSpeedLog(phLog, maxSizeInBytes) (0) +#define PaUtil_ResetHighSpeedLogTimeRef(hLog) +#define PaUtil_AddHighSpeedLogMessage(...) (0) +#define PaUtil_DumpHighSpeedLog(hLog, fileName) +#define PaUtil_DiscardHighSpeedLog(hLog) + +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_TRACE_H */ diff --git a/external/portaudio/include/pa_util.h b/external/portaudio/include/pa_util.h new file mode 100644 index 0000000..c454ea7 --- /dev/null +++ b/external/portaudio/include/pa_util.h @@ -0,0 +1,159 @@ +#ifndef PA_UTIL_H +#define PA_UTIL_H +/* + * $Id: pa_util.h 1584 2011-02-02 18:58:17Z rossb $ + * Portable Audio I/O Library implementation utilities header + * common implementation utilities and interfaces + * + * Based on the Open Source API proposed by Ross Bencina + * Copyright (c) 1999-2008 Ross Bencina, Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup common_src + + @brief Prototypes for utility functions used by PortAudio implementations. + + Some functions declared here are defined in pa_front.c while others + are implemented separately for each platform. +*/ + + +#include "portaudio.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +struct PaUtilHostApiRepresentation; + + +/** Retrieve a specific host API representation. This function can be used + by implementations to retrieve a pointer to their representation in + host api specific extension functions which aren't passed a rep pointer + by pa_front.c. + + @param hostApi A pointer to a host API represenation pointer. Apon success + this will receive the requested representation pointer. + + @param type A valid host API type identifier. + + @returns An error code. If the result is PaNoError then a pointer to the + requested host API representation will be stored in *hostApi. If the host API + specified by type is not found, this function returns paHostApiNotFound. +*/ +PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, + PaHostApiTypeId type ); + + +/** Convert a PortAudio device index into a host API specific device index. + @param hostApiDevice Pointer to a device index, on success this will recieve the + converted device index value. + @param device The PortAudio device index to convert. + @param hostApi The host api which the index should be converted for. + + @returns On success returns PaNoError and places the converted index in the + hostApiDevice parameter. +*/ +PaError PaUtil_DeviceIndexToHostApiDeviceIndex( + PaDeviceIndex *hostApiDevice, PaDeviceIndex device, + struct PaUtilHostApiRepresentation *hostApi ); + + +/** Set the host error information returned by Pa_GetLastHostErrorInfo. This + function and the paUnanticipatedHostError error code should be used as a + last resort. Implementors should use existing PA error codes where possible, + or nominate new ones. Note that at it is always better to use + PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an + ambiguous or inaccurate PaError code. + + @param hostApiType The host API which encountered the error (ie of the caller) + + @param errorCode The error code returned by the native API function. + + @param errorText A string describing the error. PaUtil_SetLastHostErrorInfo + makes a copy of the string, so it is not necessary for the pointer to remain + valid after the call to PaUtil_SetLastHostErrorInfo() returns. + +*/ +void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, + const char *errorText ); + + + +/* the following functions are implemented in a platform platform specific + .c file +*/ + +/** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */ +void *PaUtil_AllocateMemory( long size ); + + +/** Realease block if non-NULL. block may be NULL */ +void PaUtil_FreeMemory( void *block ); + + +/** Return the number of currently allocated blocks. This function can be + used for detecting memory leaks. + + @note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If + it isn't, this function will always return 0. +*/ +int PaUtil_CountCurrentlyAllocatedBlocks( void ); + + +/** Initialize the clock used by PaUtil_GetTime(). Call this before calling + PaUtil_GetTime. + + @see PaUtil_GetTime +*/ +void PaUtil_InitializeClock( void ); + + +/** Return the system time in seconds. Used to implement CPU load functions + + @see PaUtil_InitializeClock +*/ +double PaUtil_GetTime( void ); + + +/* void Pa_Sleep( long msec ); must also be implemented in per-platform .c file */ + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PA_UTIL_H */ diff --git a/external/portaudio/include/pa_win_ds.h b/external/portaudio/include/pa_win_ds.h new file mode 100644 index 0000000..5d38641 --- /dev/null +++ b/external/portaudio/include/pa_win_ds.h @@ -0,0 +1,95 @@ +#ifndef PA_WIN_DS_H +#define PA_WIN_DS_H +/* + * $Id: $ + * PortAudio Portable Real-Time Audio Library + * DirectSound specific extensions + * + * Copyright (c) 1999-2007 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief DirectSound-specific PortAudio API extension header file. +*/ + +#include "portaudio.h" +#include "pa_win_waveformat.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +#define paWinDirectSoundUseLowLevelLatencyParameters (0x01) +#define paWinDirectSoundUseChannelMask (0x04) + + +typedef struct PaWinDirectSoundStreamInfo{ + unsigned long size; /**< sizeof(PaWinDirectSoundStreamInfo) */ + PaHostApiTypeId hostApiType; /**< paDirectSound */ + unsigned long version; /**< 2 */ + + unsigned long flags; /**< enable other features of this struct */ + + /** + low-level latency setting support + Sets the size of the DirectSound host buffer. + When flags contains the paWinDirectSoundUseLowLevelLatencyParameters + this size will be used instead of interpreting the generic latency + parameters to Pa_OpenStream(). If the flag is not set this value is ignored. + + If the stream is a full duplex stream the implementation requires that + the values of framesPerBuffer for input and output match (if both are specified). + */ + unsigned long framesPerBuffer; + + /** + support for WAVEFORMATEXTENSIBLE channel masks. If flags contains + paWinDirectSoundUseChannelMask this allows you to specify which speakers + to address in a multichannel stream. Constants for channelMask + are specified in pa_win_waveformat.h + + */ + PaWinWaveFormatChannelMask channelMask; + +}PaWinDirectSoundStreamInfo; + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_WIN_DS_H */ diff --git a/external/portaudio/include/pa_win_wasapi.h b/external/portaudio/include/pa_win_wasapi.h new file mode 100644 index 0000000..a60aa04 --- /dev/null +++ b/external/portaudio/include/pa_win_wasapi.h @@ -0,0 +1,391 @@ +#ifndef PA_WIN_WASAPI_H +#define PA_WIN_WASAPI_H +/* + * $Id: $ + * PortAudio Portable Real-Time Audio Library + * DirectSound specific extensions + * + * Copyright (c) 1999-2007 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief WASAPI-specific PortAudio API extension header file. +*/ + +#include "portaudio.h" +#include "pa_win_waveformat.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/* Setup flags */ +typedef enum PaWasapiFlags +{ + /* puts WASAPI into exclusive mode */ + paWinWasapiExclusive = (1 << 0), + + /* allows to skip internal PA processing completely */ + paWinWasapiRedirectHostProcessor = (1 << 1), + + /* assigns custom channel mask */ + paWinWasapiUseChannelMask = (1 << 2), + + /* selects non-Event driven method of data read/write + Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling + method can only provide 15-20ms latency. */ + paWinWasapiPolling = (1 << 3), + + /* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority + is set to custom value. */ + paWinWasapiThreadPriority = (1 << 4) +} +PaWasapiFlags; +#define paWinWasapiExclusive (paWinWasapiExclusive) +#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor) +#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask) +#define paWinWasapiPolling (paWinWasapiPolling) +#define paWinWasapiThreadPriority (paWinWasapiThreadPriority) + + +/* Host processor. Allows to skip internal PA processing completely. + You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member + in order to have host processor redirected to your callback. + Use with caution! inputFrames and outputFrames depend solely on final device setup. + To query maximal values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer. +*/ +typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames, + void *outputBuffer, long outputFrames, + void *userData); + +/* Device role */ +typedef enum PaWasapiDeviceRole +{ + eRoleRemoteNetworkDevice = 0, + eRoleSpeakers, + eRoleLineLevel, + eRoleHeadphones, + eRoleMicrophone, + eRoleHeadset, + eRoleHandset, + eRoleUnknownDigitalPassthrough, + eRoleSPDIF, + eRoleHDMI, + eRoleUnknownFormFactor +} +PaWasapiDeviceRole; + + +/* Jack connection type */ +typedef enum PaWasapiJackConnectionType +{ + eJackConnTypeUnknown, + eJackConnType3Point5mm, + eJackConnTypeQuarter, + eJackConnTypeAtapiInternal, + eJackConnTypeRCA, + eJackConnTypeOptical, + eJackConnTypeOtherDigital, + eJackConnTypeOtherAnalog, + eJackConnTypeMultichannelAnalogDIN, + eJackConnTypeXlrProfessional, + eJackConnTypeRJ11Modem, + eJackConnTypeCombination +} +PaWasapiJackConnectionType; + + +/* Jack geometric location */ +typedef enum PaWasapiJackGeoLocation +{ + eJackGeoLocUnk = 0, + eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */ + eJackGeoLocFront, + eJackGeoLocLeft, + eJackGeoLocRight, + eJackGeoLocTop, + eJackGeoLocBottom, + eJackGeoLocRearPanel, + eJackGeoLocRiser, + eJackGeoLocInsideMobileLid, + eJackGeoLocDrivebay, + eJackGeoLocHDMI, + eJackGeoLocOutsideMobileLid, + eJackGeoLocATAPI, + eJackGeoLocReserved5, + eJackGeoLocReserved6, +} +PaWasapiJackGeoLocation; + + +/* Jack general location */ +typedef enum PaWasapiJackGenLocation +{ + eJackGenLocPrimaryBox = 0, + eJackGenLocInternal, + eJackGenLocSeparate, + eJackGenLocOther +} +PaWasapiJackGenLocation; + + +/* Jack's type of port */ +typedef enum PaWasapiJackPortConnection +{ + eJackPortConnJack = 0, + eJackPortConnIntegratedDevice, + eJackPortConnBothIntegratedAndJack, + eJackPortConnUnknown +} +PaWasapiJackPortConnection; + + +/* Thread priority */ +typedef enum PaWasapiThreadPriority +{ + eThreadPriorityNone = 0, + eThreadPriorityAudio, //!< Default for Shared mode. + eThreadPriorityCapture, + eThreadPriorityDistribution, + eThreadPriorityGames, + eThreadPriorityPlayback, + eThreadPriorityProAudio, //!< Default for Exclusive mode. + eThreadPriorityWindowManager +} +PaWasapiThreadPriority; + + +/* Stream descriptor. */ +typedef struct PaWasapiJackDescription +{ + unsigned long channelMapping; + unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */ + PaWasapiJackConnectionType connectionType; + PaWasapiJackGeoLocation geoLocation; + PaWasapiJackGenLocation genLocation; + PaWasapiJackPortConnection portConnection; + unsigned int isConnected; +} +PaWasapiJackDescription; + + +/* Stream descriptor. */ +typedef struct PaWasapiStreamInfo +{ + unsigned long size; /**< sizeof(PaWasapiStreamInfo) */ + PaHostApiTypeId hostApiType; /**< paWASAPI */ + unsigned long version; /**< 1 */ + + unsigned long flags; /**< collection of PaWasapiFlags */ + + /* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains + paWinWasapiUseChannelMask this allows you to specify which speakers + to address in a multichannel stream. Constants for channelMask + are specified in pa_win_waveformat.h. Will be used only if + paWinWasapiUseChannelMask flag is specified. + */ + PaWinWaveFormatChannelMask channelMask; + + /* Delivers raw data to callback obtained from GetBuffer() methods skipping + internal PortAudio processing inventory completely. userData parameter will + be the same that was passed to Pa_OpenStream method. Will be used only if + paWinWasapiRedirectHostProcessor flag is specified. + */ + PaWasapiHostProcessorCallback hostProcessorOutput; + PaWasapiHostProcessorCallback hostProcessorInput; + + /* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag + is specified. + + Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode) + you shall specify same value for threadPriority or othervise one of the values will be used + to setup thread priority. + */ + PaWasapiThreadPriority threadPriority; +} +PaWasapiStreamInfo; + + +/** Returns default sound format for device. Format is represented by PaWinWaveFormat or + WAVEFORMATEXTENSIBLE structure. + + @param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure. + @param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes. + @param nDevice Device index. + + @return Non-negative value indicating the number of bytes copied into format decriptor + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. +*/ +int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice ); + + +/** Returns device role (PaWasapiDeviceRole enum). + + @param nDevice device index. + + @return Non-negative value indicating device role or, a PaErrorCode (which are always negative) + if PortAudio is not initialized or an error is encountered. +*/ +int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice ); + + +/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread + which makes calls to Pa_WriteStream/Pa_ReadStream. + + @param hTask Handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority + method to revert thread priority to initial state. + + @param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying + eThreadPriorityNone does nothing. + + @return Error code indicating success or failure. + @see PaWasapi_RevertThreadPriority +*/ +PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass ); + + +/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread + which makes calls to Pa_WriteStream/Pa_ReadStream. + + @param hTask Task handle obtained by PaWasapi_BoostThreadPriority method. + @return Error code indicating success or failure. + @see PaWasapi_BoostThreadPriority +*/ +PaError PaWasapi_ThreadPriorityRevert( void *hTask ); + + +/** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which + can be locked for operations. Use this method as helper to findout maximal values of + inputFrames/outputFrames of PaWasapiHostProcessorCallback. + + @param pStream Pointer to PaStream to query. + @param nInput Pointer to variable to receive number of input frames. Can be NULL. + @param nOutput Pointer to variable to receive number of output frames. Can be NULL. + @return Error code indicating success or failure. + @see PaWasapiHostProcessorCallback +*/ +PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ); + + +/** Get number of jacks associated with a WASAPI device. Use this method to determine if + there are any jacks associated with the provided WASAPI device. Not all audio devices + will support this capability. This is valid for both input and output devices. + @param nDevice device index. + @param jcount Number of jacks is returned in this variable + @return Error code indicating success or failure + @see PaWasapi_GetJackDescription + */ +PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount); + + +/** Get the jack description associated with a WASAPI device and jack number + Before this function is called, use PaWasapi_GetJackCount to determine the + number of jacks associated with device. If jcount is greater than zero, then + each jack from 0 to jcount can be queried with this function to get the jack + description. + @param nDevice device index. + @param jindex Which jack to return information + @param KSJACK_DESCRIPTION This structure filled in on success. + @return Error code indicating success or failure + @see PaWasapi_GetJackCount + */ +PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription); + + +/* + IMPORTANT: + + WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive + share modes. + + Exclusive Mode: + + Exclusive mode allows to deliver audio data directly to hardware bypassing + software mixing. + Exclusive mode is specified by 'paWinWasapiExclusive' flag. + + Callback Interface: + + Provides best audio quality with low latency. Callback interface is implemented in + two versions: + + 1) Event-Driven: + This is the most powerful WASAPI implementation which provides glitch-free + audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is + 3 ms for HD Audio class audio chips. For the Shared mode latency can not be + lower than 20 ms. + + 2) Poll-Driven: + Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven + and provides latency at around 10-13ms. Polling must be used to overcome a system bug + under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply + times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug + does not exist in Vista x86 or Windows 7. + Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects + WOW64 bug and sets 'paWinWasapiPolling' automatically. + + Thread priority: + + Normally thread priority is set automatically and does not require modification. Although + if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority' + flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority + enum. + + Blocking Interface: + + Blocking interface is implemented but due to above described Poll-Driven method can not + deliver lowest possible latency. Specifying too low latency in Shared mode will result in + distorted audio although Exclusive mode adds stability. + + Pa_IsFormatSupported: + + To check format with correct Share Mode (Exclusive/Shared) you must supply + PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of + PaStreamParameters::hostApiSpecificStreamInfo structure. + + Pa_OpenStream: + + To set desired Share Mode (Exclusive/Shared) you must supply + PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of + PaStreamParameters::hostApiSpecificStreamInfo structure. +*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_WIN_WASAPI_H */ diff --git a/external/portaudio/include/pa_win_waveformat.h b/external/portaudio/include/pa_win_waveformat.h new file mode 100644 index 0000000..2c00267 --- /dev/null +++ b/external/portaudio/include/pa_win_waveformat.h @@ -0,0 +1,199 @@ +#ifndef PA_WIN_WAVEFORMAT_H +#define PA_WIN_WAVEFORMAT_H + +/* + * PortAudio Portable Real-Time Audio Library + * Windows WAVEFORMAT* data structure utilities + * portaudio.h should be included before this file. + * + * Copyright (c) 2007 Ross Bencina + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief Windows specific PortAudio API extension and utilities header file. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + The following #defines for speaker channel masks are the same + as those in ksmedia.h, except with PAWIN_ prepended, KSAUDIO_ removed + in some cases, and casts to PaWinWaveFormatChannelMask added. +*/ + +typedef unsigned long PaWinWaveFormatChannelMask; + +/* Speaker Positions: */ +#define PAWIN_SPEAKER_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1) +#define PAWIN_SPEAKER_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x2) +#define PAWIN_SPEAKER_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x4) +#define PAWIN_SPEAKER_LOW_FREQUENCY ((PaWinWaveFormatChannelMask)0x8) +#define PAWIN_SPEAKER_BACK_LEFT ((PaWinWaveFormatChannelMask)0x10) +#define PAWIN_SPEAKER_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20) +#define PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER ((PaWinWaveFormatChannelMask)0x40) +#define PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER ((PaWinWaveFormatChannelMask)0x80) +#define PAWIN_SPEAKER_BACK_CENTER ((PaWinWaveFormatChannelMask)0x100) +#define PAWIN_SPEAKER_SIDE_LEFT ((PaWinWaveFormatChannelMask)0x200) +#define PAWIN_SPEAKER_SIDE_RIGHT ((PaWinWaveFormatChannelMask)0x400) +#define PAWIN_SPEAKER_TOP_CENTER ((PaWinWaveFormatChannelMask)0x800) +#define PAWIN_SPEAKER_TOP_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1000) +#define PAWIN_SPEAKER_TOP_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x2000) +#define PAWIN_SPEAKER_TOP_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x4000) +#define PAWIN_SPEAKER_TOP_BACK_LEFT ((PaWinWaveFormatChannelMask)0x8000) +#define PAWIN_SPEAKER_TOP_BACK_CENTER ((PaWinWaveFormatChannelMask)0x10000) +#define PAWIN_SPEAKER_TOP_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20000) + +/* Bit mask locations reserved for future use */ +#define PAWIN_SPEAKER_RESERVED ((PaWinWaveFormatChannelMask)0x7FFC0000) + +/* Used to specify that any possible permutation of speaker configurations */ +#define PAWIN_SPEAKER_ALL ((PaWinWaveFormatChannelMask)0x80000000) + +/* DirectSound Speaker Config */ +#define PAWIN_SPEAKER_DIRECTOUT 0 +#define PAWIN_SPEAKER_MONO (PAWIN_SPEAKER_FRONT_CENTER) +#define PAWIN_SPEAKER_STEREO (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT) +#define PAWIN_SPEAKER_QUAD (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ + PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) +#define PAWIN_SPEAKER_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ + PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_BACK_CENTER) +#define PAWIN_SPEAKER_5POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ + PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ + PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) +#define PAWIN_SPEAKER_7POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ + PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ + PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ + PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER | PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER) +#define PAWIN_SPEAKER_5POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ + PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ + PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) +#define PAWIN_SPEAKER_7POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ + PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ + PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ + PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) +/* + According to the Microsoft documentation: + The following are obsolete 5.1 and 7.1 settings (they lack side speakers). Note this means + that the default 5.1 and 7.1 settings (KSAUDIO_SPEAKER_5POINT1 and KSAUDIO_SPEAKER_7POINT1 are + similarly obsolete but are unchanged for compatibility reasons). +*/ +#define PAWIN_SPEAKER_5POINT1_BACK PAWIN_SPEAKER_5POINT1 +#define PAWIN_SPEAKER_7POINT1_WIDE PAWIN_SPEAKER_7POINT1 + +/* DVD Speaker Positions */ +#define PAWIN_SPEAKER_GROUND_FRONT_LEFT PAWIN_SPEAKER_FRONT_LEFT +#define PAWIN_SPEAKER_GROUND_FRONT_CENTER PAWIN_SPEAKER_FRONT_CENTER +#define PAWIN_SPEAKER_GROUND_FRONT_RIGHT PAWIN_SPEAKER_FRONT_RIGHT +#define PAWIN_SPEAKER_GROUND_REAR_LEFT PAWIN_SPEAKER_BACK_LEFT +#define PAWIN_SPEAKER_GROUND_REAR_RIGHT PAWIN_SPEAKER_BACK_RIGHT +#define PAWIN_SPEAKER_TOP_MIDDLE PAWIN_SPEAKER_TOP_CENTER +#define PAWIN_SPEAKER_SUPER_WOOFER PAWIN_SPEAKER_LOW_FREQUENCY + + +/* + PaWinWaveFormat is defined here to provide compatibility with + compilation environments which don't have headers defining + WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc. + + The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an + unsigned char array here to avoid clients who include this file having + a dependency on windows.h and mmsystem.h, and also to to avoid having + to write separate packing pragmas for each compiler. +*/ +#define PAWIN_SIZEOF_WAVEFORMATEX 18 +#define PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE (PAWIN_SIZEOF_WAVEFORMATEX + 22) + +typedef struct{ + unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ]; + unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */ +} PaWinWaveFormat; + +/* + WAVEFORMATEXTENSIBLE fields: + + union { + WORD wValidBitsPerSample; + WORD wSamplesPerBlock; + WORD wReserved; + } Samples; + DWORD dwChannelMask; + GUID SubFormat; +*/ + +#define PAWIN_INDEXOF_WVALIDBITSPERSAMPLE (PAWIN_SIZEOF_WAVEFORMATEX+0) +#define PAWIN_INDEXOF_DWCHANNELMASK (PAWIN_SIZEOF_WAVEFORMATEX+2) +#define PAWIN_INDEXOF_SUBFORMAT (PAWIN_SIZEOF_WAVEFORMATEX+6) + + +/* + Valid values to pass for the waveFormatTag PaWin_InitializeWaveFormatEx and + PaWin_InitializeWaveFormatExtensible functions below. These must match + the standard Windows WAVE_FORMAT_* values. +*/ +#define PAWIN_WAVE_FORMAT_PCM (1) +#define PAWIN_WAVE_FORMAT_IEEE_FLOAT (3) +#define PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF (0x0092) +#define PAWIN_WAVE_FORMAT_WMA_SPDIF (0x0164) + + +/* + returns PAWIN_WAVE_FORMAT_PCM or PAWIN_WAVE_FORMAT_IEEE_FLOAT + depending on the sampleFormat parameter. +*/ +int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat ); + +/* + Use the following two functions to initialize the waveformat structure. +*/ + +void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, + int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate ); + + +void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, + int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate, + PaWinWaveFormatChannelMask channelMask ); + + +/* Map a channel count to a speaker channel mask */ +PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_WIN_WAVEFORMAT_H */ \ No newline at end of file diff --git a/external/portaudio/include/pa_win_wdmks.h b/external/portaudio/include/pa_win_wdmks.h new file mode 100644 index 0000000..9fe9284 --- /dev/null +++ b/external/portaudio/include/pa_win_wdmks.h @@ -0,0 +1,106 @@ +#ifndef PA_WIN_WDMKS_H +#define PA_WIN_WDMKS_H +/* + * $Id: pa_win_wdmks.h 1812 2012-02-14 09:32:57Z robiwan $ + * PortAudio Portable Real-Time Audio Library + * WDM/KS specific extensions + * + * Copyright (c) 1999-2007 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief WDM Kernel Streaming-specific PortAudio API extension header file. +*/ + + +#include "portaudio.h" + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + typedef struct PaWinWDMKSInfo{ + unsigned long size; /**< sizeof(PaWinWDMKSInfo) */ + PaHostApiTypeId hostApiType; /**< paWDMKS */ + unsigned long version; /**< 1 */ + + /* The number of packets to use for WaveCyclic devices, range is [2, 8]. Set to zero for default value of 2. */ + unsigned noOfPackets; + } PaWinWDMKSInfo; + + typedef enum PaWDMKSType + { + Type_kNotUsed, + Type_kWaveCyclic, + Type_kWaveRT, + Type_kCnt, + } PaWDMKSType; + + typedef enum PaWDMKSSubType + { + SubType_kUnknown, + SubType_kNotification, + SubType_kPolled, + SubType_kCnt, + } PaWDMKSSubType; + + typedef struct PaWinWDMKSDeviceInfo { + wchar_t filterPath[MAX_PATH]; /**< KS filter path in Unicode! */ + wchar_t topologyPath[MAX_PATH]; /**< Topology filter path in Unicode! */ + PaWDMKSType streamingType; + GUID deviceProductGuid; /**< The product GUID of the device (if supported) */ + } PaWinWDMKSDeviceInfo; + + typedef struct PaWDMKSDirectionSpecificStreamInfo + { + PaDeviceIndex device; + unsigned channels; /**< No of channels the device is opened with */ + unsigned framesPerHostBuffer; /**< No of frames of the device buffer */ + int endpointPinId; /**< Endpoint pin ID (on topology filter if topologyName is not empty) */ + int muxNodeId; /**< Only valid for input */ + PaWDMKSSubType streamingSubType; /**< Not known until device is opened for streaming */ + } PaWDMKSDirectionSpecificStreamInfo; + + typedef struct PaWDMKSSpecificStreamInfo { + PaWDMKSDirectionSpecificStreamInfo input; + PaWDMKSDirectionSpecificStreamInfo output; + } PaWDMKSSpecificStreamInfo; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_WIN_DS_H */ diff --git a/external/portaudio/include/pa_win_wmme.h b/external/portaudio/include/pa_win_wmme.h new file mode 100644 index 0000000..ac5efe7 --- /dev/null +++ b/external/portaudio/include/pa_win_wmme.h @@ -0,0 +1,185 @@ +#ifndef PA_WIN_WMME_H +#define PA_WIN_WMME_H +/* + * $Id: pa_win_wmme.h 1592 2011-02-04 10:41:58Z rossb $ + * PortAudio Portable Real-Time Audio Library + * MME specific extensions + * + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief WMME-specific PortAudio API extension header file. +*/ + +#include "portaudio.h" +#include "pa_win_waveformat.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/* The following are flags which can be set in + PaWinMmeStreamInfo's flags field. +*/ + +#define paWinMmeUseLowLevelLatencyParameters (0x01) +#define paWinMmeUseMultipleDevices (0x02) /* use mme specific multiple device feature */ +#define paWinMmeUseChannelMask (0x04) + +/* By default, the mme implementation drops the processing thread's priority + to THREAD_PRIORITY_NORMAL and sleeps the thread if the CPU load exceeds 100% + This flag disables any priority throttling. The processing thread will always + run at THREAD_PRIORITY_TIME_CRITICAL. +*/ +#define paWinMmeDontThrottleOverloadedProcessingThread (0x08) + +/* Flags for non-PCM spdif passthrough. +*/ +#define paWinMmeWaveFormatDolbyAc3Spdif (0x10) +#define paWinMmeWaveFormatWmaSpdif (0x20) + + +typedef struct PaWinMmeDeviceAndChannelCount{ + PaDeviceIndex device; + int channelCount; +}PaWinMmeDeviceAndChannelCount; + + +typedef struct PaWinMmeStreamInfo{ + unsigned long size; /**< sizeof(PaWinMmeStreamInfo) */ + PaHostApiTypeId hostApiType; /**< paMME */ + unsigned long version; /**< 1 */ + + unsigned long flags; + + /* low-level latency setting support + These settings control the number and size of host buffers in order + to set latency. They will be used instead of the generic parameters + to Pa_OpenStream() if flags contains the PaWinMmeUseLowLevelLatencyParameters + flag. + + If PaWinMmeStreamInfo structures with PaWinMmeUseLowLevelLatencyParameters + are supplied for both input and output in a full duplex stream, then the + input and output framesPerBuffer must be the same, or the larger of the + two must be a multiple of the smaller, otherwise a + paIncompatibleHostApiSpecificStreamInfo error will be returned from + Pa_OpenStream(). + */ + unsigned long framesPerBuffer; + unsigned long bufferCount; /* formerly numBuffers */ + + /* multiple devices per direction support + If flags contains the PaWinMmeUseMultipleDevices flag, + this functionality will be used, otherwise the device parameter to + Pa_OpenStream() will be used instead. + If devices are specified here, the corresponding device parameter + to Pa_OpenStream() should be set to paUseHostApiSpecificDeviceSpecification, + otherwise an paInvalidDevice error will result. + The total number of channels accross all specified devices + must agree with the corresponding channelCount parameter to + Pa_OpenStream() otherwise a paInvalidChannelCount error will result. + */ + PaWinMmeDeviceAndChannelCount *devices; + unsigned long deviceCount; + + /* + support for WAVEFORMATEXTENSIBLE channel masks. If flags contains + paWinMmeUseChannelMask this allows you to specify which speakers + to address in a multichannel stream. Constants for channelMask + are specified in pa_win_waveformat.h + + */ + PaWinWaveFormatChannelMask channelMask; + +}PaWinMmeStreamInfo; + + +/** Retrieve the number of wave in handles used by a PortAudio WinMME stream. + Returns zero if the stream is output only. + + @return A non-negative value indicating the number of wave in handles + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + @see PaWinMME_GetStreamInputHandle +*/ +int PaWinMME_GetStreamInputHandleCount( PaStream* stream ); + + +/** Retrieve a wave in handle used by a PortAudio WinMME stream. + + @param stream The stream to query. + @param handleIndex The zero based index of the wave in handle to retrieve. This + should be in the range [0, PaWinMME_GetStreamInputHandleCount(stream)-1]. + + @return A valid wave in handle, or NULL if an error occurred. + + @see PaWinMME_GetStreamInputHandle +*/ +HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex ); + + +/** Retrieve the number of wave out handles used by a PortAudio WinMME stream. + Returns zero if the stream is input only. + + @return A non-negative value indicating the number of wave out handles + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + @see PaWinMME_GetStreamOutputHandle +*/ +int PaWinMME_GetStreamOutputHandleCount( PaStream* stream ); + + +/** Retrieve a wave out handle used by a PortAudio WinMME stream. + + @param stream The stream to query. + @param handleIndex The zero based index of the wave out handle to retrieve. + This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1]. + + @return A valid wave out handle, or NULL if an error occurred. + + @see PaWinMME_GetStreamOutputHandleCount +*/ +HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex ); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_WIN_WMME_H */ diff --git a/external/portaudio/include/portaudio.h b/external/portaudio/include/portaudio.h new file mode 100644 index 0000000..5e11dad --- /dev/null +++ b/external/portaudio/include/portaudio.h @@ -0,0 +1,1174 @@ +#ifndef PORTAUDIO_H +#define PORTAUDIO_H +/* + * $Id: portaudio.h 1859 2012-09-01 00:10:13Z philburk $ + * PortAudio Portable Real-Time Audio Library + * PortAudio API Header File + * Latest version available at: http://www.portaudio.com/ + * + * Copyright (c) 1999-2002 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief The portable PortAudio API. +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/** Retrieve the release number of the currently running PortAudio build, + eg 1900. +*/ +int Pa_GetVersion( void ); + + +/** Retrieve a textual description of the current PortAudio build, + eg "PortAudio V19-devel 13 October 2002". +*/ +const char* Pa_GetVersionText( void ); + + +/** Error codes returned by PortAudio functions. + Note that with the exception of paNoError, all PaErrorCodes are negative. +*/ + +typedef int PaError; +typedef enum PaErrorCode +{ + paNoError = 0, + + paNotInitialized = -10000, + paUnanticipatedHostError, + paInvalidChannelCount, + paInvalidSampleRate, + paInvalidDevice, + paInvalidFlag, + paSampleFormatNotSupported, + paBadIODeviceCombination, + paInsufficientMemory, + paBufferTooBig, + paBufferTooSmall, + paNullCallback, + paBadStreamPtr, + paTimedOut, + paInternalError, + paDeviceUnavailable, + paIncompatibleHostApiSpecificStreamInfo, + paStreamIsStopped, + paStreamIsNotStopped, + paInputOverflowed, + paOutputUnderflowed, + paHostApiNotFound, + paInvalidHostApi, + paCanNotReadFromACallbackStream, + paCanNotWriteToACallbackStream, + paCanNotReadFromAnOutputOnlyStream, + paCanNotWriteToAnInputOnlyStream, + paIncompatibleStreamHostApi, + paBadBufferPtr +} PaErrorCode; + + +/** Translate the supplied PortAudio error code into a human readable + message. +*/ +const char *Pa_GetErrorText( PaError errorCode ); + + +/** Library initialization function - call this before using PortAudio. + This function initializes internal data structures and prepares underlying + host APIs for use. With the exception of Pa_GetVersion(), Pa_GetVersionText(), + and Pa_GetErrorText(), this function MUST be called before using any other + PortAudio API functions. + + If Pa_Initialize() is called multiple times, each successful + call must be matched with a corresponding call to Pa_Terminate(). + Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not + required to be fully nested. + + Note that if Pa_Initialize() returns an error code, Pa_Terminate() should + NOT be called. + + @return paNoError if successful, otherwise an error code indicating the cause + of failure. + + @see Pa_Terminate +*/ +PaError Pa_Initialize( void ); + + +/** Library termination function - call this when finished using PortAudio. + This function deallocates all resources allocated by PortAudio since it was + initialized by a call to Pa_Initialize(). In cases where Pa_Initialise() has + been called multiple times, each call must be matched with a corresponding call + to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically + close any PortAudio streams that are still open. + + Pa_Terminate() MUST be called before exiting a program which uses PortAudio. + Failure to do so may result in serious resource leaks, such as audio devices + not being available until the next reboot. + + @return paNoError if successful, otherwise an error code indicating the cause + of failure. + + @see Pa_Initialize +*/ +PaError Pa_Terminate( void ); + + + +/** The type used to refer to audio devices. Values of this type usually + range from 0 to (Pa_GetDeviceCount()-1), and may also take on the PaNoDevice + and paUseHostApiSpecificDeviceSpecification values. + + @see Pa_GetDeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification +*/ +typedef int PaDeviceIndex; + + +/** A special PaDeviceIndex value indicating that no device is available, + or should be used. + + @see PaDeviceIndex +*/ +#define paNoDevice ((PaDeviceIndex)-1) + + +/** A special PaDeviceIndex value indicating that the device(s) to be used + are specified in the host api specific stream info structure. + + @see PaDeviceIndex +*/ +#define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2) + + +/* Host API enumeration mechanism */ + +/** The type used to enumerate to host APIs at runtime. Values of this type + range from 0 to (Pa_GetHostApiCount()-1). + + @see Pa_GetHostApiCount +*/ +typedef int PaHostApiIndex; + + +/** Retrieve the number of available host APIs. Even if a host API is + available it may have no devices available. + + @return A non-negative value indicating the number of available host APIs + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + @see PaHostApiIndex +*/ +PaHostApiIndex Pa_GetHostApiCount( void ); + + +/** Retrieve the index of the default host API. The default host API will be + the lowest common denominator host API on the current platform and is + unlikely to provide the best performance. + + @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1) + indicating the default host API index or, a PaErrorCode (which are always + negative) if PortAudio is not initialized or an error is encountered. +*/ +PaHostApiIndex Pa_GetDefaultHostApi( void ); + + +/** Unchanging unique identifiers for each supported host API. This type + is used in the PaHostApiInfo structure. The values are guaranteed to be + unique and to never change, thus allowing code to be written that + conditionally uses host API specific extensions. + + New type ids will be allocated when support for a host API reaches + "public alpha" status, prior to that developers should use the + paInDevelopment type id. + + @see PaHostApiInfo +*/ +typedef enum PaHostApiTypeId +{ + paInDevelopment=0, /* use while developing support for a new host API */ + paDirectSound=1, + paMME=2, + paASIO=3, + paSoundManager=4, + paCoreAudio=5, + paOSS=7, + paALSA=8, + paAL=9, + paBeOS=10, + paWDMKS=11, + paJACK=12, + paWASAPI=13, + paAudioScienceHPI=14 +} PaHostApiTypeId; + + +/** A structure containing information about a particular host API. */ + +typedef struct PaHostApiInfo +{ + /** this is struct version 1 */ + int structVersion; + /** The well known unique identifier of this host API @see PaHostApiTypeId */ + PaHostApiTypeId type; + /** A textual description of the host API for display on user interfaces. */ + const char *name; + + /** The number of devices belonging to this host API. This field may be + used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate + all devices for this host API. + @see Pa_HostApiDeviceIndexToDeviceIndex + */ + int deviceCount; + + /** The default input device for this host API. The value will be a + device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice + if no default input device is available. + */ + PaDeviceIndex defaultInputDevice; + + /** The default output device for this host API. The value will be a + device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice + if no default output device is available. + */ + PaDeviceIndex defaultOutputDevice; + +} PaHostApiInfo; + + +/** Retrieve a pointer to a structure containing information about a specific + host Api. + + @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) + + @return A pointer to an immutable PaHostApiInfo structure describing + a specific host API. If the hostApi parameter is out of range or an error + is encountered, the function returns NULL. + + The returned structure is owned by the PortAudio implementation and must not + be manipulated or freed. The pointer is only guaranteed to be valid between + calls to Pa_Initialize() and Pa_Terminate(). +*/ +const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi ); + + +/** Convert a static host API unique identifier, into a runtime + host API index. + + @param type A unique host API identifier belonging to the PaHostApiTypeId + enumeration. + + @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or, + a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + The paHostApiNotFound error code indicates that the host API specified by the + type parameter is not available. + + @see PaHostApiTypeId +*/ +PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ); + + +/** Convert a host-API-specific device index to standard PortAudio device index. + This function may be used in conjunction with the deviceCount field of + PaHostApiInfo to enumerate all devices for the specified host API. + + @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) + + @param hostApiDeviceIndex A valid per-host device index in the range + 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1) + + @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1) + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + A paInvalidHostApi error code indicates that the host API index specified by + the hostApi parameter is out of range. + + A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter + is out of range. + + @see PaHostApiInfo +*/ +PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, + int hostApiDeviceIndex ); + + + +/** Structure used to return information about a host error condition. +*/ +typedef struct PaHostErrorInfo{ + PaHostApiTypeId hostApiType; /**< the host API which returned the error code */ + long errorCode; /**< the error code returned */ + const char *errorText; /**< a textual description of the error if available, otherwise a zero-length string */ +}PaHostErrorInfo; + + +/** Return information about the last host error encountered. The error + information returned by Pa_GetLastHostErrorInfo() will never be modified + asynchronously by errors occurring in other PortAudio owned threads + (such as the thread that manages the stream callback.) + + This function is provided as a last resort, primarily to enhance debugging + by providing clients with access to all available error information. + + @return A pointer to an immutable structure constraining information about + the host error. The values in this structure will only be valid if a + PortAudio function has previously returned the paUnanticipatedHostError + error code. +*/ +const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ); + + + +/* Device enumeration and capabilities */ + +/** Retrieve the number of available devices. The number of available devices + may be zero. + + @return A non-negative value indicating the number of available devices or, + a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. +*/ +PaDeviceIndex Pa_GetDeviceCount( void ); + + +/** Retrieve the index of the default input device. The result can be + used in the inputDevice parameter to Pa_OpenStream(). + + @return The default input device index for the default host API, or paNoDevice + if no default input device is available or an error was encountered. +*/ +PaDeviceIndex Pa_GetDefaultInputDevice( void ); + + +/** Retrieve the index of the default output device. The result can be + used in the outputDevice parameter to Pa_OpenStream(). + + @return The default output device index for the default host API, or paNoDevice + if no default output device is available or an error was encountered. + + @note + On the PC, the user can specify a default device by + setting an environment variable. For example, to use device #1. +
+ set PA_RECOMMENDED_OUTPUT_DEVICE=1
+
+ The user should first determine the available device ids by using + the supplied application "pa_devs". +*/ +PaDeviceIndex Pa_GetDefaultOutputDevice( void ); + + +/** The type used to represent monotonic time in seconds. PaTime is + used for the fields of the PaStreamCallbackTimeInfo argument to the + PaStreamCallback and as the result of Pa_GetStreamTime(). + + PaTime values have unspecified origin. + + @see PaStreamCallback, PaStreamCallbackTimeInfo, Pa_GetStreamTime +*/ +typedef double PaTime; + + +/** A type used to specify one or more sample formats. Each value indicates + a possible format for sound data passed to and from the stream callback, + Pa_ReadStream and Pa_WriteStream. + + The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8 + and aUInt8 are usually implemented by all implementations. + + The floating point representation (paFloat32) uses +1.0 and -1.0 as the + maximum and minimum respectively. + + paUInt8 is an unsigned 8 bit format where 128 is considered "ground" + + The paNonInterleaved flag indicates that audio data is passed as an array + of pointers to separate buffers, one buffer for each channel. Usually, + when this flag is not used, audio data is passed as a single buffer with + all channels interleaved. + + @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo + @see paFloat32, paInt16, paInt32, paInt24, paInt8 + @see paUInt8, paCustomFormat, paNonInterleaved +*/ +typedef unsigned long PaSampleFormat; + + +#define paFloat32 ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */ +#define paInt32 ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */ +#define paInt24 ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */ +#define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */ +#define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */ +#define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */ +#define paCustomFormat ((PaSampleFormat) 0x00010000) /**< @see PaSampleFormat */ + +#define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */ + +/** A structure providing information and capabilities of PortAudio devices. + Devices may support input, output or both input and output. +*/ +typedef struct PaDeviceInfo +{ + int structVersion; /* this is struct version 2 */ + const char *name; + PaHostApiIndex hostApi; /**< note this is a host API index, not a type id*/ + + int maxInputChannels; + int maxOutputChannels; + + /** Default latency values for interactive performance. */ + PaTime defaultLowInputLatency; + PaTime defaultLowOutputLatency; + /** Default latency values for robust non-interactive applications (eg. playing sound files). */ + PaTime defaultHighInputLatency; + PaTime defaultHighOutputLatency; + + double defaultSampleRate; +} PaDeviceInfo; + + +/** Retrieve a pointer to a PaDeviceInfo structure containing information + about the specified device. + @return A pointer to an immutable PaDeviceInfo structure. If the device + parameter is out of range the function returns NULL. + + @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1) + + @note PortAudio manages the memory referenced by the returned pointer, + the client must not manipulate or free the memory. The pointer is only + guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). + + @see PaDeviceInfo, PaDeviceIndex +*/ +const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ); + + +/** Parameters for one direction (input or output) of a stream. +*/ +typedef struct PaStreamParameters +{ + /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1) + specifying the device to be used or the special constant + paUseHostApiSpecificDeviceSpecification which indicates that the actual + device(s) to use are specified in hostApiSpecificStreamInfo. + This field must not be set to paNoDevice. + */ + PaDeviceIndex device; + + /** The number of channels of sound to be delivered to the + stream callback or accessed by Pa_ReadStream() or Pa_WriteStream(). + It can range from 1 to the value of maxInputChannels in the + PaDeviceInfo record for the device specified by the device parameter. + */ + int channelCount; + + /** The sample format of the buffer provided to the stream callback, + a_ReadStream() or Pa_WriteStream(). It may be any of the formats described + by the PaSampleFormat enumeration. + */ + PaSampleFormat sampleFormat; + + /** The desired latency in seconds. Where practical, implementations should + configure their latency based on these parameters, otherwise they may + choose the closest viable latency instead. Unless the suggested latency + is greater than the absolute upper limit for the device implementations + should round the suggestedLatency up to the next practical value - ie to + provide an equal or higher latency than suggestedLatency wherever possible. + Actual latency values for an open stream may be retrieved using the + inputLatency and outputLatency fields of the PaStreamInfo structure + returned by Pa_GetStreamInfo(). + @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo + */ + PaTime suggestedLatency; + + /** An optional pointer to a host api specific data structure + containing additional information for device setup and/or stream processing. + hostApiSpecificStreamInfo is never required for correct operation, + if not used it should be set to NULL. + */ + void *hostApiSpecificStreamInfo; + +} PaStreamParameters; + + +/** Return code for Pa_IsFormatSupported indicating success. */ +#define paFormatIsSupported (0) + +/** Determine whether it would be possible to open a stream with the specified + parameters. + + @param inputParameters A structure that describes the input parameters used to + open a stream. The suggestedLatency field is ignored. See PaStreamParameters + for a description of these parameters. inputParameters must be NULL for + output-only streams. + + @param outputParameters A structure that describes the output parameters used + to open a stream. The suggestedLatency field is ignored. See PaStreamParameters + for a description of these parameters. outputParameters must be NULL for + input-only streams. + + @param sampleRate The required sampleRate. For full-duplex streams it is the + sample rate for both input and output + + @return Returns 0 if the format is supported, and an error code indicating why + the format is not supported otherwise. The constant paFormatIsSupported is + provided to compare with the return value for success. + + @see paFormatIsSupported, PaStreamParameters +*/ +PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, + const PaStreamParameters *outputParameters, + double sampleRate ); + + + +/* Streaming types and functions */ + + +/** + A single PaStream can provide multiple channels of real-time + streaming audio input and output to a client application. A stream + provides access to audio hardware represented by one or more + PaDevices. Depending on the underlying Host API, it may be possible + to open multiple streams using the same device, however this behavior + is implementation defined. Portable applications should assume that + a PaDevice may be simultaneously used by at most one PaStream. + + Pointers to PaStream objects are passed between PortAudio functions that + operate on streams. + + @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream, + Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive, + Pa_GetStreamTime, Pa_GetStreamCpuLoad + +*/ +typedef void PaStream; + + +/** Can be passed as the framesPerBuffer parameter to Pa_OpenStream() + or Pa_OpenDefaultStream() to indicate that the stream callback will + accept buffers of any size. +*/ +#define paFramesPerBufferUnspecified (0) + + +/** Flags used to control the behavior of a stream. They are passed as + parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be + ORed together. + + @see Pa_OpenStream, Pa_OpenDefaultStream + @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput, + paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags +*/ +typedef unsigned long PaStreamFlags; + +/** @see PaStreamFlags */ +#define paNoFlag ((PaStreamFlags) 0) + +/** Disable default clipping of out of range samples. + @see PaStreamFlags +*/ +#define paClipOff ((PaStreamFlags) 0x00000001) + +/** Disable default dithering. + @see PaStreamFlags +*/ +#define paDitherOff ((PaStreamFlags) 0x00000002) + +/** Flag requests that where possible a full duplex stream will not discard + overflowed input samples without calling the stream callback. This flag is + only valid for full duplex callback streams and only when used in combination + with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using + this flag incorrectly results in a paInvalidFlag error being returned from + Pa_OpenStream and Pa_OpenDefaultStream. + + @see PaStreamFlags, paFramesPerBufferUnspecified +*/ +#define paNeverDropInput ((PaStreamFlags) 0x00000004) + +/** Call the stream callback to fill initial output buffers, rather than the + default behavior of priming the buffers with zeros (silence). This flag has + no effect for input-only and blocking read/write streams. + + @see PaStreamFlags +*/ +#define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008) + +/** A mask specifying the platform specific bits. + @see PaStreamFlags +*/ +#define paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000) + +/** + Timing information for the buffers passed to the stream callback. + + Time values are expressed in seconds and are synchronised with the time base used by Pa_GetStreamTime() for the associated stream. + + @see PaStreamCallback, Pa_GetStreamTime +*/ +typedef struct PaStreamCallbackTimeInfo{ + PaTime inputBufferAdcTime; /**< The time when the first sample of the input buffer was captured at the ADC input */ + PaTime currentTime; /**< The time when the stream callback was invoked */ + PaTime outputBufferDacTime; /**< The time when the first sample of the output buffer will output the DAC */ +} PaStreamCallbackTimeInfo; + + +/** + Flag bit constants for the statusFlags to PaStreamCallback. + + @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow, + paPrimingOutput +*/ +typedef unsigned long PaStreamCallbackFlags; + +/** In a stream opened with paFramesPerBufferUnspecified, indicates that + input data is all silence (zeros) because no real data is available. In a + stream opened without paFramesPerBufferUnspecified, it indicates that one or + more zero samples have been inserted into the input buffer to compensate + for an input underflow. + @see PaStreamCallbackFlags +*/ +#define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001) + +/** In a stream opened with paFramesPerBufferUnspecified, indicates that data + prior to the first sample of the input buffer was discarded due to an + overflow, possibly because the stream callback is using too much CPU time. + Otherwise indicates that data prior to one or more samples in the + input buffer was discarded. + @see PaStreamCallbackFlags +*/ +#define paInputOverflow ((PaStreamCallbackFlags) 0x00000002) + +/** Indicates that output data (or a gap) was inserted, possibly because the + stream callback is using too much CPU time. + @see PaStreamCallbackFlags +*/ +#define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004) + +/** Indicates that output data will be discarded because no room is available. + @see PaStreamCallbackFlags +*/ +#define paOutputOverflow ((PaStreamCallbackFlags) 0x00000008) + +/** Some of all of the output data will be used to prime the stream, input + data may be zero. + @see PaStreamCallbackFlags +*/ +#define paPrimingOutput ((PaStreamCallbackFlags) 0x00000010) + +/** + Allowable return values for the PaStreamCallback. + @see PaStreamCallback +*/ +typedef enum PaStreamCallbackResult +{ + paContinue=0, /**< Signal that the stream should continue invoking the callback and processing audio. */ + paComplete=1, /**< Signal that the stream should stop invoking the callback and finish once all output samples have played. */ + paAbort=2 /**< Signal that the stream should stop invoking the callback and finish as soon as possible. */ +} PaStreamCallbackResult; + + +/** + Functions of type PaStreamCallback are implemented by PortAudio clients. + They consume, process or generate audio in response to requests from an + active PortAudio stream. + + When a stream is running, PortAudio calls the stream callback periodically. + The callback function is responsible for processing buffers of audio samples + passed via the input and output parameters. + + The PortAudio stream callback runs at very high or real-time priority. + It is required to consistently meet its time deadlines. Do not allocate + memory, access the file system, call library functions or call other functions + from the stream callback that may block or take an unpredictable amount of + time to complete. + + In order for a stream to maintain glitch-free operation the callback + must consume and return audio data faster than it is recorded and/or + played. PortAudio anticipates that each callback invocation may execute for + a duration approaching the duration of frameCount audio frames at the stream + sample rate. It is reasonable to expect to be able to utilise 70% or more of + the available CPU time in the PortAudio callback. However, due to buffer size + adaption and other factors, not all host APIs are able to guarantee audio + stability under heavy CPU load with arbitrary fixed callback buffer sizes. + When high callback CPU utilisation is required the most robust behavior + can be achieved by using paFramesPerBufferUnspecified as the + Pa_OpenStream() framesPerBuffer parameter. + + @param input and @param output are either arrays of interleaved samples or; + if non-interleaved samples were requested using the paNonInterleaved sample + format flag, an array of buffer pointers, one non-interleaved buffer for + each channel. + + The format, packing and number of channels used by the buffers are + determined by parameters to Pa_OpenStream(). + + @param frameCount The number of sample frames to be processed by + the stream callback. + + @param timeInfo Timestamps indicating the ADC capture time of the first sample + in the input buffer, the DAC output time of the first sample in the output buffer + and the time the callback was invoked. + See PaStreamCallbackTimeInfo and Pa_GetStreamTime() + + @param statusFlags Flags indicating whether input and/or output buffers + have been inserted or will be dropped to overcome underflow or overflow + conditions. + + @param userData The value of a user supplied pointer passed to + Pa_OpenStream() intended for storing synthesis data etc. + + @return + The stream callback should return one of the values in the + ::PaStreamCallbackResult enumeration. To ensure that the callback continues + to be called, it should return paContinue (0). Either paComplete or paAbort + can be returned to finish stream processing, after either of these values is + returned the callback will not be called again. If paAbort is returned the + stream will finish as soon as possible. If paComplete is returned, the stream + will continue until all buffers generated by the callback have been played. + This may be useful in applications such as soundfile players where a specific + duration of output is required. However, it is not necessary to utilize this + mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also + be used to stop the stream. The callback must always fill the entire output + buffer irrespective of its return value. + + @see Pa_OpenStream, Pa_OpenDefaultStream + + @note With the exception of Pa_GetStreamCpuLoad() it is not permissible to call + PortAudio API functions from within the stream callback. +*/ +typedef int PaStreamCallback( + const void *input, void *output, + unsigned long frameCount, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ); + + +/** Opens a stream for either input, output or both. + + @param stream The address of a PaStream pointer which will receive + a pointer to the newly opened stream. + + @param inputParameters A structure that describes the input parameters used by + the opened stream. See PaStreamParameters for a description of these parameters. + inputParameters must be NULL for output-only streams. + + @param outputParameters A structure that describes the output parameters used by + the opened stream. See PaStreamParameters for a description of these parameters. + outputParameters must be NULL for input-only streams. + + @param sampleRate The desired sampleRate. For full-duplex streams it is the + sample rate for both input and output + + @param framesPerBuffer The number of frames passed to the stream callback + function, or the preferred block granularity for a blocking read/write stream. + The special value paFramesPerBufferUnspecified (0) may be used to request that + the stream callback will receive an optimal (and possibly varying) number of + frames based on host requirements and the requested latency settings. + Note: With some host APIs, the use of non-zero framesPerBuffer for a callback + stream may introduce an additional layer of buffering which could introduce + additional latency. PortAudio guarantees that the additional latency + will be kept to the theoretical minimum however, it is strongly recommended + that a non-zero framesPerBuffer value only be used when your algorithm + requires a fixed number of frames per stream callback. + + @param streamFlags Flags which modify the behavior of the streaming process. + This parameter may contain a combination of flags ORed together. Some flags may + only be relevant to certain buffer formats. + + @param streamCallback A pointer to a client supplied function that is responsible + for processing and filling input and output buffers. If this parameter is NULL + the stream will be opened in 'blocking read/write' mode. In blocking mode, + the client can receive sample data using Pa_ReadStream and write sample data + using Pa_WriteStream, the number of samples that may be read or written + without blocking is returned by Pa_GetStreamReadAvailable and + Pa_GetStreamWriteAvailable respectively. + + @param userData A client supplied pointer which is passed to the stream callback + function. It could for example, contain a pointer to instance data necessary + for processing the audio buffers. This parameter is ignored if streamCallback + is NULL. + + @return + Upon success Pa_OpenStream() returns paNoError and places a pointer to a + valid PaStream in the stream argument. The stream is inactive (stopped). + If a call to Pa_OpenStream() fails, a non-zero error code is returned (see + PaError for possible error codes) and the value of stream is invalid. + + @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream, + Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable +*/ +PaError Pa_OpenStream( PaStream** stream, + const PaStreamParameters *inputParameters, + const PaStreamParameters *outputParameters, + double sampleRate, + unsigned long framesPerBuffer, + PaStreamFlags streamFlags, + PaStreamCallback *streamCallback, + void *userData ); + + +/** A simplified version of Pa_OpenStream() that opens the default input + and/or output devices. + + @param stream The address of a PaStream pointer which will receive + a pointer to the newly opened stream. + + @param numInputChannels The number of channels of sound that will be supplied + to the stream callback or returned by Pa_ReadStream. It can range from 1 to + the value of maxInputChannels in the PaDeviceInfo record for the default input + device. If 0 the stream is opened as an output-only stream. + + @param numOutputChannels The number of channels of sound to be delivered to the + stream callback or passed to Pa_WriteStream. It can range from 1 to the value + of maxOutputChannels in the PaDeviceInfo record for the default output device. + If 0 the stream is opened as an output-only stream. + + @param sampleFormat The sample format of both the input and output buffers + provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream. + sampleFormat may be any of the formats described by the PaSampleFormat + enumeration. + + @param sampleRate Same as Pa_OpenStream parameter of the same name. + @param framesPerBuffer Same as Pa_OpenStream parameter of the same name. + @param streamCallback Same as Pa_OpenStream parameter of the same name. + @param userData Same as Pa_OpenStream parameter of the same name. + + @return As for Pa_OpenStream + + @see Pa_OpenStream, PaStreamCallback +*/ +PaError Pa_OpenDefaultStream( PaStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + PaStreamCallback *streamCallback, + void *userData ); + + +/** Closes an audio stream. If the audio stream is active it + discards any pending buffers as if Pa_AbortStream() had been called. +*/ +PaError Pa_CloseStream( PaStream *stream ); + + +/** Functions of type PaStreamFinishedCallback are implemented by PortAudio + clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback + function. Once registered they are called when the stream becomes inactive + (ie once a call to Pa_StopStream() will not block). + A stream will become inactive after the stream callback returns non-zero, + or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio + output, if the stream callback returns paComplete, or Pa_StopStream is called, + the stream finished callback will not be called until all generated sample data + has been played. + + @param userData The userData parameter supplied to Pa_OpenStream() + + @see Pa_SetStreamFinishedCallback +*/ +typedef void PaStreamFinishedCallback( void *userData ); + + +/** Register a stream finished callback function which will be called when the + stream becomes inactive. See the description of PaStreamFinishedCallback for + further details about when the callback will be called. + + @param stream a pointer to a PaStream that is in the stopped state - if the + stream is not stopped, the stream's finished callback will remain unchanged + and an error code will be returned. + + @param streamFinishedCallback a pointer to a function with the same signature + as PaStreamFinishedCallback, that will be called when the stream becomes + inactive. Passing NULL for this parameter will un-register a previously + registered stream finished callback function. + + @return on success returns paNoError, otherwise an error code indicating the cause + of the error. + + @see PaStreamFinishedCallback +*/ +PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); + + +/** Commences audio processing. +*/ +PaError Pa_StartStream( PaStream *stream ); + + +/** Terminates audio processing. It waits until all pending + audio buffers have been played before it returns. +*/ +PaError Pa_StopStream( PaStream *stream ); + + +/** Terminates audio processing immediately without waiting for pending + buffers to complete. +*/ +PaError Pa_AbortStream( PaStream *stream ); + + +/** Determine whether the stream is stopped. + A stream is considered to be stopped prior to a successful call to + Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream. + If a stream callback returns a value other than paContinue the stream is NOT + considered to be stopped. + + @return Returns one (1) when the stream is stopped, zero (0) when + the stream is running or, a PaErrorCode (which are always negative) if + PortAudio is not initialized or an error is encountered. + + @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive +*/ +PaError Pa_IsStreamStopped( PaStream *stream ); + + +/** Determine whether the stream is active. + A stream is active after a successful call to Pa_StartStream(), until it + becomes inactive either as a result of a call to Pa_StopStream() or + Pa_AbortStream(), or as a result of a return value other than paContinue from + the stream callback. In the latter case, the stream is considered inactive + after the last buffer has finished playing. + + @return Returns one (1) when the stream is active (ie playing or recording + audio), zero (0) when not playing or, a PaErrorCode (which are always negative) + if PortAudio is not initialized or an error is encountered. + + @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped +*/ +PaError Pa_IsStreamActive( PaStream *stream ); + + + +/** A structure containing unchanging information about an open stream. + @see Pa_GetStreamInfo +*/ + +typedef struct PaStreamInfo +{ + /** this is struct version 1 */ + int structVersion; + + /** The input latency of the stream in seconds. This value provides the most + accurate estimate of input latency available to the implementation. It may + differ significantly from the suggestedLatency value passed to Pa_OpenStream(). + The value of this field will be zero (0.) for output-only streams. + @see PaTime + */ + PaTime inputLatency; + + /** The output latency of the stream in seconds. This value provides the most + accurate estimate of output latency available to the implementation. It may + differ significantly from the suggestedLatency value passed to Pa_OpenStream(). + The value of this field will be zero (0.) for input-only streams. + @see PaTime + */ + PaTime outputLatency; + + /** The sample rate of the stream in Hertz (samples per second). In cases + where the hardware sample rate is inaccurate and PortAudio is aware of it, + the value of this field may be different from the sampleRate parameter + passed to Pa_OpenStream(). If information about the actual hardware sample + rate is not available, this field will have the same value as the sampleRate + parameter passed to Pa_OpenStream(). + */ + double sampleRate; + +} PaStreamInfo; + + +/** Retrieve a pointer to a PaStreamInfo structure containing information + about the specified stream. + @return A pointer to an immutable PaStreamInfo structure. If the stream + parameter is invalid, or an error is encountered, the function returns NULL. + + @param stream A pointer to an open stream previously created with Pa_OpenStream. + + @note PortAudio manages the memory referenced by the returned pointer, + the client must not manipulate or free the memory. The pointer is only + guaranteed to be valid until the specified stream is closed. + + @see PaStreamInfo +*/ +const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ); + + +/** Returns the current time in seconds for a stream according to the same clock used + to generate callback PaStreamCallbackTimeInfo timestamps. The time values are + monotonically increasing and have unspecified origin. + + Pa_GetStreamTime returns valid time values for the entire life of the stream, + from when the stream is opened until it is closed. Starting and stopping the stream + does not affect the passage of time returned by Pa_GetStreamTime. + + This time may be used for synchronizing other events to the audio stream, for + example synchronizing audio to MIDI. + + @return The stream's current time in seconds, or 0 if an error occurred. + + @see PaTime, PaStreamCallback, PaStreamCallbackTimeInfo +*/ +PaTime Pa_GetStreamTime( PaStream *stream ); + + +/** Retrieve CPU usage information for the specified stream. + The "CPU Load" is a fraction of total CPU time consumed by a callback stream's + audio processing routines including, but not limited to the client supplied + stream callback. This function does not work with blocking read/write streams. + + This function may be called from the stream callback function or the + application. + + @return + A floating point value, typically between 0.0 and 1.0, where 1.0 indicates + that the stream callback is consuming the maximum number of CPU cycles possible + to maintain real-time operation. A value of 0.5 would imply that PortAudio and + the stream callback was consuming roughly 50% of the available CPU time. The + return value may exceed 1.0. A value of 0.0 will always be returned for a + blocking read/write stream, or if an error occurs. +*/ +double Pa_GetStreamCpuLoad( PaStream* stream ); + + +/** Read samples from an input stream. The function doesn't return until + the entire buffer has been filled - this may involve waiting for the operating + system to supply the data. + + @param stream A pointer to an open stream previously created with Pa_OpenStream. + + @param buffer A pointer to a buffer of sample frames. The buffer contains + samples in the format specified by the inputParameters->sampleFormat field + used to open the stream, and the number of channels specified by + inputParameters->numChannels. If non-interleaved samples were requested using + the paNonInterleaved sample format flag, buffer is a pointer to the first element + of an array of buffer pointers, one non-interleaved buffer for each channel. + + @param frames The number of frames to be read into buffer. This parameter + is not constrained to a specific range, however high performance applications + will want to match this parameter to the framesPerBuffer parameter used + when opening the stream. + + @return On success PaNoError will be returned, or PaInputOverflowed if input + data was discarded by PortAudio after the previous call and before this call. +*/ +PaError Pa_ReadStream( PaStream* stream, + void *buffer, + unsigned long frames ); + + +/** Write samples to an output stream. This function doesn't return until the + entire buffer has been consumed - this may involve waiting for the operating + system to consume the data. + + @param stream A pointer to an open stream previously created with Pa_OpenStream. + + @param buffer A pointer to a buffer of sample frames. The buffer contains + samples in the format specified by the outputParameters->sampleFormat field + used to open the stream, and the number of channels specified by + outputParameters->numChannels. If non-interleaved samples were requested using + the paNonInterleaved sample format flag, buffer is a pointer to the first element + of an array of buffer pointers, one non-interleaved buffer for each channel. + + @param frames The number of frames to be written from buffer. This parameter + is not constrained to a specific range, however high performance applications + will want to match this parameter to the framesPerBuffer parameter used + when opening the stream. + + @return On success PaNoError will be returned, or paOutputUnderflowed if + additional output data was inserted after the previous call and before this + call. +*/ +PaError Pa_WriteStream( PaStream* stream, + const void *buffer, + unsigned long frames ); + + +/** Retrieve the number of frames that can be read from the stream without + waiting. + + @return Returns a non-negative value representing the maximum number of frames + that can be read from the stream without blocking or busy waiting or, a + PaErrorCode (which are always negative) if PortAudio is not initialized or an + error is encountered. +*/ +signed long Pa_GetStreamReadAvailable( PaStream* stream ); + + +/** Retrieve the number of frames that can be written to the stream without + waiting. + + @return Returns a non-negative value representing the maximum number of frames + that can be written to the stream without blocking or busy waiting or, a + PaErrorCode (which are always negative) if PortAudio is not initialized or an + error is encountered. +*/ +signed long Pa_GetStreamWriteAvailable( PaStream* stream ); + + +/* Miscellaneous utilities */ + + +/** Retrieve the size of a given sample format in bytes. + + @return The size in bytes of a single sample in the specified format, + or paSampleFormatNotSupported if the format is not supported. +*/ +PaError Pa_GetSampleSize( PaSampleFormat format ); + + +/** Put the caller to sleep for at least 'msec' milliseconds. This function is + provided only as a convenience for authors of portable code (such as the tests + and examples in the PortAudio distribution.) + + The function may sleep longer than requested so don't rely on this for accurate + musical timing. +*/ +void Pa_Sleep( long msec ); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PORTAUDIO_H */ diff --git a/external/portaudio/libs/libportaudio.dll b/external/portaudio/libs/libportaudio.dll new file mode 100644 index 0000000..47262e0 Binary files /dev/null and b/external/portaudio/libs/libportaudio.dll differ diff --git a/external/portaudio/libs/libportaudio.dll.a b/external/portaudio/libs/libportaudio.dll.a new file mode 100644 index 0000000..7c42109 Binary files /dev/null and b/external/portaudio/libs/libportaudio.dll.a differ diff --git a/external/portaudio/libs/libportaudio_static.a b/external/portaudio/libs/libportaudio_static.a new file mode 100644 index 0000000..2330eb0 Binary files /dev/null and b/external/portaudio/libs/libportaudio_static.a differ diff --git a/src/CubicSDRDefs.h b/src/CubicSDRDefs.h index 94a2a04..ed1593c 100644 --- a/src/CubicSDRDefs.h +++ b/src/CubicSDRDefs.h @@ -1,8 +1,8 @@ #pragma once -#define BUF_SIZE (16 * 32 * 512) +#define BUF_SIZE (16 * 32 * 256) #define SRATE 2500000 #define FFT_SIZE 8192 -#define DEFAULT_FREQ 105700000 +#define DEFAULT_FREQ 107500000 diff --git a/src/Demodulator.cpp b/src/Demodulator.cpp new file mode 100644 index 0000000..68372a7 --- /dev/null +++ b/src/Demodulator.cpp @@ -0,0 +1,169 @@ +#include "Demodulator.h" + +static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, void *userData) { + + Demodulator *src = (Demodulator *) userData; + + float *out = (float*) outputBuffer; + + if (!src->audio_queue.size()) { + for (int i = 0; i < framesPerBuffer * 2; i++) { + out[i] = 0; + } + return paContinue; + } + + std::vector *nextBuffer = src->audio_queue.front(); + + for (int i = 0; i < framesPerBuffer * 2; i++) { + out[i] = (*nextBuffer)[src->audio_queue_ptr]; + + src->audio_queue_ptr++; + + if (src->audio_queue_ptr == nextBuffer->size()) { + src->audio_queue.pop(); + delete nextBuffer; + src->audio_queue_ptr = 0; + if (!src->audio_queue.size()) { + break; + } + nextBuffer = src->audio_queue.front(); + } + } + + return paContinue; +} + +Demodulator::Demodulator() { + + bandwidth = 800000; + resample_ratio = (float) (bandwidth) / (float) SRATE; + audio_frequency = 44100; + audio_resample_ratio = (float) (audio_frequency) / (float) bandwidth; + + PaError err; + err = Pa_Initialize(); + if (err != paNoError) { + std::cout << "Error starting :(\n"; + } + + outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ + if (outputParameters.device == paNoDevice) { + std::cout << "Error: No default output device.\n"; + } + + outputParameters.channelCount = 2; /* Stereo output, most likely supported. */ + outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */ + outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; + outputParameters.hostApiSpecificStreamInfo = NULL; + + stream = NULL; + + err = Pa_OpenStream(&stream, NULL, &outputParameters, 44100, 256, paClipOff, &patestCallback, this); + + err = Pa_StartStream(stream); + if (err != paNoError) { + std::cout << "Error starting stream: " << Pa_GetErrorText(err) << std::endl; + std::cout << "\tPortAudio error: " << Pa_GetErrorText(err) << std::endl; + } + + float fc = 0.5f * (bandwidth / SRATE); // filter cutoff frequency + float ft = 0.05f;// filter transition + float As = 60.0f;// stop-band attenuation [dB] + float mu = 0.0f;// fractional timing offset + + // estimate required filter length and generate filter + unsigned int h_len = estimate_req_filter_len(ft, As); + float h[h_len]; + liquid_firdes_kaiser(h_len, fc, As, mu, h); + + fir_filter = firfilt_crcf_create(h, h_len); + + // create multi-stage arbitrary resampler object + resampler = msresamp_crcf_create(resample_ratio, As); + msresamp_crcf_print(resampler); + + audio_resampler = msresamp_crcf_create(audio_resample_ratio, As); + msresamp_crcf_print(audio_resampler); + + float kf = 0.1f;// modulation factor + + fdem = freqdem_create(kf); + freqdem_print(fdem); +} + +Demodulator::~Demodulator() { + PaError err; + err = Pa_StopStream(stream); + err = Pa_CloseStream(stream); + Pa_Terminate(); +} + +void Demodulator::writeBuffer(std::vector *data) { + liquid_float_complex filtered_input[BUF_SIZE / 2]; + + for (int i = 0; i < BUF_SIZE / 2; i++) { + + liquid_float_complex x; + liquid_float_complex y; + + x.real = (float) (*data)[i * 2] / 127.0f; + x.imag = (float) (*data)[i * 2 + 1] / 127.0f; + + firfilt_crcf_push(fir_filter, x); // push input sample + firfilt_crcf_execute(fir_filter, &y); // compute output + + filtered_input[i] = y; + } + + int out_size = ceil((float) (BUF_SIZE / 2) * resample_ratio); + + liquid_float_complex resampled_output[out_size]; + + unsigned int num_written; // number of values written to buffer + msresamp_crcf_execute(resampler, filtered_input, (BUF_SIZE / 2), resampled_output, &num_written); + + float waveform_ceil = 0, waveform_floor = 0; + + float pcm = 0; + + for (int i = 0; i < num_written; i++) { + freqdem_demodulate(fdem, resampled_output[i], &pcm); + + resampled_output[i].real = (float) pcm; + resampled_output[i].imag = 0; + + if (waveform_ceil < resampled_output[i].real) { + waveform_ceil = resampled_output[i].real; + } + + if (waveform_floor > resampled_output[i].real) { + waveform_floor = resampled_output[i].real; + } + } + + int audio_out_size = ceil((float) (num_written) * audio_resample_ratio); + liquid_float_complex resampled_audio_output[audio_out_size]; + + unsigned int num_audio_written; // number of values written to buffer + msresamp_crcf_execute(audio_resampler, resampled_output, num_written, resampled_audio_output, &num_audio_written); + + std::vector *newBuffer = new std::vector; + newBuffer->resize(num_audio_written * 2); + for (int i = 0; i < num_audio_written; i++) { + (*newBuffer)[i * 2] = resampled_audio_output[i].real; + (*newBuffer)[i * 2 + 1] = resampled_audio_output[i].real; + } + + audio_queue.push(newBuffer); + + if (waveform_points.size() != num_audio_written * 2) { + waveform_points.resize(num_audio_written * 2); + } + + for (int i = 0, iMax = waveform_points.size() / 2; i < iMax; i++) { + waveform_points[i * 2 + 1] = resampled_audio_output[i].real * 0.5f; + waveform_points[i * 2] = ((double) i / (double) iMax); + } +} diff --git a/src/Demodulator.h b/src/Demodulator.h new file mode 100644 index 0000000..5c51b70 --- /dev/null +++ b/src/Demodulator.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include +#include +#include + + +#include "CubicSDRDefs.h" +#include "liquid/liquid.h" + +#include "portaudio.h" +#ifdef WIN32 +#include "pa_stream.h" +#include "pa_debugprint.h" +#endif + +static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, void *userData); + +class Demodulator { +public: + std::queue *> audio_queue; + unsigned int audio_queue_ptr; + std::vector waveform_points; + + Demodulator(); + ~Demodulator(); + + void writeBuffer(std::vector *data); + +private: + firfilt_crcf fir_filter; + + msresamp_crcf resampler; + msresamp_crcf audio_resampler; + float resample_ratio; + unsigned int bandwidth; + unsigned int audio_frequency; + float audio_resample_ratio; + + PaStreamParameters outputParameters; + PaStream *stream; + freqdem fdem; +}; diff --git a/src/PrimaryGLContext.cpp b/src/PrimaryGLContext.cpp index fde55e7..636a852 100644 --- a/src/PrimaryGLContext.cpp +++ b/src/PrimaryGLContext.cpp @@ -62,7 +62,7 @@ PrimaryGLContext::PrimaryGLContext(wxGLCanvas *canvas) : CheckGLError(); } -void PrimaryGLContext::Plot(std::vector &points) { +void PrimaryGLContext::Plot(std::vector &points, std::vector &points2) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); @@ -70,22 +70,27 @@ void PrimaryGLContext::Plot(std::vector &points) { // glEnable(GL_LINE_SMOOTH); - glPushMatrix(); - glTranslatef(-1.0f, -0.9f, 0.0f); - glScalef(2.0f, 1.8f, 1.0f); if (points.size()) { + glPushMatrix(); + glTranslatef(-1.0f, -0.9f, 0.0f); + glScalef(2.0f, 1.0f, 1.0f); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &points[0]); glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2); glDisableClientState(GL_VERTEX_ARRAY); - } else { - glBegin(GL_LINE_STRIP); - glColor3f(1.0f, 1.0f, 1.0f); - glVertex3f(-1.0f, 0.0f, 0.0f); - glVertex3f(1.0f, 0.0f, 0.0f); - glEnd(); + glPopMatrix(); + } + + if (points2.size()) { + glPushMatrix(); + glTranslatef(-1.0f, 0.5f, 0.0f); + glScalef(2.0f, 1.0f, 1.0f); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, &points2[0]); + glDrawArrays(GL_LINE_STRIP, 0, points2.size() / 2); + glDisableClientState(GL_VERTEX_ARRAY); + glPopMatrix(); } - glPopMatrix(); glFlush(); @@ -97,20 +102,29 @@ EVT_KEY_DOWN(TestGLCanvas::OnKeyDown) EVT_IDLE(TestGLCanvas::OnIdle) wxEND_EVENT_TABLE() + + TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE), parent(parent) { + int in_block_size = BUF_SIZE / 2; int out_block_size = FFT_SIZE; in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size); out[0] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * out_block_size); out[1] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * out_block_size); - plan[0] = fftw_plan_dft_1d(out_block_size, in, out[0], FFTW_BACKWARD, FFTW_MEASURE); - plan[1] = fftw_plan_dft_1d(out_block_size, in, out[1], FFTW_FORWARD, FFTW_MEASURE); + plan[0] = fftw_plan_dft_1d(out_block_size, in, out[0], FFTW_FORWARD, FFTW_MEASURE); + plan[1] = fftw_plan_dft_1d(out_block_size, out[0], out[1], FFTW_BACKWARD, FFTW_MEASURE); fft_ceil_ma = fft_ceil_maa = 1.0; + + +} + +TestGLCanvas::~TestGLCanvas() { + } void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { @@ -120,7 +134,9 @@ void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { PrimaryGLContext& canvas = wxGetApp().GetContext(this); glViewport(0, 0, ClientSize.x, ClientSize.y); - canvas.Plot(points); + std::vector null_pts; + + canvas.Plot(spectrum_points, test_demod.waveform_points); SwapBuffers(); } @@ -152,24 +168,33 @@ void TestGLCanvas::OnKeyDown(wxKeyEvent& event) { } } +void multiply2(float ar, float aj, float br, float bj, float *cr, float *cj) { + *cr = ar * br - aj * bj; + *cj = aj * br + ar * bj; +} +float polar_discriminant2(float ar, float aj, float br, float bj) { + float cr, cj; + double angle; + multiply2(ar, aj, br, -bj, &cr, &cj); + angle = atan2(cj, cr); + return (angle / M_PI); +} + void TestGLCanvas::setData(std::vector *data) { if (data && data->size()) { - - if (points.size() < FFT_SIZE * 2) { - points.resize(FFT_SIZE * 2); + if (spectrum_points.size() < FFT_SIZE * 2) { + spectrum_points.resize(FFT_SIZE * 2); } for (int i = 0; i < BUF_SIZE / 2; i++) { - in[i][0] = (double) (*data)[i * 2] / 127.0f; - in[i][1] = (double) (*data)[i * 2 + 1] / 127.0f; + in[i][0] = (float) (*data)[i * 2] / 127.0f; + in[i][1] = (float) (*data)[i * 2 + 1] / 127.0f; } fftw_execute(plan[0]); - fftw_execute(plan[1]); double fft_ceil = 0; - // fft_floor, if (fft_result.size() < FFT_SIZE) { fft_result.resize(FFT_SIZE); @@ -179,21 +204,16 @@ void TestGLCanvas::setData(std::vector *data) { for (int j = 0; j < 2; j++) { for (int i = 0, iMax = FFT_SIZE / 2; i < iMax; i++) { - double a = out[j][j ? i : ((iMax - 1) - i)][0]; - double b = out[j][j ? i : ((iMax - 1) - i)][1]; + double a = out[0][i][0]; + double b = out[0][i][1]; double c = sqrt(a * a + b * b); - double x = out[j ? 0 : 1][j ? ((FFT_SIZE - 1) - i) : ((FFT_SIZE / 2) + i)][0]; - double y = out[j ? 0 : 1][j ? ((FFT_SIZE - 1) - i) : ((FFT_SIZE / 2) + i)][1]; + double x = out[0][FFT_SIZE / 2 + i][0]; + double y = out[0][FFT_SIZE / 2 + i][1]; double z = sqrt(x * x + y * y); - double r = (c < z) ? c : z; - - if (!j) { - fft_result[i] = r; - } else { - fft_result[(FFT_SIZE / 2) + i] = r; - } + fft_result[i] = (z); + fft_result[FFT_SIZE / 2 + i] = (c); } } @@ -211,10 +231,15 @@ void TestGLCanvas::setData(std::vector *data) { fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05; fft_ceil_maa = fft_ceil_maa + (fft_ceil - fft_ceil_maa) * 0.05; + // fftw_execute(plan[1]); + for (int i = 0, iMax = FFT_SIZE; i < iMax; i++) { - points[i * 2 + 1] = fft_result_maa[i] / fft_ceil_maa; - points[i * 2] = ((double) i / (double) iMax); + spectrum_points[i * 2 + 1] = log10(fft_result_maa[i]) / log10(fft_ceil_maa); +// spectrum_points[i * 2 + 1] = (fft_result_maa[i]) / (fft_ceil_maa); + spectrum_points[i * 2] = ((double) i / (double) iMax); } + + test_demod.writeBuffer(data); } } diff --git a/src/PrimaryGLContext.h b/src/PrimaryGLContext.h index e9c973a..9d25844 100644 --- a/src/PrimaryGLContext.h +++ b/src/PrimaryGLContext.h @@ -4,23 +4,25 @@ #include "wx/timer.h" #include +#include + #include "CubicSDRDefs.h" #include "fftw3.h" +#include "Demodulator.h" class PrimaryGLContext: public wxGLContext { public: PrimaryGLContext(wxGLCanvas *canvas); - void Plot(std::vector &points); + void Plot(std::vector &points, std::vector &points2); private: - // textures for the cube faces - GLuint m_textures[6]; }; class TestGLCanvas: public wxGLCanvas { public: TestGLCanvas(wxWindow *parent, int *attribList = NULL); + ~TestGLCanvas(); void setData(std::vector *data); @@ -31,7 +33,7 @@ private: void OnIdle(wxIdleEvent &event); wxWindow *parent; - std::vector points; + std::vector spectrum_points; fftw_complex *in, *out[2]; fftw_plan plan[2]; @@ -42,5 +44,6 @@ private: std::vector fft_result_ma; std::vector fft_result_maa; + Demodulator test_demod; wxDECLARE_EVENT_TABLE(); }; diff --git a/src/SDRThreadTask.h b/src/SDRThreadTask.h index 93336c1..ea6b72b 100644 --- a/src/SDRThreadTask.h +++ b/src/SDRThreadTask.h @@ -10,10 +10,10 @@ public: }; SDRThreadTask() : - m_cmd(SDR_THREAD_NULL) { + m_cmd(SDR_THREAD_NULL), arg_int(0) { } SDRThreadTask(SDR_COMMAND cmd) : - m_cmd(cmd) { + arg_int(0), m_cmd(cmd) { } void setUInt(unsigned int i);