From 0f27549c488267061292b1046a280b05942371b1 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 7 Feb 2008 22:00:10 +0000 Subject: [PATCH] inital checkin of voipcodecs library version 0.0.1 from http://www.soft-switch.org/downloads/voipcodecs/ thank you Steve git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7544 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/voipcodecs/AUTHORS | 1 + libs/voipcodecs/COPYING | 340 +++++ libs/voipcodecs/ChangeLog | 3 + libs/voipcodecs/INSTALL | 182 +++ libs/voipcodecs/Makefile.am | 93 ++ libs/voipcodecs/NEWS | 1 + libs/voipcodecs/README | 4 + libs/voipcodecs/config-h.in | 235 +++ libs/voipcodecs/configure.ac | 340 +++++ libs/voipcodecs/debian/changelog | 6 + libs/voipcodecs/debian/compat | 1 + libs/voipcodecs/debian/control | 42 + libs/voipcodecs/debian/copyright | 25 + .../debian/libvoipcodecs-dev.install | 4 + .../debian/libvoipcodecs-doc.install | 1 + libs/voipcodecs/debian/libvoipcodecs.install | 2 + libs/voipcodecs/debian/rules | 106 ++ libs/voipcodecs/debian/watch | 7 + libs/voipcodecs/doc/Makefile.am | 29 + libs/voipcodecs/doc/css.css | 564 +++++++ libs/voipcodecs/doc/libvoipcodecs-doxygen | 1229 +++++++++++++++ libs/voipcodecs/doc/wrapper.xsl | 5 + libs/voipcodecs/etsitests/Makefile.am | 27 + libs/voipcodecs/itutests/Makefile.am | 28 + libs/voipcodecs/libvoipcodecs.vcproj | 657 ++++++++ libs/voipcodecs/localtests/Makefile.am | 32 + libs/voipcodecs/localtests/dam9.wav | Bin 0 -> 343852 bytes libs/voipcodecs/localtests/dam9_lpc55.wav | Bin 0 -> 343844 bytes libs/voipcodecs/localtests/short_nb_voice.wav | Bin 0 -> 192044 bytes libs/voipcodecs/localtests/short_wb_voice.wav | Bin 0 -> 98838 bytes libs/voipcodecs/src/Makefile.am | 126 ++ libs/voipcodecs/src/bitstream.c | 137 ++ libs/voipcodecs/src/float_fudge.h | 123 ++ libs/voipcodecs/src/g711.c | 104 ++ libs/voipcodecs/src/g722_decode.c | 404 +++++ libs/voipcodecs/src/g722_encode.c | 390 +++++ libs/voipcodecs/src/g726.c | 1178 +++++++++++++++ libs/voipcodecs/src/gsm0610_decode.c | 358 +++++ libs/voipcodecs/src/gsm0610_encode.c | 334 +++++ libs/voipcodecs/src/gsm0610_local.h | 229 +++ libs/voipcodecs/src/gsm0610_long_term.c | 408 +++++ libs/voipcodecs/src/gsm0610_lpc.c | 533 +++++++ libs/voipcodecs/src/gsm0610_preprocess.c | 149 ++ libs/voipcodecs/src/gsm0610_rpe.c | 531 +++++++ libs/voipcodecs/src/gsm0610_short_term.c | 361 +++++ libs/voipcodecs/src/ima_adpcm.c | 387 +++++ libs/voipcodecs/src/libvoipcodecs.dsp | 241 +++ libs/voipcodecs/src/libvoipcodecs.sln | 29 + libs/voipcodecs/src/lpc10_analyse.c | 712 +++++++++ libs/voipcodecs/src/lpc10_decode.c | 1106 ++++++++++++++ libs/voipcodecs/src/lpc10_encdecs.h | 107 ++ libs/voipcodecs/src/lpc10_encode.c | 394 +++++ libs/voipcodecs/src/lpc10_placev.c | 335 +++++ libs/voipcodecs/src/lpc10_voicing.c | 487 ++++++ libs/voipcodecs/src/msvc/gettimeofday.c | 14 + libs/voipcodecs/src/msvc/inttypes.h | 87 ++ libs/voipcodecs/src/msvc/msvcproj.foot | 7 + libs/voipcodecs/src/msvc/msvcproj.head | 92 ++ libs/voipcodecs/src/msvc/sys/time.h | 1 + libs/voipcodecs/src/msvc/tgmath.h | 84 ++ libs/voipcodecs/src/msvc/unistd.h | 31 + libs/voipcodecs/src/msvc/vc8proj.foot | 11 + libs/voipcodecs/src/msvc/vc8proj.head | 180 +++ libs/voipcodecs/src/msvc/voipcodecs.def | 304 ++++ libs/voipcodecs/src/oki_adpcm.c | 376 +++++ libs/voipcodecs/src/vector_int.c | 347 +++++ libs/voipcodecs/src/voipcodecs.h.in | 54 + .../src/voipcodecs/bit_operations.h | 262 ++++ libs/voipcodecs/src/voipcodecs/bitstream.h | 89 ++ libs/voipcodecs/src/voipcodecs/dc_restore.h | 127 ++ libs/voipcodecs/src/voipcodecs/g711.h | 255 ++++ libs/voipcodecs/src/voipcodecs/g722.h | 180 +++ libs/voipcodecs/src/voipcodecs/g726.h | 195 +++ libs/voipcodecs/src/voipcodecs/gsm0610.h | 175 +++ libs/voipcodecs/src/voipcodecs/ima_adpcm.h | 113 ++ libs/voipcodecs/src/voipcodecs/lpc10.h | 213 +++ libs/voipcodecs/src/voipcodecs/oki_adpcm.h | 119 ++ libs/voipcodecs/src/voipcodecs/telephony.h | 67 + libs/voipcodecs/src/voipcodecs/vector_int.h | 99 ++ libs/voipcodecs/src/voipcodecs/version.h | 37 + libs/voipcodecs/src/voipcodecs/version.h.in | 37 + libs/voipcodecs/tests/Makefile.am | 60 + libs/voipcodecs/tests/g711_tests.c | 287 ++++ libs/voipcodecs/tests/g722_tests.c | 521 +++++++ libs/voipcodecs/tests/g726_tests.c | 1334 +++++++++++++++++ libs/voipcodecs/tests/gsm0610_tests.c | 649 ++++++++ libs/voipcodecs/tests/ima_adpcm_tests.c | 206 +++ libs/voipcodecs/tests/lpc10_tests.c | 307 ++++ libs/voipcodecs/tests/oki_adpcm_tests.c | 239 +++ libs/voipcodecs/tests/regression_tests.sh | 93 ++ libs/voipcodecs/voipcodecs.spec.in | 65 + libs/voipcodecs/wrapper.xsl | 5 + 92 files changed, 20449 insertions(+) create mode 100644 libs/voipcodecs/AUTHORS create mode 100644 libs/voipcodecs/COPYING create mode 100644 libs/voipcodecs/ChangeLog create mode 100644 libs/voipcodecs/INSTALL create mode 100644 libs/voipcodecs/Makefile.am create mode 100644 libs/voipcodecs/NEWS create mode 100644 libs/voipcodecs/README create mode 100644 libs/voipcodecs/config-h.in create mode 100644 libs/voipcodecs/configure.ac create mode 100644 libs/voipcodecs/debian/changelog create mode 100644 libs/voipcodecs/debian/compat create mode 100644 libs/voipcodecs/debian/control create mode 100644 libs/voipcodecs/debian/copyright create mode 100644 libs/voipcodecs/debian/libvoipcodecs-dev.install create mode 100644 libs/voipcodecs/debian/libvoipcodecs-doc.install create mode 100644 libs/voipcodecs/debian/libvoipcodecs.install create mode 100755 libs/voipcodecs/debian/rules create mode 100644 libs/voipcodecs/debian/watch create mode 100644 libs/voipcodecs/doc/Makefile.am create mode 100644 libs/voipcodecs/doc/css.css create mode 100644 libs/voipcodecs/doc/libvoipcodecs-doxygen create mode 100644 libs/voipcodecs/doc/wrapper.xsl create mode 100644 libs/voipcodecs/etsitests/Makefile.am create mode 100644 libs/voipcodecs/itutests/Makefile.am create mode 100644 libs/voipcodecs/libvoipcodecs.vcproj create mode 100644 libs/voipcodecs/localtests/Makefile.am create mode 100644 libs/voipcodecs/localtests/dam9.wav create mode 100644 libs/voipcodecs/localtests/dam9_lpc55.wav create mode 100644 libs/voipcodecs/localtests/short_nb_voice.wav create mode 100644 libs/voipcodecs/localtests/short_wb_voice.wav create mode 100644 libs/voipcodecs/src/Makefile.am create mode 100644 libs/voipcodecs/src/bitstream.c create mode 100644 libs/voipcodecs/src/float_fudge.h create mode 100644 libs/voipcodecs/src/g711.c create mode 100644 libs/voipcodecs/src/g722_decode.c create mode 100644 libs/voipcodecs/src/g722_encode.c create mode 100644 libs/voipcodecs/src/g726.c create mode 100644 libs/voipcodecs/src/gsm0610_decode.c create mode 100644 libs/voipcodecs/src/gsm0610_encode.c create mode 100644 libs/voipcodecs/src/gsm0610_local.h create mode 100644 libs/voipcodecs/src/gsm0610_long_term.c create mode 100644 libs/voipcodecs/src/gsm0610_lpc.c create mode 100644 libs/voipcodecs/src/gsm0610_preprocess.c create mode 100644 libs/voipcodecs/src/gsm0610_rpe.c create mode 100644 libs/voipcodecs/src/gsm0610_short_term.c create mode 100644 libs/voipcodecs/src/ima_adpcm.c create mode 100644 libs/voipcodecs/src/libvoipcodecs.dsp create mode 100644 libs/voipcodecs/src/libvoipcodecs.sln create mode 100644 libs/voipcodecs/src/lpc10_analyse.c create mode 100644 libs/voipcodecs/src/lpc10_decode.c create mode 100644 libs/voipcodecs/src/lpc10_encdecs.h create mode 100644 libs/voipcodecs/src/lpc10_encode.c create mode 100644 libs/voipcodecs/src/lpc10_placev.c create mode 100644 libs/voipcodecs/src/lpc10_voicing.c create mode 100644 libs/voipcodecs/src/msvc/gettimeofday.c create mode 100644 libs/voipcodecs/src/msvc/inttypes.h create mode 100644 libs/voipcodecs/src/msvc/msvcproj.foot create mode 100644 libs/voipcodecs/src/msvc/msvcproj.head create mode 100644 libs/voipcodecs/src/msvc/sys/time.h create mode 100644 libs/voipcodecs/src/msvc/tgmath.h create mode 100644 libs/voipcodecs/src/msvc/unistd.h create mode 100644 libs/voipcodecs/src/msvc/vc8proj.foot create mode 100644 libs/voipcodecs/src/msvc/vc8proj.head create mode 100644 libs/voipcodecs/src/msvc/voipcodecs.def create mode 100644 libs/voipcodecs/src/oki_adpcm.c create mode 100644 libs/voipcodecs/src/vector_int.c create mode 100644 libs/voipcodecs/src/voipcodecs.h.in create mode 100644 libs/voipcodecs/src/voipcodecs/bit_operations.h create mode 100644 libs/voipcodecs/src/voipcodecs/bitstream.h create mode 100644 libs/voipcodecs/src/voipcodecs/dc_restore.h create mode 100644 libs/voipcodecs/src/voipcodecs/g711.h create mode 100644 libs/voipcodecs/src/voipcodecs/g722.h create mode 100644 libs/voipcodecs/src/voipcodecs/g726.h create mode 100644 libs/voipcodecs/src/voipcodecs/gsm0610.h create mode 100644 libs/voipcodecs/src/voipcodecs/ima_adpcm.h create mode 100644 libs/voipcodecs/src/voipcodecs/lpc10.h create mode 100644 libs/voipcodecs/src/voipcodecs/oki_adpcm.h create mode 100644 libs/voipcodecs/src/voipcodecs/telephony.h create mode 100644 libs/voipcodecs/src/voipcodecs/vector_int.h create mode 100644 libs/voipcodecs/src/voipcodecs/version.h create mode 100644 libs/voipcodecs/src/voipcodecs/version.h.in create mode 100644 libs/voipcodecs/tests/Makefile.am create mode 100644 libs/voipcodecs/tests/g711_tests.c create mode 100644 libs/voipcodecs/tests/g722_tests.c create mode 100644 libs/voipcodecs/tests/g726_tests.c create mode 100644 libs/voipcodecs/tests/gsm0610_tests.c create mode 100644 libs/voipcodecs/tests/ima_adpcm_tests.c create mode 100644 libs/voipcodecs/tests/lpc10_tests.c create mode 100644 libs/voipcodecs/tests/oki_adpcm_tests.c create mode 100755 libs/voipcodecs/tests/regression_tests.sh create mode 100644 libs/voipcodecs/voipcodecs.spec.in create mode 100644 libs/voipcodecs/wrapper.xsl diff --git a/libs/voipcodecs/AUTHORS b/libs/voipcodecs/AUTHORS new file mode 100644 index 0000000000..0fbb495099 --- /dev/null +++ b/libs/voipcodecs/AUTHORS @@ -0,0 +1 @@ +Steve Underwood diff --git a/libs/voipcodecs/COPYING b/libs/voipcodecs/COPYING new file mode 100644 index 0000000000..d60c31a97a --- /dev/null +++ b/libs/voipcodecs/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libs/voipcodecs/ChangeLog b/libs/voipcodecs/ChangeLog new file mode 100644 index 0000000000..fc5ee32173 --- /dev/null +++ b/libs/voipcodecs/ChangeLog @@ -0,0 +1,3 @@ +08.02.08 - 0.0.1 - Steve Underwood + - The first version. + diff --git a/libs/voipcodecs/INSTALL b/libs/voipcodecs/INSTALL new file mode 100644 index 0000000000..ef77c3a46f --- /dev/null +++ b/libs/voipcodecs/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.ac' is used to create `configure' by a program +called `autoconf'. You only need `configure.ac' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/libs/voipcodecs/Makefile.am b/libs/voipcodecs/Makefile.am new file mode 100644 index 0000000000..85d1dcf16b --- /dev/null +++ b/libs/voipcodecs/Makefile.am @@ -0,0 +1,93 @@ +## +## VoIPcodecs - a series of DSP components for telephony +## +## Makefile.am -- Process this file with automake to produce Makefile.in +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 2, as +## published by the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## $Id: Makefile.am,v 1.29 2007/09/23 12:45:15 steveu Exp $ + +AM_CFLAGS = $(COMP_VENDOR_CFLAGS) + +noinst_SCRIPTS = voipcodecs.spec + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = voipcodecs.spec \ + wrapper.xsl \ + libvoipcodecs.vcproj \ + doc/libvoipcodecs-doxygen \ + src/float_fudge.h \ + src/voipcodecs/version.h.in \ + src/libvoipcodecs.dsp \ + src/libvoipcodecs.sln \ + src/msvc/gettimeofday.c \ + src/msvc/inttypes.h \ + src/msvc/tgmath.h \ + src/msvc/unistd.h \ + src/msvc/sys/time.h \ + src/msvc/voipcodecs.def \ + src/msvc/msvcproj.head \ + src/msvc/msvcproj.foot \ + src/msvc/vc8proj.head \ + src/msvc/vc8proj.foot \ + debian/changelog \ + debian/compat \ + debian/control \ + debian/copyright \ + debian/libvoipcodecs.install \ + debian/libvoipcodecs-dev.install \ + debian/libvoipcodecs-doc.install \ + debian/rules \ + debian/watch + +if COND_DOC + MAYBE_DOC=doc +endif +if COND_TESTS + MAYBE_TESTS=tests +endif +if COND_ITUTESTS + MAYBE_ITUTESTS=itutests +endif +SUBDIRS = src $(MAYBE_DOC) $(MAYBE_TESTS) $(MAYBE_ITUTESTS) + +DIST_SUBDIRS = src doc tests localtests etsitests itutests + +faq: faq.xml + cd faq ; xsltproc ../wrapper.xsl ../faq.xml + +rpm: rpm-build + +rpm-build: + $(MAKE) -$(MAKEFLAGS) bump.rpm.release + $(MAKE) -$(MAKEFLAGS) dist + rm -rf rpm/BUILD/* + rm -f rpm/RPMS/*/* + rm -f rpm/SOURCES/* + rm -f rpm/SPECS/* + rm -f rpm/SRPMS/* + rpm -ta --sign @PACKAGE@-@VERSION@.tar.gz + +bump.rpm.release: voipcodecs.spec + VERSION="x"; \ + test -f $(srcdir)/rpm.release && . $(srcdir)/rpm.release; \ + NEXT_RELEASE=0; \ + test "$$VERSION" = "@VERSION@" && NEXT_RELEASE="$$RELEASE"; \ + RELEASE=`expr $$NEXT_RELEASE + 1`; \ + echo "VERSION=@VERSION@" >$(srcdir)/rpm.release; \ + echo "RELEASE=$$RELEASE" >>$(srcdir)/rpm.release; \ + sed 's/^Release: .*/Release: '$$RELEASE'/' \ + voipcodecs.spec.new; \ + mv voipcodecs.spec.new voipcodecs.spec diff --git a/libs/voipcodecs/NEWS b/libs/voipcodecs/NEWS new file mode 100644 index 0000000000..0d09503644 --- /dev/null +++ b/libs/voipcodecs/NEWS @@ -0,0 +1 @@ +No news is good news! \ No newline at end of file diff --git a/libs/voipcodecs/README b/libs/voipcodecs/README new file mode 100644 index 0000000000..db6017b305 --- /dev/null +++ b/libs/voipcodecs/README @@ -0,0 +1,4 @@ +VoIPcodecs 0.0.1 - A set of commonly used, unencumbered, codecs for VoIP +------------------------------------------------------------------------ + +Steve Underwood diff --git a/libs/voipcodecs/config-h.in b/libs/voipcodecs/config-h.in new file mode 100644 index 0000000000..0f5758e8e7 --- /dev/null +++ b/libs/voipcodecs/config-h.in @@ -0,0 +1,235 @@ +/* config-h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_AUDIOFILE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FFTW3_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FFTW_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FLOAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FL_FL_AUDIO_METER_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FL_FL_CARTESIAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FL_FL_DRAW_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FL_FL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FL_FL_LIGHT_BUTTON_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FL_FL_OVERLAY_WINDOW_H + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `tiff' library (-ltiff). */ +#undef HAVE_LIBTIFF + +/* Define to 1 if you have the 'libxml2' library (-lxml2). */ +#undef HAVE_LIBXML2 + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBXML_PARSER_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBXML_XINCLUDE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBXML_XMLMEMORY_H + +/* Define to 1 if the system has the type `long double'. */ +#undef HAVE_LONG_DOUBLE + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MATH_H + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the header file. */ +#undef HAVE_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TGMATH_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIFFIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNICALL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_X_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to the type of arg 1 for `select'. */ +#undef SELECT_TYPE_ARG1 + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#undef SELECT_TYPE_ARG234 + +/* Define to the type of arg 5 for `select'. */ +#undef SELECT_TYPE_ARG5 + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Enable fixed point processing, where possible, instead of floating point */ +#undef VOIPCODECS_USE_FIXED_POINT + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to rpl_realloc if the replacement function should be used. */ +#undef realloc + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile diff --git a/libs/voipcodecs/configure.ac b/libs/voipcodecs/configure.ac new file mode 100644 index 0000000000..df938b2f04 --- /dev/null +++ b/libs/voipcodecs/configure.ac @@ -0,0 +1,340 @@ +# +# VoIPcodecs - a series of DSP components for telephony +# +# configure.ac -- Process this file with autoconf to produce configure +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# $Id: configure.ac,v 1.38 2007/11/10 11:14:56 steveu Exp $ + +# @start 1 + +AC_INIT + +AC_DEFUN([AX_COMPILER_VENDOR], +[ +AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, + [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown + # note: don't check for GCC first, since some other compilers define __GNUC__ + for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do + vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ +#if !($vencpp) + thisisanerror; +#endif +])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break]) + done + ]) +]) + +VOIPCODECS_MAJOR_VERSION=0 +VOIPCODECS_MINOR_VERSION=0 +VOIPCODECS_MICRO_VERSION=1 + +VOIPCODECS_LT_CURRENT=0 +VOIPCODECS_LT_REVISION=2 +VOIPCODECS_LT_AGE=0 + +VERSION=$VOIPCODECS_MAJOR_VERSION.$VOIPCODECS_MINOR_VERSION.$VOIPCODECS_MICRO_VERSION +PACKAGE=voipcodecs + +AC_SUBST(VOIPCODECS_LT_CURRENT) +AC_SUBST(VOIPCODECS_LT_REVISION) +AC_SUBST(VOIPCODECS_LT_AGE) + +AC_CONFIG_SRCDIR([src/g711.c]) +AC_CONFIG_AUX_DIR(config) +AC_CONFIG_HEADERS([src/config.h:config-h.in]) +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) + +AC_CANONICAL_HOST +AC_CANONICAL_BUILD +AC_PROG_CC +AC_PROG_CXX +AC_PROG_GCC_TRADITIONAL +AC_PROG_LIBTOOL +AC_LANG([C]) + +AX_COMPILER_VENDOR + +if test "${build}" != "${host}" +then + # If we are doing a Canadian Cross, in which the host and build systems + # are not the same, we set reasonable default values for the tools. + + CC=${CC-${host_alias}-gcc} + CFLAGS=${CFLAGS-"-g -O2"} + CXX=${CXX-${host_alias}-c++} + CXXFLAGS=${CXXFLAGS-"-g -O2"} + CC_FOR_BUILD=${CC_FOR_BUILD-gcc} +else + # Set reasonable default values for some tools even if not Canadian. + # Of course, these are different reasonable default values, originally + # specified directly in the Makefile. + # We don't export, so that autoconf can do its job. + # Note that all these settings are above the fragment inclusion point + # in Makefile.in, so can still be overridden by fragments. + # This is all going to change when we autoconfiscate... + CC_FOR_BUILD="\$(CC)" + AC_PROG_CC + + # We must set the default linker to the linker used by gcc for the correct + # operation of libtool. If LD is not defined and we are using gcc, try to + # set the LD default to the ld used by gcc. + if test -z "$LD" + then + if test "$GCC" = yes + then + case $build in + *-*-mingw*) + gcc_prog_ld=`$CC -print-prog-name=ld 2>&1 | tr -d '\015'` ;; + *) + gcc_prog_ld=`$CC -print-prog-name=ld 2>&1` ;; + esac + case $gcc_prog_ld in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + LD="$gcc_prog_ld" ;; + esac + fi + fi + + CXX=${CXX-"c++"} + CFLAGS=${CFLAGS-"-g -O2"} + CXXFLAGS=${CXXFLAGS-"-g -O2"} +fi + +AC_C_CONST +AC_C_INLINE +AC_C_VOLATILE + +AC_CHECK_TYPES(long long) +AC_CHECK_TYPES(long double) + +AC_TYPE_SIGNAL + +AC_ARG_ENABLE(doc, [ --enable-doc Build the documentation]) +AC_ARG_ENABLE(tests, [ --enable-tests Build the test programs]) +AC_ARG_ENABLE(itutests, [ --enable-itutests Build TIFF test files for some ITU test images]) +AC_ARG_ENABLE(mmx, [ --enable-mmx Enable MMX support]) +AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support]) +AC_ARG_ENABLE(fixed_point, [ --enable-fixed-point Enable fixed point support]) + +AC_FUNC_ERROR_AT_LINE +AC_FUNC_VPRINTF +AC_FUNC_MALLOC +AC_FUNC_MEMCMP +AC_FUNC_REALLOC +AC_FUNC_SELECT_ARGTYPES + +AC_CHECK_FUNCS([memmove]) +AC_CHECK_FUNCS([memset]) +AC_CHECK_FUNCS([select]) +AC_CHECK_FUNCS([strcasecmp]) +AC_CHECK_FUNCS([strchr]) +AC_CHECK_FUNCS([strdup]) +AC_CHECK_FUNCS([strerror]) +AC_CHECK_FUNCS([strstr]) +AC_CHECK_FUNCS([strtol]) +AC_CHECK_FUNCS([gettimeofday]) + +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_HEADER_TIME + +# Check for header files. +AC_CHECK_HEADERS([socket.h]) +AC_CHECK_HEADERS([inttypes.h], [INSERT_INTTYPES_HEADER="#include "]) +AC_CHECK_HEADERS([stdint.h], [INSERT_STDINT_HEADER="#include "]) +AC_CHECK_HEADERS([unistd.h]) +AC_CHECK_HEADERS([stdlib.h]) +AC_CHECK_HEADERS([string.h]) +AC_CHECK_HEADERS([strings.h]) +AC_CHECK_HEADERS([malloc.h]) +AC_CHECK_HEADERS([tgmath.h], [INSERT_TGMATH_HEADER="#include "]) +AC_CHECK_HEADERS([math.h], [INSERT_MATH_HEADER="#include "]) +AC_CHECK_HEADERS([float.h]) +AC_CHECK_HEADERS([fcntl.h]) +AC_CHECK_HEADERS([sys/time.h]) +AC_CHECK_HEADERS([sys/select.h]) +AC_CHECK_HEADERS([sys/ioctl.h]) +AC_CHECK_HEADERS([sys/fcntl.h]) +AC_CHECK_HEADERS([audiofile.h]) +AC_CHECK_HEADERS([fftw.h]) +AC_CHECK_HEADERS([fftw3.h]) +AC_CHECK_HEADERS([tiffio.h]) +AC_CHECK_HEADERS([pthread.h]) +AC_CHECK_HEADERS([unicall.h]) +if test "${build}" == "${host}" +then + AC_CHECK_HEADERS([X11/X.h]) +fi + +# Determine XML2 include path +AC_MSG_CHECKING(for libxml/xmlmemory.h) + +# Can we include headers using system include dirs? +AC_TRY_COMPILE([#include ], [int a = 1;], + XML2_INCLUDE=" ", + XML2_INCLUDE= +) + +# Hunt through several possible directories to find the includes for libxml2 +if test "x$XML2_INCLUDE" = "x"; then + old_CPPFLAGS="$CPPFLAGS" + for i in $xml2_include_dir /usr/include /usr/local/include /usr/include/libxml2 /usr/local/include/libxml2 ; do + CPPFLAGS="$old_CPPFLAGS -I$i" + AC_TRY_COMPILE([#include ], [int a = 1;], + XML2_INCLUDE="-I$i", + XML2_INCLUDE= + ) + if test "x$XML2_INCLUDE" != "x"; then + break; + fi + done + CPPFLAGS="$old_CPPFLAGS $XML2_INCLUDE" +fi + +AC_CHECK_HEADERS([libxml/xmlmemory.h]) +AC_CHECK_HEADERS([libxml/parser.h]) +AC_CHECK_HEADERS([libxml/xinclude.h]) + +AC_LANG([C++]) +AC_CHECK_HEADERS([FL/Fl.H]) +AC_CHECK_HEADERS([FL/Fl_Overlay_Window.H]) +AC_CHECK_HEADERS([FL/Fl_Light_Button.H]) +AC_CHECK_HEADERS([FL/fl_draw.H]) +AC_CHECK_HEADERS([FL/Fl_Cartesian.H], [], [], [],[[#include +]]) +AC_CHECK_HEADERS([FL/Fl_Audio_Meter.H], [], [], [],[[#include +]]) + +if test "${build}" == "${host}" +then + case "${host}" in + x86_64-*) + AC_CHECK_FILE([${prefix}/lib64], libdir='$(exec_prefix)/lib64') + ;; + esac +fi + +AC_LANG([C]) + +if test "${build}" == "${host}" +then + case "${host}" in + x86_64-*) + # X86_64 Linux machines may have both 64 bit and 32 bit libraries. We need to choose the right set + AC_CHECK_FILE([/usr/X11R6/lib64], [TESTLIBS="$TESTLIBS -L/usr/X11R6/lib64"], AC_CHECK_FILE([/usr/X11R6/lib], [TESTLIBS="$TESTLIBS -L/usr/X11R6/lib"])) + ;; + esac +fi + +# Checks for libraries. +AC_CHECK_LIB([Xft], [XftFontOpen], TESTLIBS="$TESTLIBS -lXft",, $TESTLIBS) +AC_CHECK_LIB([Xext], [XextCreateExtension], TESTLIBS="$TESTLIBS -lXext",, $TESTLIBS) +AC_CHECK_LIB([X11], [XOpenDisplay], TESTLIBS="$TESTLIBS -lX11",, $TESTLIBS) +AC_CHECK_LIB([tiff], [TIFFOpen], , AC_MSG_ERROR("Can't build without libtiff (does your system require a libtiff-devel package?)"), -lm) +AC_CHECK_LIB([m], [cos]) +AC_CHECK_LIB([m], [pow]) +AC_CHECK_LIB([m], [sqrt]) +AC_CHECK_LIB([xml2], [xmlParseFile], [AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have the 'libxml2' library (-lxml2).]) TESTLIBS="$TESTLIBS -lxml2"]) +if test -n "$enable_tests" ; then + AC_LANG([C++]) + AC_CHECK_LIB([fltk], [main], TESTLIBS="$TESTLIBS -lfltk -lsupc++") + AC_CHECK_LIB([fltk_cartesian], [main], TESTLIBS="-lfltk_cartesian $TESTLIBS") + AC_CHECK_LIB([fltk_audio_meter], [main], TESTLIBS="-lfltk_audio_meter $TESTLIBS") + AC_LANG([C]) + AC_CHECK_LIB([audiofile], [afOpenFile], TESTLIBS="$TESTLIBS -laudiofile", AC_MSG_ERROR("Can't make tests without libaudiofile (does your system require a libaudiofile-devel package?)")) + AC_CHECK_LIB([fftw3], [fftw_plan_dft_1d], TESTLIBS="$TESTLIBS -lfftw3") + AC_CHECK_LIB([fftw], [fftw_create_plan], TESTLIBS="$TESTLIBS -lfftw") + AC_CHECK_LIB([pthread], [pthread_attr_init], TESTLIBS="$TESTLIBS -lpthread") + AC_CHECK_LIB([dl], [dlopen], TESTLIBS="$TESTLIBS -ldl") + AC_CHECK_LIB([unicall], [uc_start], TESTLIBS="$TESTLIBS -lunicall",, -ltiff -ldl) +fi + +case "${ax_cv_c_compiler_vendor}" in +gnu) + COMP_VENDOR_CFLAGS="-std=gnu99 -ffast-math -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" + if test "$enable_sse" = "yes" ; then + COMP_VENDOR_CFLAGS="-msse $COMP_VENDOR_CFLAGS" + fi + if test "$enable_mmx" = "yes" ; then + COMP_VENDOR_CFLAGS="-mmmx $COMP_VENDOR_CFLAGS" + fi + ;; +*) + COMP_VENDOR_CFLAGS="-std=c99 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" + ;; +esac + +COMP_VENDOR_CFLAGS="-DNDEBUG $COMP_VENDOR_CFLAGS" + +AM_CONDITIONAL([COND_DOC], [test "$enable_doc" = yes]) +AM_CONDITIONAL([COND_TESTS], [test "$enable_tests" = yes]) +AM_CONDITIONAL([COND_ITUTESTS], [test "$enable_itutests" = yes]) +AM_CONDITIONAL([COND_MMX], [test "$enable_mmx" = yes]) +AM_CONDITIONAL([COND_SSE], [test "$enable_sse" = yes]) +if test "$enable_fixed_point" = "yes" ; then + AC_DEFINE([VOIPCODECS_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point]) + VOIPCODECS_USE_FIXED_POINT="#define VOIPCODECS_USE_FIXED_POINT 1" +else +# +# So far we deal with the embedded ARM, Blackfin, MIPS, TI DSP and XScale processors as +# things which lack fast hardware floating point. +# +# Other candidates would be the small embedded Power PCs. +# + case $basic_machine in + arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] \ + | bfin \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | tic54x | c54x* | tic55x | c55x* | tic6x | c6x* \ + | xscale | xscalee[bl] \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | bfin-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | xscale-* | xscalee[bl]-* ) + AC_DEFINE([VOIPCODECS_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point]) + VOIPCODECS_USE_FIXED_POINT="#define VOIPCODECS_USE_FIXED_POINT 1" + ;; + *) + VOIPCODECS_USE_FIXED_POINT="#undef VOIPCODECS_USE_FIXED_POINT" + ;; + esac +fi + +AC_SUBST(CC_FOR_BUILD) +AC_SUBST(COMP_VENDOR_CFLAGS) +AC_SUBST(TESTLIBS) +AC_SUBST(VOIPCODECS_USE_FIXED_POINT) +AC_SUBST(INSERT_INTTYPES_HEADER) +AC_SUBST(INSERT_STDINT_HEADER) +AC_SUBST(INSERT_TGMATH_HEADER) +AC_SUBST(INSERT_MATH_HEADER) + +AC_CONFIG_FILES([Makefile + doc/Makefile + etsitests/Makefile + itutests/Makefile + localtests/Makefile + src/Makefile + src/voipcodecs.h + tests/Makefile + voipcodecs.spec]) + +AC_OUTPUT + +# @end 1 diff --git a/libs/voipcodecs/debian/changelog b/libs/voipcodecs/debian/changelog new file mode 100644 index 0000000000..fdc543aa5b --- /dev/null +++ b/libs/voipcodecs/debian/changelog @@ -0,0 +1,6 @@ +voipcodecs (0.0.1) unstable; urgency=low + + [ Steve Underwood ] + * Begun + + -- Steve Underwood Thu, 7 Feb 2008 09:53:06 +0300 diff --git a/libs/voipcodecs/debian/compat b/libs/voipcodecs/debian/compat new file mode 100644 index 0000000000..b8626c4cff --- /dev/null +++ b/libs/voipcodecs/debian/compat @@ -0,0 +1 @@ +4 diff --git a/libs/voipcodecs/debian/control b/libs/voipcodecs/debian/control new file mode 100644 index 0000000000..b2aaa704fe --- /dev/null +++ b/libs/voipcodecs/debian/control @@ -0,0 +1,42 @@ +Source: voipcodecs +Section: libs +Priority: optional +Maintainer: Debian VoIP Team +Uploaders: Jose Carlos Garcia Sogo , Kilian Krause , Santiago Garcia Mantinan , Mark Purcell , Tzafrir Cohen , Santiago Ruano Rincón +Build-Depends: debhelper (>= 4.0.0), libtiff4-dev, libjpeg62-dev, dpatch, doxygen, autotools-dev +Standards-Version: 3.7.2 +XS-Vcs-Svn: svn://svn.debian.org/pkg-voip/ +XS-Vcs-Browser: http://svn.debian.org/wsvn/pkg-voip/ + +Package: libvoipcodecs3 +Architecture: any +Depends: ${shlibs:Depends} +Conflicts: libvoipcodecs0, libvoipcodecs1, libvoipcodecs2 +Description: Telephony signal processing library + This is a low-level signal processing library that modulate and demodulate + signals commonly used in telephony, such as the "noise" generated by a + fax modem or DTMF touchpad. + . + This package contains the shared library. + +Package: libvoipcodecs-dev +Section: libdevel +Architecture: any +Depends: libvoipcodecs3 (= ${Source-Version}), libtiff4-dev, libjpeg62-dev +Description: Telephony signal processing library + This is a low-level signal processing library that modulate and demodulate + signals commonly used in telephony, such as the "noise" generated by a + fax modem or DTMF touchpad. + . + This package contains the static library and development headers. + . + Homepage: http://www.soft-switch.org/ + +Package: libvoipcodecs-doc +Section: doc +Architecture: all +Description: Documentation for the voipcodecs signal processing library + This package contains the online API in HTML for the libvoipcodecs, a low + level signal processing library that modulate and demodulate siignals + commonly used in telephony, such as the "noise" generated by a fax + modem or DTMF touchpad. diff --git a/libs/voipcodecs/debian/copyright b/libs/voipcodecs/debian/copyright new file mode 100644 index 0000000000..ebf63aad47 --- /dev/null +++ b/libs/voipcodecs/debian/copyright @@ -0,0 +1,25 @@ +This package was debianized by Steve Underwood on +Thu, 7 Feb 2008 15:22:58 +0100. + +It was downloaded from http://soft-switch.org/downloads/voipcodecs/ + +Copyright: Steve Underwood + +License: + + This package 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; version 2 dated June, 1991. + + This package 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 package; if not, write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. diff --git a/libs/voipcodecs/debian/libvoipcodecs-dev.install b/libs/voipcodecs/debian/libvoipcodecs-dev.install new file mode 100644 index 0000000000..162bf014f7 --- /dev/null +++ b/libs/voipcodecs/debian/libvoipcodecs-dev.install @@ -0,0 +1,4 @@ +debian/tmp/usr/include +debian/tmp/usr/lib/libvoipcodecs.so +debian/tmp/usr/lib/libvoipcodecs.la +debian/tmp/usr/lib/libvoipcodecs.a diff --git a/libs/voipcodecs/debian/libvoipcodecs-doc.install b/libs/voipcodecs/debian/libvoipcodecs-doc.install new file mode 100644 index 0000000000..fbdba498d7 --- /dev/null +++ b/libs/voipcodecs/debian/libvoipcodecs-doc.install @@ -0,0 +1 @@ +doc/api/html usr/share/doc/libvoipcodecs-doc/api/ diff --git a/libs/voipcodecs/debian/libvoipcodecs.install b/libs/voipcodecs/debian/libvoipcodecs.install new file mode 100644 index 0000000000..f7b903c151 --- /dev/null +++ b/libs/voipcodecs/debian/libvoipcodecs.install @@ -0,0 +1,2 @@ +debian/tmp/usr/lib/libvoipcodecs.so.0.* +debian/tmp/usr/lib/libvoipcodecs.so.0 diff --git a/libs/voipcodecs/debian/rules b/libs/voipcodecs/debian/rules new file mode 100755 index 0000000000..8869b07778 --- /dev/null +++ b/libs/voipcodecs/debian/rules @@ -0,0 +1,106 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +DEBVERSION:=$(shell head -n 1 debian/changelog \ + | sed -e 's/^[^(]*(\([^)]*\)).*/\1/') +ORIGTARVER:=$(shell echo $(DEBVERSION) | sed -e 's/^.*://' -e 's/-[0-9.]*$$//')# -e 's/.dfsg$$//' -e 's/~//') + +UPVERSION:=$(shell echo $(ORIGTARVER) | tr -d '~') + +FILENAME := voipcodecs_$(ORIGTARVER).orig.tar.gz +FULLNAME := voipcodecs-$(UPVERSION) +URL := http://soft-switch.org/downloads/voipcodecs/voipcodecs-$(UPVERSION).tgz + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +include /usr/share/dpatch/dpatch.make + + +autotools: patch-stamp + ln -s /usr/share/misc/config.sub config.sub + ln -s /usr/share/misc/config.guess config.guess + touch autotools + +config.status: autotools configure + dh_testdir + CFLAGS="$(CFLAGS)" ./configure \ + --host=$(DEB_HOST_GNU_TYPE) \ + --build=$(DEB_BUILD_GNU_TYPE) \ + --prefix=/usr \ + --mandir=\$${prefix}/share/man \ + --infodir=\$${prefix}/share/info \ + --enable-doc + +build: build-stamp + +build-stamp: config.status + dh_testdir + $(MAKE) + touch build-stamp + +clean: clean-patched unpatch +clean-patched: + dh_testdir + dh_testroot + rm -f build-stamp autotools + -$(MAKE) distclean + + -$(RM) -f config.sub + -$(RM) -f config.guess + + dh_clean + +install: build-stamp + dh_testdir + dh_testroot + dh_clean -k + $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp + +binary-indep: build-stamp install + dh_testdir -i + dh_testroot -i + dh_installchangelogs -i ChangeLog + dh_installdocs -i DueDiligence + dh_install -i + dh_compress -i + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +binary-arch: build-stamp install + dh_testdir -a + dh_testroot -a + dh_installchangelogs -a ChangeLog + dh_installdocs -a DueDiligence + dh_install -a + dh_strip -a + dh_compress -a + dh_fixperms -a + dh_makeshlibs -a + dh_installdeb -a + dh_shlibdeps -a + dh_gencontrol -a + dh_md5sums -a + dh_builddeb -a + +get-orig-source: + -@@dh_testdir + @@[ -d ../tarballs/. ]||mkdir -p ../tarballs + @@echo Downloading $(FILENAME) from $(URL) ... + @@wget -N -nv -T10 -t3 -O ../tarballs/$(FILENAME) $(URL) + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install patch unpatch diff --git a/libs/voipcodecs/debian/watch b/libs/voipcodecs/debian/watch new file mode 100644 index 0000000000..a4b9b7773f --- /dev/null +++ b/libs/voipcodecs/debian/watch @@ -0,0 +1,7 @@ +# See uscan(1) for format + +# Compulsory line, this is a version 3 file +version=3 + +# +http://soft-switch.org/downloads/voipcodecs/ voipcodecs-(.*)\.tgz debian svn-upgrade diff --git a/libs/voipcodecs/doc/Makefile.am b/libs/voipcodecs/doc/Makefile.am new file mode 100644 index 0000000000..26c52027b3 --- /dev/null +++ b/libs/voipcodecs/doc/Makefile.am @@ -0,0 +1,29 @@ +## +## VoIPcodecs - a series of DSP components for telephony +## +## Makefile.am -- Process this file with automake to produce Makefile.in +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 2, as +## published by the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## $Id: Makefile.am,v 1.7 2007/12/20 15:06:22 steveu Exp $ + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = css.css \ + wrapper.xsl + +all: doxydocs + +doxydocs: + doxygen libvoipcodecs-doxygen diff --git a/libs/voipcodecs/doc/css.css b/libs/voipcodecs/doc/css.css new file mode 100644 index 0000000000..2f07200bdc --- /dev/null +++ b/libs/voipcodecs/doc/css.css @@ -0,0 +1,564 @@ +body { + background-image: url("../images/weave.jpg"); + font-family: Verdana, Arial, Helvetica, Sans-serif; + color: black; + margin-right: 20px; + margin-left: 20px; +} + +h1 { + text-align: center; +} + +h2 { + font-family: Verdana, Arial, Helvetica, Sans-serif; + border-color: #c00000; + color : black; + margin-top: 0.8em; + border-style: solid; + border-width: 0px 0px 3px 0.5em; + line-height : 130%; +} + +h3 { + font-family: Verdana, Arial, Helvetica, Sans-serif; + border-color: #f02020; + color : black; + border-width: 0px 0px 2px 0.5em; + border-style: solid; + margin-right: 20%; + line-height : 130%; +} +caption { + font-weight: bold +} +a.qindex {} +a.qindexRef {} +a.el { + text-decoration: none; + font-weight: bold +} +a.elRef { + font-weight: bold +} +a.code { + text-decoration: none; + font-weight: normal; + color: #4444ee +} +a.codeRef { + font-weight: normal; + color: #4444ee +} +a:hover { + text-decoration: none; + background-color: #f2f2ff +} +dl.el { + margin-left: -1cm +} +div.fragment { + width: 100%; + border: none; + background-color: #eeeeee +} +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px +} + +td { + font-family: Verdana, Arial, Helvetica, Sans-serif; + font-weight: bold; +} + +.navheader { + font-family: Verdana, Arial, Helvetica, Sans-serif; + background-color: #B2B2ff; + font-weight: bold; +} + +.navfooter { + font-family: Verdana, Arial, Helvetica, Sans-serif; + background-color: #B2B2ff; + font-weight: bold; +} + +table.menu { + background-color: #000066; + font-weight: bold; + text-align: center; + width: 100%; +} + +tr.menu { + background-color: #ccffff; + font-weight: bold; + text-align: center; +} +td.menu { + background-color: #f2e0d0; + font-weight: bold; + text-align: center; +} + +td.md { + background-color: #f2f2ff; + font-weight: bold; +} +td.mdname1 { + background-color: #f2f2ff; + font-weight: bold; + color: #602020; +} +td.mdname { + background-color: #f2f2ff; + font-weight: bold; + color: #602020; + width: 600px; +} +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold +} +div.groupText { + margin-left: 16px; + font-style: italic; + font-size: smaller +} +td.indexkey { + font-family: Verdana, Arial, Helvetica, Sans-serif; + background-color: #eeeeff; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +td.indexvalue { + font-family: Verdana, Arial, Helvetica, Sans-serif; + background-color: #eeeeff; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +span.keyword { + color: #008000 +} +span.keywordtype { + color: #604020 +} +span.keywordflow { + color: #e08000 +} +span.comment { + color: #800000 +} +span.preprocessor { + color: #806020 +} +span.stringliteral { + color: #002080 +} +span.charliteral { + color: #008080 +} +em { + color: #990000; + background-color: transparent; +} +h1,h2,h3,h4,h5,h6,p,center,td,th,ul,dl,div { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +body,td { + font-size: 90%; +} +h1 { + text-align: center; + font-size: 160%; +} +h2 { + font-size: 120%; +} +h3 { + font-size: 100%; +} +caption { + font-weight: bold +} +div.qindex { + width: 100%; + background-color: #eeeeff; + border: 1px solid #b0b0b0; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +div.nav { + width: 100%; + background-color: #eeeeff; + border: 1px solid #b0b0b0; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +div.navtab { + background-color: #eeeeff; + border: 1px solid #b0b0b0; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +td.navtab { + font-size: 70%; +} +a.qindex { + text-decoration: none; + font-weight: bold; + color: #1a419d; +} +a.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1a419d +} +a.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +a.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +a.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +a.qindexHL:visited { + text-decoration: none; + background-color: #6666cc; + color: #ffffff +} +a.el { + text-decoration: none; + font-weight: bold +} +a.elRef { + font-weight: bold +} +a.code:link { + text-decoration: none; + font-weight: normal; + color: #0000FF +} +a.code:visited { + text-decoration: none; + font-weight: normal; + color: #0000FF +} +a.codeRef:link { + font-weight: normal; + color: #0000FF +} +a.codeRef:visited { + font-weight: normal; + color: #0000FF +} +a:hover { + text-decoration: none; + background-color: #f2f2ff +} +dl.el { + margin-left: -1cm +} +.fragment { + font-family: Fixed, monospace; + font-size: 95%; +} +pre.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px +} +td.md { + background-color: #F4F4FB; + font-weight: bold; +} +td.mdPrefix { + background-color: #F4F4FB; + color: #606060; + font-size: 80%; +} +td.mdname1 { + background-color: #F4F4FB; + font-weight: bold; + color: #602020; +} +td.mdname { + background-color: #F4F4FB; + font-weight: bold; + color: #602020; + width: 600px; +} +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +div.groupText { + margin-left: 16px; + font-style: italic; + font-size: 90% +} +td.indexkey { + background-color: #eeeeff; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +td.indexvalue { + background-color: #eeeeff; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +tr.memlist { + background-color: #f0f0f0; +} +p.formulaDsp { + text-align: center; +} +img.formulaDsp { +} +img.formulaInl { + vertical-align: middle; +} +span.keyword { + color: #008000 +} +span.keywordtype { + color: #604020 +} +span.keywordflow { + color: #e08000 +} +span.comment { + color: #800000 +} +span.preprocessor { + color: #806020 +} +span.stringliteral { + color: #002080 +} +span.charliteral { + color: #008080 +} +.mdTable { + border: 1px solid #868686; + background-color: #F4F4FB; +} +.mdRow { + padding: 8px 10px; +} +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { + color: #003399; + font-weight: bold; +} +form.search { + margin-bottom: 0px; + margin-top: 0px; +} +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #eeeeff; +} +td.tiny { + font-size: 75%; +} +a { + color: #252e78; +} +a:visited { + color: #3d2185; +} +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #b0b0b0; +} +th.dirtab { + background: #eeeeff; + font-weight: bold; +} +hr { + height: 1px; + border: none; + border-top: 1px solid black; +} diff --git a/libs/voipcodecs/doc/libvoipcodecs-doxygen b/libs/voipcodecs/doc/libvoipcodecs-doxygen new file mode 100644 index 0000000000..99d7fd7448 --- /dev/null +++ b/libs/voipcodecs/doc/libvoipcodecs-doxygen @@ -0,0 +1,1229 @@ +# Doxyfile 1.4.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libvoipcodecs + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.0.1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = api + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = YES + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is YES. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = .. + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = *.c \ + *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 2 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = css.css + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/libs/voipcodecs/doc/wrapper.xsl b/libs/voipcodecs/doc/wrapper.xsl new file mode 100644 index 0000000000..89e314d781 --- /dev/null +++ b/libs/voipcodecs/doc/wrapper.xsl @@ -0,0 +1,5 @@ + + + css.css + \ No newline at end of file diff --git a/libs/voipcodecs/etsitests/Makefile.am b/libs/voipcodecs/etsitests/Makefile.am new file mode 100644 index 0000000000..8ef3325b40 --- /dev/null +++ b/libs/voipcodecs/etsitests/Makefile.am @@ -0,0 +1,27 @@ +## +## VoIPcodecs - a series of DSP components for telephony +## +## Makefile.am -- Process this file with automake to produce Makefile.in +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 2, as +## published by the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## $Id: Makefile.am,v 1.1 2008/02/07 10:49:02 steveu Exp $ + +SUBDIRS = + +DIST_SUBDIRS = + +all: + +clean: diff --git a/libs/voipcodecs/itutests/Makefile.am b/libs/voipcodecs/itutests/Makefile.am new file mode 100644 index 0000000000..e097b92dae --- /dev/null +++ b/libs/voipcodecs/itutests/Makefile.am @@ -0,0 +1,28 @@ +## +## SpanDSP - a series of DSP components for telephony +## +## Makefile.am -- Process this file with automake to produce Makefile.in +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 2, as +## published by the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## $Id: Makefile.am,v 1.5 2007/02/10 11:54:57 steveu Exp $ + +SUBDIRS = + +DIST_SUBDIRS = + +all: + +clean: + diff --git a/libs/voipcodecs/libvoipcodecs.vcproj b/libs/voipcodecs/libvoipcodecs.vcproj new file mode 100644 index 0000000000..04f7cf2f50 --- /dev/null +++ b/libs/voipcodecs/libvoipcodecs.vcproj @@ -0,0 +1,657 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/voipcodecs/localtests/Makefile.am b/libs/voipcodecs/localtests/Makefile.am new file mode 100644 index 0000000000..8b5f6d60f6 --- /dev/null +++ b/libs/voipcodecs/localtests/Makefile.am @@ -0,0 +1,32 @@ +## +## VoIPcodecs - a series of DSP components for telephony +## +## Makefile.am -- Process this file with automake to produce Makefile.in +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 2, as +## published by the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## $Id: Makefile.am,v 1.1 2008/02/07 10:49:02 steveu Exp $ + +SUBDIRS = + +DIST_SUBDIRS = + +EXTRA_DIST = dam9_lpc55.wav \ + dam9.wav \ + short_nb_voice.wav \ + short_wb_voice.wav + +all: + +clean: diff --git a/libs/voipcodecs/localtests/dam9.wav b/libs/voipcodecs/localtests/dam9.wav new file mode 100644 index 0000000000000000000000000000000000000000..65b6818d3bc6f3bd30a808292903c379f47b90e1 GIT binary patch literal 343852 zcmeFZ=aXf*btj1D{d;&XePvb_s>^ma*?rlD-J(bev?CKELefa$NE!)RX&5sRn%KJ$ z^9LZbqmkPgL7p5^6iAAcL`o#YCM9~JNw#5|YLxfY=<>c$X)4__`@5Ol!-?44ultF4 z20ezy6

pyfZAgkkzuummWxe#~ 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

&TYi=LF~ns%`zFY#61 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

*ZU+Qy@AEmx2~^vDvwmWee6n3nyF@doP||X{ zF;6u`8>uhUZPU#*IE(JGSPMt%)#fiGkz%#+0;~obxN)E|-3LbDDZo>0M%$P|^C9+f zhYnVsQErR6(zontm8+`Km@Kv>5jB{WNmJy0NbVt)!W+LwS8p#8?R?KPdba*4ujru%WPCRbO>RGz3$Dzwj;p0~I>M137CwqWfN9O`UmTACEM zB-K;`v6HtmEYpl{eABR16{!11SR|QYwaZ!bOz=AHqBrl!4XWLd_vFXMpKS`O8deYi z)+KH?JhR+?ILxqUW>yOIh9lan<`R`(lfEfJyUnOT_0mgLwayE@>b+07x>{JXMU~cB zC25fv-3tnuy3>JrE!h4OwGld865YAICXfAA|8@JY_*N;{A zHf><6Ej7+v{bmPW4D91}S2nv@k(ZIee`Hf96!h2ZQ6_rc3gJRu`CW3JX7*h?tV?g& z2?{L_Ysc0cufMMu%lpWKZQVRx1xyb+5R~k;NVdAsJL}O$$G0^fU9;1hUs`Mq2xxz@ z{n*eqZWGKzHd9quv$Fa^)sxy;^=ehQp+%f4|7rcmb-drW5M97o*UeI6{ik0+AN#x$ zlcwhR>Ktqa27hXA6L}!ygiD~jjnS_$tEx+7ZpHbU>2>w0A*KpcpuA?k!9x+aE;!Er zxzk2UsC|-Y@o`=JtK{(fYF(7gyrAh(HzIF@`M7&3l8r+egz{NsUrO1^!rD5O7rTm* zSiEs~;n@=KD)^9JoRb3`RsZ-`eB!S7xu4GF_ER@lo(eb+`6a4v>-}Dr%)9Z6nvPX| zES*zwrTjqE>&9gLOSDZ5&J8($t=Vp$qfcCGq#b3e9Dy2>`&b5lrY8`rQ8Ub)Jj^~}M zDmJOiN$;)^6Fb#+@`>o}@sfUDqxqhk@cB*bhj-tfSEYzv4h4a~+g^yuZ8s#Oty@3E zUY%c=IPg(vuRVTH~ z_C4OVy3^X2qwT*39JZOoT`9l&!!~JOf@kW6oUipusjV)z!dG>b_u1X8CA^n|hkj)4 zu>{Yj&QIIF@B1sV@rtaU*POP-xVmocaS7qW-QH0d)xCa55{ADzmO!N6DA#ba9RkCv zyPqF4zklnPPo8~*nT1aiq>pyp`|YG>tjCcz7u`<>#b$)Lkcve0gmt5RQGTktQ_p$H7B5i_AWh~82niAkbbi*tEstz z(#v;T`$avM4=V1zrNc`{x5igV?{1Zy?{M2A@t<-*^3Ho&)VJOX2eEy&Mzby^-RaDC z&(m(bc@UC#tW+t9@d<995}O^@s&ki4qr)CqHPxjj+TZlOc;T+@i(2)-?p-T+TzuD^ zz1nmh9W=%4O;t-$*qu37_dR@@F~^YacD2jgA%O##xOE}d-ETU!H;YpJ{r&30&KJJj zO8ZPUhdBS&Zeol}r<1K||3NODiGGE%5_;U7dHeaNdo{rh>X>hX`j6i@Y;T0G#Z`kJ zyU{}8)>l$d(&O3u^QJppztP%UMQaC7yJV**?;Qc9zH;ju#`yAOg+mKh)g9ONL!G3j zWLrGFyxr^<3zo*etgpnFk0PTUFh>$zoo;h(*~42IeM&qvZO}rGtd0YEw{+bTa7Ot_ zg{n&nXXWoMyk8Nbj$>3l;lU5wk1@ljFpuIc-}>(h9^NwUb<@Rf*B-tL$~;uoMtejN z9<(TSc-PzQ)XrUqvgY6_uAp1N<-F2{waCtTU*I19^_G{p9mFB8?7qf9l|H(LwD+5D ziI0}O>HEni=dR|hm2)eXn5IZw=p)B@lyl3WnxTbMAz9r=byumexoW5LOY=EM-)xzr zu`&PN!)0JkzoqPnpWB{=#{0g1{ItinNwt&cvthkD90_|He#vvCY!<1kIbYDPd{6D} z`eyk_#UsmcAs$W^;;ZHy?K6kF{Y+gc_W;p9w@0e;=T}cQJv@+>T0Pq0RLHQbshQ=0ibdnLR`uIL`zQ_O57({drIMZ)o zms-y!67%W>X^BshE^fc^{nO3rA54L(5aQEO6%!DwvYN-qnmX66EZI^1x{jkpFw2#h zZmnD|P-XhJ!bE@TKK>mtJ@3h{)%MJ4|766uJ-2(MJ}&w|?XaHT>PF}B9qoemx`vC< zh8-1caywLhCgL>rEOLBiQy40i=1Sp zFX_#I zBVXaMsH1z-d;ciEBW`aEQJ-w?^}4Hh`tQrD$@`jCJ8ui!*yeHcoVdGfjdo8=HZ9Al zQVRb|`%zWd6iZ5gWqFOPqf?NxPh?Eg(2z;K(YBMSJ-@^}JbSa>v!HilzHc_B+u4O| ziyRRf6%!k_&w2*ht62zYhZlc-t+`d#**M?ksaw6-Z|f%a!pL6HRo)vsrdoy9O-f9B z=<-PSV$J)PKduO#E{HIBVtxW+pSKYJdPS*7A)0=u#)|=AoUb-B&9%gOh z9UnEPRcGgPr$=UDY1xO~FZ;cJnxOiqDjX!Ma*GNGYo+_;`TKxX_``gKr-;YcBUSFf!>6+uYH)?ig zyNDdSbLJE+RlUeOkpH}(p^-14*zJxAcXN55b6!9|1nm}W8E(Iv+LE1|`ZQ(i*BL1* zG8F13%C3&1yt}nWu@gfZY#&+e7Z#U4{5dawO#YJ!W9eSWI=5V>{#IF@uft+P38xDV z?`-Gj&t?xx(WY$wboay8+#b4z^3JYdAs?gF(Wiooo&1%*v|Gvs+5Bwn@9_Ml=G$}>lVtVMV^iy* zAf?X_&mqn-BU`aKOZ#m>l4TN;d${2V|F>=5z@Ug*txp80ygFE^_`&t&6_fL&1?Blp z^{d1Wgq`J4w-uqvz|%e%K6mW130eKWMM7rL=bvBq=6$L9s()sd;kiBNLD0RRCU4QU zHEpRqQD68wxcFS*>FO!^SEdx{7KhfJ>-<-GAM}3j`daF1xLBhsT>f+0_rck_%N92; zL1xyjo_%~R{nq$wcJ6DwOS}b%A{Q!hijP;;sP1YSU`8)@90-awhrFhGT(wR>r*&6r zQwt|$Ps-0Iep;QZT|ln{+A-SWm-i#rSlg8fHKA4O8^2c7S1oL~+we%!n>Zd@P~oH(g-uGw4STU1i?qvA}%7-JkGu@D^&x~y}3?zqs(K|Vo@HQZ_Z+ECCq zwXVA9oc9T z#L9;9oz<6B8>zmE$I3H?QgVvbVdZA_D7%tzx2WOP2zH!@yqjzRUxj8Hj%ZezKHAKa zs0l{$RQ&ASjN*62hrM1R(hSvO0`4!nQAyn+C z9jod`zLeRTYKe#Xd(EZPHjbB7TCE_ah)Xmkl|j5km&uzfHwZu20Xj#j4ZV#yL@qTZ zsd}1JXoSQWX_SvG+oKzTqq>tiSdz|c*Tr+sSS{I~;DsY>sp&ISZ5~WB{0+I0v(ZS6 zk?ecLB!~0DW7AEwHG05wXAqU8@6^1>IE(yC`dN%I+L@2GIUr3nSO|Sp8TxT1FLI&c zCp$%W%(SN7k*DeD-^SgOO228`y~5p zUBv+=Lbi%e*Dp5xVqeJ8$V2>3{SkIoq8ZZLpOLl~j>4R3_rRFxuEoevVsA%`$8>%@OZeO3-;B%}~W= zN!AOlbggs*e^!%ZY7#UuqnN^WmnTSHksl1Njh~Q)I>B5r6%ZCeE_p`H(K0^Lcv5nK z+|Py+x9O4OVJ6P7oUf5=quhCcOl05a9?)}4&0Ia9m%kx*5r6BmxpKyvct@ohd!bFd zEqYE^DoI{RI2isDCrQ3=t7$)dKgna@sedBIvuh=jC5u2Q@u+D@ODn^6a*!gIw*mF1 zI5beQQF=tUBVOY4#4oB=yUd6b7wO4dx}nC@QFe)3Pk2gBuub~D(w%%~(N8*-UTMtY z6Ai)Ae7Zu|C7fZW8g~Gepn(1=)N)^VCu*pC3!g6hFia$mP+o9SH`KU;4&Y|deS~PC znyhAK7^VuVr19i9ldmyew3RJk)^m&a>4d-WoJmVAk=$fQin%6xX#}-ccq6XkDj8pC z6Ux)|GpwYOC1Y7PzKVS+%SK4N!(Zg1Oy;61{h8cK{Kxc`Iq_+xafU&R4WmI@IEL+` zmyv^LcV@OY*LX(UCT^1S% z$b!t`Mw6~wJ>QEsM7E-~6P-nOQh`45PJrmxK`kOyh^+(%;yhX_Mj$643e5l}?qrym zllj@=WHf@DL#Tn-vlsW5u$Cw%5$Pwq6wD|;bRNol1Sh3Zu~DcJJy8h}CJY0v&!>U_ zr^If6Z0QWx6*sg&=t;~J15pX^Yc3&Lgf8L;U{Gu%Hla=Eg#ZeQz=1hH{3w)(n4f%` z=nm+h65#tRMVE=QfB*>xF3B-~ahU*|kq&_Im;@)A^MF@#E^u^50B<^GZ0t;A339;Y ztRiZN1#n*);6Ij#yMarTAihEAzu~0yI52qM2VU{}#7lU(3$SCJ0u0aq;$Pws;AXZ1 z+oB5~VZ4FkbPVxCoC5rWZbVz?gKL1ckr77$@3R7UPKHBi0|0Ha08lykz~o;7*E<2? zCmm2rID-uH0pqL-j1Ct+O=?YJPi;+h0rR40Ex5{ctQsd z*P(2hxG3Hh#{$MC9hd++0BgA|aRG2aIPbPIFo9yMVFqyZVfJp!Ip7L>uwlUdS_3Sp zU7^-EQ@SmngD9dHY90W{CU3wr{b5mf4M-s^aAVR?Pe=Gm`v34!81IGi_WxF4gS zO8SAs{q+Gf5=P-k0f$ior4hi#$3cCXfc?(~ zkW4u90ORX0(!271=sAqwZG^HgJ`i7OE&tbl7&(dA5^$amW{txrSe)^Iv3M9Ei!%-|G7)Ej z;H(IYTGau*tO-i}!*7aFzL+@>`V@1AG`R1*2jyk{=^Fac&Am9OL?7 zEIj6Q!&#TOW*DdS2TP1`kr*|H+Yh5t2Z^5KSL!Y*UA*bEH0zl1l&nZgUo zjI1Xqwj;VODPh;~8u}*XZmNf~a~Cqo#K1_OO!LArJ{EyKB~@%Tt?ECzfJ&pr&>y&V zVhbT~|529(XQ2UNH3f!Cq9s!(Y~hCS&csf-Ojrt9l+THgz$g0(CGsXD5ndu4FzcQ{ ztN3n|6+ex9EToE6=rcErUe7Z0bU^*wM+=ni%HEn<zg8p3EXXd zG8sY7hIL>!`8P+yh_57Fi0z^UauLU~!-Wbl42=@n3gaX*Bz4Aeey7Bni!-&S=c8Ei z75&t5Xl+OBN%>wnf_+aUP@zHuThASnY^J)2o4HA(5p5#Qpw(jTKy46XNIM-v@Urcf!+K)k(Lk5mnomhc)Bn3itnmFt>g6VjUk*1YGx8-g|Z&f3Q!tVb0dw_+T@ne zEe)#QEpa*r<7{pgv50P#_{#Sv&MF3*39=c|TsjBlufT_xhL{@J>-=QmE~S*sm%oNTt=Er1Wa z0~^9oWT3K{m9h=em$WZ6jyM4cL`Av+%?izPO^L=uuQRp-^kpnsMwQa7B&{T0A-Y)0 zbcGQ&pX!ZV#lyTwAW$U9Q!bK7=~BrxdMnx^_TeuYN9dR9oOK?$i#lh+BhweItFVe# zLweA8v;%XR31nu0ZgU>#Mjb=E5FtP`muN-B&@2-vb(46}2hk(pF!$TIPk%r+T9>H1 zrB@lcvcvcxVjq-Dy3nCa9CMCo#hB<>)MA+LQgm5J;|~i%h>v6wHH|SzZZpTJ)vyA! z=jx0X^_jXLy_25RN0{!j&Ac!17R{qB(k=89#+$iA*HR}bYjQlAg}#Y8(2oAdCyBA- zL+UD%Ai2jRQCra|VJ;^#DGh7%)Ah&orH03*8Ce27>=93~5?IrIx^BKZxJ zefRReSiv;IOutKzl z=y7jq6?KeE1G_y{NaYuChd|q^*))tzWQTF1_!GiR@eHvW`IA*-M`|0joFb_ZDjPjT zN6=`Zn|M^n6`I8|q7gkKr;-k&EdnJ9p^}&K3%TD=lV5B!_nuqA_YwvGMm!&^`$+OO zth*%jo@^%7s0n>W2vEtB#GSBrS)#|thWv>}!b;B&wZeE|HlN2$;3BzU+yRaNm7;z^ z05HBECEU?V&=eX^PKUQHBuyv>T|(Yy7wk6{z?j_**7)I|%+nyIit7NUtryZ@?cEQ$ zSeJ#XLX+SPdPZZx#@|cqB0dpEfi-^*u@5lZ(}*QtLk|bMeE|Hhu+QNfFAne-Ibc0$ zfbAVKv$9|fV-6Ucm4vf)bYL}U!GglP7Z_WQttia9Vh8yJ7)uZQ{*Vid^JTEE4$je# zgPo2!2XKb4Iph{lz)_7k8|uKXz}GZj$6@X!%;JEvEO35P2K-(F&$A-7Cowmp3TlA! zh1$axV~!&VEZ?&KS&1 zHi9|$Dt=(;V%t^yzdAcYsW_V&=PqKV6>O7MLQA+q&2UaRW*TsYH~D}?h^<)6h=_Au zFq=H)xNw8N;X9nc?#G#>7Vrf)6Y39l3eJkc*#bD91v7Zy3>F!@=Z|I$3AOu^%Z+)m zFlU4X_$`=K7&C2KK%MO1oj6ws^Iu{c6=ydh$auj0f%EoohQJ@DEqoPco8VkHoDGCI zkg#2gb8>J-1kR$xnH$)$#u;Ro9YKUz;=aPnSU4*fXGZ+LKZWxUF^dKZ&;H4o!~Cb% za>w2k&fEHvLx?SToKb{x6>;_p&hh)hT*AP2;o=#p#?6xyEP)sE&hx&Mp)Jm?L5x zBt-qgE9gGPQ?PQSGT?gxUgDR~9Go10*0p$+s;-jeK%n%GGwgRtOsNRs$7s9v-%F~UZ&JNXxT zf*NjWA=UsMC5seH3x#cB0&M_mO(8BuGx^=pA9&vmemm&Czu>Qe zZ8@H=GigApY@M__rxN}VK(T}N;5_KpWC%af^i3s_q;4n2t8AmAQ*OsljA-9c8p*9Oz-pSMDR&-;U%`U5IQS`;i?XxlgGi zXN)`8wSqVEg}l$E5CPIo>

{^5hiE9Pk}(sz39b*j@J4xQ{_*?2P4og`G2phA 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 p-#vgR7bx7N6B&M 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 WNRDsXi9q>3(jjtuO3!{)&;J8M*I8x& literal 0 HcmV?d00001 diff --git a/libs/voipcodecs/localtests/short_nb_voice.wav b/libs/voipcodecs/localtests/short_nb_voice.wav new file mode 100644 index 0000000000000000000000000000000000000000..4dd098a2dfbeced8b1166a002b210190cd3554a8 GIT binary patch literal 192044 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

    *jQ^_mtmo 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 literal 0 HcmV?d00001 diff --git a/libs/voipcodecs/src/Makefile.am b/libs/voipcodecs/src/Makefile.am new file mode 100644 index 0000000000..13324a18e0 --- /dev/null +++ b/libs/voipcodecs/src/Makefile.am @@ -0,0 +1,126 @@ +## +## VoIPcodecs - a series of DSP components for telephony +## +## Makefile.am -- Process this file with automake to produce Makefile.in +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 2, as +## published by the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## $Id: Makefile.am,v 1.85 2008/02/06 09:23:26 steveu Exp $ + +AM_CFLAGS = $(COMP_VENDOR_CFLAGS) + +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I$(top_builddir) + +lib_LTLIBRARIES = libvoipcodecs.la + +libvoipcodecs_la_SOURCES = bitstream.c \ + g711.c \ + g722_encode.c \ + g722_decode.c \ + g726.c \ + gsm0610_decode.c \ + gsm0610_encode.c \ + gsm0610_long_term.c \ + gsm0610_lpc.c \ + gsm0610_preprocess.c \ + gsm0610_rpe.c \ + gsm0610_short_term.c \ + ima_adpcm.c \ + lpc10_analyse.c \ + lpc10_decode.c \ + lpc10_encode.c \ + lpc10_placev.c \ + lpc10_voicing.c \ + oki_adpcm.c \ + vector_int.c + +libvoipcodecs_la_LDFLAGS = -version-info @VOIPCODECS_LT_CURRENT@:@VOIPCODECS_LT_REVISION@:@VOIPCODECS_LT_AGE@ + +nobase_include_HEADERS = voipcodecs/bit_operations.h \ + voipcodecs/bitstream.h \ + voipcodecs/dc_restore.h \ + voipcodecs/g711.h \ + voipcodecs/g722.h \ + voipcodecs/g726.h \ + voipcodecs/gsm0610.h \ + voipcodecs/ima_adpcm.h \ + voipcodecs/lpc10.h \ + voipcodecs/oki_adpcm.h \ + voipcodecs/telephony.h \ + voipcodecs/vector_int.h \ + voipcodecs/version.h + +nodist_include_HEADERS = voipcodecs.h + +noinst_HEADERS = gsm0610_local.h \ + lpc10_encdecs.h + +# We need to run at_dictionary_gen, so it generates the +# at_interpreter_dictionary.h file + +DSP = libvoipcodecs.dsp +VCPROJ = libvoipcodecs.vcproj + +WIN32SOURCES = $(libvoipcodecs_la_SOURCES) msvc/gettimeofday.c +WIN32HEADERS = $(nobase_include_HEADERS) voipcodecs.h + +DSPOUT = | awk '{printf("%s\r\n", $$0)}' >> $(DSP) +VCPROJOUT = | awk '{printf("%s\r\n", $$0)}' >> $(VCPROJ) + +$(DSP): msvc/msvcproj.head msvc/msvcproj.foot Makefile.am + echo "creating $(DSP)" + @(cp $(srcdir)/msvc/msvcproj.head $(DSP); \ + echo "# Begin Group \"Source Files\"" $(DSPOUT); \ + for file in $(WIN32SOURCES); do \ + echo "# Begin Source File" $(DSPOUT); \ + echo "" $(DSPOUT); \ + echo "SOURCE=.\\"$$file $(DSPOUT); \ + echo "# End Source File" $(DSPOUT); \ + done; \ + echo "# End Group" $(DSPOUT); \ + echo "# Begin Group \"Header Files\"" $(DSPOUT); \ + for file in $(WIN32HEADERS); do \ + echo "# Begin Source File" $(DSPOUT); \ + echo "" $(DSPOUT); \ + echo "SOURCE=.\\"$$file $(DSPOUT); \ + echo "# End Source File" $(DSPOUT); \ + done; \ + echo "# End Group" $(DSPOUT); \ + cat $(srcdir)/msvc/msvcproj.foot $(DSPOUT) ) + +$(VCPROJ): msvc/vc8proj.head msvc/vc8proj.foot Makefile.am + echo "creating $(VCPROJ)" + @(cp $(srcdir)/msvc/vc8proj.head $(VCPROJ); \ + for file in $(WIN32SOURCES); do \ + echo "" $(VCPROJOUT); \ + done; \ + echo "" $(VCPROJOUT); \ + for file in $(WIN32HEADERS); do \ + echo "" $(VCPROJOUT); \ + done; \ + cat $(srcdir)/msvc/vc8proj.foot $(VCPROJOUT) ) + +voipcodecs/version.h: + NOWDATE=`date --utc +"%Y%m%d"` ; \ + NOWTIME=`date --utc +"%H%M%S"` ; \ + sed 's/$$VOIPCODECS_RELEASE_DATE/'$$NOWDATE'/;s/$$VOIPCODECS_RELEASE_TIME/'$$NOWTIME'/' \ + voipcodecs/version.h + +dist-hook: + NOWDATE=`date --utc +"%Y%m%d"` ; \ + NOWTIME=`date --utc +"%H%M%S"` ; \ + sed 's/$$VOIPCODECS_RELEASE_DATE/'$$NOWDATE'/;s/$$VOIPCODECS_RELEASE_TIME/'$$NOWTIME'/' \ + voipcodecs/version.h diff --git a/libs/voipcodecs/src/bitstream.c b/libs/voipcodecs/src/bitstream.c new file mode 100644 index 0000000000..db8232cd15 --- /dev/null +++ b/libs/voipcodecs/src/bitstream.c @@ -0,0 +1,137 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * bitstream.c - Bitstream composition and decomposition routines. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: bitstream.c,v 1.8 2007/08/20 15:22:21 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" + +void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits) +{ + value &= ((1 << bits) - 1); + if (s->residue + bits <= 32) + { + s->bitstream |= (value << s->residue); + s->residue += bits; + } + while (s->residue >= 8) + { + s->residue -= 8; + *(*c)++ = (uint8_t) (s->bitstream & 0xFF); + s->bitstream >>= 8; + } +} +/*- End of function --------------------------------------------------------*/ + +void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits) +{ + value &= ((1 << bits) - 1); + if (s->residue + bits <= 32) + { + s->bitstream = (s->bitstream << bits) | value; + s->residue += bits; + } + while (s->residue >= 8) + { + s->residue -= 8; + *(*c)++ = (uint8_t) ((s->bitstream >> s->residue) & 0xFF); + } +} +/*- End of function --------------------------------------------------------*/ + +unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits) +{ + unsigned int x; + + while (s->residue < (unsigned int) bits) + { + x = (unsigned int) *(*c)++; + s->bitstream |= (x << s->residue); + s->residue += 8; + } + s->residue -= bits; + x = s->bitstream & ((1 << bits) - 1); + s->bitstream >>= bits; + return x; +} +/*- End of function --------------------------------------------------------*/ + +unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits) +{ + unsigned int x; + + while (s->residue < (unsigned int) bits) + { + x = (unsigned int) *(*c)++; + s->bitstream = (s->bitstream << 8) | x; + s->residue += 8; + } + s->residue -= bits; + x = (s->bitstream >> s->residue) & ((1 << bits) - 1); + return x; +} +/*- End of function --------------------------------------------------------*/ + +void bitstream_flush(bitstream_state_t *s, uint8_t **c) +{ + if (s->residue > 0) + { + *(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF); + s->residue = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +void bitstream_flush2(bitstream_state_t *s, uint8_t **c) +{ + if (s->residue > 0) + { + *(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF); + s->residue = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +bitstream_state_t *bitstream_init(bitstream_state_t *s) +{ + if (s == NULL) + return NULL; + s->bitstream = 0; + s->residue = 0; + return s; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/float_fudge.h b/libs/voipcodecs/src/float_fudge.h new file mode 100644 index 0000000000..d3b0860913 --- /dev/null +++ b/libs/voipcodecs/src/float_fudge.h @@ -0,0 +1,123 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * float_fudge.h - A bunch of shims, to use double maths + * functions on platforms which lack the + * float versions with an 'f' at the end. + * + * Written by Steve Underwood + * + * Copyright (C) 2004 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: float_fudge.h,v 1.2 2007/08/13 11:35:32 steveu Exp $ + */ + +#if !defined(_FLOAT_FUDGE_H_) +#define _FLOAT_FUDGE_H_ + +#if defined(__USE_DOUBLE_MATH__) + +#if defined(__cplusplus) +extern "C" +{ +#endif + +static __inline__ float sinf(float x) +{ + return (float) sin((double) x); +} + +static __inline__ float cosf(float x) +{ + return (float) cos((double) x); +} + +static __inline__ float tanf(float x) +{ + return (float) tan((double) x); +} + +static __inline__ float asinf(float x) +{ + return (float) asin((double) x); +} + +static __inline__ float acosf(float x) +{ + return (float) acos((double) x); +} + +static __inline__ float atanf(float x) +{ + return (float) atan((double) x); +} + +static __inline__ float atan2f(float y, float x) +{ + return (float) atan2((double) y, (double) x); +} + +static __inline__ float ceilf(float x) +{ + return (float) ceil((double) x); +} + +static __inline__ float floorf(float x) +{ + return (float) floor((double) x); +} + +static __inline__ float expf(float x) +{ + return (float) expf((double) x); +} + +static __inline__ float logf(float x) +{ + return (float) logf((double) x); +} + +static __inline__ float log10f(float x) +{ + return (float) log10((double) x); +} + +static __inline__ float powf(float x, float y) +{ + return (float) pow((double) x, (double) y); +} + +static __inline__ int rintf(float x) +{ + return (int) rint((double) x); +} + +static __inline__ long int lrintf(float x) +{ + return (long int) lrint((double) x); +} + +#if defined(__cplusplus) +} +#endif + +#endif + +#endif + +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/g711.c b/libs/voipcodecs/src/g711.c new file mode 100644 index 0000000000..6568bd1b4b --- /dev/null +++ b/libs/voipcodecs/src/g711.c @@ -0,0 +1,104 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g711.c - A-law and u-law transcoding routines + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: g711.c,v 1.4 2006/11/19 14:07:24 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bit_operations.h" +#include "voipcodecs/g711.h" + +/* Copied from the CCITT G.711 specification */ +static const uint8_t ulaw_to_alaw_table[256] = +{ + 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, + 58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, + 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26, + 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106, + 104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120, + 126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77, + 66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93, + 82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85, + 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, + 186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181, + 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154, + 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234, + 232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248, + 254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205, + 194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221, + 210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213 +}; + +/* These transcoding tables are copied from the CCITT G.711 specification. To achieve + optimal results, do not change them. */ + +static const uint8_t alaw_to_ulaw_table[256] = +{ + 42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37, + 57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52, + 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5, + 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, + 98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94, + 116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109, + 72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67, + 86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81, + 170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165, + 185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180, + 138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133, + 154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, + 226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222, + 244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237, + 200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195, + 214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209 +}; + +uint8_t alaw_to_ulaw(uint8_t alaw) +{ + return alaw_to_ulaw_table[alaw]; +} +/*- End of function --------------------------------------------------------*/ + +uint8_t ulaw_to_alaw(uint8_t ulaw) +{ + return ulaw_to_alaw_table[ulaw]; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/g722_decode.c b/libs/voipcodecs/src/g722_decode.c new file mode 100644 index 0000000000..8b52b84342 --- /dev/null +++ b/libs/voipcodecs/src/g722_decode.c @@ -0,0 +1,404 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g722_decode.c - The ITU G.722 codec, decode part. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based in part on a single channel G.722 codec which is: + * + * Copyright (c) CMU 1993 + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722_decode.c,v 1.19 2007/03/14 11:51:01 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/g722.h" + +static void block4(g722_decode_state_t *s, int band, int d); + +static void block4(g722_decode_state_t *s, int band, int d) +{ + int wd1; + int wd2; + int wd3; + int i; + + /* Block 4, RECONS */ + s->band[band].d[0] = d; + s->band[band].r[0] = saturate(s->band[band].s + d); + + /* Block 4, PARREC */ + s->band[band].p[0] = saturate(s->band[band].sz + d); + + /* Block 4, UPPOL2 */ + for (i = 0; i < 3; i++) + s->band[band].sg[i] = s->band[band].p[i] >> 15; + wd1 = saturate(s->band[band].a[1] << 2); + + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; + if (wd2 > 32767) + wd2 = 32767; + wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128; + wd3 += (wd2 >> 7); + wd3 += (s->band[band].a[2]*32512) >> 15; + if (wd3 > 12288) + wd3 = 12288; + else if (wd3 < -12288) + wd3 = -12288; + s->band[band].ap[2] = wd3; + + /* Block 4, UPPOL1 */ + s->band[band].sg[0] = s->band[band].p[0] >> 15; + s->band[band].sg[1] = s->band[band].p[1] >> 15; + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; + wd2 = (s->band[band].a[1]*32640) >> 15; + + s->band[band].ap[1] = saturate(wd1 + wd2); + wd3 = saturate(15360 - s->band[band].ap[2]); + if (s->band[band].ap[1] > wd3) + s->band[band].ap[1] = wd3; + else if (s->band[band].ap[1] < -wd3) + s->band[band].ap[1] = -wd3; + + /* Block 4, UPZERO */ + wd1 = (d == 0) ? 0 : 128; + s->band[band].sg[0] = d >> 15; + for (i = 1; i < 7; i++) + { + s->band[band].sg[i] = s->band[band].d[i] >> 15; + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; + wd3 = (s->band[band].b[i]*32640) >> 15; + s->band[band].bp[i] = saturate(wd2 + wd3); + } + + /* Block 4, DELAYA */ + for (i = 6; i > 0; i--) + { + s->band[band].d[i] = s->band[band].d[i - 1]; + s->band[band].b[i] = s->band[band].bp[i]; + } + + for (i = 2; i > 0; i--) + { + s->band[band].r[i] = s->band[band].r[i - 1]; + s->band[band].p[i] = s->band[band].p[i - 1]; + s->band[band].a[i] = s->band[band].ap[i]; + } + + /* Block 4, FILTEP */ + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); + wd1 = (s->band[band].a[1]*wd1) >> 15; + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); + wd2 = (s->band[band].a[2]*wd2) >> 15; + s->band[band].sp = saturate(wd1 + wd2); + + /* Block 4, FILTEZ */ + s->band[band].sz = 0; + for (i = 6; i > 0; i--) + { + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; + } + s->band[band].sz = saturate(s->band[band].sz); + + /* Block 4, PREDIC */ + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); +} +/*- End of function --------------------------------------------------------*/ + +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options) +{ + if (s == NULL) + { + if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + if (rate == 48000) + s->bits_per_sample = 6; + else if (rate == 56000) + s->bits_per_sample = 7; + else + s->bits_per_sample = 8; + if ((options & G722_SAMPLE_RATE_8000)) + s->eight_k = TRUE; + if ((options & G722_PACKED) && s->bits_per_sample != 8) + s->packed = TRUE; + else + s->packed = FALSE; + s->band[0].det = 32; + s->band[1].det = 8; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int g722_decode_release(g722_decode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len) +{ + static const int wl[8] = + { + -60, -30, 58, 172, 334, 538, 1198, 3042 + }; + static const int rl42[16] = + { + 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 + }; + static const int ilb[32] = + { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, + 2383, 2435, 2489, 2543, 2599, 2656, 2714, + 2774, 2834, 2896, 2960, 3025, 3091, 3158, + 3228, 3298, 3371, 3444, 3520, 3597, 3676, + 3756, 3838, 3922, 4008 + }; + static const int wh[3] = + { + 0, -214, 798 + }; + static const int rh2[4] = + { + 2, 1, 2, 1 + }; + static const int qm2[4] = + { + -7408, -1616, 7408, 1616 + }; + static const int qm4[16] = + { + 0, -20456, -12896, -8968, + -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, + 4240, 2584, 1200, 0 + }; + static const int qm5[32] = + { + -280, -280, -23352, -17560, + -14120, -11664, -9752, -8184, + -6864, -5712, -4696, -3784, + -2960, -2208, -1520, -880, + 23352, 17560, 14120, 11664, + 9752, 8184, 6864, 5712, + 4696, 3784, 2960, 2208, + 1520, 880, 280, -280 + }; + static const int qm6[64] = + { + -136, -136, -136, -136, + -24808, -21904, -19008, -16704, + -14984, -13512, -12280, -11192, + -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, + -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, + -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, + 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, + 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, + 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, + 432, 136, -432, -136 + }; + static const int qmf_coeffs[12] = + { + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, + }; + int dlowt; + int rlow; + int ihigh; + int dhigh; + int rhigh; + int xout1; + int xout2; + int wd1; + int wd2; + int wd3; + int code; + int outlen; + int i; + int j; + + outlen = 0; + rhigh = 0; + for (j = 0; j < len; ) + { + if (s->packed) + { + /* Unpack the code bits */ + if (s->in_bits < s->bits_per_sample) + { + s->in_buffer |= (g722_data[j++] << s->in_bits); + s->in_bits += 8; + } + code = s->in_buffer & ((1 << s->bits_per_sample) - 1); + s->in_buffer >>= s->bits_per_sample; + s->in_bits -= s->bits_per_sample; + } + else + { + code = g722_data[j++]; + } + + switch (s->bits_per_sample) + { + default: + case 8: + wd1 = code & 0x3F; + ihigh = (code >> 6) & 0x03; + wd2 = qm6[wd1]; + wd1 >>= 2; + break; + case 7: + wd1 = code & 0x1F; + ihigh = (code >> 5) & 0x03; + wd2 = qm5[wd1]; + wd1 >>= 1; + break; + case 6: + wd1 = code & 0x0F; + ihigh = (code >> 4) & 0x03; + wd2 = qm4[wd1]; + break; + } + /* Block 5L, LOW BAND INVQBL */ + wd2 = (s->band[0].det*wd2) >> 15; + /* Block 5L, RECONS */ + rlow = s->band[0].s + wd2; + /* Block 6L, LIMIT */ + if (rlow > 16383) + rlow = 16383; + else if (rlow < -16384) + rlow = -16384; + + /* Block 2L, INVQAL */ + wd2 = qm4[wd1]; + dlowt = (s->band[0].det*wd2) >> 15; + + /* Block 3L, LOGSCL */ + wd2 = rl42[wd1]; + wd1 = (s->band[0].nb*127) >> 7; + wd1 += wl[wd2]; + if (wd1 < 0) + wd1 = 0; + else if (wd1 > 18432) + wd1 = 18432; + s->band[0].nb = wd1; + + /* Block 3L, SCALEL */ + wd1 = (s->band[0].nb >> 6) & 31; + wd2 = 8 - (s->band[0].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[0].det = wd3 << 2; + + block4(s, 0, dlowt); + + if (!s->eight_k) + { + /* Block 2H, INVQAH */ + wd2 = qm2[ihigh]; + dhigh = (s->band[1].det*wd2) >> 15; + /* Block 5H, RECONS */ + rhigh = dhigh + s->band[1].s; + /* Block 6H, LIMIT */ + if (rhigh > 16383) + rhigh = 16383; + else if (rhigh < -16384) + rhigh = -16384; + + /* Block 2H, INVQAH */ + wd2 = rh2[ihigh]; + wd1 = (s->band[1].nb*127) >> 7; + wd1 += wh[wd2]; + if (wd1 < 0) + wd1 = 0; + else if (wd1 > 22528) + wd1 = 22528; + s->band[1].nb = wd1; + + /* Block 3H, SCALEH */ + wd1 = (s->band[1].nb >> 6) & 31; + wd2 = 10 - (s->band[1].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[1].det = wd3 << 2; + + block4(s, 1, dhigh); + } + + if (s->itu_test_mode) + { + amp[outlen++] = (int16_t) (rlow << 1); + amp[outlen++] = (int16_t) (rhigh << 1); + } + else + { + if (s->eight_k) + { + amp[outlen++] = (int16_t) rlow; + } + else + { + /* Apply the receive QMF */ + memcpy(s->x, &s->x[2], 22*sizeof(s->x[0])); + s->x[22] = rlow + rhigh; + s->x[23] = rlow - rhigh; + + xout1 = 0; + xout2 = 0; + for (i = 0; i < 12; i++) + { + xout2 += s->x[2*i]*qmf_coeffs[i]; + xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i]; + } + amp[outlen++] = (int16_t) (xout1 >> 12); + amp[outlen++] = (int16_t) (xout2 >> 12); + } + } + } + return outlen; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/g722_encode.c b/libs/voipcodecs/src/g722_encode.c new file mode 100644 index 0000000000..3612b7d50c --- /dev/null +++ b/libs/voipcodecs/src/g722_encode.c @@ -0,0 +1,390 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g722_encode.c - The ITU G.722 codec, encode part. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based on a single channel 64kbps only G.722 codec which is: + * + ***** Copyright (c) CMU 1993 ***** + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722_encode.c,v 1.17 2007/03/14 11:51:01 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/g722.h" + +static void block4(g722_encode_state_t *s, int band, int d) +{ + int wd1; + int wd2; + int wd3; + int i; + + /* Block 4, RECONS */ + s->band[band].d[0] = d; + s->band[band].r[0] = saturate(s->band[band].s + d); + + /* Block 4, PARREC */ + s->band[band].p[0] = saturate(s->band[band].sz + d); + + /* Block 4, UPPOL2 */ + for (i = 0; i < 3; i++) + s->band[band].sg[i] = s->band[band].p[i] >> 15; + wd1 = saturate(s->band[band].a[1] << 2); + + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; + if (wd2 > 32767) + wd2 = 32767; + wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128); + wd3 += (s->band[band].a[2]*32512) >> 15; + if (wd3 > 12288) + wd3 = 12288; + else if (wd3 < -12288) + wd3 = -12288; + s->band[band].ap[2] = wd3; + + /* Block 4, UPPOL1 */ + s->band[band].sg[0] = s->band[band].p[0] >> 15; + s->band[band].sg[1] = s->band[band].p[1] >> 15; + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; + wd2 = (s->band[band].a[1]*32640) >> 15; + + s->band[band].ap[1] = saturate(wd1 + wd2); + wd3 = saturate(15360 - s->band[band].ap[2]); + if (s->band[band].ap[1] > wd3) + s->band[band].ap[1] = wd3; + else if (s->band[band].ap[1] < -wd3) + s->band[band].ap[1] = -wd3; + + /* Block 4, UPZERO */ + wd1 = (d == 0) ? 0 : 128; + s->band[band].sg[0] = d >> 15; + for (i = 1; i < 7; i++) + { + s->band[band].sg[i] = s->band[band].d[i] >> 15; + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; + wd3 = (s->band[band].b[i]*32640) >> 15; + s->band[band].bp[i] = saturate(wd2 + wd3); + } + + /* Block 4, DELAYA */ + for (i = 6; i > 0; i--) + { + s->band[band].d[i] = s->band[band].d[i - 1]; + s->band[band].b[i] = s->band[band].bp[i]; + } + + for (i = 2; i > 0; i--) + { + s->band[band].r[i] = s->band[band].r[i - 1]; + s->band[band].p[i] = s->band[band].p[i - 1]; + s->band[band].a[i] = s->band[band].ap[i]; + } + + /* Block 4, FILTEP */ + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); + wd1 = (s->band[band].a[1]*wd1) >> 15; + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); + wd2 = (s->band[band].a[2]*wd2) >> 15; + s->band[band].sp = saturate(wd1 + wd2); + + /* Block 4, FILTEZ */ + s->band[band].sz = 0; + for (i = 6; i > 0; i--) + { + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; + } + s->band[band].sz = saturate(s->band[band].sz); + + /* Block 4, PREDIC */ + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); +} +/*- End of function --------------------------------------------------------*/ + +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options) +{ + if (s == NULL) + { + if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + if (rate == 48000) + s->bits_per_sample = 6; + else if (rate == 56000) + s->bits_per_sample = 7; + else + s->bits_per_sample = 8; + if ((options & G722_SAMPLE_RATE_8000)) + s->eight_k = TRUE; + if ((options & G722_PACKED) && s->bits_per_sample != 8) + s->packed = TRUE; + else + s->packed = FALSE; + s->band[0].det = 32; + s->band[1].det = 8; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int g722_encode_release(g722_encode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len) +{ + static const int q6[32] = + { + 0, 35, 72, 110, 150, 190, 233, 276, + 323, 370, 422, 473, 530, 587, 650, 714, + 786, 858, 940, 1023, 1121, 1219, 1339, 1458, + 1612, 1765, 1980, 2195, 2557, 2919, 0, 0 + }; + static const int iln[32] = + { + 0, 63, 62, 31, 30, 29, 28, 27, + 26, 25, 24, 23, 22, 21, 20, 19, + 18, 17, 16, 15, 14, 13, 12, 11, + 10, 9, 8, 7, 6, 5, 4, 0 + }; + static const int ilp[32] = + { + 0, 61, 60, 59, 58, 57, 56, 55, + 54, 53, 52, 51, 50, 49, 48, 47, + 46, 45, 44, 43, 42, 41, 40, 39, + 38, 37, 36, 35, 34, 33, 32, 0 + }; + static const int wl[8] = + { + -60, -30, 58, 172, 334, 538, 1198, 3042 + }; + static const int rl42[16] = + { + 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 + }; + static const int ilb[32] = + { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, + 2383, 2435, 2489, 2543, 2599, 2656, 2714, + 2774, 2834, 2896, 2960, 3025, 3091, 3158, + 3228, 3298, 3371, 3444, 3520, 3597, 3676, + 3756, 3838, 3922, 4008 + }; + static const int qm4[16] = + { + 0, -20456, -12896, -8968, + -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, + 4240, 2584, 1200, 0 + }; + static const int qm2[4] = + { + -7408, -1616, 7408, 1616 + }; + static const int qmf_coeffs[12] = + { + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, + }; + static const int ihn[3] = {0, 1, 0}; + static const int ihp[3] = {0, 3, 2}; + static const int wh[3] = {0, -214, 798}; + static const int rh2[4] = {2, 1, 2, 1}; + + int dlow; + int dhigh; + int el; + int wd; + int wd1; + int ril; + int wd2; + int il4; + int ih2; + int wd3; + int eh; + int mih; + int i; + int j; + /* Low and high band PCM from the QMF */ + int xlow; + int xhigh; + int g722_bytes; + /* Even and odd tap accumulators */ + int sumeven; + int sumodd; + int ihigh; + int ilow; + int code; + + g722_bytes = 0; + xhigh = 0; + for (j = 0; j < len; ) + { + if (s->itu_test_mode) + { + xlow = + xhigh = amp[j++] >> 1; + } + else + { + if (s->eight_k) + { + xlow = amp[j++]; + } + else + { + /* Apply the transmit QMF */ + /* Shuffle the buffer down */ + memcpy(s->x, &s->x[2], 22*sizeof(s->x[0])); + s->x[22] = amp[j++]; + s->x[23] = amp[j++]; + + /* Discard every other QMF output */ + sumeven = 0; + sumodd = 0; + for (i = 0; i < 12; i++) + { + sumodd += s->x[2*i]*qmf_coeffs[i]; + sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i]; + } + xlow = (sumeven + sumodd) >> 13; + xhigh = (sumeven - sumodd) >> 13; + } + } + /* Block 1L, SUBTRA */ + el = saturate(xlow - s->band[0].s); + + /* Block 1L, QUANTL */ + wd = (el >= 0) ? el : -(el + 1); + + for (i = 1; i < 30; i++) + { + wd1 = (q6[i]*s->band[0].det) >> 12; + if (wd < wd1) + break; + } + ilow = (el < 0) ? iln[i] : ilp[i]; + + /* Block 2L, INVQAL */ + ril = ilow >> 2; + wd2 = qm4[ril]; + dlow = (s->band[0].det*wd2) >> 15; + + /* Block 3L, LOGSCL */ + il4 = rl42[ril]; + wd = (s->band[0].nb*127) >> 7; + s->band[0].nb = wd + wl[il4]; + if (s->band[0].nb < 0) + s->band[0].nb = 0; + else if (s->band[0].nb > 18432) + s->band[0].nb = 18432; + + /* Block 3L, SCALEL */ + wd1 = (s->band[0].nb >> 6) & 31; + wd2 = 8 - (s->band[0].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[0].det = wd3 << 2; + + block4(s, 0, dlow); + + if (s->eight_k) + { + /* Just leave the high bits as zero */ + code = (0xC0 | ilow) >> (8 - s->bits_per_sample); + } + else + { + /* Block 1H, SUBTRA */ + eh = saturate(xhigh - s->band[1].s); + + /* Block 1H, QUANTH */ + wd = (eh >= 0) ? eh : -(eh + 1); + wd1 = (564*s->band[1].det) >> 12; + mih = (wd >= wd1) ? 2 : 1; + ihigh = (eh < 0) ? ihn[mih] : ihp[mih]; + + /* Block 2H, INVQAH */ + wd2 = qm2[ihigh]; + dhigh = (s->band[1].det*wd2) >> 15; + + /* Block 3H, LOGSCH */ + ih2 = rh2[ihigh]; + wd = (s->band[1].nb*127) >> 7; + s->band[1].nb = wd + wh[ih2]; + if (s->band[1].nb < 0) + s->band[1].nb = 0; + else if (s->band[1].nb > 22528) + s->band[1].nb = 22528; + + /* Block 3H, SCALEH */ + wd1 = (s->band[1].nb >> 6) & 31; + wd2 = 10 - (s->band[1].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[1].det = wd3 << 2; + + block4(s, 1, dhigh); + code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample); + } + + if (s->packed) + { + /* Pack the code bits */ + s->out_buffer |= (code << s->out_bits); + s->out_bits += s->bits_per_sample; + if (s->out_bits >= 8) + { + g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF); + s->out_bits -= 8; + s->out_buffer >>= 8; + } + } + else + { + g722_data[g722_bytes++] = (uint8_t) code; + } + } + return g722_bytes; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/g726.c b/libs/voipcodecs/src/g726.c new file mode 100644 index 0000000000..e7172219ad --- /dev/null +++ b/libs/voipcodecs/src/g726.c @@ -0,0 +1,1178 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g726.c - The ITU G.726 codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based on G.721/G.723 code which is: + * + * This source code is a product of Sun Microsystems, Inc. and is provided + * for unrestricted use. Users may copy or modify this source code without + * charge. + * + * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING + * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun source code is provided with no support and without any obligation on + * the part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * $Id: g726.c,v 1.17 2006/11/19 14:07:24 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/bit_operations.h" +#include "voipcodecs/g711.h" +#include "voipcodecs/g726.h" + +/* + * Maps G.726_16 code word to reconstructed scale factor normalized log + * magnitude values. + */ +static const int g726_16_dqlntab[4] = +{ + 116, 365, 365, 116 +}; + +/* Maps G.726_16 code word to log of scale factor multiplier. */ +static const int g726_16_witab[4] = +{ + -704, 14048, 14048, -704 +}; + +/* + * Maps G.726_16 code words to a set of values whose long and short + * term averages are computed and then compared to give an indication + * how stationary (steady state) the signal is. + */ +static const int g726_16_fitab[4] = +{ + 0x000, 0xE00, 0xE00, 0x000 +}; + +static const int qtab_726_16[1] = +{ + 261 +}; + +/* + * Maps G.726_24 code word to reconstructed scale factor normalized log + * magnitude values. + */ +static const int g726_24_dqlntab[8] = +{ + -2048, 135, 273, 373, 373, 273, 135, -2048 +}; + +/* Maps G.726_24 code word to log of scale factor multiplier. */ +static const int g726_24_witab[8] = +{ + -128, 960, 4384, 18624, 18624, 4384, 960, -128 +}; + +/* + * Maps G.726_24 code words to a set of values whose long and short + * term averages are computed and then compared to give an indication + * how stationary (steady state) the signal is. + */ +static const int g726_24_fitab[8] = +{ + 0x000, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0x000 +}; + +static const int qtab_726_24[3] = +{ + 8, 218, 331 +}; + +/* + * Maps G.726_32 code word to reconstructed scale factor normalized log + * magnitude values. + */ +static const int g726_32_dqlntab[16] = +{ + -2048, 4, 135, 213, 273, 323, 373, 425, + 425, 373, 323, 273, 213, 135, 4, -2048 +}; + +/* Maps G.726_32 code word to log of scale factor multiplier. */ +static const int g726_32_witab[16] = +{ + -384, 576, 1312, 2048, 3584, 6336, 11360, 35904, + 35904, 11360, 6336, 3584, 2048, 1312, 576, -384 +}; + +/* + * Maps G.726_32 code words to a set of values whose long and short + * term averages are computed and then compared to give an indication + * how stationary (steady state) the signal is. + */ +static const int g726_32_fitab[16] = +{ + 0x000, 0x000, 0x000, 0x200, 0x200, 0x200, 0x600, 0xE00, + 0xE00, 0x600, 0x200, 0x200, 0x200, 0x000, 0x000, 0x000 +}; + +static const int qtab_726_32[7] = +{ + -124, 80, 178, 246, 300, 349, 400 +}; + +/* + * Maps G.726_40 code word to ructeconstructed scale factor normalized log + * magnitude values. + */ +static const int g726_40_dqlntab[32] = +{ + -2048, -66, 28, 104, 169, 224, 274, 318, + 358, 395, 429, 459, 488, 514, 539, 566, + 566, 539, 514, 488, 459, 429, 395, 358, + 318, 274, 224, 169, 104, 28, -66, -2048 +}; + +/* Maps G.726_40 code word to log of scale factor multiplier. */ +static const int g726_40_witab[32] = +{ + 448, 448, 768, 1248, 1280, 1312, 1856, 3200, + 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272, + 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512, + 3200, 1856, 1312, 1280, 1248, 768, 448, 448 +}; + +/* + * Maps G.726_40 code words to a set of values whose long and short + * term averages are computed and then compared to give an indication + * how stationary (steady state) the signal is. + */ +static const int g726_40_fitab[32] = +{ + 0x000, 0x000, 0x000, 0x000, 0x000, 0x200, 0x200, 0x200, + 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00, + 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200, + 0x200, 0x200, 0x200, 0x000, 0x000, 0x000, 0x000, 0x000 +}; + +static const int qtab_726_40[15] = +{ + -122, -16, 68, 139, 198, 250, 298, 339, + 378, 413, 445, 475, 502, 528, 553 +}; + +/* + * returns the integer product of the 14-bit integer "an" and + * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". + */ +static int16_t fmult(int16_t an, int16_t srn) +{ + int16_t anmag; + int16_t anexp; + int16_t anmant; + int16_t wanexp; + int16_t wanmant; + int16_t retval; + + anmag = (an > 0) ? an : ((-an) & 0x1FFF); + anexp = (int16_t) (top_bit(anmag) - 5); + anmant = (anmag == 0) ? 32 : (anexp >= 0) ? (anmag >> anexp) : (anmag << -anexp); + wanexp = anexp + ((srn >> 6) & 0xF) - 13; + + wanmant = (anmant*(srn & 0x3F) + 0x30) >> 4; + retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : (wanmant >> -wanexp); + + return (((an ^ srn) < 0) ? -retval : retval); +} +/*- End of function --------------------------------------------------------*/ + +/* + * Compute the estimated signal from the 6-zero predictor. + */ +static __inline__ int16_t predictor_zero(g726_state_t *s) +{ + int i; + int sezi; + + sezi = fmult(s->b[0] >> 2, s->dq[0]); + /* ACCUM */ + for (i = 1; i < 6; i++) + sezi += fmult(s->b[i] >> 2, s->dq[i]); + return (int16_t) sezi; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Computes the estimated signal from the 2-pole predictor. + */ +static __inline__ int16_t predictor_pole(g726_state_t *s) +{ + return (fmult(s->a[1] >> 2, s->sr[1]) + fmult(s->a[0] >> 2, s->sr[0])); +} +/*- End of function --------------------------------------------------------*/ + +/* + * Computes the quantization step size of the adaptive quantizer. + */ +static int step_size(g726_state_t *s) +{ + int y; + int dif; + int al; + + if (s->ap >= 256) + return s->yu; + y = s->yl >> 6; + dif = s->yu - y; + al = s->ap >> 2; + if (dif > 0) + y += (dif*al) >> 6; + else if (dif < 0) + y += (dif*al + 0x3F) >> 6; + return y; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Given a raw sample, 'd', of the difference signal and a + * quantization step size scale factor, 'y', this routine returns the + * ADPCM codeword to which that sample gets quantized. The step + * size scale factor division operation is done in the log base 2 domain + * as a subtraction. + */ +static int16_t quantize(int d, /* Raw difference signal sample */ + int y, /* Step size multiplier */ + const int table[], /* quantization table */ + int quantizer_states) /* table size of int16_t integers */ +{ + int16_t dqm; /* Magnitude of 'd' */ + int16_t exp; /* Integer part of base 2 log of 'd' */ + int16_t mant; /* Fractional part of base 2 log */ + int16_t dl; /* Log of magnitude of 'd' */ + int16_t dln; /* Step size scale factor normalized log */ + int i; + int size; + + /* + * LOG + * + * Compute base 2 log of 'd', and store in 'dl'. + */ + dqm = (int16_t) abs(d); + exp = (int16_t) (top_bit(dqm >> 1) + 1); + /* Fractional portion. */ + mant = ((dqm << 7) >> exp) & 0x7F; + dl = (exp << 7) + mant; + + /* + * SUBTB + * + * "Divide" by step size multiplier. + */ + dln = dl - (int16_t) (y >> 2); + + /* + * QUAN + * + * Search for codword i for 'dln'. + */ + size = (quantizer_states - 1) >> 1; + for (i = 0; i < size; i++) + { + if (dln < table[i]) + break; + } + if (d < 0) + { + /* Take 1's complement of i */ + return (int16_t) ((size << 1) + 1 - i); + } + if (i == 0 && (quantizer_states & 1)) + { + /* Zero is only valid if there are an even number of states, so + take the 1's complement if the code is zero. */ + return (int16_t) quantizer_states; + } + return (int16_t) i; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Returns reconstructed difference signal 'dq' obtained from + * codeword 'i' and quantization step size scale factor 'y'. + * Multiplication is performed in log base 2 domain as addition. + */ +static int16_t reconstruct(int sign, /* 0 for non-negative value */ + int dqln, /* G.72x codeword */ + int y) /* Step size multiplier */ +{ + int16_t dql; /* Log of 'dq' magnitude */ + int16_t dex; /* Integer part of log */ + int16_t dqt; + int16_t dq; /* Reconstructed difference signal sample */ + + dql = (int16_t) (dqln + (y >> 2)); /* ADDA */ + + if (dql < 0) + return ((sign) ? -0x8000 : 0); + /* ANTILOG */ + dex = (dql >> 7) & 15; + dqt = 128 + (dql & 127); + dq = (dqt << 7) >> (14 - dex); + return ((sign) ? (dq - 0x8000) : dq); +} +/*- End of function --------------------------------------------------------*/ + +/* + * updates the state variables for each output code + */ +static void update(g726_state_t *s, + int y, /* quantizer step size */ + int wi, /* scale factor multiplier */ + int fi, /* for long/short term energies */ + int dq, /* quantized prediction difference */ + int sr, /* reconstructed signal */ + int dqsez) /* difference from 2-pole predictor */ +{ + int16_t mag; + int16_t exp; + int16_t a2p; /* LIMC */ + int16_t a1ul; /* UPA1 */ + int16_t pks1; /* UPA2 */ + int16_t fa1; + int16_t ylint; + int16_t dqthr; + int16_t ylfrac; + int16_t thr; + int16_t pk0; + int i; + int tr; + + a2p = 0; + /* Needed in updating predictor poles */ + pk0 = (dqsez < 0) ? 1 : 0; + + /* prediction difference magnitude */ + mag = (int16_t) (dq & 0x7FFF); + /* TRANS */ + ylint = (int16_t) (s->yl >> 15); /* exponent part of yl */ + ylfrac = (int16_t) ((s->yl >> 10) & 0x1F); /* fractional part of yl */ + /* Limit threshold to 31 << 10 */ + thr = (ylint > 9) ? (31 << 10) : ((32 + ylfrac) << ylint); + dqthr = (thr + (thr >> 1)) >> 1; /* dqthr = 0.75 * thr */ + if (!s->td) /* signal supposed voice */ + tr = FALSE; + else if (mag <= dqthr) /* supposed data, but small mag */ + tr = FALSE; /* treated as voice */ + else /* signal is data (modem) */ + tr = TRUE; + + /* + * Quantizer scale factor adaptation. + */ + + /* FUNCTW & FILTD & DELAY */ + /* update non-steady state step size multiplier */ + s->yu = (int16_t) (y + ((wi - y) >> 5)); + + /* LIMB */ + if (s->yu < 544) + s->yu = 544; + else if (s->yu > 5120) + s->yu = 5120; + + /* FILTE & DELAY */ + /* update steady state step size multiplier */ + s->yl += s->yu + ((-s->yl) >> 6); + + /* + * Adaptive predictor coefficients. + */ + if (tr) + { + /* Reset the a's and b's for a modem signal */ + s->a[0] = 0; + s->a[1] = 0; + s->b[0] = 0; + s->b[1] = 0; + s->b[2] = 0; + s->b[3] = 0; + s->b[4] = 0; + s->b[5] = 0; + } + else + { + /* Update the a's and b's */ + /* UPA2 */ + pks1 = pk0 ^ s->pk[0]; + + /* Update predictor pole a[1] */ + a2p = s->a[1] - (s->a[1] >> 7); + if (dqsez != 0) + { + fa1 = (pks1) ? s->a[0] : -s->a[0]; + /* a2p = function of fa1 */ + if (fa1 < -8191) + a2p -= 0x100; + else if (fa1 > 8191) + a2p += 0xFF; + else + a2p += fa1 >> 5; + + if (pk0 ^ s->pk[1]) + { + /* LIMC */ + if (a2p <= -12160) + a2p = -12288; + else if (a2p >= 12416) + a2p = 12288; + else + a2p -= 0x80; + } + else if (a2p <= -12416) + a2p = -12288; + else if (a2p >= 12160) + a2p = 12288; + else + a2p += 0x80; + } + + /* TRIGB & DELAY */ + s->a[1] = a2p; + + /* UPA1 */ + /* Update predictor pole a[0] */ + s->a[0] -= s->a[0] >> 8; + if (dqsez != 0) + { + if (pks1 == 0) + s->a[0] += 192; + else + s->a[0] -= 192; + } + /* LIMD */ + a1ul = 15360 - a2p; + if (s->a[0] < -a1ul) + s->a[0] = -a1ul; + else if (s->a[0] > a1ul) + s->a[0] = a1ul; + + /* UPB : update predictor zeros b[6] */ + for (i = 0; i < 6; i++) + { + /* Distinguish 40Kbps mode from the others */ + s->b[i] -= s->b[i] >> ((s->bits_per_sample == 5) ? 9 : 8); + if (dq & 0x7FFF) + { + /* XOR */ + if ((dq ^ s->dq[i]) >= 0) + s->b[i] += 128; + else + s->b[i] -= 128; + } + } + } + + for (i = 5; i > 0; i--) + s->dq[i] = s->dq[i - 1]; + /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ + if (mag == 0) + { + s->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; + } + else + { + exp = (int16_t) (top_bit(mag) + 1); + s->dq[0] = (dq >= 0) + ? ((exp << 6) + ((mag << 6) >> exp)) + : ((exp << 6) + ((mag << 6) >> exp) - 0x400); + } + + s->sr[1] = s->sr[0]; + /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ + if (sr == 0) + { + s->sr[0] = 0x20; + } + else if (sr > 0) + { + exp = (int16_t) (top_bit(sr) + 1); + s->sr[0] = (int16_t) ((exp << 6) + ((sr << 6) >> exp)); + } + else if (sr > -32768) + { + mag = (int16_t) -sr; + exp = (int16_t) (top_bit(mag) + 1); + s->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; + } + else + { + s->sr[0] = (uint16_t) 0xFC20; + } + + /* DELAY A */ + s->pk[1] = s->pk[0]; + s->pk[0] = pk0; + + /* TONE */ + if (tr) /* this sample has been treated as data */ + s->td = FALSE; /* next one will be treated as voice */ + else if (a2p < -11776) /* small sample-to-sample correlation */ + s->td = TRUE; /* signal may be data */ + else /* signal is voice */ + s->td = FALSE; + + /* Adaptation speed control. */ + /* FILTA */ + s->dms += ((int16_t) fi - s->dms) >> 5; + /* FILTB */ + s->dml += (((int16_t) (fi << 2) - s->dml) >> 7); + + if (tr) + s->ap = 256; + else if (y < 1536) /* SUBTC */ + s->ap += (0x200 - s->ap) >> 4; + else if (s->td) + s->ap += (0x200 - s->ap) >> 4; + else if (abs((s->dms << 2) - s->dml) >= (s->dml >> 3)) + s->ap += (0x200 - s->ap) >> 4; + else + s->ap += (-s->ap) >> 4; +} +/*- End of function --------------------------------------------------------*/ + +static int16_t tandem_adjust_alaw(int16_t sr, /* decoder output linear PCM sample */ + int se, /* predictor estimate sample */ + int y, /* quantizer step size */ + int i, /* decoder input code */ + int sign, + const int qtab[], + int quantizer_states) +{ + uint8_t sp; /* A-law compressed 8-bit code */ + int16_t dx; /* prediction error */ + int id; /* quantized prediction error */ + int sd; /* adjusted A-law decoded sample value */ + + if (sr <= -32768) + sr = -1; + sp = linear_to_alaw((sr >> 1) << 3); + /* 16-bit prediction error */ + dx = (int16_t) ((alaw_to_linear(sp) >> 2) - se); + id = quantize(dx, y, qtab, quantizer_states); + if (id == i) + { + /* No adjustment of sp required */ + return (int16_t) sp; + } + /* sp adjustment needed */ + /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ + /* 2's complement to biased unsigned */ + if ((id ^ sign) > (i ^ sign)) + { + /* sp adjusted to next lower value */ + if (sp & 0x80) + sd = (sp == 0xD5) ? 0x55 : (((sp ^ 0x55) - 1) ^ 0x55); + else + sd = (sp == 0x2A) ? 0x2A : (((sp ^ 0x55) + 1) ^ 0x55); + } + else + { + /* sp adjusted to next higher value */ + if (sp & 0x80) + sd = (sp == 0xAA) ? 0xAA : (((sp ^ 0x55) + 1) ^ 0x55); + else + sd = (sp == 0x55) ? 0xD5 : (((sp ^ 0x55) - 1) ^ 0x55); + } + return (int16_t) sd; +} +/*- End of function --------------------------------------------------------*/ + +static int16_t tandem_adjust_ulaw(int16_t sr, /* decoder output linear PCM sample */ + int se, /* predictor estimate sample */ + int y, /* quantizer step size */ + int i, /* decoder input code */ + int sign, + const int qtab[], + int quantizer_states) +{ + uint8_t sp; /* u-law compressed 8-bit code */ + int16_t dx; /* prediction error */ + int id; /* quantized prediction error */ + int sd; /* adjusted u-law decoded sample value */ + + if (sr <= -32768) + sr = 0; + sp = linear_to_ulaw(sr << 2); + /* 16-bit prediction error */ + dx = (int16_t) ((ulaw_to_linear(sp) >> 2) - se); + id = quantize(dx, y, qtab, quantizer_states); + if (id == i) + { + /* No adjustment of sp required. */ + return (int16_t) sp; + } + /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ + /* 2's complement to biased unsigned */ + if ((id ^ sign) > (i ^ sign)) + { + /* sp adjusted to next lower value */ + if (sp & 0x80) + sd = (sp == 0xFF) ? 0x7E : (sp + 1); + else + sd = (sp == 0x00) ? 0x00 : (sp - 1); + } + else + { + /* sp adjusted to next higher value */ + if (sp & 0x80) + sd = (sp == 0x80) ? 0x80 : (sp - 1); + else + sd = (sp == 0x7F) ? 0xFE : (sp + 1); + } + return (int16_t) sd; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. + */ +static uint8_t g726_16_encoder(g726_state_t *s, int16_t amp) +{ + int y; + int16_t sei; + int16_t sezi; + int16_t se; + int16_t d; + int16_t sr; + int16_t dqsez; + int16_t dq; + int16_t i; + + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + se = sei >> 1; + d = amp - se; + + /* Quantize prediction difference */ + y = step_size(s); + i = quantize(d, y, qtab_726_16, 4); + dq = reconstruct(i & 2, g726_16_dqlntab[i], y); + + /* Reconstruct the signal */ + sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_16_witab[i], g726_16_fitab[i], dq, sr, dqsez); + return (uint8_t) i; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Decodes a 2-bit CCITT G.726_16 ADPCM code and returns + * the resulting 16-bit linear PCM, A-law or u-law sample value. + */ +static int16_t g726_16_decoder(g726_state_t *s, uint8_t code) +{ + int16_t sezi; + int16_t sei; + int16_t se; + int16_t sr; + int16_t dq; + int16_t dqsez; + int y; + + /* Mask to get proper bits */ + code &= 0x03; + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + + y = step_size(s); + dq = reconstruct(code & 2, g726_16_dqlntab[code], y); + + /* Reconstruct the signal */ + se = sei >> 1; + sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_16_witab[code], g726_16_fitab[code], dq, sr, dqsez); + + switch (s->ext_coding) + { + case G726_ENCODING_ALAW: + return tandem_adjust_alaw(sr, se, y, code, 2, qtab_726_16, 4); + case G726_ENCODING_ULAW: + return tandem_adjust_ulaw(sr, se, y, code, 2, qtab_726_16, 4); + } + return (sr << 2); +} +/*- End of function --------------------------------------------------------*/ + +/* + * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. + */ +static uint8_t g726_24_encoder(g726_state_t *s, int16_t amp) +{ + int16_t sei; + int16_t sezi; + int16_t se; + int16_t d; + int16_t sr; + int16_t dqsez; + int16_t dq; + int16_t i; + int y; + + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + se = sei >> 1; + d = amp - se; + + /* Quantize prediction difference */ + y = step_size(s); + i = quantize(d, y, qtab_726_24, 7); + dq = reconstruct(i & 4, g726_24_dqlntab[i], y); + + /* Reconstruct the signal */ + sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_24_witab[i], g726_24_fitab[i], dq, sr, dqsez); + return (uint8_t) i; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Decodes a 3-bit CCITT G.726_24 ADPCM code and returns + * the resulting 16-bit linear PCM, A-law or u-law sample value. + */ +static int16_t g726_24_decoder(g726_state_t *s, uint8_t code) +{ + int16_t sezi; + int16_t sei; + int16_t se; + int16_t sr; + int16_t dq; + int16_t dqsez; + int y; + + /* Mask to get proper bits */ + code &= 0x07; + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + + y = step_size(s); + dq = reconstruct(code & 4, g726_24_dqlntab[code], y); + + /* Reconstruct the signal */ + se = sei >> 1; + sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_24_witab[code], g726_24_fitab[code], dq, sr, dqsez); + + switch (s->ext_coding) + { + case G726_ENCODING_ALAW: + return tandem_adjust_alaw(sr, se, y, code, 4, qtab_726_24, 7); + case G726_ENCODING_ULAW: + return tandem_adjust_ulaw(sr, se, y, code, 4, qtab_726_24, 7); + } + return (sr << 2); +} +/*- End of function --------------------------------------------------------*/ + +/* + * Encodes a linear input sample and returns its 4-bit code. + */ +static uint8_t g726_32_encoder(g726_state_t *s, int16_t amp) +{ + int16_t sei; + int16_t sezi; + int16_t se; + int16_t d; + int16_t sr; + int16_t dqsez; + int16_t dq; + int16_t i; + int y; + + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + se = sei >> 1; + d = amp - se; + + /* Quantize the prediction difference */ + y = step_size(s); + i = quantize(d, y, qtab_726_32, 15); + dq = reconstruct(i & 8, g726_32_dqlntab[i], y); + + /* Reconstruct the signal */ + sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_32_witab[i], g726_32_fitab[i], dq, sr, dqsez); + return (uint8_t) i; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Decodes a 4-bit CCITT G.726_32 ADPCM code and returns + * the resulting 16-bit linear PCM, A-law or u-law sample value. + */ +static int16_t g726_32_decoder(g726_state_t *s, uint8_t code) +{ + int16_t sezi; + int16_t sei; + int16_t se; + int16_t sr; + int16_t dq; + int16_t dqsez; + int y; + + /* Mask to get proper bits */ + code &= 0x0F; + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + + y = step_size(s); + dq = reconstruct(code & 8, g726_32_dqlntab[code], y); + + /* Reconstruct the signal */ + se = sei >> 1; + sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_32_witab[code], g726_32_fitab[code], dq, sr, dqsez); + + switch (s->ext_coding) + { + case G726_ENCODING_ALAW: + return tandem_adjust_alaw(sr, se, y, code, 8, qtab_726_32, 15); + case G726_ENCODING_ULAW: + return tandem_adjust_ulaw(sr, se, y, code, 8, qtab_726_32, 15); + } + return (sr << 2); +} +/*- End of function --------------------------------------------------------*/ + +/* + * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens + * the resulting 5-bit CCITT G.726 40Kbps code. + */ +static uint8_t g726_40_encoder(g726_state_t *s, int16_t amp) +{ + int16_t sei; + int16_t sezi; + int16_t se; + int16_t d; + int16_t sr; + int16_t dqsez; + int16_t dq; + int16_t i; + int y; + + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + se = sei >> 1; + d = amp - se; + + /* Quantize prediction difference */ + y = step_size(s); + i = quantize(d, y, qtab_726_40, 31); + dq = reconstruct(i & 0x10, g726_40_dqlntab[i], y); + + /* Reconstruct the signal */ + sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_40_witab[i], g726_40_fitab[i], dq, sr, dqsez); + return (uint8_t) i; +} +/*- End of function --------------------------------------------------------*/ + +/* + * Decodes a 5-bit CCITT G.726 40Kbps code and returns + * the resulting 16-bit linear PCM, A-law or u-law sample value. + */ +static int16_t g726_40_decoder(g726_state_t *s, uint8_t code) +{ + int16_t sezi; + int16_t sei; + int16_t se; + int16_t sr; + int16_t dq; + int16_t dqsez; + int y; + + /* Mask to get proper bits */ + code &= 0x1F; + sezi = predictor_zero(s); + sei = sezi + predictor_pole(s); + + y = step_size(s); + dq = reconstruct(code & 0x10, g726_40_dqlntab[code], y); + + /* Reconstruct the signal */ + se = sei >> 1; + sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); + + /* Pole prediction difference */ + dqsez = sr + (sezi >> 1) - se; + + update(s, y, g726_40_witab[code], g726_40_fitab[code], dq, sr, dqsez); + + switch (s->ext_coding) + { + case G726_ENCODING_ALAW: + return tandem_adjust_alaw(sr, se, y, code, 0x10, qtab_726_40, 31); + case G726_ENCODING_ULAW: + return tandem_adjust_ulaw(sr, se, y, code, 0x10, qtab_726_40, 31); + } + return (sr << 2); +} +/*- End of function --------------------------------------------------------*/ + +g726_state_t *g726_init(g726_state_t *s, int bit_rate, int ext_coding, int packing) +{ + int i; + + if (bit_rate != 16000 && bit_rate != 24000 && bit_rate != 32000 && bit_rate != 40000) + return NULL; + if (s == NULL) + { + if ((s = (g726_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + s->yl = 34816; + s->yu = 544; + s->dms = 0; + s->dml = 0; + s->ap = 0; + s->rate = bit_rate; + s->ext_coding = ext_coding; + s->packing = packing; + for (i = 0; i < 2; i++) + { + s->a[i] = 0; + s->pk[i] = 0; + s->sr[i] = 32; + } + for (i = 0; i < 6; i++) + { + s->b[i] = 0; + s->dq[i] = 32; + } + s->td = FALSE; + switch (bit_rate) + { + case 16000: + s->enc_func = g726_16_encoder; + s->dec_func = g726_16_decoder; + s->bits_per_sample = 2; + break; + case 24000: + s->enc_func = g726_24_encoder; + s->dec_func = g726_24_decoder; + s->bits_per_sample = 3; + break; + case 32000: + default: + s->enc_func = g726_32_encoder; + s->dec_func = g726_32_decoder; + s->bits_per_sample = 4; + break; + case 40000: + s->enc_func = g726_40_encoder; + s->dec_func = g726_40_decoder; + s->bits_per_sample = 5; + break; + } + bitstream_init(&s->bs); + return s; +} +/*- End of function --------------------------------------------------------*/ + +int g726_release(g726_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int g726_decode(g726_state_t *s, + int16_t amp[], + const uint8_t g726_data[], + int g726_bytes) +{ + int i; + int samples; + uint8_t code; + int sl; + + for (samples = i = 0; ; ) + { + if (s->packing != G726_PACKING_NONE) + { + /* Unpack the code bits */ + if (s->packing != G726_PACKING_LEFT) + { + if (s->bs.residue < s->bits_per_sample) + { + if (i >= g726_bytes) + break; + s->bs.bitstream |= (g726_data[i++] << s->bs.residue); + s->bs.residue += 8; + } + code = (uint8_t) (s->bs.bitstream & ((1 << s->bits_per_sample) - 1)); + s->bs.bitstream >>= s->bits_per_sample; + } + else + { + if (s->bs.residue < s->bits_per_sample) + { + if (i >= g726_bytes) + break; + s->bs.bitstream = (s->bs.bitstream << 8) | g726_data[i++]; + s->bs.residue += 8; + } + code = (uint8_t) ((s->bs.bitstream >> (s->bs.residue - s->bits_per_sample)) & ((1 << s->bits_per_sample) - 1)); + } + s->bs.residue -= s->bits_per_sample; + } + else + { + if (i >= g726_bytes) + break; + code = g726_data[i++]; + } + sl = s->dec_func(s, code); + if (s->ext_coding != G726_ENCODING_LINEAR) + ((uint8_t *) amp)[samples++] = (uint8_t) sl; + else + amp[samples++] = (int16_t) sl; + } + return samples; +} +/*- End of function --------------------------------------------------------*/ + +int g726_encode(g726_state_t *s, + uint8_t g726_data[], + const int16_t amp[], + int len) +{ + int i; + int g726_bytes; + int16_t sl; + uint8_t code; + + for (g726_bytes = i = 0; i < len; i++) + { + /* Linearize the input sample to 14-bit PCM */ + switch (s->ext_coding) + { + case G726_ENCODING_ALAW: + sl = alaw_to_linear(((const uint8_t *) amp)[i]) >> 2; + break; + case G726_ENCODING_ULAW: + sl = ulaw_to_linear(((const uint8_t *) amp)[i]) >> 2; + break; + default: + sl = amp[i] >> 2; + break; + } + code = s->enc_func(s, sl); + if (s->packing != G726_PACKING_NONE) + { + /* Pack the code bits */ + if (s->packing != G726_PACKING_LEFT) + { + s->bs.bitstream |= (code << s->bs.residue); + s->bs.residue += s->bits_per_sample; + if (s->bs.residue >= 8) + { + g726_data[g726_bytes++] = (uint8_t) (s->bs.bitstream & 0xFF); + s->bs.bitstream >>= 8; + s->bs.residue -= 8; + } + } + else + { + s->bs.bitstream = (s->bs.bitstream << s->bits_per_sample) | code; + s->bs.residue += s->bits_per_sample; + if (s->bs.residue >= 8) + { + g726_data[g726_bytes++] = (uint8_t) ((s->bs.bitstream >> (s->bs.residue - 8)) & 0xFF); + s->bs.residue -= 8; + } + } + } + else + { + g726_data[g726_bytes++] = (uint8_t) code; + } + } + return g726_bytes; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_decode.c b/libs/voipcodecs/src/gsm0610_decode.c new file mode 100644 index 0000000000..a4d26371af --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_decode.c @@ -0,0 +1,358 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_decode.c - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_decode.c,v 1.14 2007/08/21 14:25:54 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/gsm0610.h" + +#include "gsm0610_local.h" + +/* 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER */ + +static void postprocessing(gsm0610_state_t *s, int16_t amp[]) +{ + int k; + int16_t msr; + int16_t tmp; + + msr = s->msr; + for (k = 0; k < GSM0610_FRAME_LEN; k++) + { + tmp = gsm_mult_r(msr, 28180); + /* De-emphasis */ + msr = gsm_add(amp[k], tmp); + /* Truncation & upscaling */ + amp[k] = (int16_t) (gsm_add(msr, msr) & 0xFFF8); + } + /*endfor*/ + s->msr = msr; +} +/*- End of function --------------------------------------------------------*/ + +static void decode_a_frame(gsm0610_state_t *s, + int16_t amp[GSM0610_FRAME_LEN], + gsm0610_frame_t *f) +{ + int j; + int k; + int16_t erp[40]; + int16_t wt[GSM0610_FRAME_LEN]; + int16_t *drp; + + drp = s->dp0 + 120; + for (j = 0; j < 4; j++) + { + gsm0610_rpe_decoding(s, f->xmaxc[j], f->Mc[j], f->xMc[j], erp); + gsm0610_long_term_synthesis_filtering(s, f->Nc[j], f->bc[j], erp, drp); + for (k = 0; k < 40; k++) + wt[j*40 + k] = drp[k]; + /*endfor*/ + } + /*endfor*/ + + gsm0610_short_term_synthesis_filter(s, f->LARc, wt, amp); + postprocessing(s, amp); +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_unpack_none(gsm0610_frame_t *s, const uint8_t c[]) +{ + int i; + int j; + int k; + + i = 0; + for (j = 0; j < 8; j++) + s->LARc[j] = c[i++]; + for (j = 0; j < 4; j++) + { + s->Nc[j] = c[i++]; + s->bc[j] = c[i++]; + s->Mc[j] = c[i++]; + s->xmaxc[j] = c[i++]; + for (k = 0; k < 13; k++) + s->xMc[j][k] = c[i++]; + } + return 76; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_unpack_wav49(gsm0610_frame_t *s, const uint8_t c[]) +{ + uint16_t sr; + int i; + + sr = *c++; + s->LARc[0] = sr & 0x3F; + sr >>= 6; + sr |= (uint16_t) *c++ << 2; + s->LARc[1] = sr & 0x3F; + sr >>= 6; + sr |= (uint16_t) *c++ << 4; + s->LARc[2] = sr & 0x1F; + sr >>= 5; + s->LARc[3] = sr & 0x1F; + sr >>= 5; + sr |= (uint16_t) *c++ << 2; + s->LARc[4] = sr & 0xF; + sr >>= 4; + s->LARc[5] = sr & 0xF; + sr >>= 4; + sr |= (uint16_t) *c++ << 2; + s->LARc[6] = sr & 0x7; + sr >>= 3; + s->LARc[7] = sr & 0x7; + sr >>= 3; + + for (i = 0; i < 4; i++) + { + sr |= (uint16_t) *c++ << 4; + s->Nc[i] = sr & 0x7F; + sr >>= 7; + s->bc[i] = sr & 0x3; + sr >>= 2; + s->Mc[i] = sr & 0x3; + sr >>= 2; + sr |= (uint16_t) *c++ << 1; + s->xmaxc[i] = sr & 0x3F; + sr >>= 6; + s->xMc[i][0] = sr & 0x7; + sr >>= 3; + sr = *c++; + s->xMc[i][1] = sr & 0x7; + sr >>= 3; + s->xMc[i][2] = sr & 0x7; + sr >>= 3; + sr |= (uint16_t) *c++ << 2; + s->xMc[i][3] = sr & 0x7; + sr >>= 3; + s->xMc[i][4] = sr & 0x7; + sr >>= 3; + s->xMc[i][5] = sr & 0x7; + sr >>= 3; + sr |= (uint16_t) *c++ << 1; + s->xMc[i][6] = sr & 0x7; + sr >>= 3; + s->xMc[i][7] = sr & 0x7; + sr >>= 3; + s->xMc[i][8] = sr & 0x7; + sr >>= 3; + sr = *c++; + s->xMc[i][9] = sr & 0x7; + sr >>= 3; + s->xMc[i][10] = sr & 0x7; + sr >>= 3; + sr |= (uint16_t) *c++ << 2; + s->xMc[i][11] = sr & 0x7; + sr >>= 3; + s->xMc[i][12] = sr & 0x7; + sr >>= 3; + } + + s++; + sr |= (uint16_t) *c++ << 4; + s->LARc[0] = sr & 0x3F; + sr >>= 6; + s->LARc[1] = sr & 0x3F; + sr >>= 6; + sr = *c++; + s->LARc[2] = sr & 0x1F; + sr >>= 5; + sr |= (uint16_t) *c++ << 3; + s->LARc[3] = sr & 0x1F; + sr >>= 5; + s->LARc[4] = sr & 0xF; + sr >>= 4; + sr |= (uint16_t) *c++ << 2; + s->LARc[5] = sr & 0xF; + sr >>= 4; + s->LARc[6] = sr & 0x7; + sr >>= 3; + s->LARc[7] = sr & 0x7; + sr >>= 3; + + for (i = 0; i < 4; i++) + { + sr = *c++; + s->Nc[i] = sr & 0x7F; + sr >>= 7; + sr |= (uint16_t) *c++ << 1; + s->bc[i] = sr & 0x3; + sr >>= 2; + s->Mc[i] = sr & 0x3; + sr >>= 2; + sr |= (uint16_t) *c++ << 5; + s->xmaxc[i] = sr & 0x3F; + sr >>= 6; + s->xMc[i][0] = sr & 0x7; + sr >>= 3; + s->xMc[i][1] = sr & 0x7; + sr >>= 3; + sr |= (uint16_t) *c++ << 1; + s->xMc[i][2] = sr & 0x7; + sr >>= 3; + s->xMc[i][3] = sr & 0x7; + sr >>= 3; + s->xMc[i][4] = sr & 0x7; + sr >>= 3; + sr = *c++; + s->xMc[i][5] = sr & 0x7; + sr >>= 3; + s->xMc[i][6] = sr & 0x7; + sr >>= 3; + sr |= (uint16_t) *c++ << 2; + s->xMc[i][7] = sr & 0x7; + sr >>= 3; + s->xMc[i][8] = sr & 0x7; + sr >>= 3; + s->xMc[i][9] = sr & 0x7; + sr >>= 3; + sr |= (uint16_t) *c++ << 1; + s->xMc[i][10] = sr & 0x7; + sr >>= 3; + s->xMc[i][11] = sr & 0x7; + sr >>= 3; + s->xMc[i][12] = sr & 0x7; + sr >>= 3; + } + return 65; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_unpack_voip(gsm0610_frame_t *s, const uint8_t c[33]) +{ + int i; + + s->LARc[0] = (*c++ & 0xF) << 2; + s->LARc[0] |= (*c >> 6) & 0x3; + s->LARc[1] = *c++ & 0x3F; + s->LARc[2] = (*c >> 3) & 0x1F; + s->LARc[3] = (*c++ & 0x7) << 2; + s->LARc[3] |= (*c >> 6) & 0x3; + s->LARc[4] = (*c >> 2) & 0xF; + s->LARc[5] = (*c++ & 0x3) << 2; + s->LARc[5] |= (*c >> 6) & 0x3; + s->LARc[6] = (*c >> 3) & 0x7; + s->LARc[7] = *c++ & 0x7; + + for (i = 0; i < 4; i++) + { + s->Nc[i] = (*c >> 1) & 0x7F; + s->bc[i] = (*c++ & 0x1) << 1; + s->bc[i] |= (*c >> 7) & 0x1; + s->Mc[i] = (*c >> 5) & 0x3; + s->xmaxc[i] = (*c++ & 0x1F) << 1; + s->xmaxc[i] |= (*c >> 7) & 0x1; + s->xMc[i][0] = (*c >> 4) & 0x7; + s->xMc[i][1] = (*c >> 1) & 0x7; + s->xMc[i][2] = (*c++ & 0x1) << 2; + s->xMc[i][2] |= (*c >> 6) & 0x3; + s->xMc[i][3] = (*c >> 3) & 0x7; + s->xMc[i][4] = *c++ & 0x7; + s->xMc[i][5] = (*c >> 5) & 0x7; + s->xMc[i][6] = (*c >> 2) & 0x7; + s->xMc[i][7] = (*c++ & 0x3) << 1; + s->xMc[i][7] |= (*c >> 7) & 0x1; + s->xMc[i][8] = (*c >> 4) & 0x7; + s->xMc[i][9] = (*c >> 1) & 0x7; + s->xMc[i][10] = (*c++ & 0x1) << 2; + s->xMc[i][10] |= (*c >> 6) & 0x3; + s->xMc[i][11] = (*c >> 3) & 0x7; + s->xMc[i][12] = *c++ & 0x7; + } + return 33; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_decode(gsm0610_state_t *s, int16_t amp[], const uint8_t code[], int quant) +{ + gsm0610_frame_t frame[2]; + const uint8_t *c; + int bytes; + int i; + + c = code; + for (i = 0; i < quant; i++) + { + switch (s->packing) + { + default: + case GSM0610_PACKING_NONE: + if ((bytes = gsm0610_unpack_none(frame, c)) >= 0) + { + decode_a_frame(s, amp, frame); + amp += GSM0610_FRAME_LEN; + } + break; + case GSM0610_PACKING_WAV49: + if ((bytes = gsm0610_unpack_wav49(frame, c)) >= 0) + { + decode_a_frame(s, amp, frame); + amp += GSM0610_FRAME_LEN; + decode_a_frame(s, amp, frame + 1); + amp += GSM0610_FRAME_LEN; + } + break; + case GSM0610_PACKING_VOIP: + if ((bytes = gsm0610_unpack_voip(frame, c)) >= 0) + { + decode_a_frame(s, amp, frame); + amp += GSM0610_FRAME_LEN; + } + break; + } + /*endswitch*/ + if (bytes < 0) + return 0; + c += bytes; + } + /*endwhile*/ + return quant*GSM0610_FRAME_LEN; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_encode.c b/libs/voipcodecs/src/gsm0610_encode.c new file mode 100644 index 0000000000..b0ce3004b8 --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_encode.c @@ -0,0 +1,334 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_encode.c - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_encode.c,v 1.17 2007/11/26 13:28:59 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/gsm0610.h" + +#include "gsm0610_local.h" + +/* 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER */ + +/* The RPE-LTD coder works on a frame by frame basis. The length of + the frame is equal to 160 samples. Some computations are done + once per frame to produce at the output of the coder the + LARc[1..8] parameters which are the coded LAR coefficients and + also to realize the inverse filtering operation for the entire + frame (160 samples of signal d[0..159]). These parts produce at + the output of the coder: + + Procedure 4.2.11 to 4.2.18 are to be executed four times per + frame. That means once for each sub-segment RPE-LTP analysis of + 40 samples. These parts produce at the output of the coder. +*/ +static void encode_a_frame(gsm0610_state_t *s, gsm0610_frame_t *f, const int16_t amp[]) +{ + int k; + int16_t *dp; + int16_t *dpp; + int16_t so[GSM0610_FRAME_LEN]; + int i; + + dp = s->dp0 + 120; + dpp = dp; + gsm0610_preprocess(s, amp, so); + gsm0610_lpc_analysis(s, so, f->LARc); + gsm0610_short_term_analysis_filter(s, f->LARc, so); + + for (k = 0; k < 4; k++) + { + gsm0610_long_term_predictor(s, + so + k*40, + dp, + s->e + 5, + dpp, + &f->Nc[k], + &f->bc[k]); + gsm0610_rpe_encoding(s, s->e + 5, &f->xmaxc[k], &f->Mc[k], f->xMc[k]); + + for (i = 0; i < 40; i++) + dp[i] = gsm_add(s->e[5 + i], dpp[i]); + /*endfor*/ + dp += 40; + dpp += 40; + } + /*endfor*/ + memcpy((char *) s->dp0, + (char *) (s->dp0 + GSM0610_FRAME_LEN), + 120*sizeof(*s->dp0)); +} +/*- End of function --------------------------------------------------------*/ + +gsm0610_state_t *gsm0610_init(gsm0610_state_t *s, int packing) +{ + if (s == NULL) + { + s = (gsm0610_state_t *) malloc(sizeof (*s)); + if (s == NULL) + return NULL; + /*endif*/ + } + /*endif*/ + memset((char *) s, '\0', sizeof (gsm0610_state_t)); + s->nrp = 40; + s->packing = packing; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_set_packing(gsm0610_state_t *s, int packing) +{ + s->packing = packing; + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_release(gsm0610_state_t *s) +{ + if (s) + free(s); + /*endif*/ + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_pack_none(uint8_t c[], const gsm0610_frame_t *s) +{ + int i; + int j; + int k; + + i = 0; + for (j = 0; j < 8; j++) + c[i++] = (uint8_t) s->LARc[j]; + for (j = 0; j < 4; j++) + { + c[i++] = (uint8_t) s->Nc[j]; + c[i++] = (uint8_t) s->bc[j]; + c[i++] = (uint8_t) s->Mc[j]; + c[i++] = (uint8_t) s->xmaxc[j]; + for (k = 0; k < 13; k++) + c[i++] = (uint8_t) s->xMc[j][k]; + } + return 76; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_pack_wav49(uint8_t c[], const gsm0610_frame_t *s) +{ + uint16_t sr; + int i; + + sr = 0; + sr = (sr >> 6) | (s->LARc[0] << 10); + sr = (sr >> 6) | (s->LARc[1] << 10); + *c++ = sr >> 4; + sr = (sr >> 5) | (s->LARc[2] << 11); + *c++ = sr >> 7; + sr = (sr >> 5) | (s->LARc[3] << 11); + sr = (sr >> 4) | (s->LARc[4] << 12); + *c++ = sr >> 6; + sr = (sr >> 4) | (s->LARc[5] << 12); + sr = (sr >> 3) | (s->LARc[6] << 13); + *c++ = sr >> 7; + sr = (sr >> 3) | (s->LARc[7] << 13); + + for (i = 0; i < 4; i++) + { + sr = (sr >> 7) | (s->Nc[i] << 9); + *c++ = sr >> 5; + sr = (sr >> 2) | (s->bc[i] << 14); + sr = (sr >> 2) | (s->Mc[i] << 14); + sr = (sr >> 6) | (s->xmaxc[i] << 10); + *c++ = sr >> 3; + sr = (sr >> 3) | (s->xMc[i][0] << 13); + *c++ = sr >> 8; + sr = (sr >> 3) | (s->xMc[i][1] << 13); + sr = (sr >> 3) | (s->xMc[i][2] << 13); + sr = (sr >> 3) | (s->xMc[i][3] << 13); + *c++ = sr >> 7; + sr = (sr >> 3) | (s->xMc[i][4] << 13); + sr = (sr >> 3) | (s->xMc[i][5] << 13); + sr = (sr >> 3) | (s->xMc[i][6] << 13); + *c++ = sr >> 6; + sr = (sr >> 3) | (s->xMc[i][7] << 13); + sr = (sr >> 3) | (s->xMc[i][8] << 13); + *c++ = sr >> 8; + sr = (sr >> 3) | (s->xMc[i][9] << 13); + sr = (sr >> 3) | (s->xMc[i][10] << 13); + sr = (sr >> 3) | (s->xMc[i][11] << 13); + *c++ = sr >> 7; + sr = (sr >> 3) | (s->xMc[i][12] << 13); + } + + s++; + sr = (sr >> 6) | (s->LARc[0] << 10); + *c++ = sr >> 6; + sr = (sr >> 6) | (s->LARc[1] << 10); + *c++ = sr >> 8; + sr = (sr >> 5) | (s->LARc[2] << 11); + sr = (sr >> 5) | (s->LARc[3] << 11); + *c++ = sr >> 6; + sr = (sr >> 4) | (s->LARc[4] << 12); + sr = (sr >> 4) | (s->LARc[5] << 12); + *c++ = sr >> 6; + sr = (sr >> 3) | (s->LARc[6] << 13); + sr = (sr >> 3) | (s->LARc[7] << 13); + *c++ = sr >> 8; + + for (i = 0; i < 4; i++) + { + sr = (sr >> 7) | (s->Nc[i] << 9); + sr = (sr >> 2) | (s->bc[i] << 14); + *c++ = sr >> 7; + sr = (sr >> 2) | (s->Mc[i] << 14); + sr = (sr >> 6) | (s->xmaxc[i] << 10); + *c++ = sr >> 7; + sr = (sr >> 3) | (s->xMc[i][0] << 13); + sr = (sr >> 3) | (s->xMc[i][1] << 13); + sr = (sr >> 3) | (s->xMc[i][2] << 13); + *c++ = sr >> 6; + sr = (sr >> 3) | (s->xMc[i][3] << 13); + sr = (sr >> 3) | (s->xMc[i][4] << 13); + *c++ = sr >> 8; + sr = (sr >> 3) | (s->xMc[i][5] << 13); + sr = (sr >> 3) | (s->xMc[i][6] << 13); + sr = (sr >> 3) | (s->xMc[i][7] << 13); + *c++ = sr >> 7; + sr = (sr >> 3) | (s->xMc[i][8] << 13); + sr = (sr >> 3) | (s->xMc[i][9] << 13); + sr = (sr >> 3) | (s->xMc[i][10] << 13); + *c++ = sr >> 6; + sr = (sr >> 3) | (s->xMc[i][11] << 13); + sr = (sr >> 3) | (s->xMc[i][12] << 13); + *c++ = sr >> 8; + } + return 65; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_pack_voip(uint8_t c[33], const gsm0610_frame_t *s) +{ + int i; + + *c++ = ((GSM0610_MAGIC & 0xF) << 4) + | ((s->LARc[0] >> 2) & 0xF); + *c++ = ((s->LARc[0] & 0x3) << 6) + | (s->LARc[1] & 0x3F); + *c++ = ((s->LARc[2] & 0x1F) << 3) + | ((s->LARc[3] >> 2) & 0x7); + *c++ = ((s->LARc[3] & 0x3) << 6) + | ((s->LARc[4] & 0xF) << 2) + | ((s->LARc[5] >> 2) & 0x3); + *c++ = ((s->LARc[5] & 0x3) << 6) + | ((s->LARc[6] & 0x7) << 3) + | (s->LARc[7] & 0x7); + + for (i = 0; i < 4; i++) + { + *c++ = ((s->Nc[i] & 0x7F) << 1) + | ((s->bc[i] >> 1) & 0x1); + *c++ = ((s->bc[i] & 0x1) << 7) + | ((s->Mc[i] & 0x3) << 5) + | ((s->xmaxc[i] >> 1) & 0x1F); + *c++ = ((s->xmaxc[i] & 0x1) << 7) + | ((s->xMc[i][0] & 0x7) << 4) + | ((s->xMc[i][1] & 0x7) << 1) + | ((s->xMc[i][2] >> 2) & 0x1); + *c++ = ((s->xMc[i][2] & 0x3) << 6) + | ((s->xMc[i][3] & 0x7) << 3) + | (s->xMc[i][4] & 0x7); + *c++ = ((s->xMc[i][5] & 0x7) << 5) + | ((s->xMc[i][6] & 0x7) << 2) + | ((s->xMc[i][7] >> 1) & 0x3); + *c++ = ((s->xMc[i][7] & 0x1) << 7) + | ((s->xMc[i][8] & 0x7) << 4) + | ((s->xMc[i][9] & 0x7) << 1) + | ((s->xMc[i][10] >> 2) & 0x1); + *c++ = ((s->xMc[i][10] & 0x3) << 6) + | ((s->xMc[i][11] & 0x7) << 3) + | (s->xMc[i][12] & 0x7); + } + return 33; +} +/*- End of function --------------------------------------------------------*/ + +int gsm0610_encode(gsm0610_state_t *s, uint8_t code[], const int16_t amp[], int quant) +{ + gsm0610_frame_t frame[2]; + uint8_t *c; + int i; + + c = code; + for (i = 0; i < quant; i++) + { + encode_a_frame(s, frame, amp); + switch (s->packing) + { + case GSM0610_PACKING_NONE: + c += gsm0610_pack_none(c, frame); + amp += GSM0610_FRAME_LEN; + break; + case GSM0610_PACKING_WAV49: + amp += GSM0610_FRAME_LEN; + encode_a_frame(s, frame + 1, amp); + amp += GSM0610_FRAME_LEN; + c += gsm0610_pack_wav49(c, frame); + break; + case GSM0610_PACKING_VOIP: + c += gsm0610_pack_voip(c, frame); + amp += GSM0610_FRAME_LEN; + break; + } + /*endswitch*/ + } + /*endwhile*/ + return (int) (c - code); +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_local.h b/libs/voipcodecs/src/gsm0610_local.h new file mode 100644 index 0000000000..066ec4184d --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_local.h @@ -0,0 +1,229 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * gsm0610_local.h - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_local.h,v 1.7 2007/01/03 14:15:35 steveu Exp $ + */ + +#if !defined(_GSM0610_LOCAL_H_) +#define _GSM0610_LOCAL_H_ + +#define GSM0610_FRAME_LEN 160 + +#define GSM0610_MAGIC 0xD + +static __inline__ int16_t gsm_add(int16_t a, int16_t b) +{ +#if defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__( + " addw %2,%0;\n" + " jno 0f;\n" + " movw $0x7fff,%0;\n" + " adcw $0,%0;\n" + "0:" + : "=r" (a) + : "0" (a), "ir" (b) + : "cc" + ); + return a; +#else + int32_t sum; + + sum = (int32_t) a + (int32_t) b; + return saturate(sum); +#endif +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int32_t gsm_l_add(int32_t a, int32_t b) +{ +#if defined(__i386__) + __asm__ __volatile__( + " addl %2,%0;\n" + " jno 0f;\n" + " movl $0x7fffffff,%0;\n" + " adcl $0,%0;\n" + "0:" + : "=r" (a) + : "0" (a), "ir" (b) + : "cc" + ); + return a; +#else + uint32_t A; + + if (a < 0) + { + if (b >= 0) + return a + b; + /*endif*/ + A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1); + return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2; + } + /*endif*/ + if (b <= 0) + return a + b; + /*endif*/ + A = (uint32_t) a + (uint32_t) b; + return (A > INT32_MAX) ? INT32_MAX : A; +#endif +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t gsm_sub(int16_t a, int16_t b) +{ + int32_t diff; + + diff = (int32_t) a - (int32_t) b; + return saturate(diff); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t gsm_mult(int16_t a, int16_t b) +{ + if (a == INT16_MIN && b == INT16_MIN) + return INT16_MAX; + /*endif*/ + return (int16_t) (((int32_t) a * (int32_t) b) >> 15); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int32_t gsm_l_mult(int16_t a, int16_t b) +{ + assert (a != INT16_MIN || b != INT16_MIN); + return ((int32_t) a * (int32_t) b) << 1; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t gsm_mult_r(int16_t a, int16_t b) +{ + int32_t prod; + + if (b == INT16_MIN && a == INT16_MIN) + return INT16_MAX; + /*endif*/ + prod = (int32_t) a * (int32_t) b + 16384; + prod >>= 15; + return (int16_t) (prod & 0xFFFF); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t gsm_abs(int16_t a) +{ + return (a == INT16_MIN) ? INT16_MAX : (int16_t) abs(a); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t gsm_asr(int16_t a, int n) +{ + if (n >= 16) + return -(a < 0); + /*endif*/ + if (n <= -16) + return 0; + /*endif*/ + if (n < 0) + return a << -n; + /*endif*/ + return a >> n; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t gsm_asl(int16_t a, int n) +{ + if (n >= 16) + return 0; + /*endif*/ + if (n <= -16) + return -(a < 0); + /*endif*/ + if (n < 0) + return gsm_asr(a, -n); + /*endif*/ + return a << n; +} +/*- End of function --------------------------------------------------------*/ + +extern void gsm0610_long_term_predictor(gsm0610_state_t *s, + int16_t d[40], + int16_t *dp, /* [-120..-1] d' IN */ + int16_t e[40], + int16_t dpp[40], + int16_t *Nc, + int16_t *bc); + +extern void gsm0610_lpc_analysis(gsm0610_state_t *s, + int16_t amp[160], + int16_t LARc[8]); + +extern void gsm0610_preprocess(gsm0610_state_t *s, + const int16_t amp[], + int16_t so[]); + +extern void gsm0610_short_term_analysis_filter(gsm0610_state_t *s, + int16_t LARc[8], + int16_t amp[160]); + +extern void gsm0610_long_term_synthesis_filtering(gsm0610_state_t *s, + int16_t Ncr, + int16_t bcr, + int16_t erp[40], + int16_t *drp); /* [-120..-1] IN, [0..40] OUT */ + +extern void gsm0610_rpe_decoding(gsm0610_state_t *s, + int16_t xmaxcr, + int16_t Mcr, + int16_t *xMcr, /* [0..12], 3 bits IN */ + int16_t erp[40]); + +extern void gsm0610_rpe_encoding(gsm0610_state_t *s, + int16_t *e, /* [-5..-1][0..39][40..44] IN/OUT */ + int16_t *xmaxc, + int16_t *Mc, + int16_t xMc[13]); + +extern void gsm0610_short_term_synthesis_filter(gsm0610_state_t *s, + int16_t LARcr[8], + int16_t drp[40], + int16_t amp[160]); + +extern int16_t gsm0610_norm(int32_t a); + +#if defined(__GNUC__) && defined(__i386__) + +void gsm0610_vec_vsraw(const int16_t *p, int n, int bits); + +int32_t gsm0610_vec_iprod(const int16_t *p, const int16_t *q, int n); + +int32_t gsm0610_vec_maxmin(const int16_t *p, int n, int16_t *out); + +int32_t gsm0610_max_cross_corr(const int16_t *wt, const int16_t *dp, int16_t *Nc_out); + +#endif + +#endif + +/*- End of include ---------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_long_term.c b/libs/voipcodecs/src/gsm0610_long_term.c new file mode 100644 index 0000000000..f8bc8902be --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_long_term.c @@ -0,0 +1,408 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_long_term.c - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_long_term.c,v 1.10 2007/08/20 15:22:22 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/gsm0610.h" + +#include "gsm0610_local.h" + +/* Table 4.3a Decision level of the LTP gain quantizer */ +static const int16_t gsm_DLB[4] = +{ + 6554, 16384, 26214, 32767 +}; + +/* Table 4.3b Quantization levels of the LTP gain quantizer */ +static const int16_t gsm_QLB[4] = +{ + 3277, 11469, 21299, 32767 +}; + +/* 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION */ + +#if defined(__GNUC__) && defined(__i386__) +int32_t gsm0610_max_cross_corr(const int16_t *wt, const int16_t *dp, int16_t *Nc_out) +{ + int32_t lmax; + int32_t out; + + __asm__ __volatile__( + " emms;\n" + " pushl %%ebx;\n" + " movl $0,%%edx;\n" /* Will be maximum inner-product */ + " movl $40,%%ebx;\n" + " movl %%ebx,%%ecx;\n" /* Will be index of max inner-product */ + " subl $80,%%esi;\n" + " .p2align 2;\n" + "1:\n" + " movq (%%edi),%%mm0;\n" + " movq (%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm0;\n" + " movq 8(%%edi),%%mm1;\n" + " movq 8(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 16(%%edi),%%mm1;\n" + " movq 16(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 24(%%edi),%%mm1;\n" + " movq 24(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 32(%%edi),%%mm1;\n" + " movq 32(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 40(%%edi),%%mm1;\n" + " movq 40(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 48(%%edi),%%mm1;\n" + " movq 48(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 56(%%edi),%%mm1;\n" + " movq 56(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 64(%%edi),%%mm1;\n" + " movq 64(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 72(%%edi),%%mm1;\n" + " movq 72(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq %%mm0,%%mm1;\n" + " punpckhdq %%mm0,%%mm1;\n" /* mm1 has high int32 of mm0 dup'd */ + " paddd %%mm1,%%mm0;\n" + " movd %%mm0,%%eax;\n" /* eax has result */ + " cmpl %%edx,%%eax;\n" + " jle 2f;\n" + " movl %%eax,%%edx;\n" + " movl %%ebx,%%ecx;\n" + " .p2align 2;\n" + "2:\n" + " subl $2,%%esi;\n" + " incl %%ebx;\n" + " cmpl $120,%%ebx;\n" + " jle 1b;\n" + " popl %%ebx;\n" + " emms;\n" + : "=d" (lmax), "=c" (out) + : "D" (wt), "S" (dp) + : "eax" + ); + *Nc_out = out; + return lmax; +} +/*- End of function --------------------------------------------------------*/ +#endif + +/* This procedure computes the LTP gain (bc) and the LTP lag (Nc) + for the long term analysis filter. This is done by calculating a + maximum of the cross-correlation function between the current + sub-segment short term residual signal d[0..39] (output of + the short term analysis filter; for simplification the index + of this array begins at 0 and ends at 39 for each sub-segment of the + RPE-LTP analysis) and the previous reconstructed short term + residual signal dp[ -120 .. -1 ]. A dynamic scaling must be + performed to avoid overflow. */ + +/* This procedure exists in three versions. First, the integer + version; then, the two floating point versions (as another + function), with or without scaling. */ + +static int16_t evaluate_ltp_parameters(int16_t d[40], + int16_t *dp, // [-120..-1] IN + int16_t *Nc_out) +{ + int k; + int16_t Nc; + int16_t bc; + int16_t wt[40]; + int32_t L_max; + int32_t L_power; + int16_t R; + int16_t S; + int16_t dmax; + int16_t scale; + int16_t temp; + int32_t L_temp; +#if !(defined(__GNUC__) && defined(__i386__)) + int16_t lambda; +#endif + + /* Search of the optimum scaling of d[0..39]. */ + dmax = 0; + for (k = 0; k < 40; k++) + { + temp = d[k]; + temp = gsm_abs(temp); + if (temp > dmax) + dmax = temp; + /*endif*/ + } + /*endfor*/ + + if (dmax == 0) + { + temp = 0; + } + else + { + assert(dmax > 0); + temp = gsm0610_norm((int32_t) dmax << 16); + } + /*endif*/ + + if (temp > 6) + scale = 0; + else + scale = (int16_t) (6 - temp); + /*endif*/ + assert(scale >= 0); + + /* Initialization of a working array wt */ + for (k = 0; k < 40; k++) + wt[k] = d[k] >> scale; + /*endfor*/ + + /* Search for the maximum cross-correlation and coding of the LTP lag */ +#if defined(__GNUC__) && defined(__i386__) + L_max = gsm0610_max_cross_corr(wt, dp, &Nc); +#else + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) + { + int32_t L_result; + + L_result = (wt[0]*dp[0 - lambda]) + + (wt[1]*dp[1 - lambda]) + + (wt[2]*dp[2 - lambda]) + + (wt[3]*dp[3 - lambda]) + + (wt[4]*dp[4 - lambda]) + + (wt[5]*dp[5 - lambda]) + + (wt[6]*dp[6 - lambda]) + + (wt[7]*dp[7 - lambda]) + + (wt[8]*dp[8 - lambda]) + + (wt[9]*dp[9 - lambda]) + + (wt[10]*dp[10 - lambda]) + + (wt[11]*dp[11 - lambda]) + + (wt[12]*dp[12 - lambda]) + + (wt[13]*dp[13 - lambda]) + + (wt[14]*dp[14 - lambda]) + + (wt[15]*dp[15 - lambda]) + + (wt[16]*dp[16 - lambda]) + + (wt[17]*dp[17 - lambda]) + + (wt[18]*dp[18 - lambda]) + + (wt[19]*dp[19 - lambda]) + + (wt[20]*dp[20 - lambda]) + + (wt[21]*dp[21 - lambda]) + + (wt[22]*dp[22 - lambda]) + + (wt[23]*dp[23 - lambda]) + + (wt[24]*dp[24 - lambda]) + + (wt[25]*dp[25 - lambda]) + + (wt[26]*dp[26 - lambda]) + + (wt[27]*dp[27 - lambda]) + + (wt[28]*dp[28 - lambda]) + + (wt[29]*dp[29 - lambda]) + + (wt[30]*dp[30 - lambda]) + + (wt[31]*dp[31 - lambda]) + + (wt[32]*dp[32 - lambda]) + + (wt[33]*dp[33 - lambda]) + + (wt[34]*dp[34 - lambda]) + + (wt[35]*dp[35 - lambda]) + + (wt[36]*dp[36 - lambda]) + + (wt[37]*dp[37 - lambda]) + + (wt[38]*dp[38 - lambda]) + + (wt[39]*dp[39 - lambda]); + + if (L_result > L_max) + { + Nc = lambda; + L_max = L_result; + } + /*endif*/ + } + /*endfor*/ +#endif + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max */ + assert(scale <= 100 && scale >= -100); + L_max = L_max >> (6 - scale); + + assert(Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual signal dp[..] */ + L_power = 0; + for (k = 0; k < 40; k++) + { + L_temp = dp[k - Nc] >> 3; + L_power += L_temp*L_temp; + } + /*endfor*/ + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power */ + if (L_max <= 0) + return 0; + /*endif*/ + if (L_max >= L_power) + return 3; + /*endif*/ + temp = gsm0610_norm(L_power); + + R = (int16_t) ((L_max << temp) >> 16); + S = (int16_t) ((L_power << temp) >> 16); + + /* Coding of the LTP gain */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + quantization of the LTP gain b to get the coded version bc. */ + for (bc = 0; bc <= 2; bc++) + { + if (R <= gsm_mult(S, gsm_DLB[bc])) + break; + /*endif*/ + } + /*endfor*/ + return bc; +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.12 */ +static void long_term_analysis_filtering(int16_t bc, + int16_t Nc, + int16_t *dp, // previous d [-120..-1] IN + int16_t d[40], + int16_t dpp[40], + int16_t e[40]) +{ + int k; + + /* In this part, we have to decode the bc parameter to compute + the samples of the estimate dpp[0..39]. The decoding of bc needs the + use of table 4.3b. The long term residual signal e[0..39] + is then calculated to be fed to the RPE encoding section. */ + for (k = 0; k < 40; k++) + { + dpp[k] = gsm_mult_r(gsm_QLB[bc], dp[k - Nc]); + e[k] = gsm_sub(d[k], dpp[k]); + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +/* 4x for 160 samples */ +void gsm0610_long_term_predictor(gsm0610_state_t *s, + int16_t d[40], + int16_t *dp, // [-120..-1] d' IN + int16_t e[40], + int16_t dpp[40], + int16_t *Nc, + int16_t *bc) +{ + assert(d); + assert(dp); + assert(e); + assert(dpp); + assert(Nc); + assert(bc); + + *bc = evaluate_ltp_parameters(d, dp, Nc); + long_term_analysis_filtering(*bc, *Nc, dp, d, dpp, e); +} +/*- End of function --------------------------------------------------------*/ + +/* 4.3.2 */ +void gsm0610_long_term_synthesis_filtering(gsm0610_state_t *s, + int16_t Ncr, + int16_t bcr, + int16_t erp[40], + int16_t *drp) // [-120..-1] IN, [0..40] OUT +{ + int k; + int16_t brp; + int16_t drpp; + int16_t Nr; + + /* This procedure uses the bcr and Ncr parameter to realize the + long term synthesis filter. The decoding of bcr needs + table 4.3b. */ + + /* Check the limits of Nr. */ + Nr = (Ncr < 40 || Ncr > 120) ? s->nrp : Ncr; + s->nrp = Nr; + assert (Nr >= 40 && Nr <= 120); + + /* Decode the LTP gain, bcr */ + brp = gsm_QLB[bcr]; + + /* Compute the reconstructed short term residual signal, drp[0..39] */ + assert(brp != INT16_MIN); + for (k = 0; k < 40; k++) + { + drpp = gsm_mult_r(brp, drp[k - Nr]); + drp[k] = gsm_add(erp[k], drpp); + } + /*endfor*/ + + /* Update the reconstructed short term residual signal, drp[-1..-120] */ + for (k = 0; k < 120; k++) + drp[k - 120] = drp[k - 80]; + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_lpc.c b/libs/voipcodecs/src/gsm0610_lpc.c new file mode 100644 index 0000000000..c53e64c7e4 --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_lpc.c @@ -0,0 +1,533 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_lpc.c - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_lpc.c,v 1.15 2007/08/20 15:22:22 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/bit_operations.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/vector_int.h" +#include "voipcodecs/gsm0610.h" + +#include "gsm0610_local.h" + +/* 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION */ + +/* The number of left shifts needed to normalize the 32 bit + variable x for positive values on the interval + with minimum of + minimum of 1073741824 (01000000000000000000000000000000) and + maximum of 2147483647 (01111111111111111111111111111111) + and for negative values on the interval with + minimum of -2147483648 (-10000000000000000000000000000000) and + maximum of -1073741824 ( -1000000000000000000000000000000). + + In order to normalize the result, the following + operation must be done: norm_var1 = x << gsm0610_norm(x); + + (That's 'ffs', only from the left, not the right..) +*/ + +int16_t gsm0610_norm(int32_t x) +{ + assert(x != 0); + + if (x < 0) + { + if (x <= -1073741824) + return 0; + /*endif*/ + x = ~x; + } + /*endif*/ + return (int16_t) (30 - top_bit(x)); +} +/*- End of function --------------------------------------------------------*/ + +/* + (From p. 46, end of section 4.2.5) + + NOTE: The following lines gives [sic] one correct implementation + of the div(num, denum) arithmetic operation. Compute div + which is the integer division of num by denom: with + denom >= num > 0 +*/ +static int16_t gsm_div(int16_t num, int16_t denom) +{ + int32_t num32; + int32_t denom32; + int16_t div; + int k; + + /* The parameter num sometimes becomes zero. + Although this is explicitly guarded against in 4.2.5, + we assume that the result should then be zero as well. */ + + assert(num >= 0 && denom >= num); + if (num == 0) + return 0; + /*endif*/ + num32 = num; + denom32 = denom; + div = 0; + k = 15; + while (k--) + { + div <<= 1; + num32 <<= 1; + + if (num32 >= denom32) + { + num32 -= denom32; + div++; + } + /*endif*/ + } + /*endwhile*/ + + return div; +} +/*- End of function --------------------------------------------------------*/ + +#if defined(__GNUC__) && defined(__i386__) +void gsm0610_vec_vsraw(const int16_t *p, int n, int bits) +{ + static const int64_t ones = 0x0001000100010001LL; + + if (n == 0) + return; + /*endif*/ + __asm__ __volatile__( + " leal -16(%%esi,%%eax,2),%%edx;\n" /* edx = top - 16 */ + " emms;\n" + " movd %%ecx,%%mm3;\n" + " movq %[ones],%%mm2;\n" + " psllw %%mm3,%%mm2;\n" + " psrlw $1,%%mm2;\n" + " cmpl %%edx,%%esi;" + " ja 4f;\n" + + " .p2align 2;\n" + /* 8 words per iteration */ + "6:\n" + " movq (%%esi),%%mm0;\n" + " movq 8(%%esi),%%mm1;\n" + " paddsw %%mm2,%%mm0;\n" + " psraw %%mm3,%%mm0;\n" + " paddsw %%mm2,%%mm1;\n" + " psraw %%mm3,%%mm1;\n" + " movq %%mm0,(%%esi);\n" + " movq %%mm1,8(%%esi);\n" + " addl $16,%%esi;\n" + " cmpl %%edx,%%esi;\n" + " jbe 6b;\n" + + " .p2align 2;\n" + "4:\n" + " addl $12,%%edx;\n" /* now edx = top-4 */ + " cmpl %%edx,%%esi;\n" + " ja 3f;\n" + + " .p2align 2;\n" + /* do up to 6 words, two per iteration */ + "5:\n" + " movd (%%esi),%%mm0;\n" + " paddsw %%mm2,%%mm0;\n" + " psraw %%mm3,%%mm0;\n" + " movd %%mm0,(%%esi);\n" + " addl $4,%%esi;\n" + " cmpl %%edx,%%esi;\n" + " jbe 5b;\n" + + " .p2align 2;\n" + "3:\n" + " addl $2,%%edx;\n" /* now edx = top-2 */ + " cmpl %%edx,%%esi;\n" + " ja 2f;\n" + + " movzwl (%%esi),%%eax;\n" + " movd %%eax,%%mm0;\n" + " paddsw %%mm2,%%mm0;\n" + " psraw %%mm3,%%mm0;\n" + " movd %%mm0,%%eax;\n" + " movw %%ax,(%%esi);\n" + + " .p2align 2;\n" + "2:\n" + " emms;\n" + : + : "S" (p), "a" (n), "c" (bits), [ones] "m" (ones) + : "edx" + ); +} +/*- End of function --------------------------------------------------------*/ +#endif + +/* 4.2.4 */ +static void autocorrelation(int16_t amp[GSM0610_FRAME_LEN], int32_t L_ACF[9]) +{ + int k; + int16_t smax; + int16_t scalauto; +#if !(defined(__GNUC__) && defined(__i386__)) + int i; + int temp; + int16_t *sp; + int16_t sl; +#endif + + /* The goal is to compute the array L_ACF[k]. The signal s[i] must + be scaled in order to avoid an overflow situation. */ + + /* Dynamic scaling of the array s[0..159] */ + /* Search for the maximum. */ +#if defined(__GNUC__) && defined(__i386__) + smax = saturate(vec_min_maxi16(amp, GSM0610_FRAME_LEN, NULL)); +#else + for (smax = 0, k = 0; k < GSM0610_FRAME_LEN; k++) + { + temp = gsm_abs(amp[k]); + if (temp > smax) + smax = (int16_t) temp; + /*endif*/ + } + /*endfor*/ +#endif + + /* Computation of the scaling factor. */ + if (smax == 0) + { + scalauto = 0; + } + else + { + assert(smax > 0); + scalauto = (int16_t) (4 - gsm0610_norm((int32_t) smax << 16)); + } + /*endif*/ + + /* Scaling of the array s[0...159] */ +#if defined(__GNUC__) && defined(__i386__) + if (scalauto > 0) + gsm0610_vec_vsraw(amp, GSM0610_FRAME_LEN, scalauto); + /*endif*/ +#else + if (scalauto > 0) + { + for (k = 0; k < GSM0610_FRAME_LEN; k++) + amp[k] = gsm_mult_r(amp[k], 16384 >> (scalauto - 1)); + /*endfor*/ + } + /*endif*/ +#endif + + /* Compute the L_ACF[..]. */ +#if defined(__GNUC__) && defined(__i386__) + for (k = 0; k < 9; k++) + L_ACF[k] = vec_dot_prodi16(amp, amp + k, GSM0610_FRAME_LEN - k) << 1; + /*endfor*/ +#else + sp = amp; + sl = *sp; + L_ACF[0] = ((int32_t) sl*sp[0]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] = ((int32_t) sl*sp[-1]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] = ((int32_t) sl*sp[-2]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] += ((int32_t) sl*sp[-2]); + L_ACF[3] = ((int32_t) sl*sp[-3]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] += ((int32_t) sl*sp[-2]); + L_ACF[3] += ((int32_t) sl*sp[-3]); + L_ACF[4] = ((int32_t) sl*sp[-4]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] += ((int32_t) sl*sp[-2]); + L_ACF[3] += ((int32_t) sl*sp[-3]); + L_ACF[4] += ((int32_t) sl*sp[-4]); + L_ACF[5] = ((int32_t) sl*sp[-5]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] += ((int32_t) sl*sp[-2]); + L_ACF[3] += ((int32_t) sl*sp[-3]); + L_ACF[4] += ((int32_t) sl*sp[-4]); + L_ACF[5] += ((int32_t) sl*sp[-5]); + L_ACF[6] = ((int32_t) sl*sp[-6]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] += ((int32_t) sl*sp[-2]); + L_ACF[3] += ((int32_t) sl*sp[-3]); + L_ACF[4] += ((int32_t) sl*sp[-4]); + L_ACF[5] += ((int32_t) sl*sp[-5]); + L_ACF[6] += ((int32_t) sl*sp[-6]); + L_ACF[7] = ((int32_t) sl*sp[-7]); + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] += ((int32_t) sl*sp[-2]); + L_ACF[3] += ((int32_t) sl*sp[-3]); + L_ACF[4] += ((int32_t) sl*sp[-4]); + L_ACF[5] += ((int32_t) sl*sp[-5]); + L_ACF[6] += ((int32_t) sl*sp[-6]); + L_ACF[7] += ((int32_t) sl*sp[-7]); + L_ACF[8] = ((int32_t) sl*sp[-8]); + for (i = 9; i < GSM0610_FRAME_LEN; i++) + { + sl = *++sp; + L_ACF[0] += ((int32_t) sl*sp[0]); + L_ACF[1] += ((int32_t) sl*sp[-1]); + L_ACF[2] += ((int32_t) sl*sp[-2]); + L_ACF[3] += ((int32_t) sl*sp[-3]); + L_ACF[4] += ((int32_t) sl*sp[-4]); + L_ACF[5] += ((int32_t) sl*sp[-5]); + L_ACF[6] += ((int32_t) sl*sp[-6]); + L_ACF[7] += ((int32_t) sl*sp[-7]); + L_ACF[8] += ((int32_t) sl*sp[-8]); + } + /*endfor*/ + for (k = 0; k < 9; k++) + L_ACF[k] <<= 1; + /*endfor*/ +#endif + /* Rescaling of the array s[0..159] */ + if (scalauto > 0) + { + assert(scalauto <= 4); + for (k = 0; k < GSM0610_FRAME_LEN; k++) + amp[k] <<= scalauto; + /*endfor*/ + } + /*endif*/ +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.5 */ +static void reflection_coefficients(int32_t L_ACF[9], int16_t r[8]) +{ + int i; + int m; + int n; + int16_t temp; + int16_t ACF[9]; + int16_t P[9]; + int16_t K[9]; + + /* Schur recursion with 16 bits arithmetic. */ + if (L_ACF[0] == 0) + { + for (i = 8; i--; *r++ = 0) + ; + /*endfor*/ + return; + } + /*endif*/ + + assert(L_ACF[0] != 0); + temp = gsm0610_norm(L_ACF[0]); + + assert(temp >= 0 && temp < 32); + + /* ? overflow ? */ + for (i = 0; i <= 8; i++) + ACF[i] = (int16_t) ((L_ACF[i] << temp) >> 16); + /*endfor*/ + + /* Initialize array P[..] and K[..] for the recursion. */ + for (i = 1; i <= 7; i++) + K[i] = ACF[i]; + /*endfor*/ + for (i = 0; i <= 8; i++) + P[i] = ACF[i]; + /*endfor*/ + /* Compute reflection coefficients */ + for (n = 1; n <= 8; n++, r++) + { + temp = P[1]; + temp = gsm_abs (temp); + if (P[0] < temp) + { + for (i = n; i <= 8; i++) + *r++ = 0; + /*endfor*/ + return; + } + /*endif*/ + + *r = gsm_div(temp, P[0]); + + assert(*r >= 0); + if (P[1] > 0) + *r = -*r; /* r[n] = sub(0, r[n]) */ + /*endif*/ + assert(*r != INT16_MIN); + if (n == 8) + return; + /*endif*/ + + /* Schur recursion */ + temp = gsm_mult_r(P[1], *r); + P[0] = gsm_add(P[0], temp); + + for (m = 1; m <= 8 - n; m++) + { + temp = gsm_mult_r(K[m], *r); + P[m] = gsm_add(P[m + 1], temp); + + temp = gsm_mult_r(P[m + 1], *r); + K[m] = gsm_add(K[m], temp); + } + /*endfor*/ + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.6 */ +static void transform_to_log_area_ratios(int16_t r[8]) +{ + int16_t temp; + int i; + + /* The following scaling for r[..] and LAR[..] has been used: + + r[..] = integer (real_r[..]*32768.); -1 <= real_r < 1. + LAR[..] = integer (real_LAR[..] * 16384); + with -1.625 <= real_LAR <= 1.625 + */ + + /* Computation of the LAR[0..7] from the r[0..7] */ + for (i = 1; i <= 8; i++, r++) + { + temp = *r; + temp = gsm_abs(temp); + assert(temp >= 0); + + if (temp < 22118) + { + temp >>= 1; + } + else if (temp < 31130) + { + assert(temp >= 11059); + temp -= 11059; + } + else + { + assert(temp >= 26112); + temp -= 26112; + temp <<= 2; + } + /*endif*/ + + *r = (*r < 0) ? -temp : temp; + assert(*r != INT16_MIN); + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.7 */ +static void quantization_and_coding(int16_t LAR[8]) +{ + int16_t temp; + + /* This procedure needs four tables; the following equations + give the optimum scaling for the constants: + + A[0..7] = integer(real_A[0..7] * 1024) + B[0..7] = integer(real_B[0..7] * 512) + MAC[0..7] = maximum of the LARc[0..7] + MIC[0..7] = minimum of the LARc[0..7] */ + +#undef STEP +#define STEP(A,B,MAC,MIC) \ + temp = gsm_mult(A, *LAR); \ + temp = gsm_add(temp, B); \ + temp = gsm_add(temp, 256); \ + temp >>= 9; \ + *LAR = (int16_t) ((temp > MAC) \ + ? \ + MAC - MIC \ + : \ + ((temp < MIC) ? 0 : temp - MIC)); \ + LAR++; + + STEP(20480, 0, 31, -32); + STEP(20480, 0, 31, -32); + STEP(20480, 2048, 15, -16); + STEP(20480, -2560, 15, -16); + + STEP(13964, 94, 7, -8); + STEP(15360, -1792, 7, -8); + STEP( 8534, -341, 3, -4); + STEP( 9036, -1144, 3, -4); +#undef STEP +} +/*- End of function --------------------------------------------------------*/ + +void gsm0610_lpc_analysis(gsm0610_state_t *s, + int16_t amp[GSM0610_FRAME_LEN], + int16_t LARc[8]) +{ + int32_t L_ACF[9]; + + autocorrelation(amp, L_ACF); + reflection_coefficients(L_ACF, LARc); + transform_to_log_area_ratios(LARc); + quantization_and_coding(LARc); +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_preprocess.c b/libs/voipcodecs/src/gsm0610_preprocess.c new file mode 100644 index 0000000000..cef911a5cc --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_preprocess.c @@ -0,0 +1,149 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_preprocess.c - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_preprocess.c,v 1.8 2007/08/20 15:22:22 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/gsm0610.h" + +#include "gsm0610_local.h" + +/* + 4.2.0 .. 4.2.3 PREPROCESSING SECTION + + After A-law to linear conversion (or directly from the + A to D converter) the following scaling is assumed for + input to the RPE-LTP algorithm: + + in: 0.1.....................12 + S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* + + Where S is the sign bit, v a valid bit, and * a "don't care" bit. + The original signal is called sop[..] + + out: 0.1................... 12 + S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 +*/ + +void gsm0610_preprocess(gsm0610_state_t *s, const int16_t amp[GSM0610_FRAME_LEN], int16_t so[GSM0610_FRAME_LEN]) +{ + int16_t z1; + int16_t mp; + int16_t s1; + int16_t msp; + int16_t SO; + int32_t L_z2; + int32_t L_s2; + int32_t L_temp; +#if !defined(__GNUC__) + int16_t lsp; +#endif + int k; + + z1 = s->z1; + L_z2 = s->L_z2; + mp = s->mp; + for (k = 0; k < GSM0610_FRAME_LEN; k++) + { + /* 4.2.1 Downscaling of the input signal */ + SO = (amp[k] >> 1) & ~3; + + assert(SO >= -0x4000); // downscaled by + assert(SO <= 0x3FFC); // previous routine. + + /* 4.2.2 Offset compensation */ + + /* This part implements a high-pass filter and requires extended + arithmetic precision for the recursive part of this filter. + The input of this procedure is the array so[0...159] and the + output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part */ + s1 = SO - z1; + z1 = SO; + + assert(s1 != INT16_MIN); + + /* Compute the recursive part */ + L_s2 = s1; + L_s2 <<= 15; + + /* Perform a 31 by 16 bits multiplication */ +#if defined(__GNUC__) + L_z2 = ((int64_t) L_z2*32735 + 0x4000) >> 15; + /* Alternate (ANSI) version of below line does slightly different rounding: + * L_temp = L_z2 >> 9; + * L_temp += L_temp >> 5; + * L_temp = (++L_temp) >> 1; + * L_z2 = L_z2 - L_temp; + */ + L_z2 = gsm_l_add(L_z2, L_s2); +#else + /* This does L_z2 = L_z2 * 0x7FD5/0x8000 + L_s2 */ + msp = (int16_t) (L_z2 >> 15); + lsp = (int16_t) (L_z2 - ((int32_t) msp << 15)); + + L_s2 += gsm_mult_r(lsp, 32735); + L_temp = (int32_t) msp*32735; + L_z2 = gsm_l_add(L_temp, L_s2); +#endif + + /* Compute sof[k] with rounding */ + L_temp = gsm_l_add(L_z2, 16384); + + /* 4.2.3 Preemphasis */ + msp = gsm_mult_r(mp, -28180); + mp = (int16_t) (L_temp >> 15); + so[k] = gsm_add(mp, msp); + } + /*endfor*/ + + s->z1 = z1; + s->L_z2 = L_z2; + s->mp = mp; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_rpe.c b/libs/voipcodecs/src/gsm0610_rpe.c new file mode 100644 index 0000000000..2e03fd9098 --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_rpe.c @@ -0,0 +1,531 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_rpe.c - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_rpe.c,v 1.14 2007/08/20 15:22:22 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/gsm0610.h" + +#include "gsm0610_local.h" + +/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION */ + +/* 4.2.13 */ +static void weighting_filter(const int16_t *e, // signal [-5..0.39.44] IN + int16_t x[40]) +{ +#if defined(__GNUC__) && defined(__i386__) + /* Table 4.4 Coefficients of the weighting filter */ + /* This must be padded to a multiple of 4 for MMX to work */ + static const int16_t gsm_H[12] = + { + -134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134, 0 + }; + + __asm__ __volatile__( + " emms;\n" + " addl $-10,%%ecx;\n" + " movl $0x1000,%%eax;\n" + " movd %%eax,%%mm5;\n" /* for rounding */ + " movq %[gsm_H],%%mm1;\n" + " movq %[gsm_H8],%%mm2;\n" + " movq %[gsm_H16],%%mm3;\n" + " xorl %%esi,%%esi;\n" + " .p2align 2;\n" + "1:;\n" + " movq (%%ecx,%%esi,2),%%mm0;\n" + " pmaddwd %%mm1,%%mm0;\n" + + " movq 8(%%ecx,%%esi,2),%%mm4;\n" + " pmaddwd %%mm2,%%mm4;\n" + " paddd %%mm4,%%mm0;\n" + + " movq 16(%%ecx,%%esi,2),%%mm4;\n" + " pmaddwd %%mm3,%%mm4;\n" + " paddd %%mm4,%%mm0;\n" + + " movq %%mm0,%%mm4;\n" + " punpckhdq %%mm0,%%mm4;\n" /* mm4 has high int32 of mm0 dup'd */ + " paddd %%mm4,%%mm0;\n" + + " paddd %%mm5,%%mm0;\n" /* Add for roundoff */ + " psrad $13,%%mm0;\n" + " packssdw %%mm0,%%mm0;\n" + " movd %%mm0,%%eax;\n" /* eax has result */ + " movw %%ax,(%%edi,%%esi,2);\n" + " incl %%esi;\n" + " cmpl $39,%%esi;\n" + " jle 1b;\n" + " emms;\n" + : + : "c" (e), "D" (x), [gsm_H] "X" (*((int64_t *) gsm_H)), [gsm_H8] "X" (*((int64_t *) (gsm_H + 4))), [gsm_H16] "X" (*((int64_t *) (gsm_H + 8))) + : "eax", "edx", "esi" + ); +#else + int32_t L_result; + int k; + + /* The coefficients of the weighting filter are stored in a table + (see table 4.4). The following scaling is used: + + H[0..10] = integer(real_H[0..10] * 8192); + */ + /* Initialization of a temporary working array wt[0...49] */ + + /* for (k = 0; k <= 4; k++) wt[k] = 0; + * for (k = 5; k <= 44; k++) wt[k] = *e++; + * for (k = 45; k <= 49; k++) wt[k] = 0; + * + * (e[-5..-1] and e[40..44] are allocated by the caller, + * are initially zero and are not written anywhere.) + */ + e -= 5; + + /* Compute the signal x[0..39] */ + for (k = 0; k < 40; k++) + { + L_result = 8192 >> 1; + + /* for (i = 0; i <= 10; i++) + * { + * L_temp = gsm_l_mult(wt[k + i], gsm_H[i]); + * L_result = gsm_l_add(L_result, L_temp); + * } + */ + +#undef STEP +#define STEP(i,H) (e[k + i] * (int32_t) H) + + /* Every one of these multiplications is done twice, + but I don't see an elegant way to optimize this. + Do you? + */ + L_result += STEP( 0, -134); + L_result += STEP( 1, -374); + // += STEP( 2, 0 ); + L_result += STEP( 3, 2054); + L_result += STEP( 4, 5741); + L_result += STEP( 5, 8192); + L_result += STEP( 6, 5741); + L_result += STEP( 7, 2054); + // += STEP( 8, 0 ); + L_result += STEP( 9, -374); + L_result += STEP(10, -134); + + /* 2 adds vs. >> 16 => 14, minus one shift to compensate for + those we lost when replacing L_MULT by '*'. */ + L_result >>= 13; + x[k] = saturate(L_result); + } + /*endfor*/ +#endif +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.14 */ +static void rpe_grid_selection(int16_t x[40], int16_t xM[13], int16_t *Mc_out) +{ + int i; + int32_t L_result; + int32_t L_temp; + int32_t EM; /* xxx should be L_EM? */ + int16_t Mc; + int32_t L_common_0_3; + + /* The signal x[0..39] is used to select the RPE grid which is + represented by Mc. */ + + EM = 0; + Mc = 0; + +#undef STEP +#define STEP(m,i) \ + L_temp = x[m + 3*i] >> 2; \ + L_result += L_temp*L_temp; + + /* Common part of 0 and 3 */ + L_result = 0; + STEP(0, 1); + STEP(0, 2); + STEP(0, 3); + STEP(0, 4); + STEP(0, 5); + STEP(0, 6); + STEP(0, 7); + STEP(0, 8); + STEP(0, 9); + STEP(0, 10); + STEP(0, 11); + STEP(0, 12); + L_common_0_3 = L_result; + + /* i = 0 */ + + STEP(0, 0); + L_result <<= 1; /* implicit in L_MULT */ + EM = L_result; + + /* i = 1 */ + + L_result = 0; + STEP(1, 0); + STEP(1, 1); + STEP(1, 2); + STEP(1, 3); + STEP(1, 4); + STEP(1, 5); + STEP(1, 6); + STEP(1, 7); + STEP(1, 8); + STEP(1, 9); + STEP(1, 10); + STEP(1, 11); + STEP(1, 12); + L_result <<= 1; + if (L_result > EM) + { + Mc = 1; + EM = L_result; + } + /*endif*/ + + /* i = 2 */ + + L_result = 0; + STEP(2, 0); + STEP(2, 1); + STEP(2, 2); + STEP(2, 3); + STEP(2, 4); + STEP(2, 5); + STEP(2, 6); + STEP(2, 7); + STEP(2, 8); + STEP(2, 9); + STEP(2, 10); + STEP(2, 11); + STEP(2, 12); + L_result <<= 1; + if (L_result > EM) + { + Mc = 2; + EM = L_result; + } + /*endif*/ + + /* i = 3 */ + + L_result = L_common_0_3; + STEP(3, 12); + L_result <<= 1; + if (L_result > EM) + { + Mc = 3; + EM = L_result; + } + /*endif*/ + + /* Down-sampling by a factor 3 to get the selected xM[0..12] + RPE sequence. */ + for (i = 0; i < 13; i++) + xM[i] = x[Mc + 3*i]; + /*endfor*/ + *Mc_out = Mc; +} +/*- End of function --------------------------------------------------------*/ + +/* 4.12.15 */ +static void apcm_quantization_xmaxc_to_exp_mant(int16_t xmaxc, + int16_t *exp_out, + int16_t *mant_out) +{ + int16_t exp; + int16_t mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc */ + exp = 0; + if (xmaxc > 15) + exp = (int16_t) ((xmaxc >> 3) - 1); + /*endif*/ + mant = xmaxc - (exp << 3); + + if (mant == 0) + { + exp = -4; + mant = 7; + } + else + { + while (mant <= 7) + { + mant = (int16_t) (mant << 1 | 1); + exp--; + } + /*endwhile*/ + mant -= 8; + } + /*endif*/ + + assert(exp >= -4 && exp <= 6); + assert(mant >= 0 && mant <= 7); + + *exp_out = exp; + *mant_out = mant; +} +/*- End of function --------------------------------------------------------*/ + +static void apcm_quantization(int16_t xM[13], + int16_t xMc[13], + int16_t *mant_out, + int16_t *exp_out, + int16_t *xmaxc_out) +{ + /* Table 4.5 Normalized inverse mantissa used to compute xM/xmax */ + static const int16_t gsm_NRFAC[8] = + { + 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 + }; + int i; + int itest; + int16_t xmax; + int16_t xmaxc; + int16_t temp; + int16_t temp1; + int16_t temp2; + int16_t exp; + int16_t mant; + + /* Find the maximum absolute value xmax of xM[0..12]. */ + xmax = 0; + for (i = 0; i < 13; i++) + { + temp = xM[i]; + temp = gsm_abs(temp); + if (temp > xmax) + xmax = temp; + /*endif*/ + } + /*endfor*/ + + /* Quantizing and coding of xmax to get xmaxc. */ + exp = 0; + temp = xmax >> 9; + itest = 0; + + for (i = 0; i <= 5; i++) + { + itest |= (temp <= 0); + temp >>= 1; + + assert(exp <= 5); + if (itest == 0) + exp++; + /*endif*/ + } + /*endfor*/ + + assert(exp <= 6 && exp >= 0); + temp = (int16_t) (exp + 5); + + assert(temp <= 11 && temp >= 0); + xmaxc = gsm_add((xmax >> temp), exp << 3); + + /* Quantizing and coding of the xM[0..12] RPE sequence + to get the xMc[0..12] */ + apcm_quantization_xmaxc_to_exp_mant(xmaxc, &exp, &mant); + + /* This computation uses the fact that the decoded version of xmaxc + can be calculated by using the exponent and the mantissa part of + xmaxc (logarithmic table). + So, this method avoids any division and uses only a scaling + of the RPE samples by a function of the exponent. A direct + multiplication by the inverse of the mantissa (NRFAC[0..7] + found in table 4.5) gives the 3 bit coded version xMc[0..12] + of the RPE samples. + */ + /* Direct computation of xMc[0..12] using table 4.5 */ + assert(exp <= 4096 && exp >= -4096); + assert(mant >= 0 && mant <= 7); + + temp1 = (int16_t) (6 - exp); /* Normalization by the exponent */ + temp2 = gsm_NRFAC[mant]; /* Inverse mantissa */ + + for (i = 0; i < 13; i++) + { + assert(temp1 >= 0 && temp1 < 16); + + temp = xM[i] << temp1; + temp = gsm_mult(temp, temp2); + temp >>= 12; + xMc[i] = (int16_t) (temp + 4); /* See note below */ + } + /*endfor*/ + + /* NOTE: This equation is used to make all the xMc[i] positive. */ + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.16 */ +static void apcm_inverse_quantization(int16_t xMc[13], + int16_t mant, + int16_t exp, + int16_t xMp[13]) +{ + /* Table 4.6 Normalized direct mantissa used to compute xM/xmax */ + static const int16_t gsm_FAC[8] = + { + 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 + }; + int i; + int16_t temp; + int16_t temp1; + int16_t temp2; + int16_t temp3; + + /* This part is for decoding the RPE sequence of coded xMc[0..12] + samples to obtain the xMp[0..12] array. Table 4.6 is used to get + the mantissa of xmaxc (FAC[0..7]). + */ + assert(mant >= 0 && mant <= 7); + + temp1 = gsm_FAC[mant]; /* See 4.2-15 for mant */ + temp2 = gsm_sub(6, exp); /* See 4.2-15 for exp */ + temp3 = gsm_asl(1, gsm_sub (temp2, 1)); + + for (i = 0; i < 13; i++) + { + assert(xMc[i] >= 0 && xMc[i] <= 7); /* 3 bit unsigned */ + + temp = (int16_t) ((xMc[i] << 1) - 7); /* Restore sign */ + assert(temp <= 7 && temp >= -7); /* 4 bit signed */ + + temp <<= 12; /* 16 bit signed */ + temp = gsm_mult_r(temp1, temp); + temp = gsm_add(temp, temp3); + xMp[i] = gsm_asr(temp, temp2); + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.17 */ +static void rpe_grid_positioning(int16_t Mc, + int16_t xMp[13], + int16_t ep[40]) +{ + int i = 13; + + /* This procedure computes the reconstructed long term residual signal + ep[0..39] for the LTP analysis filter. The inputs are the Mc + which is the grid position selection and the xMp[0..12] decoded + RPE samples which are upsampled by a factor of 3 by inserting zero + values. + */ + assert(0 <= Mc && Mc <= 3); + + switch (Mc) + { + case 3: + *ep++ = 0; + case 2: + do + { + *ep++ = 0; + case 1: + *ep++ = 0; + case 0: + *ep++ = *xMp++; + } + while (--i); + } + /*endswitch*/ + while (++Mc < 4) + *ep++ = 0; + /*endwhile*/ +} +/*- End of function --------------------------------------------------------*/ + +void gsm0610_rpe_encoding(gsm0610_state_t *s, + int16_t *e, // [-5..-1][0..39][40..44] + int16_t *xmaxc, + int16_t *Mc, + int16_t xMc[13]) +{ + int16_t x[40]; + int16_t xM[13]; + int16_t xMp[13]; + int16_t mant; + int16_t exp; + + weighting_filter(e, x); + rpe_grid_selection(x, xM, Mc); + + apcm_quantization(xM, xMc, &mant, &exp, xmaxc); + apcm_inverse_quantization(xMc, mant, exp, xMp); + + rpe_grid_positioning(*Mc, xMp, e); +} +/*- End of function --------------------------------------------------------*/ + +void gsm0610_rpe_decoding(gsm0610_state_t *s, + int16_t xmaxc, + int16_t Mcr, + int16_t xMcr[13], + int16_t erp[40]) +{ + int16_t exp; + int16_t mant; + int16_t xMp[13]; + + apcm_quantization_xmaxc_to_exp_mant(xmaxc, &exp, &mant); + apcm_inverse_quantization(xMcr, mant, exp, xMp); + rpe_grid_positioning(Mcr, xMp, erp); +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/gsm0610_short_term.c b/libs/voipcodecs/src/gsm0610_short_term.c new file mode 100644 index 0000000000..fb0cbab65c --- /dev/null +++ b/libs/voipcodecs/src/gsm0610_short_term.c @@ -0,0 +1,361 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_short_term.c - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the widely used GSM 06.10 code available from + * http://kbs.cs.tu-berlin.de/~jutta/toast.html + * + * $Id: gsm0610_short_term.c,v 1.10 2007/08/20 15:22:22 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/bitstream.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/gsm0610.h" + +#include "gsm0610_local.h" + +/* SHORT TERM ANALYSIS FILTERING SECTION */ + +/* 4.2.8 */ +static void decode_log_area_ratios(int16_t LARc[8], int16_t *LARpp) +{ + int16_t temp1; + + /* This procedure requires for efficient implementation + two tables. + INVA[1..8] = integer((32768*8)/real_A[1..8]) + MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] */ + +#undef STEP +#define STEP(B,MIC,INVA) \ + temp1 = gsm_add(*LARc++, MIC) << 10; \ + temp1 = gsm_sub(temp1, B << 1); \ + temp1 = gsm_mult_r (INVA, temp1); \ + *LARpp++ = gsm_add(temp1, temp1); + + STEP( 0, -32, 13107); + STEP( 0, -32, 13107); + STEP( 2048, -16, 13107); + STEP(-2560, -16, 13107); + + STEP( 94, -8, 19223); + STEP(-1792, -8, 17476); + STEP( -341, -4, 31454); + STEP(-1144, -4, 29708); + + /* NOTE: the addition of *MIC is used to restore the sign of *LARc. */ +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.9 */ + +/* Computation of the quantized reflection coefficients */ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] */ + +/* Within each frame of 160 analyzed speech samples the short term + analysis and synthesis filters operate with four different sets of + coefficients, derived from the previous set of decoded LARs(LARpp(j - 1)) + and the actual set of decoded LARs (LARpp(j)) + + (Initial value: LARpp(j - 1)[1..8] = 0.) +*/ + +static void coefficients_0_12(int16_t *LARpp_j_1, + int16_t *LARpp_j, + int16_t *LARp) +{ + int i; + + for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) + { + *LARp = gsm_add(*LARpp_j_1 >> 2, *LARpp_j >> 2); + *LARp = gsm_add(*LARp, *LARpp_j_1 >> 1); + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +static void coefficients_13_26(int16_t *LARpp_j_1, + int16_t *LARpp_j, + int16_t *LARp) +{ + int i; + + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) + *LARp = gsm_add(*LARpp_j_1 >> 1, *LARpp_j >> 1); + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +static void coefficients_27_39(int16_t *LARpp_j_1, + int16_t *LARpp_j, + int16_t *LARp) +{ + int i; + + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) + { + *LARp = gsm_add(*LARpp_j_1 >> 2, *LARpp_j >> 2); + *LARp = gsm_add(*LARp, *LARpp_j >> 1); + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +static void coefficients_40_159(int16_t *LARpp_j, int16_t *LARp) +{ + int i; + + for (i = 1; i <= 8; i++) + *LARp++ = *LARpp_j++; + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.9.2 */ +static void larp_to_rp(int16_t LARp[8]) +{ + int i; + int16_t *LARpx; + int16_t temp; + + /* The input to this procedure is the interpolated LARp[0..7] array. + The reflection coefficients, rp[i], are used in the analysis + filter and in the synthesis filter. + */ + + LARpx = LARp; + for (i = 1; i <= 8; i++, LARpx++) + { + temp = *LARpx; + if (temp < 0) + { + if (temp == INT16_MIN) + temp = INT16_MAX; + else + temp = -temp; + /*endif*/ + if (temp < 11059) + temp <<= 1; + else if (temp < 20070) + temp += 11059; + else + temp = gsm_add(temp >> 2, 26112); + /*endif*/ + *LARpx = -temp; + } + else + { + if (temp < 11059) + temp <<= 1; + else if (temp < 20070) + temp += 11059; + else + temp = gsm_add(temp >> 2, 26112); + /*endif*/ + *LARpx = temp; + } + /*endif*/ + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +/* 4.2.10 */ +static void short_term_analysis_filtering(gsm0610_state_t *s, + int16_t rp[8], + int k_n, // k_end - k_start + int16_t amp[]) // [0..n-1] IN/OUT +{ + /* This procedure computes the short term residual signal d[..] to be fed + to the RPE-LTP loop from the s[..] signal and from the local rp[..] + array (quantized reflection coefficients). As the call of this + procedure can be done in many ways (see the interpolation of the LAR + coefficient), it is assumed that the computation begins with index + k_start (for arrays d[..] and s[..]) and stops with index k_end + (k_start and k_end are defined in 4.2.9.1). This procedure also + needs to keep the array u[0..7] in memory for each call. + */ + int16_t *u0; + int16_t *u_top; + int i; + int16_t *u; + int16_t *rpx; + int32_t di; + int32_t u_out; + + u0 = s->u; + u_top = u0 + 8; + + for (i = 0; i < k_n; i++) + { + di = + u_out = amp[i]; + for (rpx = rp, u = u0; u < u_top; ) + { + int32_t ui; + int32_t rpi; + + ui = *u; + *u++ = (int16_t) u_out; + rpi = *rpx++; + u_out = ui + (((rpi*di) + 0x4000) >> 15); + di = di + (((rpi*ui) + 0x4000) >> 15); + u_out = saturate(u_out); + di = saturate(di); + } + /*endfor*/ + amp[i] = (int16_t) di; + } + /*endfor*/ +} +/*- End of function --------------------------------------------------------*/ + +static void short_term_synthesis_filtering(gsm0610_state_t *s, + int16_t rrp[8], + int k, // k_end - k_start + int16_t *wt, // [0..k - 1] + int16_t *sr) // [0..k - 1] +{ + int16_t *v; + int i; + int16_t sri; + int16_t tmp1; + int16_t tmp2; + + v = s->v; + while (k--) + { + sri = *wt++; + for (i = 8; i--; ) + { + tmp1 = rrp[i]; + tmp2 = v[i]; + tmp2 = ((tmp1 == INT16_MIN && tmp2 == INT16_MIN) + ? + INT16_MAX + : + (int16_t) (((int32_t) tmp1*(int32_t) tmp2 + 16384) >> 15) & 0xFFFF); + + sri = gsm_sub(sri, tmp2); + + tmp1 = ((tmp1 == INT16_MIN && sri == INT16_MIN) + ? + INT16_MAX + : + (int16_t) (((int32_t) tmp1*(int32_t) sri + 16384) >> 15) & 0xFFFF); + + v[i + 1] = gsm_add(v[i], tmp1); + } + /*endfor*/ + *sr++ = + v[0] = sri; + } + /*endwhile*/ +} +/*- End of function --------------------------------------------------------*/ + +void gsm0610_short_term_analysis_filter(gsm0610_state_t *s, + int16_t LARc[8], + int16_t amp[GSM0610_FRAME_LEN]) +{ + int16_t *LARpp_j; + int16_t *LARpp_j_1; + int16_t LARp[8]; + + LARpp_j = s->LARpp[s->j]; + LARpp_j_1 = s->LARpp[s->j ^= 1]; + + decode_log_area_ratios(LARc, LARpp_j); + + coefficients_0_12(LARpp_j_1, LARpp_j, LARp); + larp_to_rp(LARp); + short_term_analysis_filtering(s, LARp, 13, amp); + + coefficients_13_26(LARpp_j_1, LARpp_j, LARp); + larp_to_rp(LARp); + short_term_analysis_filtering(s, LARp, 14, amp + 13); + + coefficients_27_39(LARpp_j_1, LARpp_j, LARp); + larp_to_rp(LARp); + short_term_analysis_filtering(s, LARp, 13, amp + 27); + + coefficients_40_159(LARpp_j, LARp); + larp_to_rp(LARp); + short_term_analysis_filtering(s, LARp, 120, amp + 40); +} +/*- End of function --------------------------------------------------------*/ + +void gsm0610_short_term_synthesis_filter(gsm0610_state_t *s, + int16_t LARcr[8], + int16_t wt[GSM0610_FRAME_LEN], + int16_t amp[GSM0610_FRAME_LEN]) +{ + int16_t *LARpp_j; + int16_t *LARpp_j_1; + int16_t LARp[8]; + + LARpp_j = s->LARpp[s->j]; + LARpp_j_1 = s->LARpp[s->j ^= 1]; + + decode_log_area_ratios(LARcr, LARpp_j); + + coefficients_0_12(LARpp_j_1, LARpp_j, LARp); + larp_to_rp(LARp); + short_term_synthesis_filtering(s, LARp, 13, wt, amp); + + coefficients_13_26(LARpp_j_1, LARpp_j, LARp); + larp_to_rp(LARp); + short_term_synthesis_filtering(s, LARp, 14, wt + 13, amp + 13); + + coefficients_27_39(LARpp_j_1, LARpp_j, LARp); + larp_to_rp(LARp); + short_term_synthesis_filtering(s, LARp, 13, wt + 27, amp + 27); + + coefficients_40_159(LARpp_j, LARp); + larp_to_rp(LARp); + short_term_synthesis_filtering(s, LARp, 120, wt + 40, amp + 40); +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/ima_adpcm.c b/libs/voipcodecs/src/ima_adpcm.c new file mode 100644 index 0000000000..7c8c11dd06 --- /dev/null +++ b/libs/voipcodecs/src/ima_adpcm.c @@ -0,0 +1,387 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * ima_adpcm.c - Conversion routines between linear 16 bit PCM data and + * IMA/DVI/Intel ADPCM format. + * + * Written by Steve Underwood + * + * Copyright (C) 2001, 2004 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: ima_adpcm.c,v 1.18 2006/11/30 15:41:47 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/ima_adpcm.h" + +/* + * Intel/DVI ADPCM coder/decoder. + * + * The algorithm for this coder was taken from the IMA Compatability Project + * proceedings, Vol 2, Number 2; May 1992. + * + * The RTP payload specs. reference a variant of DVI, called VDVI. This attempts to + * further compresses, in a variable bit rate manner, by expressing the 4 bit codes + * from the DVI codec as: + * + * 0 00 + * 1 010 + * 2 1100 + * 3 11100 + * 4 111100 + * 5 1111100 + * 6 11111100 + * 7 11111110 + * 8 10 + * 9 011 + * 10 1101 + * 11 11101 + * 12 111101 + * 13 1111101 + * 14 11111101 + * 15 11111111 + * + * Any left over bits in the last octet of an encoded burst are set to one. + */ + +/* Intel ADPCM step variation table */ +static const int step_size[89] = +{ + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +static const int step_adjustment[8] = +{ + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +static const struct +{ + uint8_t code; + uint8_t bits; +} vdvi_encode[] = +{ + {0x00, 2}, + {0x02, 3}, + {0x0C, 4}, + {0x1C, 5}, + {0x3C, 6}, + {0x7C, 7}, + {0xFC, 8}, + {0xFE, 8}, + {0x02, 2}, + {0x03, 3}, + {0x0D, 4}, + {0x1D, 5}, + {0x3D, 6}, + {0x7D, 7}, + {0xFD, 8}, + {0xFF, 8} +}; + +static const struct +{ + uint16_t code; + uint16_t mask; + uint8_t bits; +} vdvi_decode[] = +{ + {0x0000, 0xC000, 2}, + {0x4000, 0xE000, 3}, + {0xC000, 0xF000, 4}, + {0xE000, 0xF800, 5}, + {0xF000, 0xFC00, 6}, + {0xF800, 0xFE00, 7}, + {0xFC00, 0xFF00, 8}, + {0xFE00, 0xFF00, 8}, + {0x8000, 0xC000, 2}, + {0x6000, 0xE000, 3}, + {0xD000, 0xF000, 4}, + {0xE800, 0xF800, 5}, + {0xF400, 0xFC00, 6}, + {0xFA00, 0xFE00, 7}, + {0xFD00, 0xFF00, 8}, + {0xFF00, 0xFF00, 8} +}; + +static int16_t decode(ima_adpcm_state_t *s, uint8_t adpcm) +{ + int e; + int ss; + int16_t linear; + + /* e = (adpcm+0.5)*step/4 */ + + ss = step_size[s->step_index]; + e = ss >> 3; + if (adpcm & 0x01) + e += (ss >> 2); + /*endif*/ + if (adpcm & 0x02) + e += (ss >> 1); + /*endif*/ + if (adpcm & 0x04) + e += ss; + /*endif*/ + if (adpcm & 0x08) + e = -e; + /*endif*/ + linear = saturate(s->last + e); + s->last = linear; + s->step_index += step_adjustment[adpcm & 0x07]; + if (s->step_index < 0) + s->step_index = 0; + else if (s->step_index > 88) + s->step_index = 88; + /*endif*/ + return linear; +} +/*- End of function --------------------------------------------------------*/ + +static uint8_t encode(ima_adpcm_state_t *s, int16_t linear) +{ + int e; + int ss; + int adpcm; + int diff; + int initial_e; + + ss = step_size[s->step_index]; + initial_e = + e = linear - s->last; + diff = ss >> 3; + adpcm = (uint8_t) 0x00; + if (e < 0) + { + adpcm = (uint8_t) 0x08; + e = -e; + } + /*endif*/ + if (e >= ss) + { + adpcm |= (uint8_t) 0x04; + e -= ss; + } + /*endif*/ + ss >>= 1; + if (e >= ss) + { + adpcm |= (uint8_t) 0x02; + e -= ss; + } + /*endif*/ + ss >>= 1; + if (e >= ss) + { + adpcm |= (uint8_t) 0x01; + e -= ss; + } + /*endif*/ + + if (initial_e < 0) + diff = -(diff - initial_e - e); + else + diff = diff + initial_e - e; + /*endif*/ + s->last = saturate(diff + s->last); + s->step_index += step_adjustment[adpcm & 0x07]; + if (s->step_index < 0) + s->step_index = 0; + else if (s->step_index > 88) + s->step_index = 88; + /*endif*/ + return (uint8_t) adpcm; +} +/*- End of function --------------------------------------------------------*/ + +ima_adpcm_state_t *ima_adpcm_init(ima_adpcm_state_t *s, int variant) +{ + if (s == NULL) + { + if ((s = (ima_adpcm_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + /*endif*/ + memset(s, 0, sizeof(*s)); + s->variant = variant; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int ima_adpcm_release(ima_adpcm_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int ima_adpcm_decode(ima_adpcm_state_t *s, + int16_t amp[], + const uint8_t ima_data[], + int ima_bytes) +{ + int i; + int j; + int samples; + uint16_t code; + + samples = 0; + if (s->variant == IMA_ADPCM_VDVI) + { + code = 0; + s->bits = 0; + for (i = 0; ; ) + { + if (s->bits <= 8) + { + if (i >= ima_bytes) + break; + /*endif*/ + code |= ((uint16_t) ima_data[i++] << (8 - s->bits)); + s->bits += 8; + } + /*endif*/ + for (j = 0; j < 8; j++) + { + if ((vdvi_decode[j].mask & code) == vdvi_decode[j].code) + break; + if ((vdvi_decode[j + 8].mask & code) == vdvi_decode[j + 8].code) + { + j += 8; + break; + } + /*endif*/ + } + /*endfor*/ + amp[samples++] = decode(s, (uint8_t) j); + code <<= vdvi_decode[j].bits; + s->bits -= vdvi_decode[j].bits; + } + /*endfor*/ + /* Use up the remanents of the last octet */ + while (s->bits > 0) + { + for (j = 0; j < 8; j++) + { + if ((vdvi_decode[j].mask & code) == vdvi_decode[j].code) + break; + /*endif*/ + if ((vdvi_decode[j + 8].mask & code) == vdvi_decode[j + 8].code) + { + j += 8; + break; + } + /*endif*/ + } + /*endfor*/ + if (vdvi_decode[j].bits > s->bits) + break; + /*endif*/ + amp[samples++] = decode(s, (uint8_t) j); + code <<= vdvi_decode[j].bits; + s->bits -= vdvi_decode[j].bits; + } + /*endfor*/ + } + else + { + for (i = 0; i < ima_bytes; i++) + { + amp[samples++] = decode(s, ima_data[i] & 0xF); + amp[samples++] = decode(s, (ima_data[i] >> 4) & 0xF); + } + /*endwhile*/ + } + /*endif*/ + return samples; +} +/*- End of function --------------------------------------------------------*/ + +int ima_adpcm_encode(ima_adpcm_state_t *s, + uint8_t ima_data[], + const int16_t amp[], + int len) +{ + int i; + int bytes; + uint8_t code; + + bytes = 0; + if (s->variant == IMA_ADPCM_VDVI) + { + s->bits = 0; + for (i = 0; i < len; i++) + { + code = encode(s, amp[i]); + s->ima_byte = (s->ima_byte << vdvi_encode[code].bits) | vdvi_encode[code].code; + s->bits += vdvi_encode[code].bits; + if (s->bits >= 8) + { + s->bits -= 8; + ima_data[bytes++] = (uint8_t) (s->ima_byte >> s->bits); + } + /*endif*/ + } + /*endfor*/ + if (s->bits) + { + ima_data[bytes++] = (uint8_t) (((s->ima_byte << 8) | 0xFF) >> s->bits); + } + /*endif*/ + } + else + { + for (i = 0; i < len; i++) + { + s->ima_byte = (uint8_t) ((s->ima_byte >> 4) | (encode(s, amp[i]) << 4)); + if ((s->bits++ & 1)) + ima_data[bytes++] = (uint8_t) s->ima_byte; + /*endif*/ + } + /*endfor*/ + } + /*endif*/ + return bytes; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/libvoipcodecs.dsp b/libs/voipcodecs/src/libvoipcodecs.dsp new file mode 100644 index 0000000000..c91480bb90 --- /dev/null +++ b/libs/voipcodecs/src/libvoipcodecs.dsp @@ -0,0 +1,241 @@ +# Microsoft Developer Studio Project File - Name="voipcodecs" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=voipcodecs - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "voipcodecs.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "voipcodecs.mak" CFG="voipcodecs - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "voipcodecs - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "voipcodecs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "voipcodecs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "." /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /D "_WINDLL" /FR /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libvoipcodecs.dll" + +!ELSEIF "$(CFG)" == "voipcodecs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /FR /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libvoipcodecs.dll" /pdbtype:sept +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "voipcodecs - Win32 Release" +# Name "voipcodecs - Win32 Debug" +# Begin Group "Source Files" +# Begin Source File + +SOURCE=.\bit_operations.c +# End Source File +# Begin Source File + +SOURCE=.\bitstream.c +# End Source File +# Begin Source File + +SOURCE=.\g711.c +# End Source File +# Begin Source File + +SOURCE=.\g722_encode.c +# End Source File +# Begin Source File + +SOURCE=.\g722_decode.c +# End Source File +# Begin Source File + +SOURCE=.\g726.c +# End Source File +# Begin Source File + +SOURCE=.\gsm0610_decode.c +# End Source File +# Begin Source File + +SOURCE=.\gsm0610_encode.c +# End Source File +# Begin Source File + +SOURCE=.\gsm0610_long_term.c +# End Source File +# Begin Source File + +SOURCE=.\gsm0610_lpc.c +# End Source File +# Begin Source File + +SOURCE=.\gsm0610_preprocess.c +# End Source File +# Begin Source File + +SOURCE=.\gsm0610_rpe.c +# End Source File +# Begin Source File + +SOURCE=.\gsm0610_short_term.c +# End Source File +# Begin Source File + +SOURCE=.\ima_adpcm.c +# End Source File +# Begin Source File + +SOURCE=.\lpc10_analyse.c +# End Source File +# Begin Source File + +SOURCE=.\lpc10_decode.c +# End Source File +# Begin Source File + +SOURCE=.\lpc10_encode.c +# End Source File +# Begin Source File + +SOURCE=.\lpc10_placev.c +# End Source File +# Begin Source File + +SOURCE=.\lpc10_voicing.c +# End Source File +# Begin Source File + +SOURCE=.\oki_adpcm.c +# End Source File +# Begin Source File + +SOURCE=.\vector_int.c +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/bit_operations.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/bitstream.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/dc_restore.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/g711.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/g722.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/g726.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/gsm0610.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/ima_adpcm.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/lpc10.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/oki_adpcm.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/telephony.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs/vector_int.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs.h +# End Source File +# Begin Source File + +SOURCE=.\voipcodecs.h +# End Source File +# End Group + +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/libs/voipcodecs/src/libvoipcodecs.sln b/libs/voipcodecs/src/libvoipcodecs.sln new file mode 100644 index 0000000000..dd5df26ba4 --- /dev/null +++ b/libs/voipcodecs/src/libvoipcodecs.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvoipcodecs", "libvoipcodecs.vcproj", "{CF70F278-3364-4395-A2E1-23501C9B8AD2}" + ProjectSection(ProjectDependencies) = postProject + {1CED5987-A529-46DC-B30F-870D85FF9C94} = {1CED5987-A529-46DC-B30F-870D85FF9C94} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "at_dictionary_gen", "src\msvc\at_dictionary_gen.vcproj", "{1CED5987-A529-46DC-B30F-870D85FF9C94}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF70F278-3364-4395-A2E1-23501C9B8AD2}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF70F278-3364-4395-A2E1-23501C9B8AD2}.Debug|Win32.Build.0 = Debug|Win32 + {CF70F278-3364-4395-A2E1-23501C9B8AD2}.Release|Win32.ActiveCfg = Release|Win32 + {CF70F278-3364-4395-A2E1-23501C9B8AD2}.Release|Win32.Build.0 = Release|Win32 + {1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug|Win32.ActiveCfg = Debug|Win32 + {1CED5987-A529-46DC-B30F-870D85FF9C94}.Debug|Win32.Build.0 = Debug|Win32 + {1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|Win32.ActiveCfg = Release|Win32 + {1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/voipcodecs/src/lpc10_analyse.c b/libs/voipcodecs/src/lpc10_analyse.c new file mode 100644 index 0000000000..b88eb06ccb --- /dev/null +++ b/libs/voipcodecs/src/lpc10_analyse.c @@ -0,0 +1,712 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * lpc10_analyse.c - LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the U.S. Department of Defense reference + * implementation of the LPC-10 2400 bps Voice Coder. They do not + * exert copyright claims on their code, and it may be freely used. + * + * $Id: lpc10_analyse.c,v 1.13 2007/01/03 14:15:35 steveu Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/lpc10.h" + +#include "lpc10_encdecs.h" + +static __inline__ float energyf(float amp[], int len) +{ + int i; + float rms; + + rms = 0.0f; + for (i = 0; i < len; i++) + rms += amp[i]*amp[i]; + rms = sqrtf(rms/len); + return rms; +} +/*- End of function --------------------------------------------------------*/ + +static void remove_dc_bias(float speech[], int len, float sigout[]) +{ + float bias; + int i; + + bias = 0.0f; + for (i = 0; i < len; i++) + bias += speech[i]; + bias /= len; + for (i = 0; i < len; i++) + sigout[i] = speech[i] - bias; +} +/*- End of function --------------------------------------------------------*/ + +static void eval_amdf(float speech[], + int32_t lpita, + const int32_t tau[], + int32_t ltau, + int32_t maxlag, + float amdf[], + int32_t *minptr, + int32_t *maxptr) +{ + float sum; + int i; + int j; + int n1; + int n2; + + *minptr = 0; + *maxptr = 0; + for (i = 0; i < ltau; i++) + { + n1 = (maxlag - tau[i])/2 + 1; + n2 = n1 + lpita - 1; + sum = 0.0f; + for (j = n1; j <= n2; j += 4) + sum += fabsf(speech[j - 1] - speech[j + tau[i] - 1]); + amdf[i] = sum; + if (amdf[i] < amdf[*minptr]) + *minptr = i; + if (amdf[i] > amdf[*maxptr]) + *maxptr = i; + } +} +/*- End of function --------------------------------------------------------*/ + +static void eval_highres_amdf(float speech[], + int32_t lpita, + const int32_t tau[], + int32_t ltau, + float amdf[], + int32_t *minptr, + int32_t *maxptr, + int32_t *mintau) +{ + float amdf2[6]; + int32_t tau2[6]; + int32_t minp2; + int32_t ltau2; + int32_t maxp2; + int32_t minamd; + int i; + int i2; + int ptr; + + /* Compute full AMDF using log spaced lags, find coarse minimum */ + eval_amdf(speech, lpita, tau, ltau, tau[ltau - 1], amdf, minptr, maxptr); + *mintau = tau[*minptr]; + minamd = (int32_t) amdf[*minptr]; + + /* Build table containing all lags within +/- 3 of the AMDF minimum, + excluding all that have already been computed */ + ltau2 = 0; + ptr = *minptr - 2; + i2 = min(*mintau + 4, tau[ltau - 1]); + for (i = max(*mintau - 3, 41); i < i2; i++) + { + while (tau[ptr] < i) + ptr++; + if (tau[ptr] != i) + tau2[ltau2++] = i; + } + /* Compute AMDF of the new lags, if there are any, and choose one + if it is better than the coarse minimum */ + if (ltau2 > 0) + { + eval_amdf(speech, lpita, tau2, ltau2, tau[ltau - 1], amdf2, &minp2, &maxp2); + if (amdf2[minp2] < (float) minamd) + { + *mintau = tau2[minp2]; + minamd = (int32_t) amdf2[minp2]; + } + } + /* Check one octave up, if there are any lags not yet computed */ + if (*mintau >= 80) + { + i = *mintau/2; + if ((i & 1) == 0) + { + ltau2 = 2; + tau2[0] = i - 1; + tau2[1] = i + 1; + } + else + { + ltau2 = 1; + tau2[0] = i; + } + eval_amdf(speech, lpita, tau2, ltau2, tau[ltau - 1], amdf2, &minp2, &maxp2); + if (amdf2[minp2] < (float) minamd) + { + *mintau = tau2[minp2]; + minamd = (int32_t) amdf2[minp2]; + *minptr -= 20; + } + } + /* Force minimum of the AMDF array to the high resolution minimum */ + amdf[*minptr] = (float) minamd; + /* Find maximum of AMDF within 1/2 octave of minimum */ + *maxptr = max(*minptr - 5, 0); + i2 = min(*minptr + 6, ltau); + for (i = *maxptr; i < i2; i++) + { + if (amdf[i] > amdf[*maxptr]) + *maxptr = i; + } +} +/*- End of function --------------------------------------------------------*/ + +static void dynamic_pitch_tracking(lpc10_encode_state_t *s, + float amdf[], + int32_t ltau, + int32_t *minptr, + int32_t voice, + int32_t *pitch, + int32_t *midx) +{ + int32_t pbar; + float sbar; + int32_t path[2]; + int32_t i; + int32_t j; + float alpha; + float minsc; + float maxsc; + + /* Calculate the confidence factor ALPHA, used as a threshold slope in */ + /* SEESAW. If unvoiced, set high slope so that every point in P array */ + /*is marked as a potential pitch frequency. A scaled up version (ALPHAX )*/ + /* is used to maintain arithmetic precision. */ + if (voice == 1) + s->alphax = s->alphax*0.75f + amdf[*minptr - 1]*0.5f; + else + s->alphax *= 0.984375f; + alpha = s->alphax/16; + if (voice == 0 && s->alphax < 128.0f) + alpha = 8.0f; + /* SEESAW: Construct a pitch pointer array and intermediate winner function */ + /* Left to right pass: */ + s->p[s->ipoint][0] = 1; + pbar = 1; + sbar = s->s[0]; + for (i = 0; i < ltau; i++) + { + sbar += alpha; + if (sbar < s->s[i]) + { + s->s[i] = sbar; + } + else + { + pbar = i + 1; + sbar = s->s[i]; + } + s->p[s->ipoint][i] = pbar; + } + /* Right to left pass: */ + sbar = s->s[pbar - 1]; + for (i = pbar - 2; i >= 0; i--) + { + sbar += alpha; + if (sbar < s->s[i]) + { + s->s[i] = sbar; + s->p[s->ipoint][i] = pbar; + } + else + { + pbar = s->p[s->ipoint][i]; + i = pbar - 1; + sbar = s->s[i]; + } + } + /* Update S using AMDF */ + /* Find maximum, minimum, and location of minimum */ + s->s[0] += amdf[0]/2; + minsc = s->s[0]; + maxsc = minsc; + *midx = 1; + for (i = 1; i < ltau; i++) + { + s->s[i] += amdf[i]/2; + if (s->s[i] > maxsc) + maxsc = s->s[i]; + if (s->s[i] < minsc) + { + *midx = i + 1; + minsc = s->s[i]; + } + } + /* Subtract MINSC from S to prevent overflow */ + for (i = 0; i < ltau; i++) + s->s[i] -= minsc; + maxsc -= minsc; + /* Use higher octave pitch if significant null there */ + j = 0; + for (i = 20; i <= 40; i += 10) + { + if (*midx > i) + { + if (s->s[*midx - i - 1] < maxsc / 4) + j = i; + } + } + *midx -= j; + /* TRACE: look back two frames to find minimum cost pitch estimate */ + *pitch = *midx; + for (i = 0, j = s->ipoint; i < 2; i++, j++) + { + *pitch = s->p[j & 1][*pitch - 1]; + path[i] = *pitch; + } + + /* The following statement subtracts one from IPOINT, mod DEPTH. I */ + /* think the author chose to add DEPTH-1, instead of subtracting 1, */ + /* because then it will work even if MOD doesn't work as desired on */ + /* negative arguments. */ + s->ipoint = (s->ipoint + 1) & 1; +} +/*- End of function --------------------------------------------------------*/ + +/* Detection of onsets in (or slightly preceding) the futuremost frame of speech. */ +static void onset(lpc10_encode_state_t *s, + float *pebuf, + int32_t osbuf[], + int32_t *osptr, + int32_t oslen, + int32_t sbufl, + int32_t sbufh, + int32_t lframe) +{ + int32_t i; + float r1; + float l2sum2; + + pebuf -= sbufl; + + if (s->hyst) + s->lasti -= lframe; + for (i = sbufh - lframe + 1; i <= sbufh; i++) + { + /* Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1. */ + s->n = (pebuf[i]*pebuf[i - 1] + s->n*63.0f)/64.0f; + /* Computing 2nd power */ + r1 = pebuf[i - 1]; + s->d__ = (r1*r1 + s->d__*63.0f)/64.0f; + if (s->d__ != 0.0f) + { + if (fabsf(s->n) > s->d__) + s->fpc = r_sign(1.0f, s->n); + else + s->fpc = s->n/s->d__; + } + /* Filter FPC */ + l2sum2 = s->l2buf[s->l2ptr1 - 1]; + s->l2sum1 = s->l2sum1 - s->l2buf[s->l2ptr2 - 1] + s->fpc; + s->l2buf[s->l2ptr2 - 1] = s->l2sum1; + s->l2buf[s->l2ptr1 - 1] = s->fpc; + s->l2ptr1 = (s->l2ptr1 & 0xF) + 1; + s->l2ptr2 = (s->l2ptr2 & 0xF) + 1; + if (fabsf(s->l2sum1 - l2sum2) > 1.7f) + { + if (!s->hyst) + { + /* Ignore if buffer full */ + if (*osptr <= oslen) + { + osbuf[*osptr - 1] = i - 9; + (*osptr)++; + } + s->hyst = TRUE; + } + s->lasti = i; + /* After one onset detection, at least OSHYST sample times must go */ + /* by before another is allowed to occur. */ + } + else if (s->hyst && i - s->lasti >= 10) + { + s->hyst = FALSE; + } + } +} +/*- End of function --------------------------------------------------------*/ + +/* Load a covariance matrix. */ +static void mload(int32_t order, int32_t awins, int32_t awinf, float speech[], float phi[], float psi[]) +{ + int32_t start; + int i; + int r; + + start = awins + order; + for (r = 1; r <= order; r++) + { + phi[r - 1] = 0.0f; + for (i = start; i <= awinf; i++) + phi[r - 1] += speech[i - 2]*speech[i - r - 1]; + } + + /* Load last element of vector PSI */ + psi[order - 1] = 0.0f; + for (i = start - 1; i < awinf; i++) + psi[order - 1] += speech[i]*speech[i - order]; + /* End correct to get additional columns of phi */ + for (r = 1; r < order; r++) + { + for (i = 1; i <= r; i++) + { + phi[i*order + r] = phi[(i - 1)*order + r - 1] + - speech[awinf - (r + 1)]*speech[awinf - (i + 1)] + + speech[start - (r + 2)]*speech[start - (i + 2)]; + } + } + /* End correct to get additional elements of PSI */ + for (i = 0; i < order - 1; i++) + { + psi[i] = phi[i + 1] + - speech[start - 2]*speech[start - i - 3] + + speech[awinf - 1]*speech[awinf - i - 2]; + } +} +/*- End of function --------------------------------------------------------*/ + +/* Preemphasize speech with a single-zero filter. */ +/* (When coef = .9375, preemphasis is as in LPC43.) */ +static float preemp(float inbuf[], float pebuf[], int nsamp, float coeff, float z) +{ + float temp; + int i; + + for (i = 0; i < nsamp; i++) + { + temp = inbuf[i] - coeff*z; + z = inbuf[i]; + pebuf[i] = temp; + } + return z; +} +/*- End of function --------------------------------------------------------*/ + +/* Invert a covariance matrix using Choleski decomposition method. */ +static void invert(int32_t order, float phi[], float psi[], float rc[]) +{ + float r1; + int32_t i; + int32_t j; + int32_t k; + float v[10][10]; + + for (j = 0; j < order; j++) + { + for (i = j; i < order; i++) + v[j][i] = phi[i + j*order]; + for (k = 0; k < j; k++) + { + r1 = v[k][j]*v[k][k]; + for (i = j; i <= order; i++) + v[j][i] -= v[k][i]*r1; + } + /* Compute intermediate results, which are similar to RC's */ + if (fabsf(v[j][j]) < 1.0e-10f) + { + for (i = j; i < order; i++) + rc[i] = 0.0f; + return; + } + rc[j] = psi[j]; + for (k = 0; k < j; k++) + rc[j] -= rc[k]*v[k][j]; + v[j][j] = 1.0f/v[j][j]; + rc[j] *= v[j][j]; + r1 = min(rc[j], 0.999f); + rc[j] = max(r1, -0.999f); + } +} +/*- End of function --------------------------------------------------------*/ + +/* Check RC's, repeat previous frame's RC's if unstable */ +static int rcchk(int order, float rc1f[], float rc2f[]) +{ + int i; + + for (i = 0; i < order; i++) + { + if (fabsf(rc2f[i]) > 0.99f) + { + for (i = 0; i < order; i++) + rc2f[i] = rc1f[i]; + break; + } + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static void lpfilt(float inbuf[], float lpbuf[], int32_t len, int32_t nsamp) +{ + int32_t j; + float t; + + /* 31 point equiripple FIR LPF */ + /* Linear phase, delay = 15 samples */ + /* Passband: ripple = 0.25 dB, cutoff = 800 Hz */ + /* Stopband: atten. = 40. dB, cutoff = 1240 Hz */ + + for (j = len - nsamp; j < len; j++) + { + t = (inbuf[j] + inbuf[j - 30]) * -0.0097201988f; + t += (inbuf[j - 1] + inbuf[j - 29]) * -0.0105179986f; + t += (inbuf[j - 2] + inbuf[j - 28]) * -0.0083479648f; + t += (inbuf[j - 3] + inbuf[j - 27]) * 5.860774e-4f; + t += (inbuf[j - 4] + inbuf[j - 26]) * 0.0130892089f; + t += (inbuf[j - 5] + inbuf[j - 25]) * 0.0217052232f; + t += (inbuf[j - 6] + inbuf[j - 24]) * 0.0184161253f; + t += (inbuf[j - 7] + inbuf[j - 23]) * 3.39723e-4f; + t += (inbuf[j - 8] + inbuf[j - 22]) * -0.0260797087f; + t += (inbuf[j - 9] + inbuf[j - 21]) * -0.0455563702f; + t += (inbuf[j - 10] + inbuf[j - 20]) * -0.040306855f; + t += (inbuf[j - 11] + inbuf[j - 19]) * 5.029835e-4f; + t += (inbuf[j - 12] + inbuf[j - 18]) * 0.0729262903f; + t += (inbuf[j - 13] + inbuf[j - 17]) * 0.1572008878f; + t += (inbuf[j - 14] + inbuf[j - 16]) * 0.2247288674f; + t += inbuf[j - 15] * 0.250535965f; + lpbuf[j] = t; + } +} +/*- End of function --------------------------------------------------------*/ + +/* 2nd order inverse filter, speech is decimated 4:1 */ +static void ivfilt(float lpbuf[], float ivbuf[], int32_t len, int32_t nsamp, float ivrc[]) +{ + int32_t i; + int32_t j; + int32_t k; + float r[3]; + float pc1; + float pc2; + + /* Calculate autocorrelations */ + for (i = 1; i <= 3; i++) + { + r[i - 1] = 0.0f; + k = (i - 1) << 2; + for (j = (i << 2) + len - nsamp; j <= len; j += 2) + r[i - 1] += lpbuf[j - 1]*lpbuf[j - k - 1]; + } + /* Calculate predictor coefficients */ + pc1 = 0.0f; + pc2 = 0.0f; + ivrc[0] = 0.0f; + ivrc[1] = 0.0f; + if (r[0] > 1.0e-10f) + { + ivrc[0] = r[1]/r[0]; + ivrc[1] = (r[2] - ivrc[0]*r[1])/(r[0] - ivrc[0]*r[1]); + pc1 = ivrc[0] - ivrc[0]*ivrc[1]; + pc2 = ivrc[1]; + } + /* Inverse filter LPBUF into IVBUF */ + for (i = len - nsamp; i < len; i++) + ivbuf[i] = lpbuf[i] - pc1*lpbuf[i - 4] - pc2*lpbuf[i - 8]; +} +/*- End of function --------------------------------------------------------*/ + +void lpc10_analyse(lpc10_encode_state_t *s, float speech[], int32_t voice[], int32_t *pitch, float *rms, float rc[]) +{ + static const int32_t tau[60] = + { + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 84, 88, 92, 96, + 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, + 148, 152, 156 + }; + static const int32_t buflim[4] = + { + 181, 720, 25, 720 + }; + static const float precoef = 0.9375f; + + float amdf[60]; + float abuf[156]; + float ivrc[2]; + float temp; + float phi[100] /* was [10][10] */; + float psi[10]; + int32_t half; + int32_t midx; + int32_t ewin[3][2]; + int32_t i; + int32_t j; + int32_t lanal; + int32_t ipitch; + int32_t mintau; + int32_t minptr; + int32_t maxptr; + + /* Calculations are done on future frame due to requirements + of the pitch tracker. Delay RMS and RC's 2 frames to give + current frame parameters on return. */ + + for (i = 0; i <= 720 - LPC10_SAMPLES_PER_FRAME - 181; i++) + { + s->inbuf[i] = s->inbuf[LPC10_SAMPLES_PER_FRAME + i]; + s->pebuf[i] = s->pebuf[LPC10_SAMPLES_PER_FRAME + i]; + } + for (i = 0; i <= 540 - LPC10_SAMPLES_PER_FRAME - 229; i++) + s->ivbuf[i] = s->ivbuf[LPC10_SAMPLES_PER_FRAME + i]; + for (i = 0; i <= 720 - LPC10_SAMPLES_PER_FRAME - 25; i++) + s->lpbuf[i] = s->lpbuf[LPC10_SAMPLES_PER_FRAME + i]; + for (i = 0, j = 0; i < s->osptr - 1; i++) + { + if (s->osbuf[i] > LPC10_SAMPLES_PER_FRAME) + s->osbuf[j++] = s->osbuf[i] - LPC10_SAMPLES_PER_FRAME; + } + s->osptr = j + 1; + s->voibuf[0][0] = s->voibuf[1][0]; + s->voibuf[0][1] = s->voibuf[1][1]; + for (i = 0; i < 2; i++) + { + s->vwin[i][0] = s->vwin[i + 1][0] - LPC10_SAMPLES_PER_FRAME; + s->vwin[i][1] = s->vwin[i + 1][1] - LPC10_SAMPLES_PER_FRAME; + s->awin[i][0] = s->awin[i + 1][0] - LPC10_SAMPLES_PER_FRAME; + s->awin[i][1] = s->awin[i + 1][1] - LPC10_SAMPLES_PER_FRAME; + s->obound[i] = s->obound[i + 1]; + s->voibuf[i + 1][0] = s->voibuf[i + 2][0]; + s->voibuf[i + 1][1] = s->voibuf[i + 2][1]; + s->rmsbuf[i] = s->rmsbuf[i + 1]; + for (j = 0; j < LPC10_ORDER; j++) + s->rcbuf[i][j] = s->rcbuf[i + 1][j]; + } + /* If the average value in the frame was over 1/4096 (after current + BIAS correction), then subtract that much more from samples in the + next frame. If the average value in the frame was under + -1/4096, add 1/4096 more to samples in next frame. In all other + cases, keep BIAS the same. */ + temp = 0.0f; + for (i = 0; i < LPC10_SAMPLES_PER_FRAME; i++) + { + s->inbuf[720 - 2*LPC10_SAMPLES_PER_FRAME + i] = speech[i]*4096.0f - s->bias; + temp += s->inbuf[720 - 2*LPC10_SAMPLES_PER_FRAME + i]; + } + if (temp > (float) LPC10_SAMPLES_PER_FRAME) + s->bias++; + else if (temp < (float) (-LPC10_SAMPLES_PER_FRAME)) + s->bias--; + /* Place voicing window */ + i = 721 - LPC10_SAMPLES_PER_FRAME; + s->zpre = preemp(&s->inbuf[i - 181], &s->pebuf[i - 181], LPC10_SAMPLES_PER_FRAME, precoef, s->zpre); + onset(s, s->pebuf, s->osbuf, &s->osptr, 10, 181, 720, LPC10_SAMPLES_PER_FRAME); + + lpc10_placev(s->osbuf, &s->osptr, 10, &s->obound[2], s->vwin, 3, LPC10_SAMPLES_PER_FRAME, 90, 156, 307, 462); + /* The Pitch Extraction algorithm estimates the pitch for a frame + of speech by locating the minimum of the average magnitude difference + function (AMDF). The AMDF operates on low-pass, inverse filtered + speech. (The low-pass filter is an 800 Hz, 19 tap, equiripple, FIR + filter and the inverse filter is a 2nd-order LPC filter.) The pitch + estimate is later refined by dynamic tracking. However, since some + of the tracking parameters are a function of the voicing decisions, + a voicing decision must precede the final pitch estimation. */ + /* See subroutines LPFILT, IVFILT, and eval_highres_amdf. */ + /* LPFILT reads indices LBUFH-LFRAME-29 = 511 through LBUFH = 720 + of INBUF, and writes indices LBUFH+1-LFRAME = 541 through LBUFH + = 720 of LPBUF. */ + lpfilt(&s->inbuf[228], &s->lpbuf[384], 312, LPC10_SAMPLES_PER_FRAME); + /* IVFILT reads indices (PWINH-LFRAME-7) = 353 through PWINH = 540 + of LPBUF, and writes indices (PWINH-LFRAME+1) = 361 through + PWINH = 540 of IVBUF. */ + ivfilt(&s->lpbuf[204], s->ivbuf, 312, LPC10_SAMPLES_PER_FRAME, ivrc); + /* eval_highres_amdf reads indices PWINL = 229 through + (PWINL-1)+MAXWIN+(TAU(LTAU)-TAU(1))/2 = 452 of IVBUF, and writes + indices 1 through LTAU = 60 of AMDF. */ + eval_highres_amdf(s->ivbuf, 156, tau, 60, amdf, &minptr, &maxptr, &mintau); + /* Voicing decisions are made for each half frame of input speech. + An initial voicing classification is made for each half of the + analysis frame, and the voicing decisions for the present frame + are finalized. See subroutine VOICIN. */ + /* The voicing detector (VOICIN) classifies the input signal as + unvoiced (including silence) or voiced using the AMDF windowed + maximum-to-minimum ratio, the zero crossing rate, energy measures, + reflection coefficients, and prediction gains. */ + /* The pitch and voicing rules apply smoothing and isolated + corrections to the pitch and voicing estimates and, in the process, + introduce two frames of delay into the corrected pitch estimates and + voicing decisions. */ + for (half = 0; half < 2; half++) + { + lpc10_voicing(s, + &s->vwin[2][0], + s->inbuf, + s->lpbuf, + buflim, + half, + &amdf[minptr], + &amdf[maxptr], + &mintau, + ivrc, + s->obound); + } + /* Find the minimum cost pitch decision over several frames, + given the current voicing decision and the AMDF array */ + minptr++; + dynamic_pitch_tracking(s, amdf, 60, &minptr, s->voibuf[3][1], pitch, &midx); + ipitch = tau[midx - 1]; + /* Place spectrum analysis and energy windows */ + lpc10_placea(&ipitch, s->voibuf, &s->obound[2], 3, s->vwin, s->awin, ewin, LPC10_SAMPLES_PER_FRAME, 156); + /* Remove short term DC bias over the analysis window. */ + lanal = s->awin[2][1] + 1 - s->awin[2][0]; + remove_dc_bias(&s->pebuf[s->awin[2][0] - 181], lanal, abuf); + /* Compute RMS over integer number of pitch periods within the analysis window. */ + /* Note that in a hardware implementation this computation may be + simplified by using diagonal elements of phi computed by mload(). */ + s->rmsbuf[2] = energyf(&abuf[ewin[2][0] - s->awin[2][0]], ewin[2][1] - ewin[2][0] + 1); + /* Matrix load and invert, check RC's for stability */ + mload(LPC10_ORDER, 1, lanal, abuf, phi, psi); + invert(LPC10_ORDER, phi, psi, &s->rcbuf[2][0]); + rcchk(LPC10_ORDER, &s->rcbuf[1][0], &s->rcbuf[2][0]); + /* Set return parameters */ + voice[0] = s->voibuf[1][0]; + voice[1] = s->voibuf[1][1]; + *rms = s->rmsbuf[0]; + for (i = 0; i < LPC10_ORDER; i++) + rc[i] = s->rcbuf[0][i]; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/lpc10_decode.c b/libs/voipcodecs/src/lpc10_decode.c new file mode 100644 index 0000000000..e58ab02047 --- /dev/null +++ b/libs/voipcodecs/src/lpc10_decode.c @@ -0,0 +1,1106 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * lpc10_decode.c - LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the U.S. Department of Defense reference + * implementation of the LPC-10 2400 bps Voice Coder. They do not + * exert copyright claims on their code, and it may be freely used. + * + * $Id: lpc10_decode.c,v 1.16 2007/11/26 13:28:59 steveu Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/lpc10.h" + +#define LPC10_ORDER 10 + +#if !defined(min) +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif +#if !defined(max) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +/* Pseudo random number generator based on Knuth, Vol 2, p. 27. */ +/* lpc10_random - int32_t variable, uniformly distributed over -32768 to 32767 */ +static int32_t lpc10_random(lpc10_decode_state_t *s) +{ + int32_t ret_val; + + /* The following is a 16 bit 2's complement addition, + with overflow checking disabled */ + s->y[s->k] += s->y[s->j]; + ret_val = s->y[s->k]; + if (--s->k < 0) + s->k = 4; + if (--s->j < 0) + s->j = 4; + return ret_val; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int32_t pow_ii(int32_t x, int32_t n) +{ + int32_t pow; + uint32_t u; + + if (n <= 0) + { + if (n == 0 || x == 1) + return 1; + if (x != -1) + return (x == 0) ? 1/x : 0; + n = -n; + } + u = n; + for (pow = 1; ; ) + { + if ((u & 1)) + pow *= x; + if ((u >>= 1) == 0) + break; + x *= x; + } + return pow; +} +/*- End of function --------------------------------------------------------*/ + +/* Synthesize one pitch epoch */ +static void bsynz(lpc10_decode_state_t *s, + float coef[], + int32_t ip, + int32_t *iv, + float sout[], + float rms, + float ratio, + float g2pass) +{ + static const int32_t kexc[25] = + { + 8, -16, 26, -48, 86, -162, 294, -502, 718, -728, 184, + 672, -610, -672, 184, 728, 718, 502, 294, 162, 86, 48, 26, 16, 8 + }; + int32_t i; + int32_t j; + int32_t k; + int32_t px; + float noise[166]; + float pulse; + float r1; + float gain; + float xssq; + float sscale; + float xy; + float sum; + float ssq; + float lpi0; + float hpi0; + + /* MAXPIT + MAXORD = 166 */ + /* Calculate history scale factor XY and scale filter state */ + /* Computing MIN */ + r1 = s->rmso_bsynz/(rms + 1.0e-6f); + xy = min(r1, 8.0f); + s->rmso_bsynz = rms; + for (i = 0; i < LPC10_ORDER; i++) + s->exc2[i] = s->exc2[s->ipo + i]*xy; + s->ipo = ip; + if (*iv == 0) + { + /* Generate white noise for unvoiced */ + for (i = 0; i < ip; i++) + s->exc[LPC10_ORDER + i] = (float) (lpc10_random(s)/64); + /* Impulse double excitation for plosives */ + px = (lpc10_random(s) + 32768)*(ip - 1)/65536 + LPC10_ORDER + 1; + r1 = ratio/4.0f; + pulse = r1*342; + if (pulse > 2.0e3f) + pulse = 2.0e3f; + s->exc[px - 1] += pulse; + s->exc[px] -= pulse; + } + else + { + sscale = sqrtf((float) ip)/6.928f; + for (i = 0; i < ip; i++) + { + s->exc[LPC10_ORDER + i] = 0.0f; + if (i < 25) + s->exc[LPC10_ORDER + i] = sscale*kexc[i]; + lpi0 = s->exc[LPC10_ORDER + i]; + s->exc[LPC10_ORDER + i] = s->exc[LPC10_ORDER + i]*0.125f + s->lpi[0]*0.75f + s->lpi[1]*0.125f; + s->lpi[1] = s->lpi[0]; + s->lpi[0] = lpi0; + } + for (i = 0; i < ip; i++) + { + noise[LPC10_ORDER + i] = lpc10_random(s)/64.0f; + hpi0 = noise[LPC10_ORDER + i]; + noise[LPC10_ORDER + i] = noise[LPC10_ORDER + i]*-0.125f + s->hpi[0]*0.25f + s->hpi[1]*-0.125f; + s->hpi[1] = s->hpi[0]; + s->hpi[0] = hpi0; + } + for (i = 0; i < ip; i++) + s->exc[LPC10_ORDER + i] += noise[LPC10_ORDER + i]; + } + /* Synthesis filters: */ + /* Modify the excitation with all-zero filter 1 + G*SUM */ + xssq = 0.0f; + for (i = 0; i < ip; i++) + { + k = LPC10_ORDER + i; + sum = 0.0f; + for (j = 0; j < LPC10_ORDER; j++) + sum += coef[j]*s->exc[k - j - 1]; + sum *= g2pass; + s->exc2[k] = sum + s->exc[k]; + } + /* Synthesize using the all pole filter 1/(1 - SUM) */ + for (i = 0; i < ip; i++) + { + k = LPC10_ORDER + i; + sum = 0.0f; + for (j = 0; j < LPC10_ORDER; j++) + sum += coef[j]*s->exc2[k - j - 1]; + s->exc2[k] = sum + s->exc2[k]; + xssq += s->exc2[k]*s->exc2[k]; + } + /* Save filter history for next epoch */ + for (i = 0; i < LPC10_ORDER; i++) + { + s->exc[i] = s->exc[ip + i]; + s->exc2[i] = s->exc2[ip + i]; + } + /* Apply gain to match RMS */ + ssq = rms*rms*ip; + gain = sqrtf(ssq/xssq); + for (i = 0; i < ip; i++) + sout[i] = gain*s->exc2[LPC10_ORDER + i]; +} +/*- End of function --------------------------------------------------------*/ + +/* Synthesize a single pitch epoch */ +static int pitsyn(lpc10_decode_state_t *s, + int voice[], + int32_t *pitch, + float *rms, + float *rc, + int32_t ivuv[], + int32_t ipiti[], + float *rmsi, + float *rci, + int32_t *nout, + float *ratio) +{ + int32_t rci_dim1; + int32_t rci_offset; + int32_t i1; + int32_t i; + int32_t j; + int32_t vflag; + int32_t jused; + int32_t lsamp; + int32_t ip; + int32_t nl; + int32_t ivoice; + int32_t istart; + float r1; + float alrn; + float alro; + float yarc[10]; + float prop; + float slope; + float uvpit; + float xxy; + + rci_dim1 = LPC10_ORDER; + rci_offset = rci_dim1 + 1; + rci -= rci_offset; + + if (*rms < 1.0f) + *rms = 1.0f; + if (s->rmso < 1.0f) + s->rmso = 1.0f; + uvpit = 0.0f; + *ratio = *rms/(s->rmso + 8.0f); + if (s->first_pitsyn) + { + lsamp = 0; + ivoice = voice[1]; + if (ivoice == 0) + *pitch = LPC10_SAMPLES_PER_FRAME/4; + *nout = LPC10_SAMPLES_PER_FRAME / *pitch; + s->jsamp = LPC10_SAMPLES_PER_FRAME - *nout * *pitch; + + i1 = *nout; + for (i = 0; i < i1; i++) + { + for (j = 0; j < LPC10_ORDER; j++) + rci[j + (i + 1)*rci_dim1 + 1] = rc[j]; + ivuv[i] = ivoice; + ipiti[i] = *pitch; + rmsi[i] = *rms; + } + s->first_pitsyn = FALSE; + } + else + { + vflag = 0; + lsamp = LPC10_SAMPLES_PER_FRAME + s->jsamp; + slope = (*pitch - s->ipito)/(float) lsamp; + *nout = 0; + jused = 0; + istart = 1; + if (voice[0] == s->ivoico && voice[1] == voice[0]) + { + if (voice[1] == 0) + { + /* SSUV - - 0 , 0 , 0 */ + *pitch = LPC10_SAMPLES_PER_FRAME/4; + s->ipito = *pitch; + if (*ratio > 8.0f) + s->rmso = *rms; + } + /* SSVC - - 1 , 1 , 1 */ + slope = (*pitch - s->ipito)/(float) lsamp; + ivoice = voice[1]; + } + else + { + if (s->ivoico != 1) + { + if (s->ivoico == voice[0]) + { + /* UV2VC2 - - 0 , 0 , 1 */ + nl = lsamp - LPC10_SAMPLES_PER_FRAME/4; + } + else + { + /* UV2VC1 - - 0 , 1 , 1 */ + nl = lsamp - LPC10_SAMPLES_PER_FRAME*3/4; + } + ipiti[0] = nl/2; + ipiti[1] = nl - ipiti[0]; + ivuv[0] = 0; + ivuv[1] = 0; + rmsi[0] = s->rmso; + rmsi[1] = s->rmso; + for (i = 0; i < LPC10_ORDER; i++) + { + rci[i + rci_dim1 + 1] = s->rco[i]; + rci[i + (rci_dim1 << 1) + 1] = s->rco[i]; + s->rco[i] = rc[i]; + } + slope = 0.0f; + *nout = 2; + s->ipito = *pitch; + jused = nl; + istart = nl + 1; + ivoice = 1; + } + else + { + if (s->ivoico != voice[0]) + { + /* VC2UV1 - - 1 , 0 , 0 */ + lsamp = LPC10_SAMPLES_PER_FRAME/4 + s->jsamp; + } + else + { + /* VC2UV2 - - 1 , 1 , 0 */ + lsamp = LPC10_SAMPLES_PER_FRAME*3/4 + s->jsamp; + } + for (i = 0; i < LPC10_ORDER; i++) + { + yarc[i] = rc[i]; + rc[i] = s->rco[i]; + } + ivoice = 1; + slope = 0.0f; + vflag = 1; + } + } + /* Here is the value of most variables that are used below, depending on */ + /* the values of IVOICO, VOICE(1), and VOICE(2). VOICE(1) and VOICE(2) */ + /* are input arguments, and IVOICO is the value of VOICE(2) on the */ + /* previous call (see notes for the IF (NOUT .NE. 0) statement near the */ + /* end). Each of these three values is either 0 or 1. These three */ + /* values below are given as 3-bit long strings, in the order IVOICO, */ + /* VOICE(1), and VOICE(2). It appears that the code above assumes that */ + /* the bit sequences 010 and 101 never occur, but I wonder whether a */ + /* large enough number of bit errors in the channel could cause such a */ + /* thing to happen, and if so, could that cause NOUT to ever go over 11? */ + + /* Note that all of the 180 values in the table are floatly LFRAME, but */ + /* 180 has fewer characters, and it makes the table a little more */ + /* concrete. If LFRAME is ever changed, keep this in mind. Similarly, */ + /* 135's are 3*LFRAME/4, and 45's are LFRAME/4. If LFRAME is not a */ + /* multiple of 4, then the 135 for NL-JSAMP is actually LFRAME-LFRAME/4, */ + /* and the 45 for NL-JSAMP is actually LFRAME-3*LFRAME/4. */ + + /* Note that LSAMP-JSAMP is given as the variable. This was just for */ + /* brevity, to avoid adding "+JSAMP" to all of the column entries. */ + /* Similarly for NL-JSAMP. */ + + /* Variable | 000 001 011,010 111 110 100,101 */ + /* ------------+-------------------------------------------------- */ + /* ISTART | 1 NL+1 NL+1 1 1 1 */ + /* LSAMP-JSAMP | 180 180 180 180 135 45 */ + /* IPITO | 45 PITCH PITCH oldPITCH oldPITCH oldPITCH */ + /* SLOPE | 0 0 0 seebelow 0 0 */ + /* JUSED | 0 NL NL 0 0 0 */ + /* PITCH | 45 PITCH PITCH PITCH PITCH PITCH */ + /* NL-JSAMP | -- 135 45 -- -- -- */ + /* VFLAG | 0 0 0 0 1 1 */ + /* NOUT | 0 2 2 0 0 0 */ + /* IVOICE | 0 1 1 1 1 1 */ + + /* while_loop | once once once once twice twice */ + + /* ISTART | -- -- -- -- JUSED+1 JUSED+1 */ + /* LSAMP-JSAMP | -- -- -- -- 180 180 */ + /* IPITO | -- -- -- -- oldPITCH oldPITCH */ + /* SLOPE | -- -- -- -- 0 0 */ + /* JUSED | -- -- -- -- ?? ?? */ + /* PITCH | -- -- -- -- PITCH PITCH */ + /* NL-JSAMP | -- -- -- -- -- -- */ + /* VFLAG | -- -- -- -- 0 0 */ + /* NOUT | -- -- -- -- ?? ?? */ + /* IVOICE | -- -- -- -- 0 0 */ + + /* UVPIT is always 0.0 on the first pass through the DO WHILE (TRUE) + loop below. */ + + /* The only possible non-0 value of SLOPE (in column 111) is + (PITCH-IPITO)/FLOAT(LSAMP) */ + + /* Column 101 is identical to 100. Any good properties we can prove + for 100 will also hold for 101. Similarly for 010 and 011. */ + + /* synths() calls this subroutine with PITCH restricted to the range 20 to + 156. IPITO is similarly restricted to this range, after the first + call. IP below is also restricted to this range, given the + definitions of IPITO, SLOPE, UVPIT, and that I is in the range ISTART + to LSAMP. */ + + for (;;) + { + for (i = istart; i <= lsamp; i++) + { + r1 = s->ipito + slope*i; + ip = (int32_t) (r1 + 0.5f); + if (uvpit != 0.0f) + ip = (int32_t) uvpit; + if (ip <= i - jused) + { + ++(*nout); + ipiti[*nout - 1] = ip; + *pitch = ip; + ivuv[*nout - 1] = ivoice; + jused += ip; + prop = (jused - ip/2)/(float) lsamp; + for (j = 0; j < LPC10_ORDER; j++) + { + alro = logf((s->rco[j] + 1)/(1 - s->rco[j])); + alrn = logf((rc[j] + 1)/(1 - rc[j])); + xxy = alro + prop*(alrn - alro); + xxy = expf(xxy); + rci[j + *nout*rci_dim1 + 1] = (xxy - 1.0f)/(xxy + 1.0f); + } + rmsi[*nout - 1] = logf(s->rmso) + prop*(logf(*rms) - logf(s->rmso)); + rmsi[*nout - 1] = expf(rmsi[*nout - 1]); + } + } + if (vflag != 1) + break; + + vflag = 0; + istart = jused + 1; + lsamp = LPC10_SAMPLES_PER_FRAME + s->jsamp; + slope = 0.0f; + ivoice = 0; + uvpit = (float) ((lsamp - istart)/2); + if (uvpit > 90.0f) + uvpit /= 2; + s->rmso = *rms; + for (i = 0; i < LPC10_ORDER; i++) + { + rc[i] = yarc[i]; + s->rco[i] = yarc[i]; + } + } + s->jsamp = lsamp - jused; + } + if (*nout != 0) + { + s->ivoico = voice[1]; + s->ipito = *pitch; + s->rmso = *rms; + for (i = 0; i < LPC10_ORDER; i++) + s->rco[i] = rc[i]; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static void deemp(lpc10_decode_state_t *s, float x[], int len) +{ + int i; + float r1; + float dei0; + + for (i = 0; i < len; i++) + { + dei0 = x[i]; + r1 = x[i] - s->dei[0]*1.9998f + s->dei[1]; + x[i] = r1 + s->deo[0]*2.5f - s->deo[1]*2.0925f + s->deo[2]*0.585f; + s->dei[1] = s->dei[0]; + s->dei[0] = dei0; + s->deo[2] = s->deo[1]; + s->deo[1] = s->deo[0]; + s->deo[0] = x[i]; + } +} +/*- End of function --------------------------------------------------------*/ + +/* Convert reflection coefficients to predictor coefficients */ +static float reflection_coeffs_to_predictor_coeffs(float rc[], float pc[], float gprime) +{ + float temp[10]; + float g2pass; + int i; + int j; + + g2pass = 1.0f; + for (i = 0; i < LPC10_ORDER; i++) + g2pass *= 1.0f - rc[i]*rc[i]; + g2pass = gprime*sqrtf(g2pass); + pc[0] = rc[0]; + for (i = 1; i < LPC10_ORDER; i++) + { + for (j = 0; j < i; j++) + temp[j] = pc[j] - rc[i]*pc[i - j - 1]; + for (j = 0; j < i; j++) + pc[j] = temp[j]; + pc[i] = rc[i]; + } + return g2pass; +} +/*- End of function --------------------------------------------------------*/ + +static int synths(lpc10_decode_state_t *s, + int voice[], + int32_t *pitch, + float *rms, + float *rc, + float speech[]) +{ + int32_t i1; + int32_t ivuv[16]; + int32_t ipiti[16]; + int32_t nout; + int32_t i; + int32_t j; + float rmsi[16]; + float ratio; + float g2pass; + float pc[10]; + float rci[160]; + + i1 = min(*pitch, 156); + *pitch = max(i1, 20); + for (i = 0; i < LPC10_ORDER; i++) + rc[i] = max(min(rc[i], 0.99f), -0.99f); + pitsyn(s, voice, pitch, rms, rc, ivuv, ipiti, rmsi, rci, &nout, &ratio); + if (nout > 0) + { + for (j = 0; j < nout; j++) + { + /* Add synthesized speech for pitch period J to the end of s->buf. */ + g2pass = reflection_coeffs_to_predictor_coeffs(&rci[j*10], pc, 0.7f); + bsynz(s, pc, ipiti[j], &ivuv[j], &s->buf[s->buflen], rmsi[j], ratio, g2pass); + deemp(s, &s->buf[s->buflen], ipiti[j]); + s->buflen += ipiti[j]; + } + /* Copy first MAXFRM samples from BUF to output array speech (scaling them), + and then remove them from the beginning of s->buf. */ + + for (i = 0; i < LPC10_SAMPLES_PER_FRAME; i++) + speech[i] = s->buf[i]/4096.0f; + s->buflen -= LPC10_SAMPLES_PER_FRAME; + for (i = 0; i < s->buflen; i++) + s->buf[i] = s->buf[i + LPC10_SAMPLES_PER_FRAME]; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static void lpc10_unpack(lpc10_frame_t *t, const uint8_t ibits[]) +{ + static const int bit[10] = + { + 2, 4, 8, 8, 8, 8, 16, 16, 16, 16 + }; + static const int iblist[53] = + { + 13, 12, 11, 1, 2, 13, 12, 11, 1, 2, + 13, 10, 11, 2, 1, 10, 13, 12, 11, 10, + 2, 13, 12, 11, 10, 2, 1, 12, 7, 6, + 1, 10, 9, 8, 7, 4, 6, 9, 8, 7, + 5, 1, 9, 8, 4, 6, 1, 5, 9, 8, + 7, 5, 6 + }; + int32_t itab[13]; + int x; + int i; + + /* ibits is 54 bits of LPC data ordered as follows: */ + /* R1-0, R2-0, R3-0, P-0, A-0, */ + /* R1-1, R2-1, R3-1, P-1, A-1, */ + /* R1-2, R4-0, R3-2, A-2, P-2, R4-1, */ + /* R1-3, R2-2, R3-3, R4-2, A-3, */ + /* R1-4, R2-3, R3-4, R4-3, A-4, */ + /* P-3, R2-4, R7-0, R8-0, P-4, R4-4, */ + /* R5-0, R6-0, R7-1,R10-0, R8-1, */ + /* R5-1, R6-1, R7-2, R9-0, P-5, */ + /* R5-2, R6-2,R10-1, R8-2, P-6, R9-1, */ + /* R5-3, R6-3, R7-3, R9-2, R8-3, SYNC */ + + /* Reconstruct ITAB */ + for (i = 0; i < 13; i++) + itab[i] = 0; + for (i = 0; i < 53; i++) + { + x = 52 - i; + x = (ibits[x >> 3] >> (7 - (x & 7))) & 1; + itab[iblist[52 - i] - 1] = (itab[iblist[52 - i] - 1] << 1) | x; + } + /* Sign extend the RC's */ + for (i = 0; i < LPC10_ORDER; i++) + { + if ((itab[i + 3] & bit[i])) + itab[i + 3] -= (bit[i] << 1); + } + /* Restore variables */ + t->ipitch = itab[0]; + t->irms = itab[1]; + for (i = 0; i < LPC10_ORDER; i++) + t->irc[i] = itab[LPC10_ORDER - 1 - i + 3]; +} +/*- End of function --------------------------------------------------------*/ + +/* Hamming 8, 4 decoder - can correct 1 out of seven bits + and can detect up to two errors. */ + +/* This subroutine is entered with an eight bit word in INPUT. The 8th */ +/* bit is parity and is stripped off. The remaining 7 bits address the */ +/* hamming 8, 4 table and the output OUTPUT from the table gives the 4 */ +/* bits of corrected data. If bit 4 is set, no error was detected. */ +/* ERRCNT is the number of errors counted. */ + +static int32_t hamming_84_decode(int32_t input, int *errcnt) +{ + static const uint8_t dactab[128] = + { + 16, 0, 0, 3, 0, 5, 14, 7, 0, 9, 14, 11, 14, 13, 30, 14, + 0, 9, 2, 7, 4, 7, 7, 23, 9, 25, 10, 9, 12, 9, 14, 7, + 0, 5, 2, 11, 5, 21, 6, 5, 8, 11, 11, 27, 12, 5, 14, 11, + 2, 1, 18, 2, 12, 5, 2, 7, 12, 9, 2, 11, 28, 12, 12, 15, + 0, 3, 3, 19, 4, 13, 6, 3, 8, 13, 10, 3, 13, 29, 14, 13, + 4, 1, 10, 3, 20, 4, 4, 7, 10, 9, 26, 10, 4, 13, 10, 15, + 8, 1, 6, 3, 6, 5, 22, 6, 24, 8, 8, 11, 8, 13, 6, 15, + 1, 17 , 2, 1, 4, 1, 6, 15, 8, 1, 10, 15, 12, 15, 15, 31 + }; + int i; + int parity; + int32_t output; + + parity = input & 255; + parity ^= parity >> 4; + parity ^= parity >> 2; + parity ^= parity >> 1; + parity &= 1; + i = dactab[input & 127]; + output = i & 15; + if ((i & 16)) + { + /* No errors detected in seven bits */ + if (parity) + (*errcnt)++; + } + else + { + /* One or two errors detected */ + (*errcnt)++; + if (parity == 0) + { + /* Two errors detected */ + (*errcnt)++; + output = -1; + } + } + return output; +} +/*- End of function --------------------------------------------------------*/ + +static int32_t median(int32_t d1, int32_t d2, int32_t d3) +{ + int32_t ret_val; + + ret_val = d2; + if (d2 > d1 && d2 > d3) + { + ret_val = d1; + if (d3 > d1) + ret_val = d3; + } + else if (d2 < d1 && d2 < d3) + { + ret_val = d1; + if (d3 < d1) + ret_val = d3; + } + return ret_val; +} +/*- End of function --------------------------------------------------------*/ + +static void decode(lpc10_decode_state_t *s, + lpc10_frame_t *t, + int voice[], + int32_t *pitch, + float *rms, + float rc[]) +{ + static const int32_t ivtab[32] = + { + 24960, 24960, 24960, 24960, 25480, 25480, 25483, 25480, + 16640, 1560, 1560, 1560, 16640, 1816, 1563, 1560, + 24960, 24960, 24859, 24856, 26001, 25881, 25915, 25913, + 1560, 1560, 7800, 3640, 1561, 1561, 3643, 3641 + }; + static const float corth[32] = + { + 32767.0f, 10.0f, 5.0f, 0.0f, 32767.0f, 8.0f, 4.0f, 0.0f, + 32.0f, 6.4f, 3.2f, 0.0f, 32.0f, 6.4f, 3.2f, 0.0f, + 32.0f, 11.2f, 6.4f, 0.0f, 32.0f, 11.2f, 6.4f, 0.0f, + 16.0f, 5.6f, 3.2f, 0.0f, 16.0f, 5.6f, 3.2f, 0.0f + }; + static const int32_t detau[128] = + { + 0, 0, 0, 3, 0, 3, 3, 31, + 0, 3, 3, 21, 3, 3, 29, 30, + 0, 3, 3, 20, 3, 25, 27, 26, + 3, 23, 58, 22, 3, 24, 28, 3, + 0, 3, 3, 3, 3, 39, 33, 32, + 3, 37, 35, 36, 3, 38, 34, 3, + 3, 42, 46, 44, 50, 40, 48, 3, + 54, 3, 56, 3, 52, 3, 3, 1, + 0, 3, 3, 108, 3, 78, 100, 104, + 3, 84, 92, 88, 156, 80, 96, 3, + 3, 74, 70, 72, 66, 76, 68, 3, + 62, 3, 60, 3, 64, 3, 3, 1, + 3, 116, 132, 112, 148, 152, 3, 3, + 140, 3, 136, 3, 144, 3, 3, 1, + 124, 120, 128, 3, 3, 3, 3, 1, + 3, 3, 3, 1, 3, 1, 1, 1 + }; + static const int32_t rmst[64] = + { + 1024, 936, 856, 784, 718, 656, 600, 550, + 502, 460, 420, 384, 352, 328, 294, 270, + 246, 226, 206, 188, 172, 158, 144, 132, + 120, 110, 102, 92, 84, 78, 70, 64, + 60, 54, 50, 46, 42, 38, 34, 32, + 30, 26, 24, 22, 20, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0 + }; + static const int32_t detab7[32] = + { + 4, 11, 18, 25, 32, 39, 46, 53, + 60, 66, 72, 77, 82, 87, 92, 96, + 101, 104, 108, 111, 114, 115, 117, 119, + 121, 122, 123, 124, 125, 126, 127, 127 + }; + static const float descl[8] = + { + 0.6953f, 0.625f, 0.5781f, 0.5469f, 0.5312f, 0.5391f, 0.4688f, 0.3828f + }; + static const int32_t deadd[8] = + { + 1152, -2816, -1536, -3584, -1280, -2432, 768, -1920 + }; + static const int32_t qb[8] = + { + 511, 511, 1023, 1023, 1023, 1023, 2047, 4095 + }; + static const int32_t nbit[10] = + { + 8, 8, 5, 5, 4, 4, 4, 4, 3, 2 + }; + static const int32_t zrc[10] = + { + 0, 0, 0, 0, 0, 3, 0, 2, 0, 0 + }; + static const int32_t bit[5] = + { + 2, 4, 8, 16, 32 + }; + int32_t ipit; + int32_t iout; + int32_t i; + int32_t icorf; + int32_t index; + int32_t ivoic; + int32_t ixcor; + int32_t i1; + int32_t i2; + int32_t i4; + int32_t ishift; + int32_t lsb; + int errcnt; + + /* If no error correction, do pitch and voicing then jump to decode */ + i4 = detau[t->ipitch]; + if (!s->error_correction) + { + voice[0] = 1; + voice[1] = 1; + if (t->ipitch <= 1) + voice[0] = 0; + if (t->ipitch == 0 || t->ipitch == 2) + voice[1] = 0; + if (i4 <= 4) + i4 = s->iptold; + *pitch = i4; + if (voice[0] == 1 && voice[1] == 1) + s->iptold = *pitch; + if (voice[0] != voice[1]) + *pitch = s->iptold; + } + else + { + /* Do error correction pitch and voicing */ + if (i4 > 4) + { + s->dpit[0] = i4; + ivoic = 2; + s->iavgp = (s->iavgp*15 + i4 + 8)/16; + } + else + { + s->dpit[0] = s->iavgp; + ivoic = i4; + } + s->drms[0] = t->irms; + for (i = 0; i < LPC10_ORDER; i++) + s->drc[i][0] = t->irc[i]; + /* Determine index to IVTAB from V/UV decision */ + /* If error rate is high then use alternate table */ + index = (s->ivp2h << 4) + (s->iovoic << 2) + ivoic + 1; + i1 = ivtab[index - 1]; + ipit = i1 & 3; + icorf = i1 >> 3; + if (s->erate < 2048) + icorf /= 64; + /* Determine error rate: 4=high 1=low */ + ixcor = 4; + if (s->erate < 2048) + ixcor = 3; + if (s->erate < 1024) + ixcor = 2; + if (s->erate < 128) + ixcor = 1; + /* Voice/unvoice decision determined from bits 0 and 1 of IVTAB */ + voice[0] = icorf/2 & 1; + voice[1] = icorf & 1; + /* Skip decoding on first frame because present data not yet available */ + if (s->first) + { + s->first = FALSE; + /* Assign PITCH a "default" value on the first call, since */ + /* otherwise it would be left uninitialized. The two lines */ + /* below were copied from above, since it seemed like a */ + /* reasonable thing to do for the first call. */ + if (i4 <= 4) + i4 = s->iptold; + *pitch = i4; + } + else + { + /* If bit 4 of ICORF is set then correct RMS and RC(1) - RC(4). */ + /* Determine error rate and correct errors using a Hamming 8,4 code */ + /* during transition of unvoiced frames. If IOUT is negative, */ + /* more than 1 error occurred, use previous frame's parameters. */ + if ((icorf & bit[3]) != 0) + { + errcnt = 0; + lsb = s->drms[1] & 1; + index = (s->drc[7][1] << 4) + s->drms[1]/2; + iout = hamming_84_decode(index, &errcnt); + s->drms[1] = s->drms[2]; + if (iout >= 0) + s->drms[1] = (iout << 1) + lsb; + for (i = 1; i <= 4; i++) + { + if (i == 1) + i1 = ((s->drc[8][1] & 7) << 1) + (s->drc[9][1] & 1); + else + i1 = s->drc[8 - i][1] & 15; + i2 = s->drc[4 - i][1] & 31; + lsb = i2 & 1; + index = (i1 << 4) + (i2 >> 1); + iout = hamming_84_decode(index, &errcnt); + if (iout >= 0) + { + iout = (iout << 1) + lsb; + if ((iout & 16) == 16) + iout -= 32; + } + else + { + iout = s->drc[4 - i][2]; + } + s->drc[4 - i][1] = iout; + } + /* Determine error rate */ + s->erate = (int32_t) (s->erate*0.96875f + errcnt*102.0f); + } + /* Get unsmoothed RMS, RC's, and PITCH */ + t->irms = s->drms[1]; + for (i = 0; i < LPC10_ORDER; i++) + t->irc[i] = s->drc[i][1]; + if (ipit == 1) + s->dpit[1] = s->dpit[2]; + if (ipit == 3) + s->dpit[1] = s->dpit[0]; + *pitch = s->dpit[1]; + /* If bit 2 of ICORF is set then smooth RMS and RC's, */ + if ((icorf & bit[1]) != 0) + { + if ((float) abs(s->drms[1] - s->drms[0]) >= corth[ixcor + 3] + && + (float) abs(s->drms[1] - s->drms[2]) >= corth[ixcor + 3]) + { + t->irms = median(s->drms[2], s->drms[1], s->drms[0]); + } + for (i = 0; i < 6; i++) + { + if ((float) abs(s->drc[i][1] - s->drc[i][0]) >= corth[ixcor + ((i + 3) << 2) - 5] + && + (float) abs(s->drc[i][1] - s->drc[i][2]) >= corth[ixcor + ((i + 3) << 2) - 5]) + { + t->irc[i] = median(s->drc[i][2], s->drc[i][1], s->drc[i][0]); + } + } + } + /* If bit 3 of ICORF is set then smooth pitch */ + if ((icorf & bit[2]) != 0) + { + if ((float) abs(s->dpit[1] - s->dpit[0]) >= corth[ixcor - 1] + && + (float) abs(s->dpit[1] - s->dpit[2]) >= corth[ixcor - 1]) + { + *pitch = median(s->dpit[2], s->dpit[1], s->dpit[0]); + } + } + /* If bit 5 of ICORF is set then RC(5) - RC(10) are loaded with + values so that after quantization bias is removed in decode + the values will be zero. */ + } + if ((icorf & bit[4]) != 0) + { + for (i = 4; i < LPC10_ORDER; i++) + t->irc[i] = zrc[i]; + } + /* Housekeeping - one frame delay */ + s->iovoic = ivoic; + s->ivp2h = voice[1]; + s->dpit[2] = s->dpit[1]; + s->dpit[1] = s->dpit[0]; + s->drms[2] = s->drms[1]; + s->drms[1] = s->drms[0]; + for (i = 0; i < LPC10_ORDER; i++) + { + s->drc[i][2] = s->drc[i][1]; + s->drc[i][1] = s->drc[i][0]; + } + } + /* Decode RMS */ + t->irms = rmst[(31 - t->irms)*2]; + /* Decode RC(1) and RC(2) from log-area-ratios */ + /* Protect from illegal coded value (-16) caused by bit errors */ + for (i = 0; i < 2; i++) + { + i2 = t->irc[i]; + i1 = 0; + if (i2 < 0) + { + i1 = 1; + i2 = -i2; + if (i2 > 15) + i2 = 0; + } + i2 = detab7[i2*2]; + if (i1 == 1) + i2 = -i2; + ishift = 15 - nbit[i]; + t->irc[i] = i2*pow_ii(2, ishift); + } + /* Decode RC(3)-RC(10) to sign plus 14 bits */ + for (i = 2; i < LPC10_ORDER; i++) + { + ishift = 15 - nbit[i]; + i2 = t->irc[i]*pow_ii(2, ishift) + qb[i - 2]; + t->irc[i] = (int32_t) (i2*descl[i - 2] + deadd[i - 2]); + } + /* Scale RMS and RC's to floats */ + *rms = (float) t->irms; + for (i = 0; i < LPC10_ORDER; i++) + rc[i] = t->irc[i]/16384.0f; +} +/*- End of function --------------------------------------------------------*/ + +lpc10_decode_state_t *lpc10_decode_init(lpc10_decode_state_t *s, int error_correction) +{ + static const int16_t rand_init[] = + { + -21161, + -8478, + 30892, + -10216, + 16950 + }; + int i; + int j; + + if (s == NULL) + { + if ((s = (lpc10_decode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + + s->error_correction = error_correction; + + /* State used by function decode */ + s->iptold = 60; + s->first = TRUE; + s->ivp2h = 0; + s->iovoic = 0; + s->iavgp = 60; + s->erate = 0; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 10; j++) + s->drc[j][i] = 0; + s->dpit[i] = 0; + s->drms[i] = 0; + } + + /* State used by function synths */ + for (i = 0; i < 360; i++) + s->buf[i] = 0.0f; + s->buflen = LPC10_SAMPLES_PER_FRAME; + + /* State used by function pitsyn */ + s->rmso = 1.0f; + s->first_pitsyn = TRUE; + + /* State used by function bsynz */ + s->ipo = 0; + for (i = 0; i < 166; i++) + { + s->exc[i] = 0.0f; + s->exc2[i] = 0.0f; + } + for (i = 0; i < 3; i++) + { + s->lpi[i] = 0.0f; + s->hpi[i] = 0.0f; + } + s->rmso_bsynz = 0.0f; + + /* State used by function lpc10_random */ + s->j = 1; + s->k = 4; + for (i = 0; i < 5; i++) + s->y[i] = rand_init[i]; + + /* State used by function deemp */ + for (i = 0; i < 2; i++) + s->dei[i] = 0.0f; + for (i = 0; i < 3; i++) + s->deo[i] = 0.0f; + + return s; +} +/*- End of function --------------------------------------------------------*/ + +int lpc10_decode_release(lpc10_decode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int lpc10_decode(lpc10_decode_state_t *s, int16_t amp[], const uint8_t code[], int quant) +{ + int voice[2]; + int32_t pitch; + float speech[LPC10_SAMPLES_PER_FRAME]; + float rc[LPC10_ORDER]; + lpc10_frame_t frame; + float rms; + int i; + int j; + + /* Decode 54 bits to LPC10_SAMPLES_PER_FRAME speech samples. */ + for (i = 0; i < quant; i++) + { + lpc10_unpack(&frame, &code[i*7]); + decode(s, &frame, voice, &pitch, &rms, rc); + synths(s, voice, &pitch, &rms, rc, speech); + for (j = 0; j < LPC10_SAMPLES_PER_FRAME; j++) + amp[i*LPC10_SAMPLES_PER_FRAME + j] = (int16_t) rintf(32768.0f*speech[j]); + } + + return quant*LPC10_SAMPLES_PER_FRAME; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/lpc10_encdecs.h b/libs/voipcodecs/src/lpc10_encdecs.h new file mode 100644 index 0000000000..836e570ee3 --- /dev/null +++ b/libs/voipcodecs/src/lpc10_encdecs.h @@ -0,0 +1,107 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * lpc10_encdecs.h - LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: lpc10_encdecs.h,v 1.9 2006/11/30 15:41:47 steveu Exp $ + */ + +#define LPC10_ORDER 10 + +#if !defined(min) +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif +#if !defined(max) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +void lpc10_placea(int32_t *ipitch, + int32_t voibuf[4][2], + int32_t *obound, + int32_t af, + int32_t vwin[3][2], + int32_t awin[3][2], + int32_t ewin[3][2], + int32_t lframe, + int32_t maxwin); + +void lpc10_placev(int32_t *osbuf, + int32_t *osptr, + int32_t oslen, + int32_t *obound, + int32_t vwin[3][2], + int32_t af, + int32_t lframe, + int32_t minwin, + int32_t maxwin, + int32_t dvwinl, + int32_t dvwinh); + +void lpc10_voicing(lpc10_encode_state_t *st, + int32_t *vwin, + float *inbuf, + float *lpbuf, + const int32_t buflim[], + int32_t half, + float *minamd, + float *maxamd, + int32_t *mintau, + float *ivrc, + int32_t *obound); + +void lpc10_analyse(lpc10_encode_state_t *st, float *speech, int32_t *voice, int32_t *pitch, float *rms, float rc[]); + +static __inline__ int32_t pow_ii(int32_t x, int32_t n) +{ + int32_t pow; + uint32_t u; + + if (n <= 0) + { + if (n == 0 || x == 1) + return 1; + if (x != -1) + return (x == 0) ? 1/x : 0; + n = -n; + } + u = n; + for (pow = 1; ; ) + { + if ((u & 1)) + pow *= x; + if ((u >>= 1) == 0) + break; + x *= x; + } + return pow; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ float r_sign(float a, float b) +{ + float x; + + x = fabsf(a); + return (b >= 0.0f) ? x : -x; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/lpc10_encode.c b/libs/voipcodecs/src/lpc10_encode.c new file mode 100644 index 0000000000..83a15eb428 --- /dev/null +++ b/libs/voipcodecs/src/lpc10_encode.c @@ -0,0 +1,394 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * lpc10_encode.c - LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the U.S. Department of Defense reference + * implementation of the LPC-10 2400 bps Voice Coder. They do not + * exert copyright claims on their code, and it may be freely used. + * + * $Id: lpc10_encode.c,v 1.17 2007/11/26 13:28:59 steveu Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/lpc10.h" + +#include "lpc10_encdecs.h" + +static void lpc10_pack(lpc10_encode_state_t *s, uint8_t ibits[], lpc10_frame_t *t) +{ + static const int iblist[53] = + { + 13, 12, 11, 1, 2, 13, 12, 11, 1, 2, + 13, 10, 11, 2, 1, 10, 13, 12, 11, 10, + 2, 13, 12, 11, 10, 2, 1, 12, 7, 6, + 1, 10, 9, 8, 7, 4, 6, 9, 8, 7, + 5, 1, 9, 8, 4, 6, 1, 5, 9, 8, + 7, 5, 6 + }; + int32_t itab[13]; + int x; + int i; + + /* ibits is 54 bits of LPC data ordered as follows: */ + /* R1-0, R2-0, R3-0, P-0, A-0, */ + /* R1-1, R2-1, R3-1, P-1, A-1, */ + /* R1-2, R4-0, R3-2, A-2, P-2, R4-1, */ + /* R1-3, R2-2, R3-3, R4-2, A-3, */ + /* R1-4, R2-3, R3-4, R4-3, A-4, */ + /* P-3, R2-4, R7-0, R8-0, P-4, R4-4, */ + /* R5-0, R6-0, R7-1,R10-0, R8-1, */ + /* R5-1, R6-1, R7-2, R9-0, P-5, */ + /* R5-2, R6-2,R10-1, R8-2, P-6, R9-1, */ + /* R5-3, R6-3, R7-3, R9-2, R8-3, SYNC */ + + itab[0] = t->ipitch; + itab[1] = t->irms; + itab[2] = 0; + for (i = 0; i < LPC10_ORDER; i++) + itab[i + 3] = t->irc[LPC10_ORDER - 1 - i] & 0x7FFF; + /* Put 54 bits into the output buffer */ + x = 0; + for (i = 0; i < 53; i++) + { + x = (x << 1) | (itab[iblist[i] - 1] & 1); + if ((i & 7) == 7) + ibits[i >> 3] = (uint8_t) (x & 0xFF); + itab[iblist[i] - 1] >>= 1; + } + x = (x << 1) | (s->isync & 1); + s->isync ^= 1; + x <<= 2; + ibits[6] = (uint8_t) (x & 0xFF); +} +/*- End of function --------------------------------------------------------*/ + +/* Quantize LPC parameters for transmission */ +static int encode(lpc10_encode_state_t *s, + lpc10_frame_t *t, + int32_t *voice, + int32_t pitch, + float rms, + float *rc) +{ + static const int32_t enctab[16] = + { + 0, 7, 11, 12, 13, 10, 6, 1, 14, 9, 5, 2, 3, 4, 8, 15 + }; + static const int32_t entau[60] = + { + 19, 11, 27, 25, 29, 21, 23, 22, 30, 14, 15, 7, 39, 38, 46, + 42, 43, 41, 45, 37, 53, 49, 51, 50, 54, 52, 60, 56, 58, 26, + 90, 88, 92, 84, 86, 82, 83, 81, 85, 69, 77, 73, 75, 74, 78, + 70, 71, 67, 99, 97, 113, 112, 114, 98, 106, 104, 108, 100, + 101, 76 + }; + static const int32_t enadd[8] = + { + 1920, -768, 2432, 1280, 3584, 1536, 2816, -1152 + }; + static const float enscl[8] = + { + 0.0204f, 0.0167f, 0.0145f, 0.0147f, 0.0143f, 0.0135f, 0.0125f, 0.0112f + }; + static const int32_t enbits[8] = + { + 6, 5, 4, 4, 4, 4, 3, 3 + }; + static const int32_t entab6[64] = + { + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 13, 14, 15 + }; + static const int32_t rmst[64] = + { + 1024, 936, 856, 784, 718, 656, 600, 550, 502, + 460, 420, 384, 352, 328, 294, 270, 246, 226, + 206, 188, 172, 158, 144, 132, 120, 110, 102, + 92, 84, 78, 70, 64, 60, 54, 50, + 46, 42, 38, 34, 32, 30, 26, 24, + 22, 20, 18, 17, 16, 15, 14, 13, + 12, 11, 10, 9, 8, 7, 6, 5, 4, + 3, 2, 1, 0 + }; + + int32_t idel; + int32_t nbit; + int32_t i; + int32_t j; + int32_t i2; + int32_t i3; + int32_t mrk; + + /* Scale RMS and RC's to int32_ts */ + t->irms = (int32_t) rms; + for (i = 0; i < LPC10_ORDER; i++) + t->irc[i] = (int32_t) (rc[i]*32768.0f); + if (voice[0] != 0 && voice[1] != 0) + { + t->ipitch = entau[pitch - 1]; + } + else + { + if (s->error_correction) + { + t->ipitch = 0; + if (voice[0] != voice[1]) + t->ipitch = 127; + } + else + { + t->ipitch = (voice[0] << 1) + voice[1]; + } + } + /* Encode RMS by binary table search */ + j = 32; + idel = 16; + t->irms = min(t->irms, 1023); + while (idel > 0) + { + if (t->irms > rmst[j - 1]) + j -= idel; + if (t->irms < rmst[j - 1]) + j += idel; + idel /= 2; + } + if (t->irms > rmst[j - 1]) + --j; + t->irms = 31 - j/2; + /* Encode RC(1) and (2) as log-area-ratios */ + for (i = 0; i < 2; i++) + { + i2 = t->irc[i]; + mrk = 0; + if (i2 < 0) + { + i2 = -i2; + mrk = 1; + } + i2 = min(i2/512, 63); + i2 = entab6[i2]; + if (mrk != 0) + i2 = -i2; + t->irc[i] = i2; + } + /* Encode RC(3) - (10) linearly, remove bias then scale */ + for (i = 2; i < LPC10_ORDER; i++) + { + i2 = (int32_t) ((t->irc[i]/2 + enadd[LPC10_ORDER - 1 - i])*enscl[LPC10_ORDER - 1 - i]); + i2 = max(i2, -127); + i2 = min(i2, 127); + nbit = enbits[LPC10_ORDER - 1 - i]; + i3 = (i2 < 0); + i2 /= pow_ii(2, nbit); + if (i3) + i2--; + t->irc[i] = i2; + } + /* Protect the most significant bits of the most + important parameters during non-voiced frames. + RC(1) - RC(4) are protected using 20 parity bits + replacing RC(5) - RC(10). */ + if (s->error_correction) + { + if (t->ipitch == 0 || t->ipitch == 127) + { + t->irc[4] = enctab[(t->irc[0] & 0x1E) >> 1]; + t->irc[5] = enctab[(t->irc[1] & 0x1E) >> 1]; + t->irc[6] = enctab[(t->irc[2] & 0x1E) >> 1]; + t->irc[7] = enctab[(t->irms & 0x1E) >> 1]; + t->irc[8] = enctab[(t->irc[3] & 0x1E) >> 1] >> 1; + t->irc[9] = enctab[(t->irc[3] & 0x1E) >> 1] & 1; + } + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static void high_pass_100hz(lpc10_encode_state_t *s, float speech[], int start, int len) +{ + float si; + float err; + int i; + + /* 100 Hz high pass filter */ + for (i = start; i < len; i++) + { + si = speech[i]; + err = si + s->z11*1.859076f - s->z21*0.8648249f; + si = err - s->z11*2.0f + s->z21; + s->z21 = s->z11; + s->z11 = err; + err = si + s->z12*1.935715f - s->z22*0.9417004f; + si = err - s->z12*2.0f + s->z22; + s->z22 = s->z12; + s->z12 = err; + speech[i] = si*0.902428f; + } +} +/*- End of function --------------------------------------------------------*/ + +lpc10_encode_state_t *lpc10_encode_init(lpc10_encode_state_t *s, int error_correction) +{ + int i; + int j; + + if (s == NULL) + { + if ((s = (lpc10_encode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + + s->error_correction = error_correction; + + /* State used only by function high_pass_100hz */ + s->z11 = 0.0f; + s->z21 = 0.0f; + s->z12 = 0.0f; + s->z22 = 0.0f; + + /* State used by function lpc10_analyse */ + for (i = 0; i < 540; i++) + { + s->inbuf[i] = 0.0f; + s->pebuf[i] = 0.0f; + } + for (i = 0; i < 696; i++) + s->lpbuf[i] = 0.0f; + for (i = 0; i < 312; i++) + s->ivbuf[i] = 0.0f; + s->bias = 0.0f; + s->osptr = 1; + for (i = 0; i < 3; i++) + s->obound[i] = 0; + s->vwin[2][0] = 307; + s->vwin[2][1] = 462; + s->awin[2][0] = 307; + s->awin[2][1] = 462; + for (i = 0; i < 4; i++) + { + s->voibuf[i][0] = 0; + s->voibuf[i][1] = 0; + } + for (i = 0; i < 3; i++) + s->rmsbuf[i] = 0.0f; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 10; j++) + s->rcbuf[i][j] = 0.0f; + } + s->zpre = 0.0f; + + /* State used by function onset */ + s->n = 0.0f; + s->d__ = 1.0f; + for (i = 0; i < 16; i++) + s->l2buf[i] = 0.0f; + s->l2sum1 = 0.0f; + s->l2ptr1 = 1; + s->l2ptr2 = 9; + s->hyst = FALSE; + + /* State used by function lpc10_voicing */ + s->dither = 20.0f; + s->maxmin = 0.0f; + for (i = 0; i < 3; i++) + { + s->voice[i][0] = 0.0f; + s->voice[i][1] = 0.0f; + } + s->lbve = 3000; + s->fbve = 3000; + s->fbue = 187; + s->ofbue = 187; + s->sfbue = 187; + s->lbue = 93; + s->olbue = 93; + s->slbue = 93; + s->snr = (float) (s->fbve / s->fbue << 6); + + /* State used by function dynamic_pitch_tracking */ + for (i = 0; i < 60; i++) + s->s[i] = 0.0f; + for (i = 0; i < 2; i++) + { + for (j = 0; j < 60; j++) + s->p[i][j] = 0; + } + s->ipoint = 0; + s->alphax = 0.0f; + + /* State used by function lpc10_pack */ + s->isync = 0; + + return s; +} +/*- End of function --------------------------------------------------------*/ + +int lpc10_encode_release(lpc10_encode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int lpc10_encode(lpc10_encode_state_t *s, uint8_t code[], const int16_t amp[], int quant) +{ + int32_t voice[2]; + int32_t pitch; + float speech[LPC10_SAMPLES_PER_FRAME]; + float rc[LPC10_ORDER]; + float rms; + lpc10_frame_t frame; + int i; + int j; + + for (i = 0; i < quant; i++) + { + for (j = 0; j < LPC10_SAMPLES_PER_FRAME; j++) + speech[j] = (float) amp[i*LPC10_SAMPLES_PER_FRAME + j]/32768.0f; + high_pass_100hz(s, speech, 0, LPC10_SAMPLES_PER_FRAME); + lpc10_analyse(s, speech, voice, &pitch, &rms, rc); + encode(s, &frame, voice, pitch, rms, rc); + lpc10_pack(s, &code[7*i], &frame); + } + return quant*7; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/lpc10_placev.c b/libs/voipcodecs/src/lpc10_placev.c new file mode 100644 index 0000000000..e1d819ba38 --- /dev/null +++ b/libs/voipcodecs/src/lpc10_placev.c @@ -0,0 +1,335 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * lpc10_placev.c - LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the U.S. Department of Defense reference + * implementation of the LPC-10 2400 bps Voice Coder. They do not + * exert copyright claims on their code, and it may be freely used. + * + * $Id: lpc10_placev.c,v 1.12 2007/01/03 14:15:35 steveu Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/lpc10.h" + +#include "lpc10_encdecs.h" + +#define subsc(x,y) (((x) << 1) + (y)) + +void lpc10_placea(int32_t *ipitch, + int32_t voibuf[3][2], + int32_t *obound, + int32_t af, + int32_t vwin[3][2], + int32_t awin[3][2], + int32_t ewin[3][2], + int32_t lframe, + int32_t maxwin) +{ + int allv; + int winv; + int32_t i; + int32_t j; + int32_t k; + int32_t l; + int32_t hrange; + int ephase; + int32_t lrange; + + lrange = (af - 2)*lframe + 1; + hrange = af*lframe; + + /* Place the analysis window based on the voicing window placement, + onsets, tentative voicing decision, and pitch. */ + + /* Case 1: Sustained voiced speech + If the five most recent voicing decisions are + voiced, then the window is placed phase-synchronously with the + previous window, as close to the present voicing window if possible. + If onsets bound the voicing window, then preference is given to + a phase-synchronous placement which does not overlap these onsets. */ + + /* Case 2: Voiced transition + If at least one voicing decision in AF is voicied, and there are no + onsets, then the window is placed as in case 1. */ + + /* Case 3: Unvoiced speech or onsets + If both voicing decisions in AF are unvoiced, or there are onsets + then the window is placed coincident with the voicing window. */ + + /* Note: During phase-synchronous placement of windows, the length + is not altered from MAXWIN, since this would defeat the purpose + of phase-synchronous placement. */ + + /* Check for case 1 and case 2 */ + allv = voibuf[af - 2][1] == 1 + && + voibuf[af - 1][0] == 1 + && + voibuf[af - 1][1] == 1 + && + voibuf[af][0] == 1 + && + voibuf[af][1] == 1; + winv = voibuf[af][0] == 1 || voibuf[af][1] == 1; + if (allv || (winv && *obound == 0)) + { + /* APHASE: Phase synchronous window placement. */ + /* Get minimum lower index of the window. */ + i = (lrange + *ipitch - 1 - awin[af - 2][0]) / *ipitch; + i *= *ipitch; + i += awin[af - 2][0]; + /* l = the actual length of this frame's analysis window. */ + l = maxwin; + /* Calculate the location where a perfectly centered window would start. */ + k = (vwin[af - 1][0] + vwin[af - 1][1] + 1 - l)/2; + /* Choose the actual location to be the pitch multiple closest to this */ + awin[af - 1][0] = i + ((int) floorf((float) (k - i)/(float) *ipitch + 0.5f))*(*ipitch); + awin[af - 1][1] = awin[af - 1][0] + l - 1; + /* If there is an onset bounding the right of the voicing window and the + analysis window overlaps that, then move the analysis window backward + to avoid this onset. */ + if (*obound >= 2 && awin[af - 1][1] > vwin[af - 1][1]) + { + awin[af - 1][0] -= *ipitch; + awin[af - 1][1] -= *ipitch; + } + /* Similarly for the left of the voicing window. */ + if ((*obound == 1 || *obound == 3) && awin[af - 1][0] < vwin[af - 1][0]) + { + awin[af - 1][0] += *ipitch; + awin[af - 1][1] += *ipitch; + } + /* If this placement puts the analysis window above HRANGE, then + move it backward an integer number of pitch periods. */ + while (awin[af - 1][1] > hrange) + { + awin[af - 1][0] -= *ipitch; + awin[af - 1][1] -= *ipitch; + } + /* Similarly if the placement puts the analysis window below LRANGE. */ + while (awin[af - 1][0] < lrange) + { + awin[af - 1][0] += *ipitch; + awin[af - 1][1] += *ipitch; + } + /* Make energy window be phase-synchronous. */ + ephase = TRUE; + } + else + { + /* Case 3 */ + awin[af - 1][0] = vwin[af - 1][0]; + awin[af - 1][1] = vwin[af - 1][1]; + ephase = FALSE; + } + /* RMS is computed over an integer number of pitch periods in the analysis + window. When it is not placed phase-synchronously, it is placed as close + as possible to onsets. */ + j = (awin[af - 1][1] - awin[af - 1][0] + 1) / *ipitch * *ipitch; + if (j == 0 || !winv) + { + ewin[af - 1][0] = vwin[af - 1][0]; + ewin[af - 1][1] = vwin[af - 1][1]; + } + else if (!ephase && *obound == 2) + { + ewin[af - 1][0] = awin[af - 1][1] - j + 1; + ewin[af - 1][1] = awin[af - 1][1]; + } + else + { + ewin[af - 1][0] = awin[af - 1][0]; + ewin[af - 1][1] = awin[af - 1][0] + j - 1; + } +} +/*- End of function --------------------------------------------------------*/ + +void lpc10_placev(int32_t *osbuf, + int32_t *osptr, + int32_t oslen, + int32_t *obound, + int32_t vwin[3][2], + int32_t af, + int32_t lframe, + int32_t minwin, + int32_t maxwin, + int32_t dvwinl, + int32_t dvwinh) +{ + int32_t i1; + int32_t i2; + int crit; + int32_t q; + int32_t osptr1; + int32_t hrange; + int32_t lrange; + int i; + + /* Voicing window placement */ + + /* __________________ __________________ ______________ */ + /* | | | */ + /* | 1F | 2F | 3F ... */ + /* |__________________|__________________|______________ */ + + /* Previous | */ + /* Window | */ + /* ...________| */ + + /* | | */ + /* ------>| This window's placement range |<------ */ + /* | | */ + + /* There are three cases. Note these are different from those + given in the LPC-10e phase 1 report. */ + + /* 1. If there are no onsets in this range, then the voicing window + is centered in the pitch window. If such a placement is not within + the window's placement range, then the window is placed in the left-most + portion of the placement range. Its length is always MAXWIN. */ + + /* 2. If the first onset is in 2F and there is sufficient room to place + the window immediately before this onset, then the window is placed + there, and its length is set to the maximum possible under these + constraints. */ + + /* "Critical Region Exception": If there is another onset in 2F + such that a window can be placed between the two onsets, the + window is placed there (ie, as in case 3). */ + + /* 3. Otherwise, the window is placed immediately after the onset. The + window's length is the longest length that can fit in the range under these + constraints, except that the window may be shortened even further to avoid + overlapping other onsets in the placement range. In any case, the window's + length is at least MINWIN. */ + + /* Note that the values of MINWIN and LFRAME must be chosen such + that case 2 = false implies case 3 = true. This means that + MINWIN <= LFRAME/2. If this were not the case, then a fourth case + would have to be added for when the window cannot fit either before + or after the onset. */ + + /* Note also that onsets which weren't in 2F last time may be in 1F this + time, due to the filter delays in computing onsets. The result is that + occasionally a voicing window will overlap that onset. The only way + to circumvent this problem is to add more delay in processing input + speech. In the trade-off between delay and window-placement, window + placement lost. */ + + /* Compute the placement range */ + + /* Computing MAX */ + i1 = vwin[af - 2][1] + 1; + i2 = (af - 2)*lframe + 1; + lrange = max(i1, i2); + hrange = af*lframe; + /* Compute OSPTR1, so the following code only looks at relevant onsets. */ + for (osptr1 = *osptr - 1; osptr1 >= 1; osptr1--) + { + if (osbuf[osptr1 - 1] <= hrange) + break; + } + osptr1++; + /* Check for case 1 first (fast case) */ + if (osptr1 <= 1 || osbuf[osptr1 - 2] < lrange) + { + /* Compute max */ + i1 = vwin[af - 2][1] + 1; + vwin[af - 1][0] = max(i1, dvwinl); + vwin[af - 1][1] = vwin[af - 1][0] + maxwin - 1; + *obound = 0; + } + else + { + /* Search backward in OSBUF for first onset in range. */ + /* This code relies on the above check being performed first. */ + for (q = osptr1 - 1; q >= 1; q--) + { + if (osbuf[q - 1] < lrange) + break; + } + q++; + /* Check for case 2 (placement before onset): */ + /* Check for critical region exception: */ + crit = FALSE; + for (i = q + 1; i < osptr1; i++) + { + if (osbuf[i - 1] - osbuf[q - 1] >= minwin) + { + crit = TRUE; + break; + } + } + /* Compute max */ + i1 = (af - 1)*lframe; + i2 = lrange + minwin - 1; + if (!crit && osbuf[q - 1] > max(i1, i2)) + { + vwin[af - 1][1] = osbuf[q - 1] - 1; + /* Compute max */ + i2 = vwin[af - 1][1] - maxwin + 1; + vwin[af - 1][0] = max(lrange, i2); + *obound = 2; + } + else + { + /* Case 3 (placement after onset) */ + vwin[af - 1][0] = osbuf[q - 1]; + do + { + if (++q >= osptr1 + || + osbuf[q - 1] > vwin[af - 1][0] + maxwin) + { + /* Compute min */ + i1 = vwin[af - 1][0] + maxwin - 1; + vwin[af - 1][1] = min(i1, hrange); + *obound = 1; + return; + } + } + while (osbuf[q - 1] < vwin[af - 1][0] + minwin); + vwin[af - 1][1] = osbuf[q - 1] - 1; + *obound = 3; + } + } +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/lpc10_voicing.c b/libs/voipcodecs/src/lpc10_voicing.c new file mode 100644 index 0000000000..cd297c0cb1 --- /dev/null +++ b/libs/voipcodecs/src/lpc10_voicing.c @@ -0,0 +1,487 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * lpc10_voicing.c - LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * This code is based on the U.S. Department of Defense reference + * implementation of the LPC-10 2400 bps Voice Coder. They do not + * exert copyright claims on their code, and it may be freely used. + * + * $Id: lpc10_voicing.c,v 1.7 2006/11/30 15:41:47 steveu Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif + +#include "voipcodecs/telephony.h" +#include "voipcodecs/dc_restore.h" +#include "voipcodecs/lpc10.h" + +#include "lpc10_encdecs.h" + +static void vparms(int32_t vwin[], + float *inbuf, + float *lpbuf, + const int32_t buflim[], + int32_t half, + float *dither, + int32_t *mintau, + int32_t *zc, + int32_t *lbe, + int32_t *fbe, + float *qs, + float *rc1, + float *ar_b, + float *ar_f) +{ + int32_t inbuf_offset; + int32_t lpbuf_offset; + int32_t vlen; + int32_t stop; + int32_t i; + int32_t start; + float r1; + float r2; + float e_pre; + float ap_rms; + float e_0; + float oldsgn; + float lp_rms; + float e_b; + float e_f; + float r_b; + float r_f; + float e0ap; + + /* Calculate zero crossings (ZC) and several energy and correlation */ + /* measures on low band and full band speech. Each measure is taken */ + /* over either the first or the second half of the voicing window, */ + /* depending on the variable HALF. */ + lpbuf_offset = buflim[2]; + lpbuf -= lpbuf_offset; + inbuf_offset = buflim[0]; + inbuf -= inbuf_offset; + + lp_rms = 0.0f; + ap_rms = 0.0f; + e_pre = 0.0f; + e0ap = 0.0f; + *rc1 = 0.0f; + e_0 = 0.0f; + e_b = 0.0f; + e_f = 0.0f; + r_f = 0.0f; + r_b = 0.0f; + *zc = 0; + vlen = vwin[1] - vwin[0] + 1; + start = vwin[0] + half*vlen/2 + 1; + stop = start + vlen/2 - 1; + + /* I'll use the symbol HVL in the table below to represent the value */ + /* VLEN/2. Note that if VLEN is odd, then HVL should be rounded down, */ + /* i.e., HVL = (VLEN-1)/2. */ + + /* HALF START STOP */ + + /* 1 VWIN(1)+1 VWIN(1)+HVL */ + /* 2 VWIN(1)+HVL+1 VWIN(1)+2*HVL */ + oldsgn = r_sign(1.0f, inbuf[start - 1] - *dither); + for (i = start; i <= stop; i++) + { + lp_rms += fabsf(lpbuf[i]); + ap_rms += fabsf(inbuf[i]); + e_pre += fabsf(inbuf[i] - inbuf[i - 1]); + r1 = inbuf[i]; + e0ap += r1*r1; + *rc1 += inbuf[i]*inbuf[i - 1]; + r1 = lpbuf[i]; + e_0 += r1*r1; + r1 = lpbuf[i - *mintau]; + e_b += r1*r1; + r1 = lpbuf[i + *mintau]; + e_f += r1*r1; + r_f += lpbuf[i]*lpbuf[i + *mintau]; + r_b += lpbuf[i]*lpbuf[i - *mintau]; + r1 = inbuf[i] + *dither; + if (r_sign(1.0f, r1) != oldsgn) + { + ++(*zc); + oldsgn = -oldsgn; + } + *dither = -(*dither); + } + /* Normalized short-term autocovariance coefficient at unit sample delay */ + *rc1 /= max(e0ap, 1.0f); + /* Ratio of the energy of the first difference signal (6 dB/oct preemphasis)*/ + /* to the energy of the full band signal */ + /* Computing MAX */ + r1 = ap_rms*2.0f; + *qs = e_pre/max(r1, 1.0f); + /* aR_b is the product of the forward and reverse prediction gains, */ + /* looking backward in time (the causal case). */ + *ar_b = r_b/max(e_b, 1.0f)*(r_b/max(e_0, 1.0f)); + /* aR_f is the same as aR_b, but looking forward in time (non causal case).*/ + *ar_f = r_f/max(e_f, 1.0f)*(r_f/max(e_0, 1.0f)); + /* Normalize ZC, LBE, and FBE to old fixed window length of 180. */ + /* (The fraction 90/VLEN has a range of 0.58 to 1) */ + r2 = (float) (*zc << 1); + *zc = lrintf(r2*(90.0f/vlen)); + r1 = lp_rms/4*(90.0f/vlen); + *lbe = min(lrintf(r1), 32767); + r1 = ap_rms/4*(90.0f/vlen); + *fbe = min(lrintf(r1), 32767); +} +/*- End of function --------------------------------------------------------*/ + +/* Voicing detection makes voicing decisions for each half */ +/* frame of input speech. Tentative voicing decisions are made two frames*/ +/* in the future (2F) for each half frame. These decisions are carried */ +/* through one frame in the future (1F) to the present (P) frame where */ +/* they are examined and smoothed, resulting in the final voicing */ +/* decisions for each half frame. */ + +/* The voicing parameter (signal measurement) column vector (VALUE) */ +/* is based on a rectangular window of speech samples determined by the */ +/* window placement algorithm. The voicing parameter vector contains the*/ +/* AMDF windowed maximum-to-minimum ratio, the zero crossing rate, energy*/ +/* measures, reflection coefficients, and prediction gains. The voicing */ +/* window is placed to avoid contamination of the voicing parameter vector*/ +/* with speech onsets. */ + +/* The input signal is then classified as unvoiced (including */ +/* silence) or voiced. This decision is made by a linear discriminant */ +/* function consisting of a dot product of the voicing decision */ +/* coefficient (VDC) row vector with the measurement column vector */ +/* (VALUE). The VDC vector is 2-dimensional, each row vector is optimized*/ +/* for a particular signal-to-noise ratio (SNR). So, before the dot */ +/* product is performed, the SNR is estimated to select the appropriate */ +/* VDC vector. */ + +/* The smoothing algorithm is a modified median smoother. The */ +/* voicing discriminant function is used by the smoother to determine how*/ +/* strongly voiced or unvoiced a signal is. The smoothing is further */ +/* modified if a speech onset and a voicing decision transition occur */ +/* within one half frame. In this case, the voicing decision transition */ +/* is extended to the speech onset. For transmission purposes, there are*/ +/* constraints on the duration and transition of voicing decisions. The */ +/* smoother takes these constraints into account. */ + +/* Finally, the energy estimates are updated along with the dither */ +/* threshold used to calculate the zero crossing rate (ZC). */ + +void lpc10_voicing(lpc10_encode_state_t *s, + int32_t vwin[], + float *inbuf, + float *lpbuf, + const int32_t buflim[], + int32_t half, + float *minamd, + float *maxamd, + int32_t *mintau, + float ivrc[], + int32_t obound[]) +{ + static const float vdc[100] = + { + 0.0f, 1714.0f, -110.0f, 334.0f, -4096.0f, -654.0f, 3752.0f, 3769.0f, 0.0f, 1181.0f, + 0.0f, 874.0f, -97.0f, 300.0f, -4096.0f, -1021.0f, 2451.0f, 2527.0f, 0.0f, -500.0f, + 0.0f, 510.0f, -70.0f, 250.0f, -4096.0f, -1270.0f, 2194.0f, 2491.0f, 0.0f, -1500.0f, + 0.0f, 500.0f, -10.0f, 200.0f, -4096.0f, -1300.0f, 2.0e3f, 2.0e3f, 0.0f, -2.0e3f, + 0.0f, 500.0f, 0.0f, 0.0f, -4096.0f, -1300.0f, 2.0e3f, 2.0e3f, 0.0f, -2500.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f + }; + static const int nvdcl = 5; + static const float vdcl[10] = + { + 600.0f, 450.0f, 300.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f + }; + + int32_t inbuf_offset; + int32_t lpbuf_offset; + int32_t i1; + float r1; + float r2; + float ar_b; + float ar_f; + int32_t snrl; + int32_t i; + float value[9]; + int32_t zc; + int ot; + float qs; + int32_t vstate; + float rc1; + int32_t fbe; + int32_t lbe; + float snr2; + + inbuf_offset = 0; + lpbuf_offset = 0; + if (inbuf) + { + inbuf_offset = buflim[0]; + inbuf -= inbuf_offset; + } + if (lpbuf) + { + lpbuf_offset = buflim[2]; + lpbuf -= lpbuf_offset; + } + + /* Voicing Decision Parameter vector (* denotes zero coefficient): */ + + /* * MAXMIN */ + /* LBE/LBVE */ + /* ZC */ + /* RC1 */ + /* QS */ + /* IVRC2 */ + /* aR_B */ + /* aR_F */ + /* * LOG(LBE/LBVE) */ + /* Define 2-D voicing decision coefficient vector according to the voicing */ + /* parameter order above. Each row (VDC vector) is optimized for a specific */ + /* SNR. The last element of the vector is the constant. */ + /* E ZC RC1 Qs IVRC2 aRb aRf c */ + + /* The VOICE array contains the result of the linear discriminant function*/ + /* (analog values). The VOIBUF array contains the hard-limited binary */ + /* voicing decisions. The VOICE and VOIBUF arrays, according to FORTRAN */ + /* memory allocation, are addressed as: */ + + /* (half-frame number, future-frame number) */ + + /* | Past | Present | Future1 | Future2 | */ + /* | 1,0 | 2,0 | 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 | ---> time */ + + /* Update linear discriminant function history each frame: */ + if (half == 0) + { + s->voice[0][0] = s->voice[1][0]; + s->voice[0][1] = s->voice[1][1]; + s->voice[1][0] = s->voice[2][0]; + s->voice[1][1] = s->voice[2][1]; + s->maxmin = *maxamd / max(*minamd, 1.0f); + } + /* Calculate voicing parameters twice per frame */ + vparms(vwin, + &inbuf[inbuf_offset], + &lpbuf[lpbuf_offset], + buflim, + half, + &s->dither, + mintau, + &zc, + &lbe, + &fbe, + &qs, + &rc1, + &ar_b, + &ar_f); + /* Estimate signal-to-noise ratio to select the appropriate VDC vector. */ + /* The SNR is estimated as the running average of the ratio of the */ + /* running average full-band voiced energy to the running average */ + /* full-band unvoiced energy. SNR filter has gain of 63. */ + r1 = (s->snr + s->fbve/(float) max(s->fbue, 1))*63/64.0f; + s->snr = (float) lrintf(r1); + snr2 = s->snr*s->fbue/max(s->lbue, 1); + /* Quantize SNR to SNRL according to VDCL thresholds. */ + i1 = nvdcl - 1; + for (snrl = 0; snrl < i1; snrl++) + { + if (snr2 > vdcl[snrl]) + break; + } + /* (Note: SNRL = NVDCL here) */ + /* Linear discriminant voicing parameters: */ + value[0] = s->maxmin; + value[1] = (float) lbe/max(s->lbve, 1); + value[2] = (float) zc; + value[3] = rc1; + value[4] = qs; + value[5] = ivrc[1]; + value[6] = ar_b; + value[7] = ar_f; + /* Evaluation of linear discriminant function: */ + s->voice[2][half] = vdc[snrl*10 + 9]; + for (i = 0; i < 8; i++) + s->voice[2][half] += vdc[snrl*10 + i]*value[i]; + /* Classify as voiced if discriminant > 0, otherwise unvoiced */ + /* Voicing decision for current half-frame: 1 = Voiced; 0 = Unvoiced */ + s->voibuf[3][half] = (s->voice[2][half] > 0.0f) ? 1 : 0; + /* Skip voicing decision smoothing in first half-frame: */ + /* Give a value to VSTATE, so that trace statements below will print */ + /* a consistent value from one call to the next when HALF .EQ. 1. */ + /* The value of VSTATE is not used for any other purpose when this is */ + /* true. */ + vstate = -1; + if (half != 0) + { + /* Voicing decision smoothing rules (override of linear combination): */ + + /* Unvoiced half-frames: At least two in a row. */ + /* -------------------- */ + + /* Voiced half-frames: At least two in a row in one frame. */ + /* ------------------- Otherwise at least three in a row. */ + /* (Due to the way transition frames are encoded) */ + + /* In many cases, the discriminant function determines how to smooth. */ + /* In the following chart, the decisions marked with a * may be overridden. */ + + /* Voicing override of transitions at onsets: */ + /* If a V/UV or UV/V voicing decision transition occurs within one-half */ + /* frame of an onset bounding a voicing window, then the transition is */ + /* moved to occur at the onset. */ + + /* P 1F */ + /* ----- ----- */ + /* 0 0 0 0 */ + /* 0 0 0* 1 (If there is an onset there) */ + /* 0 0 1* 0* (Based on 2F and discriminant distance) */ + /* 0 0 1 1 */ + /* 0 1* 0 0 (Always) */ + /* 0 1* 0* 1 (Based on discriminant distance) */ + /* 0* 1 1 0* (Based on past, 2F, and discriminant distance) */ + /* 0 1* 1 1 (If there is an onset there) */ + /* 1 0* 0 0 (If there is an onset there) */ + /* 1 0 0 1 */ + /* 1 0* 1* 0 (Based on discriminant distance) */ + /* 1 0* 1 1 (Always) */ + /* 1 1 0 0 */ + /* 1 1 0* 1* (Based on 2F and discriminant distance) */ + /* 1 1 1* 0 (If there is an onset there) */ + /* 1 1 1 1 */ + + /* Determine if there is an onset transition between P and 1F. */ + /* OT (Onset Transition) is true if there is an onset between */ + /* P and 1F but not after 1F. */ + ot = ((obound[0] & 2) != 0 || obound[1] == 1) && (obound[2] & 1) == 0; + /* Multi-way dispatch on voicing decision history: */ + vstate = (s->voibuf[1][0] << 3) + (s->voibuf[1][1] << 2) + (s->voibuf[2][0] << 1) + s->voibuf[2][1]; + switch (vstate + 1) + { + case 2: + if (ot && s->voibuf[3][0] == 1) + s->voibuf[2][0] = 1; + break; + case 3: + if (s->voibuf[3][0] == 0 || s->voice[1][0] < -s->voice[1][1]) + s->voibuf[2][0] = 0; + else + s->voibuf[2][1] = 1; + break; + case 5: + s->voibuf[1][1] = 0; + break; + case 6: + if (s->voice[0][1] < -s->voice[1][0]) + s->voibuf[1][1] = 0; + else + s->voibuf[2][0] = 1; + break; + case 7: + if (s->voibuf[0][0] == 1 || s->voibuf[3][0] == 1 || s->voice[1][1] > s->voice[0][0]) + s->voibuf[2][1] = 1; + else + s->voibuf[1][0] = 1; + break; + case 8: + if (ot) + s->voibuf[1][1] = 0; + break; + case 9: + if (ot) + s->voibuf[1][1] = 1; + break; + case 11: + if (s->voice[1][9] < -s->voice[0][1]) + s->voibuf[2][0] = 0; + else + s->voibuf[1][1] = 1; + break; + case 12: + s->voibuf[1][1] = 1; + break; + case 14: + if (s->voibuf[3][0] == 0 && s->voice[1][1] < -s->voice[1][0]) + s->voibuf[2][1] = 0; + else + s->voibuf[2][0] = 1; + break; + case 15: + if (ot && s->voibuf[3][0] == 0) + s->voibuf[2][0] = 0; + break; + } + } + /* During unvoiced half-frames, update the low band and full band unvoiced*/ + /* energy estimates (LBUE and FBUE) and also the zero crossing */ + /* threshold (DITHER). (The input to the unvoiced energy filters is */ + /* restricted to be less than 10dB above the previous inputs of the */ + /* filters.) */ + /* During voiced half-frames, update the low-pass (LBVE) and all-pass */ + /* (FBVE) voiced energy estimates. */ + if (s->voibuf[3][half] == 0) + { + r1 = (s->sfbue*63 + (min(fbe, s->ofbue*3) << 3))/64.0f; + s->sfbue = lrintf(r1); + s->fbue = s->sfbue/8; + s->ofbue = fbe; + r1 = (s->slbue*63 + (min(lbe, s->olbue*3) << 3))/64.0f; + s->slbue = lrintf(r1); + s->lbue = s->slbue/8; + s->olbue = lbe; + } + else + { + s->lbve = lrintf((s->lbve*63 + lbe)/64.0f); + s->fbve = lrintf((s->fbve*63 + fbe)/64.0f); + } + /* Set dither threshold to yield proper zero crossing rates in the */ + /* presence of low frequency noise and low level signal input. */ + /* NOTE: The divisor is a function of REF, the expected energies. */ + /* Computing MIN */ + /* Computing MAX */ + r2 = sqrtf((float) (s->lbue*s->lbve))*64/3000; + r1 = max(r2, 1.0f); + s->dither = min(r1, 20.0f); + /* Voicing decisions are returned in VOIBUF. */ +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/msvc/gettimeofday.c b/libs/voipcodecs/src/msvc/gettimeofday.c new file mode 100644 index 0000000000..c59f19e0b8 --- /dev/null +++ b/libs/voipcodecs/src/msvc/gettimeofday.c @@ -0,0 +1,14 @@ +#ifdef _MSC_VER +#pragma warning(disable:4100) +#endif + +#include "windows.h" + +void gettimeofday(struct timeval *tv, void *tz) +{ + long int l = GetTickCount(); + + tv->tv_sec = l / 1000; + tv->tv_usec = (l % 1000) * 1000; + return; +} diff --git a/libs/voipcodecs/src/msvc/inttypes.h b/libs/voipcodecs/src/msvc/inttypes.h new file mode 100644 index 0000000000..5980bec935 --- /dev/null +++ b/libs/voipcodecs/src/msvc/inttypes.h @@ -0,0 +1,87 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * inttypes.h - a fudge for MSVC, which lacks this header + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Michael Jerris + * + * + * This file is released in the public domain. + * + */ + +#if !defined(_INTTYPES_H_) +#define _INTTYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +#if (_MSC_VER >= 1400) // VC8+ +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif +#endif // VC8+ +#include +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +#define inline __inline +#define __inline__ __inline +#define INT16_MAX 0x7fff +#define INT16_MIN (-INT16_MAX - 1) +#define _MMX_H_ + +/* disable the following warnings + * C4100: The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored. + * C4200: Non standard extension C zero sized array + * C4706: assignment within conditional expression + * C4244: conversion from 'type1' to 'type2', possible loss of data + * C4295: array is too small to include a terminating null character + * C4125: decimal digit terminates octal escape sequence + */ +#pragma warning(disable:4100 4200 4706 4295 4125) + +#pragma comment(lib, "ws2_32.lib") + +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#define snprintf _snprintf + +#if !defined(INFINITY) +#define INFINITY 0x7fffffff +#endif +#endif + +#define PACKAGE "voipcodecs" +#define VERSION "0.0.1andabit" + +#define INT32_MAX (2147483647) +#define INT32_MIN (-2147483647 - 1) + +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "ld" +#define PRId64 "lld" + +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "lu" +#define PRIu64 "llu" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/voipcodecs/src/msvc/msvcproj.foot b/libs/voipcodecs/src/msvc/msvcproj.foot new file mode 100644 index 0000000000..e8b521ca54 --- /dev/null +++ b/libs/voipcodecs/src/msvc/msvcproj.foot @@ -0,0 +1,7 @@ + +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/libs/voipcodecs/src/msvc/msvcproj.head b/libs/voipcodecs/src/msvc/msvcproj.head new file mode 100644 index 0000000000..cabf08b497 --- /dev/null +++ b/libs/voipcodecs/src/msvc/msvcproj.head @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="voipcodecs" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=voipcodecs - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "voipcodecs.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "voipcodecs.mak" CFG="voipcodecs - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "voipcodecs - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "voipcodecs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "voipcodecs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "." /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /D "_WINDLL" /FR /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libvoipcodecs.dll" + +!ELSEIF "$(CFG)" == "voipcodecs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "." /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D HAVE_TGMATH_H /FR /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib ws2_32.lib winmm.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libvoipcodecs.dll" /pdbtype:sept +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "voipcodecs - Win32 Release" +# Name "voipcodecs - Win32 Debug" diff --git a/libs/voipcodecs/src/msvc/sys/time.h b/libs/voipcodecs/src/msvc/sys/time.h new file mode 100644 index 0000000000..bd3bcb2c7b --- /dev/null +++ b/libs/voipcodecs/src/msvc/sys/time.h @@ -0,0 +1 @@ +extern void gettimeofday(struct timeval *tv, void *tz); diff --git a/libs/voipcodecs/src/msvc/tgmath.h b/libs/voipcodecs/src/msvc/tgmath.h new file mode 100644 index 0000000000..a19c88153e --- /dev/null +++ b/libs/voipcodecs/src/msvc/tgmath.h @@ -0,0 +1,84 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * tgmath.h - a fudge for MSVC, which lacks this header + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Michael Jerris + * + * + * This file is released in the public domain. + * + */ + +#if !defined(_TGMATH_H_) +#define _TGMATH_H_ + +#include + +#if !defined(M_PI) +/* C99 systems may not define M_PI */ +#define M_PI 3.14159265358979323846264338327 +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/* A kindofa rint() for VC++ (only kindofa, because rint should be type generic, + and this one is purely float to int */ +static inline long int lrintf(float a) +{ + long int i; + + __asm + { + fld a + fistp i + } + return i; +} + +static inline long int lrint(double a) +{ + long int i; + + __asm + { + fld a + fistp i + } + return i; +} + +static inline int rintf(float a) +{ + int i; + + __asm + { + fld a + fistp i + } + return i; +} + +static inline int rint(double a) +{ + int i; + + __asm + { + fld a + fistp i + } + return i; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/voipcodecs/src/msvc/unistd.h b/libs/voipcodecs/src/msvc/unistd.h new file mode 100644 index 0000000000..fc8cd06d7b --- /dev/null +++ b/libs/voipcodecs/src/msvc/unistd.h @@ -0,0 +1,31 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * inttypes.h - a fudge for MSVC, which lacks this header + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Michael Jerris + * + * + * This file is released in the public domain. + * + */ + +#if !defined(_INTTYPES_H_) +#define _INTTYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define open _open +#define write _write + +extern int gethostname (char *name, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/voipcodecs/src/msvc/vc8proj.foot b/libs/voipcodecs/src/msvc/vc8proj.foot new file mode 100644 index 0000000000..2b57fb4e9f --- /dev/null +++ b/libs/voipcodecs/src/msvc/vc8proj.foot @@ -0,0 +1,11 @@ + + + + + + + diff --git a/libs/voipcodecs/src/msvc/vc8proj.head b/libs/voipcodecs/src/msvc/vc8proj.head new file mode 100644 index 0000000000..1c12275b7f --- /dev/null +++ b/libs/voipcodecs/src/msvc/vc8proj.head @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/voipcodecs/src/msvc/voipcodecs.def b/libs/voipcodecs/src/msvc/voipcodecs.def new file mode 100644 index 0000000000..cb5076c2fa --- /dev/null +++ b/libs/voipcodecs/src/msvc/voipcodecs.def @@ -0,0 +1,304 @@ +EXPORTS +adsi_rx_init +adsi_rx +adsi_tx_init +adsi_send_alert_tone +adsi_put_message +adsi_next_field +adsi_add_field +async_tx_init +async_rx_init +awgn +bert_init +bert_get_bit +bert_put_bit +bert_set_report +bert_result +filter_create +filter_delete +filter_step +cfilter_create +cfilter_delete +cfilter_step +dds_phase_rate +dds_frequency +dds_scaling_dbm0 +dds_scaling_dbov +dds_lookup +dds_offset +dds +dds_mod +dds_complex +dds_complex_mod +dds_phase_ratef +dds_frequencyf +dds_scaling_dbm0f +dds_scaling_dbovf +ddsf +dds_modf +dds_complexf +dds_complex_modf +echo_can_create +echo_can_free +echo_can_flush +echo_can_adaption_mode +echo_can_update +fax_rx +fax_tx +fax_set_flush_handler +fax_init +fax_release +fsk_tx_init +fsk_tx_power +fsk_tx_set_get_bit +fsk_tx +fsk_rx_signal_power +fsk_rx_signal_cutoff +fsk_rx_init +fsk_rx +fsk_rx_set_put_bit +g722_encode_init +g722_encode_release +g722_encode +g722_decode_init +g722_decode_release +g722_decode +g726_init +g726_release +crc_itu32_calc +crc_itu32_append +crc_itu32_check +crc_itu16_calc +crc_itu16_append +crc_itu16_check +hdlc_rx_init +hdlc_rx_get_stats +hdlc_tx_init +hdlc_tx_frame +hdlc_tx_preamble +ima_adpcm_init +ima_adpcm_release +span_log_test +span_log +span_log_buf +span_log_init +span_log_set_protocol +span_set_message_handler +span_set_error_handler +modem_echo_can_create +modem_echo_can_free +modem_echo_can_flush +modem_echo_can_adaption_mode +modem_echo_can_update +noise +oki_adpcm_init +oki_adpcm_release +playout_put +playout_get +playout_get_unconditional +playout_current_length +playout_next_due +playout_new +playout_free +playout_restart +plc_rx +plc_fillin +plc_init +plc_release +power_meter_init +power_meter_damping +power_meter_update +power_meter_dbm0 +power_meter_dbov +power_meter_level_dbm0 +power_meter_level_dbov +queue_empty +queue_free_space +queue_contents +queue_flush +queue_view +queue_read +queue_write +queue_test_msg +queue_read_msg +queue_write_msg +queue_create +queue_delete +sig_tone_init +sig_tone_rx +sig_tone_tx +super_tone_rx_make_descriptor +super_tone_rx_add_tone +super_tone_rx_add_element +super_tone_rx_init +super_tone_rx_free +super_tone_rx_segment_callback +super_tone_rx +super_tone_tx_make_step +super_tone_tx_free +super_tone_tx_init +super_tone_tx +t30_init +t30_release +t30_restart +t30_create +t30_free +t30_frametype +t30_decode_dis_dtc_dcs +t30_completion_code_to_str +t30_set_header_info +t30_set_local_ident +t30_get_sub_address +t30_get_header_info +t30_get_local_ident +t30_get_far_ident +t30_get_transfer_statistics +t30_set_phase_b_handler +t30_set_phase_d_handler +t30_set_phase_e_handler +t30_set_document_handler +t30_set_rx_file +t30_set_tx_file +t30_local_interrupt_request +t30_send_complete +t30_hdlc_accept +t30_timer_update +t31_call_event +t31_at_rx +t31_rx +t31_tx +t31_init +t31_release +t35_decode +t38_indicator +t38_data_type +t38_field_type +t38_terminal_init +t38_gateway_init +t4_rx_create +t4_rx_init +t4_rx_start_page +t4_rx_end_page +t4_rx_delete +t4_rx_end +t4_rx_set_rx_encoding +t4_rx_set_sub_address +t4_rx_set_far_ident +t4_rx_set_vendor +t4_rx_set_model +t4_tx_create +t4_tx_init +t4_tx_start_page +t4_tx_restart_page +t4_tx_end_page +t4_tx_delete +t4_tx_end +t4_tx_set_tx_encoding +t4_tx_set_min_row_bits +t4_tx_set_local_ident +t4_tx_set_header_info +t4_get_transfer_statistics +t4_encoding_to_str +time_scale_init +time_scale_rate +time_scale +make_goertzel_descriptor +goertzel_init +goertzel_update +goertzel_result +dtmf_rx_init +dtmf_rx_set_realtime_callback +dtmf_rx_parms +dtmf_rx +make_tone_descriptor +make_tone_gen_descriptor +tone_gen_init +tone_gen +dtmf_tx_init +dtmf_tx +v17_rx_init +v17_rx_restart +v17_rx_release +v17_rx_set_put_bit +v17_rx +v17_rx_equalizer_state +v17_rx_carrier_frequency +v17_rx_symbol_timing_correction +v17_rx_signal_power +v17_rx_signal_cutoff +v17_rx_set_qam_report_handler +v17_tx_power +v17_tx_init +v17_tx_restart +v17_tx_release +v17_tx_set_get_bit +v17_tx +v22bis_rx_restart +v22bis_rx +v22bis_rx_equalizer_state +v22bis_rx_carrier_frequency +v22bis_rx_symbol_timing_correction +v22bis_rx_signal_power +v22bis_rx_set_qam_report_handler +v22bis_tx +v22bis_tx_power +v22bis_restart +v22bis_init +v22bis_set_get_bit +v22bis_set_put_bit +v27ter_rx_init +v27ter_rx_restart +v27ter_rx_release +v27ter_rx_set_put_bit +v27ter_rx +v27ter_rx_equalizer_state +v27ter_rx_carrier_frequency +v27ter_rx_symbol_timing_correction +v27ter_rx_signal_power +v27ter_rx_signal_cutoff +v27ter_rx_set_qam_report_handler +v27ter_tx_power +v27ter_tx_init +v27ter_tx_restart +v27ter_tx_release +v27ter_tx_set_get_bit +v27ter_tx +v29_rx_init +v29_rx_restart +v29_rx_release +v29_rx_set_put_bit +v29_rx +v29_rx_equalizer_state +v29_rx_carrier_frequency +v29_rx_symbol_timing_correction +v29_rx_signal_power +v29_rx_signal_cutoff +v29_rx_set_qam_report_handler +v29_tx_power +v29_tx_init +v29_tx_restart +v29_tx_release +v29_tx_set_get_bit +v29_tx +lapm_dump +lapm_receive +lapm_tx +lapm_tx_iframe +v42_set_status_callback +v42_rx_bit +v42_tx_bit +v42_init +v42_restart +v42_release +v42bis_compress +v42bis_compress_flush +v42bis_decompress +v42bis_decompress_flush +v42bis_init +v42bis_release +v8_init +v8_release +v8_tx +v8_rx +v8_log_supported_modulations + diff --git a/libs/voipcodecs/src/oki_adpcm.c b/libs/voipcodecs/src/oki_adpcm.c new file mode 100644 index 0000000000..1073048795 --- /dev/null +++ b/libs/voipcodecs/src/oki_adpcm.c @@ -0,0 +1,376 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * oki_adpcm.c - Conversion routines between linear 16 bit PCM data and + * OKI (Dialogic) ADPCM format. Supports with the 32kbps + * and 24kbps variants used by Dialogic. + * + * Written by Steve Underwood + * + * Copyright (C) 2001, 2004 Steve Underwood + * + * The actual OKI ADPCM encode and decode method is derived from freely + * available code, whose exact origins seem uncertain. + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: oki_adpcm.c,v 1.22 2006/11/28 16:59:56 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/oki_adpcm.h" + +/* Routines to convert 12 bit linear samples to the Oki ADPCM coding format, + widely used in CTI, because Dialogic use it. */ + +static const int16_t step_size[49] = +{ + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1408, + 1552 +}; + +static const int16_t step_adjustment[8] = +{ + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +/* Band limiting filter, to allow sample rate conversion to and + from 6k samples/second. */ +static const float cutoff_coeffs[] = +{ + -3.648392e-4f, + 5.062391e-4f, + 1.206247e-3f, + 1.804452e-3f, + 1.691750e-3f, + 4.083405e-4f, + -1.931085e-3f, + -4.452107e-3f, + -5.794821e-3f, + -4.778489e-3f, + -1.161266e-3f, + 3.928504e-3f, + 8.259786e-3f, + 9.500425e-3f, + 6.512800e-3f, + 2.227856e-4f, + -6.531275e-3f, + -1.026843e-2f, + -8.718062e-3f, + -2.280487e-3f, + 5.817733e-3f, + 1.096777e-2f, + 9.634404e-3f, + 1.569301e-3f, + -9.522632e-3f, + -1.748273e-2f, + -1.684408e-2f, + -6.100054e-3f, + 1.071206e-2f, + 2.525209e-2f, + 2.871779e-2f, + 1.664411e-2f, + -7.706268e-3f, + -3.331083e-2f, + -4.521249e-2f, + -3.085962e-2f, + 1.373653e-2f, + 8.089593e-2f, + 1.529060e-1f, + 2.080487e-1f, + 2.286834e-1f, + 2.080487e-1f, + 1.529060e-1f, + 8.089593e-2f, + 1.373653e-2f, + -3.085962e-2f, + -4.521249e-2f, + -3.331083e-2f, + -7.706268e-3f, + 1.664411e-2f, + 2.871779e-2f, + 2.525209e-2f, + 1.071206e-2f, + -6.100054e-3f, + -1.684408e-2f, + -1.748273e-2f, + -9.522632e-3f, + 1.569301e-3f, + 9.634404e-3f, + 1.096777e-2f, + 5.817733e-3f, + -2.280487e-3f, + -8.718062e-3f, + -1.026843e-2f, + -6.531275e-3f, + 2.227856e-4f, + 6.512800e-3f, + 9.500425e-3f, + 8.259786e-3f, + 3.928504e-3f, + -1.161266e-3f, + -4.778489e-3f, + -5.794821e-3f, + -4.452107e-3f, + -1.931085e-3f, + 4.083405e-4f, + 1.691750e-3f, + 1.804452e-3f, + 1.206247e-3f, + 5.062391e-4f, + -3.648392e-4f +}; + +static int16_t decode(oki_adpcm_state_t *s, uint8_t adpcm) +{ + int16_t e; + int16_t ss; + int16_t linear; + + /* Doing the next part as follows: + * + * x = adpcm & 0x07; + * e = (step_size[s->step_index]*(x + x + 1)) >> 3; + * + * Seems an obvious improvement on a modern machine, but remember + * the truncation errors do not come out the same. It would + * not, therefore, be an exact match for what this code is doing. + * + * Just what a Dialogic card does, I do not know! + */ + + ss = step_size[s->step_index]; + e = ss >> 3; + if (adpcm & 0x01) + e += (ss >> 2); + /*endif*/ + if (adpcm & 0x02) + e += (ss >> 1); + /*endif*/ + if (adpcm & 0x04) + e += ss; + /*endif*/ + if (adpcm & 0x08) + e = -e; + /*endif*/ + linear = s->last + e; + + /* Saturate the values to +/- 2^11 (supposed to be 12 bits) */ + if (linear > 2047) + linear = 2047; + else if (linear < -2048) + linear = -2048; + /*endif*/ + + s->last = linear; + s->step_index += step_adjustment[adpcm & 0x07]; + if (s->step_index < 0) + s->step_index = 0; + else if (s->step_index > 48) + s->step_index = 48; + /*endif*/ + /* Note: the result here is a 12 bit value */ + return linear; +} +/*- End of function --------------------------------------------------------*/ + +static uint8_t encode(oki_adpcm_state_t *s, int16_t linear) +{ + int16_t e; + int16_t ss; + uint8_t adpcm; + + ss = step_size[s->step_index]; + e = (linear >> 4) - s->last; + adpcm = (uint8_t) 0x00; + if (e < 0) + { + adpcm = (uint8_t) 0x08; + e = -e; + } + /*endif*/ + if (e >= ss) + { + adpcm |= (uint8_t) 0x04; + e -= ss; + } + /*endif*/ + if (e >= (ss >> 1)) + { + adpcm |= (uint8_t) 0x02; + e -= ss; + } + /*endif*/ + if (e >= (ss >> 2)) + adpcm |= (uint8_t) 0x01; + /*endif*/ + + /* Use the decoder to set the estimate of the last sample. */ + /* It also will adjust the step_index for us. */ + s->last = decode(s, adpcm); + return adpcm; +} +/*- End of function --------------------------------------------------------*/ + +oki_adpcm_state_t *oki_adpcm_init(oki_adpcm_state_t *s, int bit_rate) +{ + if (bit_rate != 32000 && bit_rate != 24000) + return NULL; + if (s == NULL) + { + if ((s = (oki_adpcm_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + s->bit_rate = bit_rate; + + return s; +} +/*- End of function --------------------------------------------------------*/ + +int oki_adpcm_release(oki_adpcm_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int oki_adpcm_decode(oki_adpcm_state_t *s, + int16_t amp[], + const uint8_t oki_data[], + int oki_bytes) +{ + int i; + int x; + int l; + int n; + int samples; + float z; + + samples = 0; + if (s->bit_rate == 32000) + { + for (i = 0; i < oki_bytes; i++) + { + amp[samples++] = decode(s, (oki_data[i] >> 4) & 0xF) << 4; + amp[samples++] = decode(s, oki_data[i] & 0xF) << 4; + } + /*endwhile*/ + } + else + { + n = 0; + for (i = 0; i < oki_bytes; ) + { + /* 6k to 8k sample/second conversion */ + if (s->phase) + { + s->history[s->ptr++] = + decode(s, (n++ & 1) ? (oki_data[i++] & 0xF) : ((oki_data[i] >> 4) & 0xF)) << 4; + s->ptr &= (32 - 1); + } + /*endif*/ + z = 0.0f; + for (l = 80 - 3 + s->phase, x = s->ptr - 1; l >= 0; l -= 4, x--) + z += cutoff_coeffs[l]*s->history[x & (32 - 1)]; + amp[samples++] = (int16_t) (z*4.0f); + if (++s->phase > 3) + s->phase = 0; + /*endif*/ + } + /*endfor*/ + } + /*endif*/ + return samples; +} +/*- End of function --------------------------------------------------------*/ + +int oki_adpcm_encode(oki_adpcm_state_t *s, + uint8_t oki_data[], + const int16_t amp[], + int len) +{ + int x; + int l; + int n; + int bytes; + float z; + + bytes = 0; + if (s->bit_rate == 32000) + { + for (n = 0; n < len; n++) + { + s->oki_byte = (s->oki_byte << 4) | encode(s, amp[n]); + if ((s->mark++ & 1)) + oki_data[bytes++] = s->oki_byte; + /*endif*/ + } + /*endfor*/ + } + else + { + n = 0; + for (;;) + { + /* 8k to 6k sample/second conversion */ + if (s->phase > 2) + { + s->history[s->ptr++] = amp[n]; + s->ptr &= (32 - 1); + s->phase = 0; + if (++n >= len) + break; + /*endif*/ + } + /*endif*/ + s->history[s->ptr++] = amp[n]; + s->ptr &= (32 - 1); + z = 0.0f; + for (l = 80 - s->phase, x = s->ptr - 1; l >= 0; l -= 3, x--) + z += cutoff_coeffs[l]*s->history[x & (32 - 1)]; + /*endfor*/ + s->oki_byte = (s->oki_byte << 4) | encode(s, (int16_t) (z*3.0f)); + if ((s->mark++ & 1)) + oki_data[bytes++] = s->oki_byte; + /*endif*/ + s->phase++; + if (++n >= len) + break; + /*endif*/ + } + /*endfor*/ + } + /*endif*/ + return bytes; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/vector_int.c b/libs/voipcodecs/src/vector_int.c new file mode 100644 index 0000000000..e8ab8dce70 --- /dev/null +++ b/libs/voipcodecs/src/vector_int.c @@ -0,0 +1,347 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * vector_int.c - Integer vector arithmetic + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: vector_int.c,v 1.6 2007/08/21 14:25:54 steveu Exp $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#if defined(HAVE_TGMATH_H) +#include +#endif +#if defined(HAVE_MATH_H) +#include +#endif +#include + +#include "voipcodecs/telephony.h" +#include "voipcodecs/vector_int.h" + +int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n) +{ + int32_t z; + +#if defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__( + " emms;\n" + " pxor %%mm0,%%mm0;\n" + " leal -32(%%esi,%%eax,2),%%edx;\n" /* edx = top - 32 */ + + " cmpl %%edx,%%esi;\n" + " ja 1f;\n" + + /* Work in blocks of 16 int16_t's until we are near the end */ + " .p2align 2;\n" + "2:\n" + " movq (%%edi),%%mm1;\n" + " movq (%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 8(%%edi),%%mm1;\n" + " movq 8(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 16(%%edi),%%mm1;\n" + " movq 16(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + " movq 24(%%edi),%%mm1;\n" + " movq 24(%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + + " addl $32,%%esi;\n" + " addl $32,%%edi;\n" + " cmpl %%edx,%%esi;\n" + " jbe 2b;\n" + + " .p2align 2;\n" + "1:\n" + " addl $24,%%edx;\n" /* now edx = top - 8 */ + " cmpl %%edx,%%esi;\n" + " ja 3f;\n" + + /* Work in blocks of 4 int16_t's until we are near the end */ + " .p2align 2;\n" + "4:\n" + " movq (%%edi),%%mm1;\n" + " movq (%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + + " addl $8,%%esi;\n" + " addl $8,%%edi;\n" + " cmpl %%edx,%%esi;" + " jbe 4b;\n" + + " .p2align 2;\n" + "3:\n" + " addl $4,%%edx;\n" /* now edx = top - 4 */ + " cmpl %%edx,%%esi;\n" + " ja 5f;\n" + + /* Work in a block of 2 int16_t's */ + " movd (%%edi),%%mm1;\n" + " movd (%%esi),%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + + " addl $4,%%esi;\n" + " addl $4,%%edi;\n" + + " .p2align 2;\n" + "5:\n" + " addl $2,%%edx;\n" /* now edx = top - 2 */ + " cmpl %%edx,%%esi;\n" + " ja 6f;\n" + + /* Deal with the very last int16_t, when n is odd */ + " movswl (%%edi),%%eax;\n" + " andl $65535,%%eax;\n" + " movd %%eax,%%mm1;\n" + " movswl (%%esi),%%eax;\n" + " andl $65535,%%eax;\n" + " movd %%eax,%%mm2;\n" + " pmaddwd %%mm2,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + + " .p2align 2;\n" + "6:\n" + /* Merge the pieces of the answer */ + " movq %%mm0,%%mm1;\n" + " punpckhdq %%mm0,%%mm1;\n" + " paddd %%mm1,%%mm0;\n" + /* et voila, eax has the final result */ + " movd %%mm0,%%eax;\n" + + " emms;\n" + : "=a" (z) + : "S" (x), "D" (y), "a" (n) + : "cc" + ); +#else + int i; + + z = 0; + for (i = 0; i < n; i++) + z += (int32_t) x[i]*(int32_t) y[i]; +#endif + return z; +} +/*- End of function --------------------------------------------------------*/ + +int32_t vec_min_maxi16(const int16_t x[], int n, int16_t out[]) +{ +#if defined(__GNUC__) && defined(__i386__) + static const int32_t lower_bound = 0x80008000; + static const int32_t upper_bound = 0x7FFF7FFF; + int32_t max; + + __asm__ __volatile__( + " emms;\n" + " pushl %%edx;\n" + " leal -8(%%esi,%%eax,2),%%edx;\n" + + " cmpl %%edx,%%esi;\n" + " jbe 2f;\n" + " movd %[lower],%%mm0;\n" + " movd %[upper],%%mm1;\n" + " jmp 1f;\n" + + " .p2align 2;\n" + "2:\n" + " movq (%%esi),%%mm0;\n" /* mm0 will be max's */ + " movq %%mm0,%%mm1;\n" /* mm1 will be min's */ + " addl $8,%%esi;\n" + " cmpl %%edx,%%esi;\n" + " ja 4f;\n" + + " .p2align 2;\n" + "3:\n" + " movq (%%esi),%%mm2;\n" + + " movq %%mm2,%%mm3;\n" + " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */ + " movq %%mm3,%%mm4;\n" + " pand %%mm2,%%mm3;\n" /* mm3 is mm2 masked to new max's */ + " pandn %%mm0,%%mm4;\n" /* mm4 is mm0 masked to its max's */ + " por %%mm3,%%mm4;\n" + " movq %%mm4,%%mm0;\n" /* Now mm0 is updated max's */ + + " movq %%mm1,%%mm3;\n" + " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */ + " pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */ + " pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */ + " por %%mm3,%%mm2;\n" + " movq %%mm2,%%mm1;\n" /* now mm1 is updated min's */ + + " addl $8,%%esi;\n" + " cmpl %%edx,%%esi;\n" + " jbe 3b;\n" + + " .p2align 2;\n" + "4:\n" + /* Merge down the 4-word max/mins to lower 2 words */ + " movq %%mm0,%%mm2;\n" + " psrlq $32,%%mm2;\n" + " movq %%mm2,%%mm3;\n" + " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */ + " pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new max's */ + " pandn %%mm0,%%mm3;\n" /* mm3 is mm0 masked to its max's */ + " por %%mm3,%%mm2;\n" + " movq %%mm2,%%mm0;\n" /* now mm0 is updated max's */ + + " movq %%mm1,%%mm2;\n" + " psrlq $32,%%mm2;\n" + " movq %%mm1,%%mm3;\n" + " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */ + " pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */ + " pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */ + " por %%mm3,%%mm2;\n" + " movq %%mm2,%%mm1;\n" /* now mm1 is updated min's */ + + " .p2align 2;\n" + "1:\n" + " addl $4,%%edx;\n" /* now dx = top-4 */ + " cmpl %%edx,%%esi;\n" + " ja 5f;\n" + /* Here, there are >= 2 words of input remaining */ + " movd (%%esi),%%mm2;\n" + + " movq %%mm2,%%mm3;\n" + " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */ + " movq %%mm3,%%mm4;\n" + " pand %%mm2,%%mm3;\n" /* mm3 is mm2 masked to new max's */ + " pandn %%mm0,%%mm4;\n" /* mm4 is mm0 masked to its max's */ + " por %%mm3,%%mm4;\n" + " movq %%mm4,%%mm0;\n" /* now mm0 is updated max's */ + + " movq %%mm1,%%mm3;\n" + " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */ + " pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */ + " pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */ + " por %%mm3,%%mm2;\n" + " movq %%mm2,%%mm1;\n" /* now mm1 is updated min's */ + + " addl $4,%%esi;\n" + + " .p2align 2;\n" + "5:\n" + /* Merge down the 2-word max/mins to 1 word */ + " movq %%mm0,%%mm2;\n" + " psrlq $16,%%mm2;\n" + " movq %%mm2,%%mm3;\n" + " pcmpgtw %%mm0,%%mm3;\n" /* mm3 is bitmask for words where mm2 > mm0 */ + " pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new max's */ + " pandn %%mm0,%%mm3;\n" /* mm3 is mm0 masked to its max's */ + " por %%mm3,%%mm2;\n" + " movd %%mm2,%%ecx;\n" /* cx is max so far */ + + " movq %%mm1,%%mm2;\n" + " psrlq $16,%%mm2;\n" + " movq %%mm1,%%mm3;\n" + " pcmpgtw %%mm2,%%mm3;\n" /* mm3 is bitmask for words where mm2 < mm1 */ + " pand %%mm3,%%mm2;\n" /* mm2 is mm2 masked to new min's */ + " pandn %%mm1,%%mm3;\n" /* mm3 is mm1 masked to its min's */ + " por %%mm3,%%mm2;\n" + " movd %%mm2,%%eax;\n" /* ax is min so far */ + + " addl $2,%%edx;\n" /* now dx = top-2 */ + " cmpl %%edx,%%esi;\n" + " ja 6f;\n" + + /* Here, there is one word of input left */ + " cmpw (%%esi),%%cx;\n" + " jge 9f;\n" + " movw (%%esi),%%cx;\n" + " .p2align 2;\n" + "9:\n" + " cmpw (%%esi),%%ax;\n" + " jle 6f;\n" + " movw (%%esi),%%ax;\n" + + " .p2align 2;\n" + "6:\n" + /* (finally!) cx is the max, ax the min */ + " movswl %%cx,%%ecx;\n" + " movswl %%ax,%%eax;\n" + + " popl %%edx;\n" /* ptr to output max,min vals */ + " andl %%edx,%%edx;\n" + " jz 7f;\n" + " movw %%cx,(%%edx);\n" /* max */ + " movw %%ax,2(%%edx);\n" /* min */ + " .p2align 2;\n" + "7:\n" + /* Now calculate max absolute value */ + " negl %%eax;\n" + " cmpl %%ecx,%%eax;\n" + " jge 8f;\n" + " movl %%ecx,%%eax;\n" + " .p2align 2;\n" + "8:\n" + " emms;\n" + : "=a" (max) + : "S" (x), "a" (n), "d" (out), [lower] "m" (lower_bound), [upper] "m" (upper_bound) + : "ecx" + ); + return max; +#else + int i; + int16_t min; + int16_t max; + int16_t temp; + int32_t z; + + max = INT16_MIN; + min = INT16_MAX; + for (i = 0; i < n; i++) + { + temp = x[i]; + if (temp > max) + max = temp; + /*endif*/ + if (temp < min) + min = temp; + /*endif*/ + } + /*endfor*/ + out[0] = max; + out[1] = min; + z = abs(min); + if (z > max) + return z; + return max; +#endif +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs.h.in b/libs/voipcodecs/src/voipcodecs.h.in new file mode 100644 index 0000000000..41c7c030fa --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs.h.in @@ -0,0 +1,54 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * voipcodecs.h - The head guy amongst the headers + * + * Written by Steve Underwood + * + * Copyright (C) 2003 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +/*! \file */ + +#if !defined(_VOIPCODECS_H_) +#define _VOIPCODECS_H_ + +@VOIPCODECS_USE_FIXED_POINT@ + +#include +@INSERT_INTTYPES_HEADER@ +#include +#include +#include +@INSERT_MATH_HEADER@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/bit_operations.h b/libs/voipcodecs/src/voipcodecs/bit_operations.h new file mode 100644 index 0000000000..9d5e928ca4 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/bit_operations.h @@ -0,0 +1,262 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * bit_operations.h - Various bit level operations, such as bit reversal + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: bit_operations.h,v 1.19 2007/12/13 11:31:32 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_BIT_OPERATIONS_H_) +#define _SPANDSP_BIT_OPERATIONS_H_ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! \brief Find the bit position of the highest set bit in a word + \param bits The word to be searched + \return The bit number of the highest set bit, or -1 if the word is zero. */ +static __inline__ int top_bit(unsigned int bits) +{ + int res; + +#if defined(__i386__) || defined(__x86_64__) + __asm__ (" xorl %[res],%[res];\n" + " decl %[res];\n" + " bsrl %[bits],%[res]\n" + : [res] "=&r" (res) + : [bits] "rm" (bits)); + return res; +#elif defined(__ppc__) || defined(__powerpc__) + __asm__ ("cntlzw %[res],%[bits];\n" + : [res] "=&r" (res) + : [bits] "r" (bits)); + return 31 - res; +#else + if (bits == 0) + return -1; + res = 0; + if (bits & 0xFFFF0000) + { + bits &= 0xFFFF0000; + res += 16; + } + if (bits & 0xFF00FF00) + { + bits &= 0xFF00FF00; + res += 8; + } + if (bits & 0xF0F0F0F0) + { + bits &= 0xF0F0F0F0; + res += 4; + } + if (bits & 0xCCCCCCCC) + { + bits &= 0xCCCCCCCC; + res += 2; + } + if (bits & 0xAAAAAAAA) + { + bits &= 0xAAAAAAAA; + res += 1; + } + return res; +#endif +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Find the bit position of the lowest set bit in a word + \param bits The word to be searched + \return The bit number of the lowest set bit, or -1 if the word is zero. */ +static __inline__ int bottom_bit(unsigned int bits) +{ + int res; + +#if defined(__i386__) || defined(__x86_64__) + __asm__ (" xorl %[res],%[res];\n" + " decl %[res];\n" + " bsfl %[bits],%[res]\n" + : [res] "=&r" (res) + : [bits] "rm" (bits)); + return res; +#else + if (bits == 0) + return -1; + res = 31; + if (bits & 0x0000FFFF) + { + bits &= 0x0000FFFF; + res -= 16; + } + if (bits & 0x00FF00FF) + { + bits &= 0x00FF00FF; + res -= 8; + } + if (bits & 0x0F0F0F0F) + { + bits &= 0x0F0F0F0F; + res -= 4; + } + if (bits & 0x33333333) + { + bits &= 0x33333333; + res -= 2; + } + if (bits & 0x55555555) + { + bits &= 0x55555555; + res -= 1; + } + return res; +#endif +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Bit reverse a byte. + \param data The byte to be reversed. + \return The bit reversed version of data. */ +static __inline__ uint8_t bit_reverse8(uint8_t x) +{ +#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__powerpc__) + /* If multiply is fast */ + return ((x*0x0802U & 0x22110U) | (x*0x8020U & 0x88440U))*0x10101U >> 16; +#else + /* If multiply is slow, but we have a barrel shifter */ + x = (x >> 4) | (x << 4); + x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2); + return ((x & 0xAA) >> 1) | ((x & 0x55) << 1); +#endif +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Bit reverse a 16 bit word. + \param data The word to be reversed. + \return The bit reversed version of data. */ +uint16_t bit_reverse16(uint16_t data); + +/*! \brief Bit reverse a 32 bit word. + \param data The word to be reversed. + \return The bit reversed version of data. */ +uint32_t bit_reverse32(uint32_t data); + +/*! \brief Bit reverse each of the four bytes in a 32 bit word. + \param data The word to be reversed. + \return The bit reversed version of data. */ +uint32_t bit_reverse_4bytes(uint32_t data); + +#if defined(__x86_64__) +/*! \brief Bit reverse each of the eight bytes in a 64 bit word. + \param data The word to be reversed. + \return The bit reversed version of data. */ +uint64_t bit_reverse_8bytes(uint64_t data); +#endif + +/*! \brief Bit reverse each bytes in a buffer. + \param to The buffer to place the reversed data in. + \param from The buffer containing the data to be reversed. + \param len The length of the data in the buffer. */ +void bit_reverse(uint8_t to[], const uint8_t from[], int len); + +/*! \brief Find the number of set bits in a 32 bit word. + \param x The word to be searched. + \return The number of set bits. */ +int one_bits32(uint32_t x); + +/*! \brief Create a mask as wide as the number in a 32 bit word. + \param x The word to be searched. + \return The mask. */ +uint32_t make_mask32(uint32_t x); + +/*! \brief Create a mask as wide as the number in a 16 bit word. + \param x The word to be searched. + \return The mask. */ +uint16_t make_mask16(uint16_t x); + +/*! \brief Find the least significant one in a word, and return a word + with just that bit set. + \param x The word to be searched. + \return The word with the single set bit. */ +static __inline__ uint32_t least_significant_one32(uint32_t x) +{ + return (x & (-(int32_t) x)); +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Find the most significant one in a word, and return a word + with just that bit set. + \param x The word to be searched. + \return The word with the single set bit. */ +static __inline__ uint32_t most_significant_one32(uint32_t x) +{ +#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__powerpc__) + return 1 << top_bit(x); +#else + x = make_mask32(x); + return (x ^ (x >> 1)); +#endif +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Find the parity of a byte. + \param x The byte to be checked. + \return 1 for odd, or 0 for even. */ +static __inline__ int parity8(uint8_t x) +{ + x = (x ^ (x >> 4)) & 0x0F; + return (0x6996 >> x) & 1; +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Find the parity of a 16 bit word. + \param x The word to be checked. + \return 1 for odd, or 0 for even. */ +static __inline__ int parity16(uint16_t x) +{ + x ^= (x >> 8); + x = (x ^ (x >> 4)) & 0x0F; + return (0x6996 >> x) & 1; +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Find the parity of a 32 bit word. + \param x The word to be checked. + \return 1 for odd, or 0 for even. */ +static __inline__ int parity32(uint32_t x) +{ + x ^= (x >> 16); + x ^= (x >> 8); + x = (x ^ (x >> 4)) & 0x0F; + return (0x6996 >> x) & 1; +} +/*- End of function --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/bitstream.h b/libs/voipcodecs/src/voipcodecs/bitstream.h new file mode 100644 index 0000000000..15131fdcce --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/bitstream.h @@ -0,0 +1,89 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * bitstream.h - Bitstream composition and decomposition routines. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: bitstream.h,v 1.8 2007/12/13 11:31:32 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_BITSTREAM_H_) +#define _SPANDSP_BITSTREAM_H_ + +/*! \page bitstream_page Bitstream composition and decomposition +\section bitstream_page_sec_1 What does it do? + +\section bitstream_page_sec_2 How does it work? +*/ + +/*! Bitstream handler state */ +typedef struct +{ + /*! The bit stream. */ + unsigned int bitstream; + /*! The residual bits in bitstream. */ + unsigned int residue; +} bitstream_state_t; + + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! \brief Put a chunk of bits into the output buffer. + \param s A pointer to the bitstream context. + \param c A pointer to the bitstream output buffer. + \param value The value to be pushed into the output buffer. + \param bits The number of bits of value to be pushed. 1 to 25 bit is valid. */ +void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits); + +void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits); + +/*! \brief Get a chunk of bits from the input buffer. + \param s A pointer to the bitstream context. + \param c A pointer to the bitstream input buffer. + \param bits The number of bits of value to be grabbed. 1 to 25 bit is valid. + \return The value retrieved from the input buffer. */ +unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits); + +unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits); + +/*! \brief Flush any residual bit to the output buffer. + \param s A pointer to the bitstream context. + \param c A pointer to the bitstream output buffer. */ +void bitstream_flush(bitstream_state_t *s, uint8_t **c); + +void bitstream_flush2(bitstream_state_t *s, uint8_t **c); + +/*! \brief Initialise a bitstream context. + \param s A pointer to the bitstream context. + \return A pointer to the bitstream context. */ +bitstream_state_t *bitstream_init(bitstream_state_t *s); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/dc_restore.h b/libs/voipcodecs/src/voipcodecs/dc_restore.h new file mode 100644 index 0000000000..64fee03456 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/dc_restore.h @@ -0,0 +1,127 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * dc_restore.h - General telephony routines to restore the zero D.C. + * level to audio which has a D.C. bias. + * + * Written by Steve Underwood + * + * Copyright (C) 2001 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: dc_restore.h,v 1.18 2007/04/08 08:16:17 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_DC_RESTORE_H_) +#define _SPANDSP_DC_RESTORE_H_ + +/*! \page dc_restore_page Removing DC bias from a signal + +\section dc_restore_page_sec_1 What does it do? + +Telecoms signals often contain considerable DC, but DC upsets a lot of signal +processing functions. Placing a zero DC restorer at the front of the processing +chain can often simplify the downstream processing. + +\section dc_restore_page_sec_2 How does it work? + +The DC restorer uses a leaky integrator to provide a long-ish term estimate of +the DC bias in the signal. A 32 bit estimate is used for the 16 bit audio, so +the noise introduced by the estimation can be keep in the lower bits, and the 16 +bit DC value, which is subtracted from the signal, is fairly clean. The +following code fragment shows the algorithm used. dc_bias is a 32 bit integer, +while the sample and the resulting clean_sample are 16 bit integers. + + dc_bias += ((((int32_t) sample << 15) - dc_bias) >> 14); + clean_sample = sample - (dc_bias >> 15); +*/ + +/*! + Zero DC restoration descriptor. This defines the working state for a single + instance of DC content filter. +*/ +typedef struct +{ + int32_t state; +} dc_restore_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +static __inline__ void dc_restore_init(dc_restore_state_t *dc) +{ + dc->state = 0; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t dc_restore(dc_restore_state_t *dc, int16_t sample) +{ + dc->state += ((((int32_t) sample << 15) - dc->state) >> 14); + return (int16_t) (sample - (dc->state >> 15)); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t dc_restore_estimate(dc_restore_state_t *dc) +{ + return (int16_t) (dc->state >> 15); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t saturate(int32_t amp) +{ + int16_t amp16; + + /* Hopefully this is optimised for the common case - not clipping */ + amp16 = (int16_t) amp; + if (amp == amp16) + return amp16; + if (amp > INT16_MAX) + return INT16_MAX; + return INT16_MIN; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t fsaturatef(float famp) +{ + if (famp > 32767.0) + return INT16_MAX; + if (famp < -32768.0) + return INT16_MIN; + return (int16_t) rintf(famp); +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int16_t fsaturate(double damp) +{ + if (damp > 32767.0) + return INT16_MAX; + if (damp < -32768.0) + return INT16_MIN; + return (int16_t) rint(damp); +} +/*- End of function --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/g711.h b/libs/voipcodecs/src/voipcodecs/g711.h new file mode 100644 index 0000000000..bf4b8e72b8 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/g711.h @@ -0,0 +1,255 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g711.h - In line A-law and u-law conversion routines + * + * Written by Steve Underwood + * + * Copyright (C) 2001 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: g711.h,v 1.8 2007/12/13 11:31:32 steveu Exp $ + */ + +/*! \file */ + +/*! \page g711_page A-law and mu-law handling +Lookup tables for A-law and u-law look attractive, until you consider the impact +on the CPU cache. If it causes a substantial area of your processor cache to get +hit too often, cache sloshing will severely slow things down. The main reason +these routines are slow in C, is the lack of direct access to the CPU's "find +the first 1" instruction. A little in-line assembler fixes that, and the +conversion routines can be faster than lookup tables, in most real world usage. +A "find the first 1" instruction is available on most modern CPUs, and is a +much underused feature. + +If an assembly language method of bit searching is not available, these routines +revert to a method that can be a little slow, so the cache thrashing might not +seem so bad :( + +Feel free to submit patches to add fast "find the first 1" support for your own +favourite processor. + +Look up tables are used for transcoding between A-law and u-law, since it is +difficult to achieve the precise transcoding procedure laid down in the G.711 +specification by other means. +*/ + +#if !defined(_SPANDSP_G711_H_) +#define _SPANDSP_G711_H_ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* N.B. It is tempting to use look-up tables for A-law and u-law conversion. + * However, you should consider the cache footprint. + * + * A 64K byte table for linear to x-law and a 512 byte table for x-law to + * linear sound like peanuts these days, and shouldn't an array lookup be + * real fast? No! When the cache sloshes as badly as this one will, a tight + * calculation may be better. The messiest part is normally finding the + * segment, but a little inline assembly can fix that on an i386, x86_64 and + * many other modern processors. + */ + +/* + * Mu-law is basically as follows: + * + * Biased Linear Input Code Compressed Code + * ------------------------ --------------- + * 00000001wxyza 000wxyz + * 0000001wxyzab 001wxyz + * 000001wxyzabc 010wxyz + * 00001wxyzabcd 011wxyz + * 0001wxyzabcde 100wxyz + * 001wxyzabcdef 101wxyz + * 01wxyzabcdefg 110wxyz + * 1wxyzabcdefgh 111wxyz + * + * Each biased linear code has a leading 1 which identifies the segment + * number. The value of the segment number is equal to 7 minus the number + * of leading 0's. The quantization interval is directly available as the + * four bits wxyz. * The trailing bits (a - h) are ignored. + * + * Ordinarily the complement of the resulting code word is used for + * transmission, and so the code word is complemented before it is returned. + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */ +#define ULAW_BIAS 0x84 /* Bias for linear code. */ + +/*! \brief Encode a linear sample to u-law + \param linear The sample to encode. + \return The u-law value. +*/ +static __inline__ uint8_t linear_to_ulaw(int linear) +{ + uint8_t u_val; + int mask; + int seg; + + /* Get the sign and the magnitude of the value. */ + if (linear >= 0) + { + linear = ULAW_BIAS + linear; + mask = 0xFF; + } + else + { + linear = ULAW_BIAS - linear; + mask = 0x7F; + } + + seg = top_bit(linear | 0xFF) - 7; + + /* + * Combine the sign, segment, quantization bits, + * and complement the code word. + */ + if (seg >= 8) + u_val = (uint8_t) (0x7F ^ mask); + else + u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask); +#ifdef ULAW_ZEROTRAP + /* Optional ITU trap */ + if (u_val == 0) + u_val = 0x02; +#endif + return u_val; +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Decode an u-law sample to a linear value. + \param ulaw The u-law sample to decode. + \return The linear value. +*/ +static __inline__ int16_t ulaw_to_linear(uint8_t ulaw) +{ + int t; + + /* Complement to obtain normal u-law value. */ + ulaw = ~ulaw; + /* + * Extract and bias the quantization bits. Then + * shift up by the segment number and subtract out the bias. + */ + t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4); + return (int16_t) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS)); +} +/*- End of function --------------------------------------------------------*/ + +/* + * A-law is basically as follows: + * + * Linear Input Code Compressed Code + * ----------------- --------------- + * 0000000wxyza 000wxyz + * 0000001wxyza 001wxyz + * 000001wxyzab 010wxyz + * 00001wxyzabc 011wxyz + * 0001wxyzabcd 100wxyz + * 001wxyzabcde 101wxyz + * 01wxyzabcdef 110wxyz + * 1wxyzabcdefg 111wxyz + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ + +#define ALAW_AMI_MASK 0x55 + +/*! \brief Encode a linear sample to A-law + \param linear The sample to encode. + \return The A-law value. +*/ +static __inline__ uint8_t linear_to_alaw(int linear) +{ + int mask; + int seg; + + if (linear >= 0) + { + /* Sign (bit 7) bit = 1 */ + mask = ALAW_AMI_MASK | 0x80; + } + else + { + /* Sign (bit 7) bit = 0 */ + mask = ALAW_AMI_MASK; + linear = -linear - 1; + } + + /* Convert the scaled magnitude to segment number. */ + seg = top_bit(linear | 0xFF) - 7; + if (seg >= 8) + { + if (linear >= 0) + { + /* Out of range. Return maximum value. */ + return (uint8_t) (0x7F ^ mask); + } + /* We must be just a tiny step below zero */ + return (uint8_t) (0x00 ^ mask); + } + /* Combine the sign, segment, and quantization bits. */ + return (uint8_t) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask); +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Decode an A-law sample to a linear value. + \param alaw The A-law sample to decode. + \return The linear value. +*/ +static __inline__ int16_t alaw_to_linear(uint8_t alaw) +{ + int i; + int seg; + + alaw ^= ALAW_AMI_MASK; + i = ((alaw & 0x0F) << 4); + seg = (((int) alaw & 0x70) >> 4); + if (seg) + i = (i + 0x108) << (seg - 1); + else + i += 8; + return (int16_t) ((alaw & 0x80) ? i : -i); +} +/*- End of function --------------------------------------------------------*/ + +/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711. + \param alaw The A-law sample to transcode. + \return The best matching u-law value. +*/ +uint8_t alaw_to_ulaw(uint8_t alaw); + +/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711. + \param ulaw The u-law sample to transcode. + \return The best matching A-law value. +*/ +uint8_t ulaw_to_alaw(uint8_t ulaw); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/g722.h b/libs/voipcodecs/src/voipcodecs/g722.h new file mode 100644 index 0000000000..d96d15b21d --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/g722.h @@ -0,0 +1,180 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g722.h - The ITU G.722 codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based on a single channel G.722 codec which is: + * + ***** Copyright (c) CMU 1993 ***** + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722.h,v 1.16 2007/04/08 08:16:17 steveu Exp $ + */ + + +/*! \file */ + +#if !defined(_SPANDSP_G722_H_) +#define _SPANDSP_G722_H_ + +/*! \page g722_page G.722 encoding and decoding +\section g722_page_sec_1 What does it do? +The G.722 module is a bit exact implementation of the ITU G.722 specification for all three +specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests. + +To allow fast and flexible interworking with narrow band telephony, the encoder and decoder +support an option for the linear audio to be an 8k samples/second stream. In this mode the +codec is considerably faster, and still fully compatible with wideband terminals using G.722. + +\section g722_page_sec_2 How does it work? +???. +*/ + +enum +{ + G722_SAMPLE_RATE_8000 = 0x0001, + G722_PACKED = 0x0002 +}; + +typedef struct +{ + /*! TRUE if the operating in the special ITU test mode, with the band split filters + disabled. */ + int itu_test_mode; + /*! TRUE if the G.722 data is packed */ + int packed; + /*! TRUE if encode from 8k samples/second */ + int eight_k; + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ + int bits_per_sample; + + /*! Signal history for the QMF */ + int x[24]; + + struct + { + int s; + int sp; + int sz; + int r[3]; + int a[3]; + int ap[3]; + int p[3]; + int d[7]; + int b[7]; + int bp[7]; + int sg[7]; + int nb; + int det; + } band[2]; + + unsigned int in_buffer; + int in_bits; + unsigned int out_buffer; + int out_bits; +} g722_encode_state_t; + +typedef struct +{ + /*! TRUE if the operating in the special ITU test mode, with the band split filters + disabled. */ + int itu_test_mode; + /*! TRUE if the G.722 data is packed */ + int packed; + /*! TRUE if decode to 8k samples/second */ + int eight_k; + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ + int bits_per_sample; + + /*! Signal history for the QMF */ + int x[24]; + + struct + { + int s; + int sp; + int sz; + int r[3]; + int a[3]; + int ap[3]; + int p[3]; + int d[7]; + int b[7]; + int bp[7]; + int sg[7]; + int nb; + int det; + } band[2]; + + unsigned int in_buffer; + int in_bits; + unsigned int out_buffer; + int out_bits; +} g722_decode_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Initialise an G.722 encode context. + \param s The G.722 encode context. + \param rate The required bit rate for the G.722 data. + The valid rates are 64000, 56000 and 48000. + \param options + \return A pointer to the G.722 encode context, or NULL for error. */ +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options); + +int g722_encode_release(g722_encode_state_t *s); + +/*! Encode a buffer of linear PCM data to G.722 + \param s The G.722 context. + \param g722_data The G.722 data produced. + \param amp The audio sample buffer. + \param len The number of samples in the buffer. + \return The number of bytes of G.722 data produced. */ +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len); + +/*! Initialise an G.722 decode context. + \param s The G.722 decode context. + \param rate The bit rate of the G.722 data. + The valid rates are 64000, 56000 and 48000. + \param options + \return A pointer to the G.722 decode context, or NULL for error. */ +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options); + +int g722_decode_release(g722_decode_state_t *s); + +/*! Decode a buffer of G.722 data to linear PCM. + \param s The G.722 context. + \param amp The audio sample buffer. + \param g722_data + \param len + \return The number of samples returned. */ +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/libs/voipcodecs/src/voipcodecs/g726.h b/libs/voipcodecs/src/voipcodecs/g726.h new file mode 100644 index 0000000000..df2e0b9480 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/g726.h @@ -0,0 +1,195 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g726.h - ITU G.726 codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based on G.721/G.723 code which is: + * + * This source code is a product of Sun Microsystems, Inc. and is provided + * for unrestricted use. Users may copy or modify this source code without + * charge. + * + * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING + * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun source code is provided with no support and without any obligation on + * the part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * $Id: g726.h,v 1.18 2007/12/13 11:31:32 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_G726_H_) +#define _SPANDSP_G726_H_ + +/*! \page g726_page G.726 encoding and decoding +\section g726_page_sec_1 What does it do? + +The G.726 module is a bit exact implementation of the full ITU G.726 specification. +It supports: + - 16 kbps, 24kbps, 32kbps, and 40kbps operation. + - Tandem adjustment, for interworking with A-law and u-law. + - Annex A support, for use in environments not using A-law or u-law. + +It passes the ITU tests. + +\section g726_page_sec_2 How does it work? +???. +*/ + +enum +{ + G726_ENCODING_LINEAR = 0, /* Interworking with 16 bit signed linear */ + G726_ENCODING_ULAW, /* Interworking with u-law */ + G726_ENCODING_ALAW /* Interworking with A-law */ +}; + +enum +{ + G726_PACKING_NONE = 0, + G726_PACKING_LEFT = 1, + G726_PACKING_RIGHT = 2 +}; + +struct g726_state_s; + +typedef int16_t (*g726_decoder_func_t)(struct g726_state_s *s, uint8_t code); + +typedef uint8_t (*g726_encoder_func_t)(struct g726_state_s *s, int16_t amp); + +/*! + * The following is the definition of the state structure + * used by the G.726 encoder and decoder to preserve their internal + * state between successive calls. The meanings of the majority + * of the state structure fields are explained in detail in the + * CCITT Recommendation G.721. The field names are essentially indentical + * to variable names in the bit level description of the coding algorithm + * included in this Recommendation. + */ +typedef struct g726_state_s +{ + /*! The bit rate */ + int rate; + /*! The external coding, for tandem operation */ + int ext_coding; + /*! The number of bits per sample */ + unsigned int bits_per_sample; + /*! One of the G.726_PACKING_xxx options */ + int packing; + + /*! Locked or steady state step size multiplier. */ + int32_t yl; + /*! Unlocked or non-steady state step size multiplier. */ + int16_t yu; + /*! int16_t term energy estimate. */ + int16_t dms; + /*! Long term energy estimate. */ + int16_t dml; + /*! Linear weighting coefficient of 'yl' and 'yu'. */ + int16_t ap; + + /*! Coefficients of pole portion of prediction filter. */ + int16_t a[2]; + /*! Coefficients of zero portion of prediction filter. */ + int16_t b[6]; + /*! Signs of previous two samples of a partially reconstructed signal. */ + int16_t pk[2]; + /*! Previous 6 samples of the quantized difference signal represented in + an internal floating point format. */ + int16_t dq[6]; + /*! Previous 2 samples of the quantized difference signal represented in an + internal floating point format. */ + int16_t sr[2]; + /*! Delayed tone detect */ + int td; + + /*! \brief The bit stream processing context. */ + bitstream_state_t bs; + + /*! \brief The current encoder function. */ + g726_encoder_func_t enc_func; + /*! \brief The current decoder function. */ + g726_decoder_func_t dec_func; +} g726_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Initialise a G.726 encode or decode context. + \param s The G.726 context. + \param bit_rate The required bit rate for the ADPCM data. + The valid rates are 16000, 24000, 32000 and 40000. + \param ext_coding The coding used outside G.726. + \param packing One of the G.726_PACKING_xxx options. + \return A pointer to the G.726 context, or NULL for error. */ +g726_state_t *g726_init(g726_state_t *s, int bit_rate, int ext_coding, int packing); + +/*! Free a G.726 encode or decode context. + \param s The G.726 context. + \return 0 for OK. */ +int g726_release(g726_state_t *s); + +/*! Decode a buffer of G.726 ADPCM data to linear PCM, a-law or u-law. + \param s The G.726 context. + \param amp The audio sample buffer. + \param g726_data + \param g726_bytes + \return The number of samples returned. */ +int g726_decode(g726_state_t *s, + int16_t amp[], + const uint8_t g726_data[], + int g726_bytes); + +/*! Encode a buffer of linear PCM data to G.726 ADPCM. + \param s The G.726 context. + \param g726_data The G.726 data produced. + \param amp The audio sample buffer. + \param len The number of samples in the buffer. + \return The number of bytes of G.726 data produced. */ +int g726_encode(g726_state_t *s, + uint8_t g726_data[], + const int16_t amp[], + int len); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/gsm0610.h b/libs/voipcodecs/src/voipcodecs/gsm0610.h new file mode 100644 index 0000000000..282065adcc --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/gsm0610.h @@ -0,0 +1,175 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * gsm0610.h - GSM 06.10 full rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: gsm0610.h,v 1.13 2007/12/13 11:31:32 steveu Exp $ + */ + +#if !defined(_SPANDSP_GSM0610_H_) +#define _SPANDSP_GSM0610_H_ + +/*! \page gsm0610_page GSM 06.10 encoding and decoding +\section gsm0610_page_sec_1 What does it do? + +The GSM 06.10 module is an version of the widely used GSM FR codec software +available from http://kbs.cs.tu-berlin.de/~jutta/toast.html. This version +was produced since some versions of this codec are not bit exact, or not +very efficient on modern processors. This implementation can use MMX instructions +on Pentium class processors, or alternative methods on other processors. It +passes all the ETSI test vectors. That is, it is a tested bit exact implementation. + +This implementation supports encoded data in one of three packing formats: + - Unpacked, with the 76 parameters of a GSM 06.10 code frame each occupying a + separate byte. (note that none of the parameters exceed 8 bits). + - Packed the the 33 byte per frame, used for VoIP, where 4 bits per frame are wasted. + - Packed in WAV49 format, where 2 frames are packed into 65 bytes. + +\section gsm0610_page_sec_2 How does it work? +???. +*/ + +enum +{ + GSM0610_PACKING_NONE, + GSM0610_PACKING_WAV49, + GSM0610_PACKING_VOIP +}; + +/*! + GSM 06.10 FR codec unpacked frame. +*/ +typedef struct +{ + int16_t LARc[8]; + int16_t Nc[4]; + int16_t bc[4]; + int16_t Mc[4]; + int16_t xmaxc[4]; + int16_t xMc[4][13]; +} gsm0610_frame_t; + +/*! + GSM 06.10 FR codec state descriptor. This defines the state of + a single working instance of the GSM 06.10 FR encoder or decoder. +*/ +typedef struct +{ + /*! \brief One of the packing modes */ + int packing; + + int16_t dp0[280]; + + /*! Preprocessing */ + int16_t z1; + int32_t L_z2; + /*! Pre-emphasis */ + int16_t mp; + + /*! Short term delay filter */ + int16_t u[8]; + int16_t LARpp[2][8]; + int16_t j; + + /*! Long term synthesis */ + int16_t nrp; + /*! Short term synthesis */ + int16_t v[9]; + /*! Decoder postprocessing */ + int16_t msr; + + /*! Encoder data */ + int16_t e[50]; +} gsm0610_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Initialise a GSM 06.10 encode or decode context. + \param s The GSM 06.10 context + \param packing One of the GSM0610_PACKING_xxx options. + \return A pointer to the GSM 06.10 context, or NULL for error. */ +gsm0610_state_t *gsm0610_init(gsm0610_state_t *s, int packing); + +/*! Release a GSM 06.10 encode or decode context. + \param s The GSM 06.10 context + \return 0 for success, else -1. */ +int gsm0610_release(gsm0610_state_t *s); + +/*! Set the packing format for a GSM 06.10 encode or decode context. + \param s The GSM 06.10 context + \param packing One of the GSM0610_PACKING_xxx options. + \return 0 for success, else -1. */ +int gsm0610_set_packing(gsm0610_state_t *s, int packing); + +/*! Encode a buffer of linear PCM data to GSM 06.10. + \param s The GSM 06.10 context. + \param code The GSM 06.10 data produced. + \param amp The audio sample buffer. + \param quant The number of samples in the buffer. + \return The number of bytes of GSM 06.10 data produced. */ +int gsm0610_encode(gsm0610_state_t *s, uint8_t code[], const int16_t amp[], int quant); + +/*! Decode a buffer of GSM 06.10 data to linear PCM. + \param s The GSM 06.10 context. + \param amp The audio sample buffer. + \param code The GSM 06.10 data. + \param quant The number of frames of GSM 06.10 data to be decoded. + \return The number of samples returned. */ +int gsm0610_decode(gsm0610_state_t *s, int16_t amp[], const uint8_t code[], int quant); + +int gsm0610_pack_none(uint8_t c[], const gsm0610_frame_t *s); + +/*! Pack a pair of GSM 06.10 frames in the format used for wave files (wave type 49). + \param c The buffer for the packed data. This must be at least 65 bytes long. + \param s A pointer to the frames to be packed. + \return The number of bytes generated. */ +int gsm0610_pack_wav49(uint8_t c[], const gsm0610_frame_t *s); + +/*! Pack a GSM 06.10 frames in the format used for VoIP. + \param c The buffer for the packed data. This must be at least 33 bytes long. + \param s A pointer to the frame to be packed. + \return The number of bytes generated. */ +int gsm0610_pack_voip(uint8_t c[], const gsm0610_frame_t *s); + +int gsm0610_unpack_none(gsm0610_frame_t *s, const uint8_t c[]); + +/*! Unpack a pair of GSM 06.10 frames from the format used for wave files (wave type 49). + \param s A pointer to a buffer into which the frames will be packed. + \param c The buffer containing the data to be unpacked. This must be at least 65 bytes long. + \return The number of bytes absorbed. */ +int gsm0610_unpack_wav49(gsm0610_frame_t *s, const uint8_t c[]); + +/*! Unpack a GSM 06.10 frame from the format used for VoIP. + \param s A pointer to a buffer into which the frame will be packed. + \param c The buffer containing the data to be unpacked. This must be at least 33 bytes long. + \return The number of bytes absorbed. */ +int gsm0610_unpack_voip(gsm0610_frame_t *s, const uint8_t c[]); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of include ---------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/ima_adpcm.h b/libs/voipcodecs/src/voipcodecs/ima_adpcm.h new file mode 100644 index 0000000000..8a54cb48f6 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/ima_adpcm.h @@ -0,0 +1,113 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * imaadpcm.c - Conversion routines between linear 16 bit PCM data and + * IMA/DVI/Intel ADPCM format. + * + * Written by Steve Underwood + * + * Copyright (C) 2004 Steve Underwood + * + * Based on a bit from here, a bit from there, eye of toad, + * ear of bat, etc - plus, of course, my own 2 cents. + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: ima_adpcm.h,v 1.16 2007/12/13 11:31:32 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_IMA_ADPCM_H_) +#define _SPANDSP_IMA_ADPCM_H_ + +/*! \page ima_adpcm_page IMA/DVI/Intel ADPCM encoding and decoding +\section ima_adpcm_page_sec_1 What does it do? +IMA ADPCM offers a good balance of simplicity and quality at a rate of +32kbps. + +\section ima_adpcm_page_sec_2 How does it work? + +\section ima_adpcm_page_sec_3 How do I use it? +*/ + +enum +{ + IMA_ADPCM_DVI4 = 0, + IMA_ADPCM_VDVI = 1 +}; + +/*! + IMA (DVI/Intel) ADPCM conversion state descriptor. This defines the state of + a single working instance of the IMA ADPCM converter. This is used for + either linear to ADPCM or ADPCM to linear conversion. +*/ +typedef struct +{ + int variant; + /*! \brief The last state of the ADPCM algorithm. */ + int last; + /*! \brief Current index into the step size table. */ + int step_index; + /*! \brief The current IMA code byte in progress. */ + uint16_t ima_byte; + int bits; +} ima_adpcm_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Initialise an IMA ADPCM encode or decode context. + \param s The IMA ADPCM context + \param variant ??? + \return A pointer to the IMA ADPCM context, or NULL for error. */ +ima_adpcm_state_t *ima_adpcm_init(ima_adpcm_state_t *s, int variant); + +/*! Free an IMA ADPCM encode or decode context. + \param s The IMA ADPCM context. + \return 0 for OK. */ +int ima_adpcm_release(ima_adpcm_state_t *s); + +/*! Encode a buffer of linear PCM data to IMA ADPCM. + \param s The IMA ADPCM context. + \param ima_data The IMA ADPCM data produced. + \param amp The audio sample buffer. + \param len The number of samples in the buffer. + \return The number of bytes of IMA ADPCM data produced. */ +int ima_adpcm_encode(ima_adpcm_state_t *s, + uint8_t ima_data[], + const int16_t amp[], + int len); + +/*! Decode a buffer of IMA ADPCM data to linear PCM. + \param s The IMA ADPCM context. + \param amp The audio sample buffer. + \param ima_data + \param ima_bytes + \return The number of samples returned. */ +int ima_adpcm_decode(ima_adpcm_state_t *s, + int16_t amp[], + const uint8_t ima_data[], + int ima_bytes); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/lpc10.h b/libs/voipcodecs/src/voipcodecs/lpc10.h new file mode 100644 index 0000000000..192d63dcac --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/lpc10.h @@ -0,0 +1,213 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * lpc10.h - LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: lpc10.h,v 1.13 2007/04/08 08:16:18 steveu Exp $ + */ + +#if !defined(_SPANDSP_LPC10_H_) +#define _SPANDSP_LPC10_H_ + +/*! \page lpc10_page LPC10 encoding and decoding +\section lpc10_page_sec_1 What does it do? +The LPC10 module implements the US Department of Defense LPC10 +codec. This codec produces compressed data at 2400bps. At such +a low rate high fidelity cannot be expected. However, the speech +clarity is quite good, and this codec is unencumbered by patent +or other restrictions. + +\section lpc10_page_sec_2 How does it work? +???. +*/ + +#define LPC10_SAMPLES_PER_FRAME 180 +#define LPC10_BITS_IN_COMPRESSED_FRAME 54 + +/*! + LPC10 codec unpacked frame. +*/ +typedef struct +{ + int32_t ipitch; + int32_t irms; + int32_t irc[10]; +} lpc10_frame_t; + +/*! + LPC10 codec encoder state descriptor. This defines the state of + a single working instance of the LPC10 encoder. +*/ +typedef struct +{ + int error_correction; + + /* State used only by function high_pass_100hz */ + float z11; + float z21; + float z12; + float z22; + + /* State used by function lpc10_analyse */ + float inbuf[LPC10_SAMPLES_PER_FRAME*3]; + float pebuf[LPC10_SAMPLES_PER_FRAME*3]; + float lpbuf[696]; + float ivbuf[312]; + float bias; + int32_t osbuf[10]; /* No initial value necessary */ + int32_t osptr; /* Initial value 1 */ + int32_t obound[3]; + int32_t vwin[3][2]; /* Initial value vwin[2][0] = 307; vwin[2][1] = 462; */ + int32_t awin[3][2]; /* Initial value awin[2][0] = 307; awin[2][1] = 462; */ + int32_t voibuf[4][2]; + float rmsbuf[3]; + float rcbuf[3][10]; + float zpre; + + /* State used by function onset */ + float n; + float d__; /* Initial value 1.0f */ + float fpc; /* No initial value necessary */ + float l2buf[16]; + float l2sum1; + int32_t l2ptr1; /* Initial value 1 */ + int32_t l2ptr2; /* Initial value 9 */ + int32_t lasti; /* No initial value necessary */ + int hyst; /* Initial value FALSE */ + + /* State used by function lpc10_voicing */ + float dither; /* Initial value 20.0f */ + float snr; + float maxmin; + float voice[3][2]; /* Initial value is probably unnecessary */ + int32_t lbve; + int32_t lbue; + int32_t fbve; + int32_t fbue; + int32_t ofbue; + int32_t sfbue; + int32_t olbue; + int32_t slbue; + + /* State used by function dynamic_pitch_tracking */ + float s[60]; + int32_t p[2][60]; + int32_t ipoint; + float alphax; + + /* State used by function lpc10_pack */ + int32_t isync; +} lpc10_encode_state_t; + +/*! + LPC10 codec decoder state descriptor. This defines the state of + a single working instance of the LPC10 decoder. +*/ +typedef struct +{ + int error_correction; + + /* State used by function decode */ + int32_t iptold; /* Initial value 60 */ + int first; /* Initial value TRUE */ + int32_t ivp2h; + int32_t iovoic; + int32_t iavgp; /* Initial value 60 */ + int32_t erate; + int32_t drc[10][3]; + int32_t dpit[3]; + int32_t drms[3]; + + /* State used by function synths */ + float buf[LPC10_SAMPLES_PER_FRAME*2]; + int32_t buflen; /* Initial value LPC10_SAMPLES_PER_FRAME */ + + /* State used by function pitsyn */ + int32_t ivoico; /* No initial value necessary as long as first_pitsyn is initially TRUE_ */ + int32_t ipito; /* No initial value necessary as long as first_pitsyn is initially TRUE_ */ + float rmso; /* Initial value 1.0f */ + float rco[10]; /* No initial value necessary as long as first_pitsyn is initially TRUE_ */ + int32_t jsamp; /* Nno initial value necessary as long as first_pitsyn is initially TRUE_ */ + int first_pitsyn; /* Initial value TRUE */ + + /* State used by function bsynz */ + int32_t ipo; + float exc[166]; + float exc2[166]; + float lpi[3]; + float hpi[3]; + float rmso_bsynz; + + /* State used by function random */ + int32_t j; + int32_t k; + int16_t y[5]; + + /* State used by function deemp */ + float dei[2]; + float deo[3]; +} lpc10_decode_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Initialise an LPC10e encode context. + \param s The LPC10e context + \param error_correction ??? + \return A pointer to the LPC10e context, or NULL for error. */ +lpc10_encode_state_t *lpc10_encode_init(lpc10_encode_state_t *s, int error_correction); + +int lpc10_encode_release(lpc10_encode_state_t *s); + +/*! Encode a buffer of linear PCM data to LPC10e. + \param s The LPC10e context. + \param ima_data The LPC10e data produced. + \param amp The audio sample buffer. + \param len The number of samples in the buffer. + \return The number of bytes of LPC10e data produced. */ +int lpc10_encode(lpc10_encode_state_t *s, uint8_t code[], const int16_t amp[], int quant); + +/*! Initialise an LPC10e decode context. + \param s The LPC10e context + \param error_correction ??? + \return A pointer to the LPC10e context, or NULL for error. */ +lpc10_decode_state_t *lpc10_decode_init(lpc10_decode_state_t *st, int error_correction); + +int lpc10_decode_release(lpc10_decode_state_t *s); + +/*! Decode a buffer of LPC10e data to linear PCM. + \param s The LPC10e context. + \param amp The audio sample buffer. + \param code The LPC10e data. + \param quant The number of frames of LPC10e data to be decoded. + \return The number of samples returned. */ +int lpc10_decode(lpc10_decode_state_t *s, int16_t amp[], const uint8_t code[], int quant); + + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of include ---------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/oki_adpcm.h b/libs/voipcodecs/src/voipcodecs/oki_adpcm.h new file mode 100644 index 0000000000..d050a995ee --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/oki_adpcm.h @@ -0,0 +1,119 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * oki_adpcm.h - Conversion routines between linear 16 bit PCM data and + * OKI (Dialogic) ADPCM format. + * + * Written by Steve Underwood + * + * Copyright (C) 2001 Steve Underwood + * + * Based on a bit from here, a bit from there, eye of toad, + * ear of bat, etc - plus, of course, my own 2 cents. + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: oki_adpcm.h,v 1.17 2007/12/13 11:31:33 steveu Exp $ + */ + +/*! \file */ + +#if !defined(_SPANDSP_OKI_ADPCM_H_) +#define _SPANDSP_OKI_ADPCM_H_ + +/*! \page okiadpcm_page OKI (Dialogic) ADPCM encoding and decoding +\section okiadpcm_page_sec_1 What does it do? +OKI ADPCM is widely used in the CTI industry because it is the principal format +supported by Dialogic. As the market leader, they tend to define "common +practice". It offers a good balance of simplicity and quality at rates of +24kbps or 32kbps. 32kbps is obtained by ADPCM compressing 8k samples/second linear +PCM. 24kbps is obtained by resampling to 6k samples/second and using the same ADPCM +compression algorithm on the slower samples. + +The algorithms for this ADPCM codec can be found in "PC Telephony - The complete guide +to designing, building and programming systems using Dialogic and Related Hardware" +by Bob Edgar. pg 272-276. */ + +/*! + Oki (Dialogic) ADPCM conversion state descriptor. This defines the state of + a single working instance of the Oki ADPCM converter. This is used for + either linear to ADPCM or ADPCM to linear conversion. +*/ +typedef struct +{ + /*! \brief The bit rate - 24000 or 32000. */ + int bit_rate; + /*! \brief The last state of the ADPCM algorithm. */ + int16_t last; + /*! \brief Current index into the step size table. */ + int16_t step_index; + /*! \brief The compressed data byte in progress. */ + uint8_t oki_byte; + /*! \brief The signal history for the sample rate converter. */ + int16_t history[32]; + /*! \brief Pointer into the history buffer. */ + int ptr; + /*! \brief Odd/even sample counter. */ + int mark; + /*! \brief Phase accumulator for the sample rate converter. */ + int phase; +} oki_adpcm_state_t; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/*! Initialise an Oki ADPCM encode or decode context. + \param s The Oki ADPCM context. + \param bit_rate The required bit rate for the ADPCM data. + The valid rates are 24000 and 32000. + \return A pointer to the Oki ADPCM context, or NULL for error. */ +oki_adpcm_state_t *oki_adpcm_init(oki_adpcm_state_t *s, int bit_rate); + +/*! Free an Oki ADPCM encode or decode context. + \param s The Oki ADPCM context. + \return 0 for OK. */ +int oki_adpcm_release(oki_adpcm_state_t *s); + +/*! Decode a buffer of Oki ADPCM data to linear PCM. + \param s The Oki ADPCM context. + \param amp The audio sample buffer. + \param oki_data + \param oki_bytes + \return The number of samples returned. */ +int oki_adpcm_decode(oki_adpcm_state_t *s, + int16_t amp[], + const uint8_t oki_data[], + int oki_bytes); + +/*! Encode a buffer of linear PCM data to Oki ADPCM. + \param s The Oki ADPCM context. + \param oki_data The Oki ADPCM data produced + \param amp The audio sample buffer. + \param len The number of samples in the buffer. + \return The number of bytes of Oki ADPCM data produced. */ +int oki_adpcm_encode(oki_adpcm_state_t *s, + uint8_t oki_data[], + const int16_t amp[], + int len); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/telephony.h b/libs/voipcodecs/src/voipcodecs/telephony.h new file mode 100644 index 0000000000..e9f079a27b --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/telephony.h @@ -0,0 +1,67 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * telephony.h - some very basic telephony definitions + * + * Written by Steve Underwood + * + * Copyright (C) 2003 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: telephony.h,v 1.10 2007/04/05 19:20:50 steveu Exp $ + */ + +#if !defined(_SPANDSP_TELEPHONY_H_) +#define _SPANDSP_TELEPHONY_H_ + +#define SAMPLE_RATE 8000 + +/* This is based on A-law, but u-law is only 0.03dB different */ +#define DBM0_MAX_POWER (3.14f + 3.02f) +#define DBM0_MAX_SINE_POWER (3.14f) +/* This is based on the ITU definition of dbOv in G.100.1 */ +#define DBOV_MAX_POWER (0.0f) +#define DBOV_MAX_SINE_POWER (-3.02f) + +/*! \brief A handler for pure receive. The buffer cannot be altered. */ +typedef int (span_rx_handler_t)(void *s, const int16_t amp[], int len); + +/*! \brief A handler for receive, where the buffer can be altered. */ +typedef int (span_mod_handler_t)(void *s, int16_t amp[], int len); + +/*! \brief A handler for transmit, where the buffer will be filled. */ +typedef int (span_tx_handler_t)(void *s, int16_t amp[], int max_len); + +#define ms_to_samples(t) (((t)*SAMPLE_RATE)/1000) + +#if !defined(FALSE) +#define FALSE 0 +#endif +#if !defined(TRUE) +#define TRUE (!FALSE) +#endif + +#if defined(__cplusplus) +/* C++ doesn't seem to have sane rounding functions/macros yet */ +#ifndef _MSC_VER +#define lrint(x) ((long int) (x)) +#define lrintf(x) ((long int) (x)) +#endif +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/vector_int.h b/libs/voipcodecs/src/voipcodecs/vector_int.h new file mode 100644 index 0000000000..92591ef096 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/vector_int.h @@ -0,0 +1,99 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * vector_int.h + * + * Written by Steve Underwood + * + * Copyright (C) 2003 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: vector_int.h,v 1.8 2007/12/13 11:31:33 steveu Exp $ + */ + +#if !defined(_SPANDSP_VECTOR_INT_H_) +#define _SPANDSP_VECTOR_INT_H_ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n); + +/*! \brief Find the minimum and maximum values in a vector. + \param x The vector to be searched. + \param n The number of elements in the vetor. + \param out A two element vector. The first will receive the + maximum. The second will receive the minimum. This parameter + may be set to NULL. + \return The absolute maximum value. Since the range of negative numbers + exceeds the range of positive one, the returned integer is longer + than the ones being searched. */ +int32_t vec_min_maxi16(const int16_t x[], int n, int16_t out[]); + +static __inline__ int vec_norm2i16(const int16_t *vec, int len) +{ + int i; + int sum; + + sum = 0; + for (i = 0; i < len; i++) + sum += vec[i]*vec[i]; + return sum; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ void vec_sari16(int16_t *vec, int len, int shift) +{ + int i; + + for (i = 0; i < len; i++) + vec[i] >>= shift; +} +/*- End of function --------------------------------------------------------*/ + +static __inline__ int vec_max_bitsi16(const int16_t *vec, int len) +{ + int i; + int max; + int v; + int b; + + max = 0; + for (i = 0; i < len; i++) + { + v = abs(vec[i]); + if (v > max) + max = v; + } + b = 0; + while (max != 0) + { + b++; + max >>= 1; + } + return b; +} +/*- End of function --------------------------------------------------------*/ + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/version.h b/libs/voipcodecs/src/voipcodecs/version.h new file mode 100644 index 0000000000..9991ad2268 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/version.h @@ -0,0 +1,37 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * version.h - A tag file, so the exact installed revision can be assertained. + * + * Written by Steve Underwood + * + * Copyright (C) 2007 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: version.h.in,v 1.2 2007/04/06 13:20:36 steveu Exp $ + */ + +#if !defined(_SPANDSP_VERSION_H_) +#define _SPANDSP_VERSION_H_ + +/* The date and time of the version are in UTC form. */ + +#define SPANDSP_RELEASE_DATE $SPANDSP_RELEASE_DATE +#define SPANDSP_RELEASE_TIME $SPANDSP_RELEASE_TIME + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/src/voipcodecs/version.h.in b/libs/voipcodecs/src/voipcodecs/version.h.in new file mode 100644 index 0000000000..9991ad2268 --- /dev/null +++ b/libs/voipcodecs/src/voipcodecs/version.h.in @@ -0,0 +1,37 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * version.h - A tag file, so the exact installed revision can be assertained. + * + * Written by Steve Underwood + * + * Copyright (C) 2007 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: version.h.in,v 1.2 2007/04/06 13:20:36 steveu Exp $ + */ + +#if !defined(_SPANDSP_VERSION_H_) +#define _SPANDSP_VERSION_H_ + +/* The date and time of the version are in UTC form. */ + +#define SPANDSP_RELEASE_DATE $SPANDSP_RELEASE_DATE +#define SPANDSP_RELEASE_TIME $SPANDSP_RELEASE_TIME + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/Makefile.am b/libs/voipcodecs/tests/Makefile.am new file mode 100644 index 0000000000..0f9c2a3a1e --- /dev/null +++ b/libs/voipcodecs/tests/Makefile.am @@ -0,0 +1,60 @@ +## +## SpanDSP - a series of DSP components for telephony +## +## Makefile.am -- Process this file with automake to produce Makefile.in +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 2, as +## published by the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## $Id: Makefile.am,v 1.94 2008/01/31 13:34:40 steveu Exp $ + +AM_CFLAGS = $(COMP_VENDOR_CFLAGS) + +LIBS += $(TESTLIBS) + +EXTRA_DIST = regression_tests.sh + +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I$(top_builddir)/src -DDATADIR="\"$(pkgdatadir)\"" + +LIBDIR = -L$(top_builddir)/src + +noinst_PROGRAMS = g711_tests \ + g722_tests \ + g726_tests \ + gsm0610_tests \ + ima_adpcm_tests \ + lpc10_tests \ + oki_adpcm_tests + +g711_tests_SOURCES = g711_tests.c +g711_tests_LDADD = $(LIBDIR) -lvoipcodecs -lspandsp + +g722_tests_SOURCES = g722_tests.c +g722_tests_LDADD = $(LIBDIR) -lvoipcodecs + +g726_tests_SOURCES = g726_tests.c +g726_tests_LDADD = $(LIBDIR) -lvoipcodecs + +gsm0610_tests_SOURCES = gsm0610_tests.c +gsm0610_tests_LDADD = $(LIBDIR) -lvoipcodecs + +ima_adpcm_tests_SOURCES = ima_adpcm_tests.c +ima_adpcm_tests_LDADD = $(LIBDIR) -lvoipcodecs + +lpc10_tests_SOURCES = lpc10_tests.c +lpc10_tests_LDADD = $(LIBDIR) -lvoipcodecs + +oki_adpcm_tests_SOURCES = oki_adpcm_tests.c +oki_adpcm_tests_LDADD = $(LIBDIR) -lvoipcodecs diff --git a/libs/voipcodecs/tests/g711_tests.c b/libs/voipcodecs/tests/g711_tests.c new file mode 100644 index 0000000000..d99f3201e2 --- /dev/null +++ b/libs/voipcodecs/tests/g711_tests.c @@ -0,0 +1,287 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g711_tests.c + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: g711_tests.c,v 1.7 2007/11/10 11:14:58 steveu Exp $ + */ + +/*! \page g711_tests_page A-law and u-law conversion tests +\section g711_tests_page_sec_1 What does it do? + +\section g711_tests_page_sec_2 How is it used? +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include "voipcodecs.h" +#include + +#define OUT_FILE_NAME "g711.wav" + +int16_t amp[65536]; + +const uint8_t alaw_1khz_sine[] = {0x34, 0x21, 0x21, 0x34, 0xB4, 0xA1, 0xA1, 0xB4}; +const uint8_t ulaw_1khz_sine[] = {0x1E, 0x0B, 0x0B, 0x1E, 0x9E, 0x8B, 0x8B, 0x9E}; + +int main(int argc, char *argv[]) +{ + AFfilehandle outhandle; + AFfilesetup filesetup; + power_meter_t power_meter; + int outframes; + int i; + int block; + int pre; + int post; + int post_post; + int alaw_failures; + int ulaw_failures; + float worst_alaw; + float worst_ulaw; + float tmp; + + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + + if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + + printf("Conversion accuracy tests.\n"); + alaw_failures = 0; + ulaw_failures = 0; + worst_alaw = 0.0; + worst_ulaw = 0.0; + for (block = 0; block < 1; block++) + { + for (i = 0; i < 65536; i++) + { + pre = i - 32768; + post = alaw_to_linear(linear_to_alaw(pre)); + if (abs(pre) > 140) + { + tmp = (float) abs(post - pre)/(float) abs(pre); + if (tmp > 0.10) + { + printf("A-law: Excessive error at %d (%d)\n", pre, post); + alaw_failures++; + } + if (tmp > worst_alaw) + worst_alaw = tmp; + } + else + { + /* Small values need different handling for sensible measurement */ + if (abs(post - pre) > 15) + { + printf("A-law: Excessive error at %d (%d)\n", pre, post); + alaw_failures++; + } + } + amp[i] = post; + } + outframes = afWriteFrames(outhandle, + AF_DEFAULT_TRACK, + amp, + 65536); + if (outframes != 65536) + { + fprintf(stderr, " Error writing wave file\n"); + exit(2); + } + for (i = 0; i < 65536; i++) + { + pre = i - 32768; + post = ulaw_to_linear(linear_to_ulaw(pre)); + if (abs(pre) > 40) + { + tmp = (float) abs(post - pre)/(float) abs(pre); + if (tmp > 0.10) + { + printf("u-law: Excessive error at %d (%d)\n", pre, post); + ulaw_failures++; + } + if (tmp > worst_ulaw) + worst_ulaw = tmp; + } + else + { + /* Small values need different handling for sensible measurement */ + if (abs(post - pre) > 4) + { + printf("u-law: Excessive error at %d (%d)\n", pre, post); + ulaw_failures++; + } + } + amp[i] = post; + } + outframes = afWriteFrames(outhandle, + AF_DEFAULT_TRACK, + amp, + 65536); + if (outframes != 65536) + { + fprintf(stderr, " Error writing wave file\n"); + exit(2); + } + } + printf("Worst A-law error (ignoring small values) %f%%\n", worst_alaw*100.0); + printf("Worst u-law error (ignoring small values) %f%%\n", worst_ulaw*100.0); + if (alaw_failures || ulaw_failures) + { + printf("%d A-law values with excessive error\n", alaw_failures); + printf("%d u-law values with excessive error\n", ulaw_failures); + printf("Tests failed\n"); + exit(2); + } + + printf("Cyclic conversion repeatability tests.\n"); + /* Find what happens to every possible linear value after a round trip. */ + for (i = 0; i < 65536; i++) + { + pre = i - 32768; + /* Make a round trip */ + post = alaw_to_linear(linear_to_alaw(pre)); + /* A second round trip should cause no further change */ + post_post = alaw_to_linear(linear_to_alaw(post)); + if (post_post != post) + { + printf("A-law second round trip mismatch - at %d, %d != %d\n", pre, post, post_post); + printf("Tests failed\n"); + exit(2); + } + /* Make a round trip */ + post = ulaw_to_linear(linear_to_ulaw(pre)); + /* A second round trip should cause no further change */ + post_post = ulaw_to_linear(linear_to_ulaw(post)); + if (post_post != post) + { + printf("u-law round trip mismatch - at %d, %d != %d\n", pre, post, post_post); + printf("Tests failed\n"); + exit(2); + } + } + + printf("Reference power level tests.\n"); + power_meter_init(&power_meter, 7); + + for (i = 0; i < 8000; i++) + { + amp[i] = ulaw_to_linear(ulaw_1khz_sine[i & 7]); + power_meter_update(&power_meter, amp[i]); + } + printf("Reference u-law 1kHz tone is %fdBm0\n", power_meter_current_dbm0(&power_meter)); + outframes = afWriteFrames(outhandle, + AF_DEFAULT_TRACK, + amp, + 8000); + if (outframes != 8000) + { + fprintf(stderr, " Error writing wave file\n"); + exit(2); + } + if (0.1f < fabs(power_meter_current_dbm0(&power_meter))) + { + printf("Test failed.\n"); + exit(2); + } + + for (i = 0; i < 8000; i++) + { + amp[i] = alaw_to_linear(alaw_1khz_sine[i & 7]); + power_meter_update(&power_meter, amp[i]); + } + printf("Reference A-law 1kHz tone is %fdBm0\n", power_meter_current_dbm0(&power_meter)); + outframes = afWriteFrames(outhandle, + AF_DEFAULT_TRACK, + amp, + 8000); + if (outframes != 8000) + { + fprintf(stderr, " Error writing wave file\n"); + exit(2); + } + if (0.1f < fabs(power_meter_current_dbm0(&power_meter))) + { + printf("Test failed.\n"); + exit(2); + } + + /* Check the transcoding functions. */ + printf("Testing transcoding A-law -> u-law -> A-law\n"); + for (i = 0; i < 256; i++) + { + if (alaw_to_ulaw(ulaw_to_alaw(i)) != i) + { + if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1) + { + printf("u-law -> A-law -> u-law gave %d -> %d\n", i, alaw_to_ulaw(ulaw_to_alaw(i))); + printf("Test failed\n"); + exit(2); + } + } + } + + printf("Testing transcoding u-law -> A-law -> u-law\n"); + for (i = 0; i < 256; i++) + { + if (ulaw_to_alaw(alaw_to_ulaw(i)) != i) + { + if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1) + { + printf("A-law -> u-law -> A-law gave %d -> %d\n", i, ulaw_to_alaw(alaw_to_ulaw(i))); + printf("Test failed\n"); + exit(2); + } + } + } + + if (afCloseFile(outhandle)) + { + fprintf(stderr, " Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + + printf("Tests passed.\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/g722_tests.c b/libs/voipcodecs/tests/g722_tests.c new file mode 100644 index 0000000000..bf281ffb84 --- /dev/null +++ b/libs/voipcodecs/tests/g722_tests.c @@ -0,0 +1,521 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g722_tests.c - Test G.722 encode and decode. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: g722_tests.c,v 1.19 2007/11/10 11:14:58 steveu Exp $ + */ + +/*! \file */ + +/*! \page g722_tests_page G.722 tests +\section g722_tests_page_sec_1 What does it do? +This modules implements two sets of tests: + - The tests defined in the G.722 specification, using the test data files supplied + with the specification. + - A generally audio quality test, consisting of compressing and decompressing a speeech + file for audible comparison. + +The speech file should be recorded at 16 bits/sample, 16000 samples/second, and named +"pre_g722.wav". + +The ITU tests use the codec in a special mode, in which the QMFs, which split and recombine the +sub-bands, are disabled. This means they do not test 100% of the codec. This is the reason for +including the additional listening test. + +\section g722_tests_page_sec_2 How is it used? +To perform the tests in the G.722 specification you need to obtain the test data files from the +specification. These are copyright material, and so cannot be distributed with this test software. + +The files, containing test vectors, which are supplied with the G.722 specification, should be +copied to itutests/g722. The ITU tests can then be run by executing g722_tests without +any parameters. + +To perform a general audio quality test, g722_tests should be run with a parameter specifying +the required bit rate for compression. The valid parameters are "-48", "-56", and "-64". +The file ../localtests/short_wb_voice.wav will be compressed to the specified bit rate, decompressed, +and the resulting audio stored in post_g722.wav. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "voipcodecs.h" + +#define G722_SAMPLE_RATE 16000 + +#define BLOCK_LEN 320 + +#define MAX_TEST_VECTOR_LEN 40000 + +#define TESTDATA_DIR "../itutests/g722/" + +#define EIGHTK_IN_FILE_NAME "../localtests/short_nb_voice.wav" +#define IN_FILE_NAME "../localtests/short_wb_voice.wav" +#define OUT_FILE_NAME "post_g722.wav" + +#if 0 +static const char *itu_test_files[] = +{ + TESTDATA_DIR "T1C1.XMT", /* 69973 bytes */ + TESTDATA_DIR "T1C2.XMT", /* 3605 bytes */ + TESTDATA_DIR "T1D3.COD", /* 69973 bytes */ + + TESTDATA_DIR "T2R1.COD", /* 69973 bytes */ + TESTDATA_DIR "T2R2.COD", /* 3605 bytes */ + + TESTDATA_DIR "T3L1.RC1", /* 69973 bytes */ + TESTDATA_DIR "T3L1.RC2", /* 69973 bytes */ + TESTDATA_DIR "T3L1.RC3", /* 69973 bytes */ + TESTDATA_DIR "T3H1.RC0", /* 69973 bytes */ + TESTDATA_DIR "T3L2.RC1", /* 3605 bytes */ + TESTDATA_DIR "T3L2.RC2", /* 3605 bytes */ + TESTDATA_DIR "T3L2.RC3", /* 3605 bytes */ + TESTDATA_DIR "T3H2.RC0", /* 3605 bytes */ + TESTDATA_DIR "T3L3.RC1", /* 69973 bytes */ + TESTDATA_DIR "T3L3.RC2", /* 69973 bytes */ + TESTDATA_DIR "T3L3.RC3", /* 69973 bytes */ + TESTDATA_DIR "T3H3.RC0" /* 69973 bytes */ +}; +#endif + +static const char *encode_test_files[] = +{ + TESTDATA_DIR "T1C1.XMT", TESTDATA_DIR "T2R1.COD", + TESTDATA_DIR "T1C2.XMT", TESTDATA_DIR "T2R2.COD", + NULL +}; + +static const char *decode_test_files[] = +{ + TESTDATA_DIR "T2R1.COD", + TESTDATA_DIR "T3L1.RC1", + TESTDATA_DIR "T3L1.RC2", + TESTDATA_DIR "T3L1.RC3", + TESTDATA_DIR "T3H1.RC0", + + TESTDATA_DIR "T2R2.COD", + TESTDATA_DIR "T3L2.RC1", + TESTDATA_DIR "T3L2.RC2", + TESTDATA_DIR "T3L2.RC3", + TESTDATA_DIR "T3H2.RC0", + + TESTDATA_DIR "T1D3.COD", + TESTDATA_DIR "T3L3.RC1", + TESTDATA_DIR "T3L3.RC2", + TESTDATA_DIR "T3L3.RC3", + TESTDATA_DIR "T3H3.RC0", + + NULL +}; + +int16_t itu_data[MAX_TEST_VECTOR_LEN]; +uint16_t itu_ref[MAX_TEST_VECTOR_LEN]; +uint16_t itu_ref_upper[MAX_TEST_VECTOR_LEN]; +uint8_t compressed[MAX_TEST_VECTOR_LEN]; +int16_t decompressed[MAX_TEST_VECTOR_LEN]; + +static int hex_get(char *s) +{ + int i; + int value; + int x; + + for (value = i = 0; i < 4; i++) + { + x = *s++ - 0x30; + if (x > 9) + x -= 0x07; + if (x > 15) + x -= 0x20; + if (x < 0 || x > 15) + return -1; + value <<= 4; + value |= x; + } + return value; +} +/*- End of function --------------------------------------------------------*/ + +static int get_vector(FILE *file, uint16_t vec[]) +{ + char buf[132 + 1]; + char *s; + int i; + int value; + + while (fgets(buf, 133, file)) + { + if (buf[0] == '/' && buf[1] == '*') + continue; + s = buf; + i = 0; + while ((value = hex_get(s)) >= 0) + { + vec[i++] = value; + s += 4; + } + return i; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int get_test_vector(const char *file, uint16_t buf[], int max_len) +{ + int octets; + int i; + FILE *infile; + + if ((infile = fopen(file, "r")) == NULL) + { + fprintf(stderr, " Failed to open '%s'\n", file); + exit(2); + } + octets = 0; + while ((i = get_vector(infile, buf + octets)) > 0) + octets += i; + fclose(infile); + return octets; +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + g722_encode_state_t enc_state; + g722_decode_state_t dec_state; + int len; + int len_comp; + int len_comp_upper; + int len_data; + int len2; + int len3; + int i; + int j; + int k; + int file; + AFfilehandle inhandle; + AFfilehandle outhandle; + AFfilesetup filesetup; + int outframes; + int samples; + int mode; + int itutests; + int bit_rate; + int eight_k_in; + int eight_k_out; + float x; + int16_t indata[BLOCK_LEN]; + int16_t outdata[BLOCK_LEN]; + uint8_t adpcmdata[BLOCK_LEN]; + + i = 1; + bit_rate = 64000; + eight_k_in = FALSE; + eight_k_out = FALSE; + itutests = TRUE; + while (argc > i) + { + if (strcmp(argv[i], "-48") == 0) + { + bit_rate = 48000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-56") == 0) + { + bit_rate = 56000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-64") == 0) + { + bit_rate = 64000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-8k8k") == 0) + { + eight_k_in = TRUE; + eight_k_out = TRUE; + i++; + } + else if (strcmp(argv[i], "-8k16k") == 0) + { + eight_k_in = TRUE; + eight_k_out = FALSE; + i++; + } + else if (strcmp(argv[i], "-16k8k") == 0) + { + eight_k_in = FALSE; + eight_k_out = TRUE; + i++; + } + else if (strcmp(argv[i], "-16k16k") == 0) + { + eight_k_in = FALSE; + eight_k_out = FALSE; + i++; + } + else + { + fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]); + exit(2); + } + } + + if (itutests) + { + /* ITU G.722 encode tests, using configuration 1. The QMF is bypassed */ + for (file = 0; encode_test_files[file]; file += 2) + { + printf("Testing %s -> %s\n", encode_test_files[file], encode_test_files[file + 1]); + + /* Get the input data */ + len_data = get_test_vector(encode_test_files[file], (uint16_t *) itu_data, MAX_TEST_VECTOR_LEN); + + /* Get the reference output data */ + len_comp = get_test_vector(encode_test_files[file + 1], itu_ref, MAX_TEST_VECTOR_LEN); + + /* Process the input data */ + /* Skip the reset stuff at each end of the data */ + for (i = 0; i < len_data; i++) + { + if ((itu_data[i] & 1) == 0) + break; + } + for (j = i; j < len_data; j++) + { + if ((itu_data[j] & 1)) + break; + } + len = j - i; + g722_encode_init(&enc_state, 64000, 0); + enc_state.itu_test_mode = TRUE; + len2 = g722_encode(&enc_state, compressed, itu_data + i, len); + + /* Check the result against the ITU's reference output data */ + j = 0; + for (k = 0; k < len2; k++) + { + if ((compressed[k] & 0xFF) != ((itu_ref[k + i] >> 8) & 0xFF)) + { + printf(">>> %6d %4x %4x\n", k, compressed[k] & 0xFF, itu_ref[k + i] & 0xFFFF); + j++; + } + } + printf("%d bad samples, out of %d/%d samples\n", j, len, len_data); + if (j) + { + printf("Test failed\n"); + exit(2); + } + printf("Test passed\n"); + } + + /* ITU G.722 decode tests, using configuration 2. The QMF is bypassed */ + /* Run each of the tests for each of the modes - 48kbps, 56kbps and 64kbps. */ + for (mode = 1; mode <= 3; mode++) + { + for (file = 0; decode_test_files[file]; file += 5) + { + printf("Testing mode %d, %s -> %s + %s\n", + mode, + decode_test_files[file], + decode_test_files[file + mode], + decode_test_files[file + 4]); + + /* Get the input data */ + len_data = get_test_vector(decode_test_files[file], (uint16_t *) itu_data, MAX_TEST_VECTOR_LEN); + + /* Get the lower reference output data */ + len_comp = get_test_vector(decode_test_files[file + mode], itu_ref, MAX_TEST_VECTOR_LEN); + + /* Get the upper reference output data */ + len_comp_upper = get_test_vector(decode_test_files[file + 4], itu_ref_upper, MAX_TEST_VECTOR_LEN); + + /* Process the input data */ + /* Skip the reset stuff at each end of the data */ + for (i = 0; i < len_data; i++) + { + if ((itu_data[i] & 1) == 0) + break; + } + for (j = i; j < len_data; j++) + { + if ((itu_data[j] & 1)) + break; + } + len = j - i; + for (k = 0; k < len; k++) + compressed[k] = itu_data[k + i] >> ((mode == 3) ? 10 : (mode == 2) ? 9 : 8); + + g722_decode_init(&dec_state, (mode == 3) ? 48000 : (mode == 2) ? 56000 : 64000, 0); + dec_state.itu_test_mode = TRUE; + len2 = g722_decode(&dec_state, decompressed, compressed, len); + + /* Check the result against the ITU's reference output data */ + j = 0; + for (k = 0; k < len2; k += 2) + { + if ((decompressed[k] & 0xFFFF) != (itu_ref[(k >> 1) + i] & 0xFFFF) + || + (decompressed[k + 1] & 0xFFFF) != (itu_ref_upper[(k >> 1) + i] & 0xFFFF)) + { + printf(">>> %6d %4x %4x %4x %4x\n", k >> 1, decompressed[k] & 0xFFFF, decompressed[k + 1] & 0xFFFF, itu_ref[(k >> 1) + i] & 0xFFFF, itu_ref_upper[(k >> 1) + i] & 0xFFFF); + j++; + } + } + printf("%d bad samples, out of %d/%d samples\n", j, len, len_data); + if (j) + { + printf("Test failed\n"); + exit(2); + } + printf("Test passed\n"); + } + } + + printf("Tests passed.\n"); + } + else + { + if (eight_k_in) + { + if ((inhandle = afOpenFile(EIGHTK_IN_FILE_NAME, "r", NULL)) == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot open wave file '%s'\n", EIGHTK_IN_FILE_NAME); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", EIGHTK_IN_FILE_NAME); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate %f in wave file '%s'\n", x, EIGHTK_IN_FILE_NAME); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", EIGHTK_IN_FILE_NAME); + exit(2); + } + } + else + { + if ((inhandle = afOpenFile(IN_FILE_NAME, "r", NULL)) == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot open wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) G722_SAMPLE_RATE) + { + printf(" Unexpected sample rate %f in wave file '%s'\n", x, IN_FILE_NAME); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + } + + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + if (eight_k_out) + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + else + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) G722_SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + if (eight_k_in) + g722_encode_init(&enc_state, bit_rate, G722_PACKED | G722_SAMPLE_RATE_8000); + else + g722_encode_init(&enc_state, bit_rate, G722_PACKED); + if (eight_k_out) + g722_decode_init(&dec_state, bit_rate, G722_PACKED | G722_SAMPLE_RATE_8000); + else + g722_decode_init(&dec_state, bit_rate, G722_PACKED); + for (;;) + { + samples = afReadFrames(inhandle, + AF_DEFAULT_TRACK, + indata, + BLOCK_LEN); + if (samples <= 0) + break; + len2 = g722_encode(&enc_state, adpcmdata, indata, samples); + len3 = g722_decode(&dec_state, outdata, adpcmdata, len2); + outframes = afWriteFrames(outhandle, + AF_DEFAULT_TRACK, + outdata, + len3); + if (outframes != len3) + { + fprintf(stderr, " Error writing wave file\n"); + exit(2); + } + } + if (afCloseFile(inhandle)) + { + fprintf(stderr, " Cannot close wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if (afCloseFile(outhandle)) + { + fprintf(stderr, " Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + + printf("'%s' transcoded to '%s' at %dbps.\n", IN_FILE_NAME, OUT_FILE_NAME, bit_rate); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/g726_tests.c b/libs/voipcodecs/tests/g726_tests.c new file mode 100644 index 0000000000..91fb64a798 --- /dev/null +++ b/libs/voipcodecs/tests/g726_tests.c @@ -0,0 +1,1334 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * g726_tests.c - Test G.726 encode and decode. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: g726_tests.c,v 1.17 2007/11/10 11:14:58 steveu Exp $ + */ + +/*! \file */ + +/*! \page g726_tests_page G.726 tests +\section g726_tests_page_sec_1 What does it do? +Two sets of tests are performed: + - The tests defined in the G.726 specification, using the test data files supplied with + the specification. + - A generally audio quality test, consisting of compressing and decompressing a speeech + file for audible comparison. + +The speech file should be recorded at 16 bits/sample, 8000 samples/second, and named +"pre_g726.wav". + +\section g726_tests_page_sec_2 How is it used? +To perform the tests in the G.726 specification you need to obtain the test data files from the +specification. These are copyright material, and so cannot be distributed with this test software. + +The files, containing test vectors, which are supplied with the G.726 specification, should be +copied to itutests/g726 so the files are arranged in the same directory heirarchy in which they +are supplied. That is, you should have file names like + + - itutests/g726/DISK1/INPUT/NRM.M + - itutests/g726/DISK1/INPUT/OVR.M + - itutests/g726/DISK2/INPUT/NRM.A + - itutests/g726/DISK2/INPUT/OVR.A + +in your source tree. The ITU tests can then be run by executing g726_tests without +any parameters. + +To perform a general audio quality test, g726_tests should be run with a parameter specifying +the required bit rate for compression. The valid parameters are "-16", "-24", "-32", and "-40". +The test file ../localtests/short_nb_voice.wav will be compressed to the specified bit rate, +decompressed, and the resulting audio stored in post_g726.wav. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "voipcodecs.h" + +#define BLOCK_LEN 320 +#define MAX_TEST_VECTOR_LEN 40000 + +#define IN_FILE_NAME "../localtests/short_nb_voice.wav" +#define OUT_FILE_NAME "post_g726.wav" + +#define TESTDATA_DIR "../itutests/g726/" + +int16_t outdata[MAX_TEST_VECTOR_LEN]; +uint8_t adpcmdata[MAX_TEST_VECTOR_LEN]; + +int16_t itudata[MAX_TEST_VECTOR_LEN]; +uint8_t itu_ref[MAX_TEST_VECTOR_LEN]; +uint8_t unpacked[MAX_TEST_VECTOR_LEN]; +uint8_t xlaw[MAX_TEST_VECTOR_LEN]; + +/* +Table 4 - V Reset and homing sequences for u-law + Normal I-input Overload +Algorithm Input Intermediate Output Input Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) + +16F NRM.M RN16FM.I RN16FM.O I16 RI16FM.O OVR.M RV16FM.I RV16FM.O + HN16FM.I HN16FM.O HI16FM.O HV16FM.I HV16FM.O + +24F NRM.M RN24FM.I RN24FM.O I24 RI24FM.O OVR.M RV24FM.I RV24FM.O + HN24FM.I HN24FM.O HI24FM.O HV24FM.I HV24FM.O + +32F NRM.M RN32FM.I RN32FM.O I32 RI32FM.O OVR.M RV32FM.I RV32FM.O + HN32FM.I HN32FM.O HI32FM.O HV32FM.I HV32FM.O + +40F NRM.M RN40FM.I RN40FM.O I40 RI40FM.O OVR.M RV40FM.I RV40FM.O + HN40FM.I HN40FM.O HI40FM.O HV40FM.I HV40FM.O + + +Table 5 - V Reset and homing sequences for A-law + Normal I-input Overload +Algorithm Input Intermediate Output Input Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) +16F NRM.A RN16FA.I RN16FA.O I16 RI16FA.O OVR.A RV16FA.I RV16FA.O + HN16FA.I HN16FA.O HI16FA.O HV16FA.I HV16FA.O + +24F NRM.A RN24FA.I RN24FA.O I24 RI24FA.O OVR.A RV24FA.I RV24FA.O + HN24FA.I HN24FA.O HI24FA.O HV24FA.I HV24FA.O + +32F NRM.A RN32FA.I RN32FA.O I32 RI32FA.O OVR.A RV32FA.I RV32FA.O + HN32FA.I HN32FA.O HI32FA.O HV32FA.I HV32FA.O + +40F NRM.A RN40FA.I RN40FA.O I40 RI40FA.O OVR.A RV40FA.I RV40FA.O + HN40FA.I HN40FA.O HI40FA.O HV40FA.I HV40FA.O + +Table 6 ¡V Reset and homing cross sequences for u-law -> A-law + Normal Overload +Algorithm Input Intermediate Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) +16F NRM.M RN16FM.I RN16FC.O OVR.M RV16FM.I RV16FC.O + HN16FM.I HN16FC.O HV16FM.I HV16FC.O + +24F NRM.M RN24FM.I RN24FC.O OVR.M RV24FM.I RV24FC.O + HN24FM.I HN24FC.O HV24FM.I HV24FC.O + +32F NRM.M RN32FM.I RN32FC.O OVR.M RV32FM.I RV32FC.O + HN32FM.I HN32FC.O HV32FM.I HV32FC.O + +40F NRM.M RN40FM.I RN40FC.O OVR.M RV40FM.I RV40FC.O + HN40FM.I HN40FC.O HV40FM.I HV40FC.O + +Table 7 ¡V Reset and homing cross sequences for A-law -> u-law + Normal Overload +Algorithm Input Intermediate Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) +16F NRM.A RN16FA.I RN16FX.O OVR.A RV16FA.I RV16FX.O + HN16FA.I HN16FX.O HV16FA.I HV16FX.O + +24F NRM.A RN24FA.I RN24FX.O OVR.A RV24FA.I RV24FX.O + HN24FA.I HN24FX.O HV24FA.I HV24FX.O + +32F NRM.A RN32FA.I RN32FX.O OVR.A RV32FA.I RV32FX.O + HN32FA.I HN32FX.O HV32FA.I HV32FX.O + +40F NRM.A RN40FA.I RN40FX.O OVR.A RV40FA.I RV40FX.O + HN40FA.I HN40FX.O HV40FA.I HV40FX.O +*/ + +#define G726_ENCODING_NONE 9999 + +typedef struct +{ + const char *conditioning_pcm_file; + const char *pcm_file; + const char *conditioning_adpcm_file; + const char *adpcm_file; + const char *output_file; + int rate; + int compression_law; + int decompression_law; +} test_set_t; + +static test_set_t itu_test_sets[] = +{ + /* u-law to u-law tests */ + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RN16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RN16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I16", + TESTDATA_DIR "DISK1/RESET/16/RI16FM.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RV16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RV16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RN24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RN24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I24", + TESTDATA_DIR "DISK1/RESET/24/RI24FM.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RV24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RV24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RN32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RN32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I32", + TESTDATA_DIR "DISK1/RESET/32/RI32FM.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RV32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RV32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RN40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RN40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I40", + TESTDATA_DIR "DISK1/RESET/40/RI40FM.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RV40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RV40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + /* A-law to A-law tests */ + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RN16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RN16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I16", + TESTDATA_DIR "DISK2/RESET/16/RI16FA.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RV16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RV16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RN24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RN24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I24", + TESTDATA_DIR "DISK2/RESET/24/RI24FA.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RV24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RV24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RN32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RN32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I32", + TESTDATA_DIR "DISK2/RESET/32/RI32FA.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RV32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RV32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RN40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RN40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I40", + TESTDATA_DIR "DISK2/RESET/40/RI40FA.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RV40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RV40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + /* u-law to A-law tests */ + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RN16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RN16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RV16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RV16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RN24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RN24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RV24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RV24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RN32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RN32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RV32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RV32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RN40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RN40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RV40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RV40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + /* A-law to u-law tests */ + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RN16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RN16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RV16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RV16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RN24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RN24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RV24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RV24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RN32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RN32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RV32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RV32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RN40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RN40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RV40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RV40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + /* u-law to u-law tests */ + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK1/HOMING/16/HN16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HN16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK1/INPUT/I16", + TESTDATA_DIR "DISK1/HOMING/16/HI16FM.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK1/HOMING/16/HV16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HV16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK1/HOMING/24/HN24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HN24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK1/INPUT/I24", + TESTDATA_DIR "DISK1/HOMING/24/HI24FM.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK1/HOMING/24/HV24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HV24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK1/HOMING/32/HN32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HN32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK1/INPUT/I32", + TESTDATA_DIR "DISK1/HOMING/32/HI32FM.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK1/HOMING/32/HV32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HV32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK1/HOMING/40/HN40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HN40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK1/INPUT/I40", + TESTDATA_DIR "DISK1/HOMING/40/HI40FM.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK1/HOMING/40/HV40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HV40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + /* A-law to A-law tests */ + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK2/HOMING/16/HN16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HN16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK2/INPUT/I16", + TESTDATA_DIR "DISK2/HOMING/16/HI16FA.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK2/HOMING/16/HV16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HV16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK2/HOMING/24/HN24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HN24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK2/INPUT/I24", + TESTDATA_DIR "DISK2/HOMING/24/HI24FA.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK2/HOMING/24/HV24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HV24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK2/HOMING/32/HN32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HN32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK2/INPUT/I32", + TESTDATA_DIR "DISK2/HOMING/32/HI32FA.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK2/HOMING/32/HV32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HV32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK2/HOMING/40/HN40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HN40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK2/INPUT/I40", + TESTDATA_DIR "DISK2/HOMING/40/HI40FA.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK2/HOMING/40/HV40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HV40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + /* u-law to A-law tests */ + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK1/HOMING/16/HN16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HN16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK1/HOMING/16/HV16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HV16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK1/HOMING/24/HN24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HN24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK1/HOMING/24/HV24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HV24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK1/HOMING/32/HN32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HN32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK1/HOMING/32/HV32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HV32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK1/HOMING/40/HN40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HN40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK1/HOMING/40/HV40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HV40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + /* A-law to u-law tests */ + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK2/HOMING/16/HN16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HN16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK2/HOMING/16/HV16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HV16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK2/HOMING/24/HN24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HN24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK2/HOMING/24/HV24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HV24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK2/HOMING/32/HN32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HN32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK2/HOMING/32/HV32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HV32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK2/HOMING/40/HN40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HN40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK2/HOMING/40/HV40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HV40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0 + } +}; + +static int hex_get(char *s) +{ + int i; + int value; + int x; + + for (value = i = 0; i < 2; i++) + { + x = *s++ - 0x30; + if (x > 9) + x -= 0x07; + if (x > 15) + x -= 0x20; + if (x < 0 || x > 15) + return -1; + value <<= 4; + value |= x; + } + return value; +} +/*- End of function --------------------------------------------------------*/ + +static int get_vector(FILE *file, uint8_t vec[]) +{ + char buf[132 + 1]; + char *s; + int i; + int value; + + while (fgets(buf, 133, file)) + { + s = buf; + i = 0; + while ((value = hex_get(s)) >= 0) + { + vec[i++] = value; + s += 2; + } + return i; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int get_test_vector(const char *file, uint8_t buf[], int max_len) +{ + int octets; + int i; + int sum; + FILE *infile; + + if ((infile = fopen(file, "r")) == NULL) + { + fprintf(stderr, " Failed to open '%s'\n", file); + exit(2); + } + octets = 0; + while ((i = get_vector(infile, buf + octets)) > 0) + octets += i; + fclose(infile); + /* The last octet is a sumcheck, so the real data octets are one less than + the total we have */ + octets--; + /* Test the checksum */ + for (sum = i = 0; i < octets; i++) + sum += buf[i]; + if (sum%255 != (int) buf[i]) + { + fprintf(stderr, " Sumcheck failed in '%s' - %x %x\n", file, sum%255, buf[i]); + exit(2); + } + return octets; +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + g726_state_t enc_state; + g726_state_t dec_state; + int len2; + int len3; + int i; + int test; + int bits_per_code; + int itutests; + int bit_rate; + int bad_samples; + AFfilehandle inhandle; + AFfilehandle outhandle; + AFfilesetup filesetup; + int16_t amp[1024]; + int frames; + int outframes; + int conditioning_samples; + int samples; + int conditioning_adpcm; + int adpcm; + int packing; + float x; + + i = 1; + bit_rate = 32000; + itutests = TRUE; + packing = G726_PACKING_NONE; + while (argc > i) + { + if (strcmp(argv[i], "-16") == 0) + { + bit_rate = 16000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-24") == 0) + { + bit_rate = 24000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-32") == 0) + { + bit_rate = 32000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-40") == 0) + { + bit_rate = 40000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-l") == 0) + { + packing = G726_PACKING_LEFT; + i++; + } + else if (strcmp(argv[i], "-r") == 0) + { + packing = G726_PACKING_RIGHT; + i++; + } + else + { + fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]); + exit(2); + } + } + + len2 = 0; + conditioning_samples = 0; + if (itutests) + { + for (test = 0; itu_test_sets[test].rate; test++) + { + printf("Test %2d: '%s' + '%s'\n" + " -> '%s' + '%s'\n" + " -> '%s' [%d, %d, %d]\n", + test, + itu_test_sets[test].conditioning_pcm_file, + itu_test_sets[test].pcm_file, + itu_test_sets[test].conditioning_adpcm_file, + itu_test_sets[test].adpcm_file, + itu_test_sets[test].output_file, + itu_test_sets[test].rate, + itu_test_sets[test].compression_law, + itu_test_sets[test].decompression_law); + switch (itu_test_sets[test].rate) + { + case 16000: + bits_per_code = 2; + break; + case 24000: + bits_per_code = 3; + break; + case 32000: + default: + bits_per_code = 4; + break; + case 40000: + bits_per_code = 5; + break; + } + if (itu_test_sets[test].compression_law != G726_ENCODING_NONE) + { + /* Test the encode side */ + g726_init(&enc_state, itu_test_sets[test].rate, itu_test_sets[test].compression_law, G726_PACKING_NONE); + if (itu_test_sets[test].conditioning_pcm_file[0]) + { + conditioning_samples = get_test_vector(itu_test_sets[test].conditioning_pcm_file, xlaw, MAX_TEST_VECTOR_LEN); + printf("Test %d: Homing %d samples at %dbps\n", test, conditioning_samples, itu_test_sets[test].rate); + } + else + { + conditioning_samples = 0; + } + samples = get_test_vector(itu_test_sets[test].pcm_file, xlaw + conditioning_samples, MAX_TEST_VECTOR_LEN); + memcpy(itudata, xlaw, samples + conditioning_samples); + printf("Test %d: Compressing %d samples at %dbps\n", test, samples, itu_test_sets[test].rate); + len2 = g726_encode(&enc_state, adpcmdata, itudata, conditioning_samples + samples); + } + /* Test the decode side */ + g726_init(&dec_state, itu_test_sets[test].rate, itu_test_sets[test].decompression_law, G726_PACKING_NONE); + if (itu_test_sets[test].conditioning_adpcm_file[0]) + { + conditioning_adpcm = get_test_vector(itu_test_sets[test].conditioning_adpcm_file, unpacked, MAX_TEST_VECTOR_LEN); + printf("Test %d: Homing %d octets at %dbps\n", test, conditioning_adpcm, itu_test_sets[test].rate); + } + else + { + conditioning_adpcm = 0; + } + adpcm = get_test_vector(itu_test_sets[test].adpcm_file, unpacked + conditioning_adpcm, MAX_TEST_VECTOR_LEN); + if (itu_test_sets[test].compression_law != G726_ENCODING_NONE) + { + /* Test our compressed version against the reference compressed version */ + printf("Test %d: Compressed data check - %d/%d octets\n", test, conditioning_adpcm + adpcm, len2); + if (conditioning_adpcm + adpcm == len2) + { + for (bad_samples = 0, i = conditioning_samples; i < len2; i++) + { + if (adpcmdata[i] != unpacked[i]) + { + bad_samples++; + printf("Test %d: Compressed mismatch %d %x %x\n", test, i, adpcmdata[i], unpacked[i]); + } + } + if (bad_samples > 0) + { + printf("Test failed\n"); + exit(2); + } + printf("Test passed\n"); + } + else + { + printf("Test %d: Length mismatch - ref = %d, processed = %d\n", test, conditioning_adpcm + adpcm, len2); + exit(2); + } + } + + len3 = g726_decode(&dec_state, outdata, unpacked, conditioning_adpcm + adpcm); + + /* Get the output reference data */ + samples = get_test_vector(itu_test_sets[test].output_file, xlaw, MAX_TEST_VECTOR_LEN); + memcpy(itu_ref, xlaw, samples); + /* Test our decompressed version against the reference decompressed version */ + printf("Test %d: Decompressed data check - %d/%d samples\n", test, samples, len3 - conditioning_adpcm); + if (samples == len3 - conditioning_adpcm) + { + for (bad_samples = 0, i = 0; i < len3; i++) + { + if (itu_ref[i] != ((uint8_t *) outdata)[i + conditioning_adpcm]) + { + bad_samples++; + printf("Test %d: Decompressed mismatch %d %x %x\n", test, i, itu_ref[i], ((uint8_t *) outdata)[i + conditioning_adpcm]); + } + } + if (bad_samples > 0) + { + printf("Test failed\n"); + exit(2); + } + printf("Test passed\n"); + } + else + { + printf("Test %d: Length mismatch - ref = %d, processed = %d\n", test, samples, len3 - conditioning_adpcm); + exit(2); + } + } + + printf("Tests passed.\n"); + } + else + { + if ((inhandle = afOpenFile(IN_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE) + { + printf(" Cannot open wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + + outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup); + if (outhandle == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + + printf("ADPCM packing is %d\n", packing); + g726_init(&enc_state, bit_rate, G726_ENCODING_LINEAR, packing); + g726_init(&dec_state, bit_rate, G726_ENCODING_LINEAR, packing); + + while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, amp, 159))) + { + adpcm = g726_encode(&enc_state, adpcmdata, amp, frames); + frames = g726_decode(&dec_state, amp, adpcmdata, adpcm); + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, amp, frames); + } + if (afCloseFile(inhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if (afCloseFile(outhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + printf("'%s' transcoded to '%s' at %dbps.\n", IN_FILE_NAME, OUT_FILE_NAME, bit_rate); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/gsm0610_tests.c b/libs/voipcodecs/tests/gsm0610_tests.c new file mode 100644 index 0000000000..bf8f6afb64 --- /dev/null +++ b/libs/voipcodecs/tests/gsm0610_tests.c @@ -0,0 +1,649 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * gsm0610_tests.c - Test the GSM 06.10 FR codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: gsm0610_tests.c,v 1.8 2007/11/10 11:14:58 steveu Exp $ + */ + +/*! \file */ + +/*! \page gsm0610_tests_page GSM 06.10 full rate codec tests +\section gsm0610_tests_page_sec_1 What does it do? +Two sets of tests are performed: + - The tests defined in the GSM 06.10 specification, using the test data files supplied with + the specification. + - A generally audio quality test, consisting of compressing and decompressing a speeech + file for audible comparison. + +The speech file should be recorded at 16 bits/sample, 8000 samples/second, and named +"pre_gsm0610.wav". + +\section gsm0610_tests_page_sec_2 How is it used? +To perform the tests in the GSM 06.10 specification you need to obtain the test data files from the +specification. These are copyright material, and so cannot be distributed with this test software. +They can, however, be freely downloaded from the ETSI web site. + +The files, containing test vectors, which are supplied with the GSM 06.10 specification, should be +copied to etsitests/gsm0610/unpacked so the files are arranged in the following directories. + +./fr_A: + Seq01-A.cod Seq01-A.inp Seq01-A.out + Seq02-A.cod Seq02-A.inp Seq02-A.out + Seq03-A.cod Seq03-A.inp Seq03-A.out + Seq04-A.cod Seq04-A.inp Seq04-A.out + Seq05-A.out + +./fr_L: + Seq01.cod Seq01.inp Seq01.out + Seq02.cod Seq02.inp Seq02.out + Seq03.cod Seq03.inp Seq03.out + Seq04.cod Seq04.inp Seq04.out + Seq05.cod Seq05.out + +./fr_U: + Seq01-U.cod Seq01-U.inp Seq01-U.out + Seq02-U.cod Seq02-U.inp Seq02-U.out + Seq03-U.cod Seq03-U.inp Seq03-U.out + Seq04-U.cod Seq04-U.inp Seq04-U.out + Seq05-U.out + +./fr_homing_A: + Homing01_A.out + Seq01H_A.cod Seq01H_A.inp Seq01H_A.out + Seq02H_A.cod Seq02H_A.inp Seq02H_A.out + Seq03H_A.cod Seq03H_A.inp Seq03H_A.out + Seq04H_A.cod Seq04H_A.inp Seq04H_A.out + Seq05H_A.out + Seq06H_A.cod Seq06H_A.inp + +./fr_homing_L: + Homing01.cod Homing01.out + Seq01h.cod Seq01h.inp Seq01h.out + Seq02h.cod Seq02h.inp Seq02h.out + Seq03h.cod Seq03h.inp Seq03h.out + Seq04h.cod Seq04h.inp Seq04h.out + Seq05h.cod Seq05h.out + Seq06h.cod Seq06h.inp + +./fr_homing_U: + Homing01_U.out + Seq01H_U.cod Seq01H_U.inp Seq01H_U.out + Seq02H_U.cod Seq02H_U.inp Seq02H_U.out + Seq03H_U.cod Seq03H_U.inp Seq03H_U.out + Seq04H_U.cod Seq04H_U.inp Seq04H_U.out + Seq05H_U.out + Seq06H_U.cod Seq06H_U.inp + +./fr_sync_A: + Seqsync_A.inp + Sync000_A.cod --to-- Sync159_A.cod + +./fr_sync_L: + Bitsync.inp + Seqsync.inp + Sync000.cod --to-- Sync159.cod + +./fr_sync_U: + Seqsync_U.inp + Sync000_U.cod --to-- Sync159_U.cod + +This is different from the directory structure in which they are supplied. Also, the files names are a little +different. The supplied names are messy, and inconsistent across the sets. The names required by these tests +just clean up these inconsistencies. Note that you will need a Windows machine to unpack some of the supplied +files. + +To perform a general audio quality test, gsm0610_tests should be run. The file ../localtests/short_nb_voice.wav +will be compressed to GSM 06.10 data, decompressed, and the resulting audio stored in post_gsm0610.wav. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "voipcodecs.h" + +#define BLOCK_LEN 160 + +#define TEST_DIR "../etsitests/gsm0610/unpacked/fr_" + +#define IN_FILE_NAME "../localtests/short_nb_voice.wav" +#define OUT_FILE_NAME "post_gsm0610.wav" + +#define HIST_LEN 1000 + +uint8_t law_in_vector[1000000]; +int16_t in_vector[1000000]; +uint16_t code_vector_buf[1000000]; +uint8_t code_vector[1000000]; +uint8_t ref_code_vector[1000000]; +uint8_t decoder_code_vector[1000000]; +uint8_t law_out_vector[1000000]; +int16_t out_vector[1000000]; +int16_t ref_out_vector[1000000]; +uint8_t ref_law_out_vector[1000000]; +int vector_len; + +static int get_test_vector(int full, int disk, const char *name) +{ + char buf[500]; + int in; + int len; + int i; + + if (full) + { + sprintf(buf, "%s%c/%s.inp", TEST_DIR, 'L', name); + if ((in = open(buf, O_RDONLY)) < 0) + { + fprintf(stderr, "Cannot open %s\n", buf); + exit(2); + } + len = read(in, in_vector, 1000000); + close(in); + len /= sizeof(int16_t); + vector_len = len; + } + + sprintf(buf, "%s%c/%s.out", TEST_DIR, 'L', name); + if ((in = open(buf, O_RDONLY)) < 0) + { + fprintf(stderr, "Cannot open %s\n", buf); + exit(2); + } + len = read(in, ref_out_vector, 1000000); + close(in); + len /= sizeof(int16_t); + if (full) + { + if (len != vector_len) + { + fprintf(stderr, "Input and reference vector lengths do not match - %d %d\n", vector_len, len); + exit(2); + } + } + else + { + vector_len = len; + } + + sprintf(buf, "%s%c/%s.cod", TEST_DIR, 'L', name); + if ((in = open(buf, O_RDONLY)) < 0) + { + fprintf(stderr, "Cannot open %s\n", buf); + exit(2); + } + len = read(in, code_vector_buf, 1000000); + close(in); + len /= sizeof(int16_t); + for (i = 0; i < len; i++) + { + ref_code_vector[i] = code_vector_buf[i]; + decoder_code_vector[i] = code_vector_buf[i]; + } + if (len*BLOCK_LEN != vector_len*76) + { + fprintf(stderr, "Input and code vector lengths do not match - %d %d\n", vector_len, len); + exit(2); + } + + return len; +} +/*- End of function --------------------------------------------------------*/ + +static int get_law_test_vector(int full, int law, const char *name) +{ + char buf[500]; + int in; + int len; + int i; + int law_uc; + + law_uc = toupper(law); + + if (full) + { + sprintf(buf, "%s%c/%s-%c.inp", TEST_DIR, law_uc, name, law_uc); + if ((in = open(buf, O_RDONLY)) < 0) + { + fprintf(stderr, "Cannot open %s\n", buf); + exit(2); + } + len = read(in, law_in_vector, 1000000); + close(in); + vector_len = len; + + sprintf(buf, "%s%c/%s-%c.cod", TEST_DIR, law_uc, name, law_uc); + if ((in = open(buf, O_RDONLY)) < 0) + { + fprintf(stderr, "Cannot open %s\n", buf); + exit(2); + } + len = read(in, code_vector_buf, 1000000); + close(in); + len /= sizeof(int16_t); + for (i = 0; i < len; i++) + ref_code_vector[i] = code_vector_buf[i]; + if (len*BLOCK_LEN != vector_len*76) + { + fprintf(stderr, "Input and code vector lengths do not match - %d %d\n", vector_len, len); + exit(2); + } + } + + sprintf(buf, "%s%c/%s-%c.out", TEST_DIR, law_uc, name, law_uc); + if ((in = open(buf, O_RDONLY)) < 0) + { + fprintf(stderr, "Cannot open %s\n", buf); + exit(2); + } + len = read(in, ref_law_out_vector, 1000000); + close(in); + if (full) + { + if (len != vector_len) + { + fprintf(stderr, "Input and reference vector lengths do not match - %d %d\n", vector_len, len); + exit(2); + } + } + else + { + vector_len = len; + } + + sprintf(buf, "%s%c/%s.cod", TEST_DIR, 'L', name); + if ((in = open(buf, O_RDONLY)) < 0) + { + fprintf(stderr, "Cannot open %s\n", buf); + exit(2); + } + len = read(in, code_vector_buf, 1000000); + close(in); + len /= sizeof(int16_t); + for (i = 0; i < len; i++) + decoder_code_vector[i] = code_vector_buf[i]; + + return len; +} +/*- End of function --------------------------------------------------------*/ + +static int perform_linear_test(int full, int disk, const char *name) +{ + gsm0610_state_t *gsm0610_enc_state; + gsm0610_state_t *gsm0610_dec_state; + int i; + int xxx; + int mismatches; + + printf("Performing linear test '%s' from disk %d\n", name, disk); + + get_test_vector(full, disk, name); + + if (full) + { + if ((gsm0610_enc_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL) + { + fprintf(stderr, " Cannot create encoder\n"); + exit(2); + } + xxx = gsm0610_encode(gsm0610_enc_state, code_vector, in_vector, vector_len/BLOCK_LEN); + + printf("Check code vector of length %d\n", xxx); + for (i = 0, mismatches = 0; i < xxx; i++) + { + if (code_vector[i] != ref_code_vector[i]) + { + printf("%8d/%3d: %6d %6d\n", i/76, i%76, code_vector[i], ref_code_vector[i]); + mismatches++; + } + } + gsm0610_release(gsm0610_enc_state); + if (mismatches) + { + printf("Test failed: %d of %d samples mismatch\n", mismatches, xxx); + exit(2); + } + printf("Test passed\n"); + } + + if ((gsm0610_dec_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL) + { + fprintf(stderr, " Cannot create decoder\n"); + exit(2); + } + xxx = gsm0610_decode(gsm0610_dec_state, out_vector, decoder_code_vector, vector_len/BLOCK_LEN); + printf("Check output vector of length %d\n", vector_len); + for (i = 0, mismatches = 0; i < vector_len; i++) + { + if (out_vector[i] != ref_out_vector[i]) + { + printf("%8d: %6d %6d\n", i, out_vector[i], ref_out_vector[i]); + mismatches++; + } + } + if (mismatches) + { + printf("Test failed: %d of %d samples mismatch\n", mismatches, vector_len); + exit(2); + } + gsm0610_release(gsm0610_dec_state); + printf("Test passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int perform_law_test(int full, int law, const char *name) +{ + gsm0610_state_t *gsm0610_enc_state; + gsm0610_state_t *gsm0610_dec_state; + int i; + int xxx; + int mismatches; + + if (law == 'a') + printf("Performing A-law test '%s'\n", name); + else + printf("Performing u-law test '%s'\n", name); + + get_law_test_vector(full, law, name); + + if (full) + { + if ((gsm0610_enc_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL) + { + fprintf(stderr, " Cannot create encoder\n"); + exit(2); + } + if (law == 'a') + { + for (i = 0; i < vector_len; i++) + in_vector[i] = alaw_to_linear(law_in_vector[i]); + } + else + { + for (i = 0; i < vector_len; i++) + in_vector[i] = ulaw_to_linear(law_in_vector[i]); + } + xxx = gsm0610_encode(gsm0610_enc_state, code_vector, in_vector, vector_len/BLOCK_LEN); + + printf("Check code vector of length %d\n", xxx); + for (i = 0, mismatches = 0; i < xxx; i++) + { + if (code_vector[i] != ref_code_vector[i]) + { + printf("%8d/%3d: %6d %6d %6d\n", i/76, i%76, code_vector[i], ref_code_vector[i], decoder_code_vector[i]); + mismatches++; + } + } + if (mismatches) + { + printf("Test failed: %d of %d samples mismatch\n", mismatches, xxx); + exit(2); + } + printf("Test passed\n"); + gsm0610_release(gsm0610_enc_state); + } + + if ((gsm0610_dec_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL) + { + fprintf(stderr, " Cannot create decoder\n"); + exit(2); + } + xxx = gsm0610_decode(gsm0610_dec_state, out_vector, decoder_code_vector, vector_len/BLOCK_LEN); + if (law == 'a') + { + for (i = 0; i < vector_len; i++) + law_out_vector[i] = linear_to_alaw(out_vector[i]); + } + else + { + for (i = 0; i < vector_len; i++) + law_out_vector[i] = linear_to_ulaw(out_vector[i]); + } + printf("Check output vector of length %d\n", vector_len); + for (i = 0, mismatches = 0; i < vector_len; i++) + { + if (law_out_vector[i] != ref_law_out_vector[i]) + { + printf("%8d: %6d %6d\n", i, law_out_vector[i], ref_law_out_vector[i]); + mismatches++; + } + } + if (mismatches) + { + printf("Test failed: %d of %d samples mismatch\n", mismatches, vector_len); + exit(2); + } + gsm0610_release(gsm0610_dec_state); + printf("Test passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int repack_gsm0610_voip_to_wav49(uint8_t c[], const uint8_t d[]) +{ + gsm0610_frame_t frame[2]; + int n; + + n = gsm0610_unpack_voip(&frame[0], d); + gsm0610_unpack_voip(&frame[1], d + n); + n = gsm0610_pack_wav49(c, frame); + return n; +} +/*- End of function --------------------------------------------------------*/ + +static int repack_gsm0610_wav49_to_voip(uint8_t d[], const uint8_t c[]) +{ + gsm0610_frame_t frame[2]; + int n[2]; + + gsm0610_unpack_wav49(frame, c); + n[0] = gsm0610_pack_voip(d, &frame[0]); + n[1] = gsm0610_pack_voip(d + n[0], &frame[1]); + return n[0] + n[1]; +} +/*- End of function --------------------------------------------------------*/ + +static int perform_pack_unpack_test(void) +{ + uint8_t a[66]; + uint8_t b[66]; + uint8_t c[66]; + int i; + int j; + + printf("Performing packing/unpacking tests (not part of the ETSI conformance tests).\n"); + /* Try trans-packing a lot of random data looking for before/after mismatch. */ + for (j = 0; j < 1000; j++) + { + for (i = 0; i < 65; i++) + a[i] = rand(); + repack_gsm0610_wav49_to_voip(b, a); + repack_gsm0610_voip_to_wav49(c, b); + if (memcmp(a, c, 65)) + { + printf("Test failed: data mismatch\n"); + exit(2); + } + + for (i = 0; i < 66; i++) + a[i] = rand(); + /* Insert the magic code */ + a[0] = (a[0] & 0xF) | 0xD0; + a[33] = (a[33] & 0xF) | 0xD0; + repack_gsm0610_voip_to_wav49(b, a); + repack_gsm0610_wav49_to_voip(c, b); + //for (i = 0; i < 66; i++) + // printf("%2d: 0x%02X 0x%02X\n", i, a[i], c[i]); + if (memcmp(a, c, 66)) + { + printf("Test failed: data mismatch\n"); + exit(2); + } + } + printf("Test passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + AFfilehandle inhandle; + AFfilehandle outhandle; + AFfilesetup filesetup; + int frames; + int outframes; + float x; + int16_t pre_amp[HIST_LEN]; + int16_t post_amp[HIST_LEN]; + uint8_t gsm0610_data[HIST_LEN]; + gsm0610_state_t *gsm0610_enc_state; + gsm0610_state_t *gsm0610_dec_state; + int etsitests; + int packing; + int i; + + etsitests = TRUE; + packing = GSM0610_PACKING_NONE; + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-l") == 0) + { + etsitests = FALSE; + continue; + } + if (strcmp(argv[i], "-p") == 0) + { + packing = atoi(argv[++i]); + continue; + } + fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]); + exit(2); + } + + if (etsitests) + { + perform_linear_test(TRUE, 1, "Seq01"); + perform_linear_test(TRUE, 1, "Seq02"); + perform_linear_test(TRUE, 1, "Seq03"); + perform_linear_test(TRUE, 1, "Seq04"); + perform_linear_test(FALSE, 1, "Seq05"); + perform_law_test(TRUE, 'a', "Seq01"); + perform_law_test(TRUE, 'a', "Seq02"); + perform_law_test(TRUE, 'a', "Seq03"); + perform_law_test(TRUE, 'a', "Seq04"); + perform_law_test(FALSE, 'a', "Seq05"); + perform_law_test(TRUE, 'u', "Seq01"); + perform_law_test(TRUE, 'u', "Seq02"); + perform_law_test(TRUE, 'u', "Seq03"); + perform_law_test(TRUE, 'u', "Seq04"); + perform_law_test(FALSE, 'u', "Seq05"); + /* This is not actually an ETSI test */ + perform_pack_unpack_test(); + + printf("Tests passed.\n"); + } + else + { + if ((inhandle = afOpenFile(IN_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE) + { + printf(" Cannot open wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + + outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup); + if (outhandle == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + + if ((gsm0610_enc_state = gsm0610_init(NULL, packing)) == NULL) + { + fprintf(stderr, " Cannot create encoder\n"); + exit(2); + } + + if ((gsm0610_dec_state = gsm0610_init(NULL, packing)) == NULL) + { + fprintf(stderr, " Cannot create decoder\n"); + exit(2); + } + + while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, 2*BLOCK_LEN))) + { + gsm0610_encode(gsm0610_enc_state, gsm0610_data, pre_amp, (packing == GSM0610_PACKING_WAV49) ? 1 : 2); + gsm0610_decode(gsm0610_dec_state, post_amp, gsm0610_data, (packing == GSM0610_PACKING_WAV49) ? 1 : 2); + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_amp, frames); + } + + if (afCloseFile(inhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if (afCloseFile(outhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + gsm0610_release(gsm0610_enc_state); + gsm0610_release(gsm0610_dec_state); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/ima_adpcm_tests.c b/libs/voipcodecs/tests/ima_adpcm_tests.c new file mode 100644 index 0000000000..ca40533c06 --- /dev/null +++ b/libs/voipcodecs/tests/ima_adpcm_tests.c @@ -0,0 +1,206 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * ima_adpcm_tests.c - Test the IMA/DVI/Intel ADPCM encode and decode + * software. + * + * Written by Steve Underwood + * + * Copyright (C) 2004 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +/*! \file */ + +/*! \page ima_adpcm_tests_page IMA ADPCM tests +\section ima_adpcm_tests_page_sec_1 What does it do? +To perform a general audio quality test, ima_adpcm_tests should be run. The test file +../localtests/short_nb_voice.wav will be compressed to the specified bit rate, +decompressed, and the resulting audio stored in post_ima_adpcm.wav. A simple SNR test +is automatically performed. Listening tests may be used for a more detailed evaluation +of the degradation in quality caused by the compression. + +\section ima_adpcm_tests_page_sec_2 How is it used? +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "voipcodecs.h" + +#define IN_FILE_NAME "../localtests/short_nb_voice.wav" +#define OUT_FILE_NAME "post_ima_adpcm.wav" + +#define HIST_LEN 1000 + +int main(int argc, char *argv[]) +{ + int i; + AFfilehandle inhandle; + AFfilehandle outhandle; + AFfilesetup filesetup; + int frames; + int dec_frames; + int outframes; + int ima_bytes; + float x; + double pre_energy; + double post_energy; + double diff_energy; + int16_t pre_amp[HIST_LEN]; + int16_t post_amp[HIST_LEN]; + uint8_t ima_data[HIST_LEN]; + int16_t history[HIST_LEN]; + int hist_in; + int hist_out; + ima_adpcm_state_t *ima_enc_state; + ima_adpcm_state_t *ima_dec_state; + int xx; + int vbr; + const char *in_file_name; + + vbr = FALSE; + in_file_name = IN_FILE_NAME; + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-v") == 0) + { + vbr = TRUE; + continue; + } + if (strcmp(argv[i], "-i") == 0) + { + in_file_name = argv[++i]; + continue; + } + fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]); + exit(2); + } + + if ((inhandle = afOpenFile(in_file_name, "r", 0)) == AF_NULL_FILEHANDLE) + { + printf(" Cannot open wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate in wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", in_file_name); + exit(2); + } + + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + + if ((ima_enc_state = ima_adpcm_init(NULL, (vbr) ? IMA_ADPCM_VDVI : IMA_ADPCM_DVI4)) == NULL) + { + fprintf(stderr, " Cannot create encoder\n"); + exit(2); + } + + if ((ima_dec_state = ima_adpcm_init(NULL, (vbr) ? IMA_ADPCM_VDVI : IMA_ADPCM_DVI4)) == NULL) + { + fprintf(stderr, " Cannot create decoder\n"); + exit(2); + } + + hist_in = 0; + hist_out = 0; + pre_energy = 0.0; + post_energy = 0.0; + diff_energy = 0.0; + while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, 159))) + { + ima_bytes = ima_adpcm_encode(ima_enc_state, ima_data, pre_amp, frames); + dec_frames = ima_adpcm_decode(ima_dec_state, post_amp, ima_data, ima_bytes); + for (i = 0; i < frames; i++) + { + history[hist_in++] = pre_amp[i]; + if (hist_in >= HIST_LEN) + hist_in = 0; + pre_energy += (double) pre_amp[i] * (double) pre_amp[i]; + } + for (i = 0; i < dec_frames; i++) + { + post_energy += (double) post_amp[i] * (double) post_amp[i]; + xx = post_amp[i] - history[hist_out++]; + if (hist_out >= HIST_LEN) + hist_out = 0; + diff_energy += (double) xx * (double) xx; + } + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_amp, dec_frames); + } + if (afCloseFile(inhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", in_file_name); + exit(2); + } + if (afCloseFile(outhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + ima_adpcm_release(ima_enc_state); + ima_adpcm_release(ima_dec_state); + + printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy); + printf("Residual energy is %f%% of the total.\n", 100.0*diff_energy/post_energy); + if (fabs(1.0 - post_energy/pre_energy) > 0.05 + || + fabs(diff_energy/post_energy) > 0.03) + { + printf("Tests failed.\n"); + exit(2); + } + + printf("Tests passed.\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/lpc10_tests.c b/libs/voipcodecs/tests/lpc10_tests.c new file mode 100644 index 0000000000..b7f5afa258 --- /dev/null +++ b/libs/voipcodecs/tests/lpc10_tests.c @@ -0,0 +1,307 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * lpc10_tests.c - Test the LPC10 low bit rate speech codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: lpc10_tests.c,v 1.11 2007/11/10 11:14:58 steveu Exp $ + */ + +/*! \file */ + +/*! \page lpc10_tests_page LPC10 codec tests +\section lpc10_tests_page_sec_1 What does it do? + +\section lpc10_tests_page_sec_2 How is it used? +To perform a general audio quality test, lpc10 should be run. The file ../localtests/short_nb_voice.wav +will be compressed to LPC10 data, decompressed, and the resulting audio stored in post_lpc10.wav. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "voipcodecs.h" + +#define BLOCK_LEN 180 + +#define BLOCKS_PER_READ 1 + +#define IN_FILE_NAME "../localtests/dam9.wav" +#define REF_FILE_NAME "../localtests/dam9_lpc55.wav" +#define COMPRESS_FILE_NAME "lpc10_out.lpc10" +#define DECOMPRESS_FILE_NAME "lpc10_in.lpc10" +#define OUT_FILE_NAME "post_lpc10.wav" + +int main(int argc, char *argv[]) +{ + AFfilehandle inhandle; + AFfilehandle refhandle; + AFfilehandle outhandle; + AFfilesetup filesetup; + int frames; + int outframes; + float x; + double pre_energy; + double post_energy; + double ref_energy; + double diff_energy; + int16_t pre_amp[BLOCKS_PER_READ*BLOCK_LEN]; + int16_t post_amp[BLOCKS_PER_READ*BLOCK_LEN]; + int16_t ref_amp[BLOCKS_PER_READ*BLOCK_LEN]; + int16_t log_amp[BLOCKS_PER_READ*BLOCK_LEN*3]; + uint8_t lpc10_data[BLOCKS_PER_READ*7]; + double xx; + lpc10_encode_state_t *lpc10_enc_state; + lpc10_decode_state_t *lpc10_dec_state; + int i; + int block_no; + int log_error; + int compress; + int decompress; + const char *in_file_name; + int compress_file; + int decompress_file; + int len; + + compress = FALSE; + decompress = FALSE; + log_error = TRUE; + in_file_name = IN_FILE_NAME; + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-c") == 0) + { + compress = TRUE; + continue; + } + if (strcmp(argv[i], "-d") == 0) + { + decompress = TRUE; + continue; + } + if (strcmp(argv[i], "-i") == 0) + { + in_file_name = argv[++i]; + continue; + } + if (strcmp(argv[i], "-l") == 0) + { + log_error = FALSE; + continue; + } + } + + compress_file = -1; + decompress_file = -1; + inhandle = AF_NULL_FILEHANDLE; + refhandle = AF_NULL_FILEHANDLE; + outhandle = AF_NULL_FILEHANDLE; + if (!decompress) + { + if ((inhandle = afOpenFile(in_file_name, "r", 0)) == AF_NULL_FILEHANDLE) + { + printf(" Cannot open wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate in wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", in_file_name); + exit(2); + } + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + + if ((refhandle = afOpenFile(REF_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE) + { + printf(" Cannot open wave file '%s'\n", REF_FILE_NAME); + exit(2); + } + if ((x = afGetFrameSize(refhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", REF_FILE_NAME); + exit(2); + } + if ((x = afGetRate(refhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate in wave file '%s'\n", REF_FILE_NAME); + exit(2); + } + if ((x = afGetChannels(refhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", REF_FILE_NAME); + exit(2); + } + } + else + { + if ((decompress_file = open(DECOMPRESS_FILE_NAME, O_RDONLY)) < 0) + { + fprintf(stderr, " Cannot open decompressed data file '%s'\n", DECOMPRESS_FILE_NAME); + exit(2); + } + } + + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + + if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + + if ((lpc10_enc_state = lpc10_encode_init(NULL, TRUE)) == NULL) + { + fprintf(stderr, " Cannot create encoder\n"); + exit(2); + } + + if ((lpc10_dec_state = lpc10_decode_init(NULL, TRUE)) == NULL) + { + fprintf(stderr, " Cannot create decoder\n"); + exit(2); + } + + if (compress) + { + if ((compress_file = open(COMPRESS_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) + { + fprintf(stderr, " Cannot create compressed data file '%s'\n", COMPRESS_FILE_NAME); + exit(2); + } + } + + pre_energy = 0.0; + post_energy = 0.0; + ref_energy = 0.0; + diff_energy = 0.0; + + if (decompress) + { + while ((len = read(decompress_file, lpc10_data, BLOCKS_PER_READ*7)) > 0) + { + lpc10_decode(lpc10_dec_state, post_amp, lpc10_data, len/7); + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_amp, BLOCK_LEN*len/7); + } + } + else + { + block_no = 0; + while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, BLOCKS_PER_READ*BLOCK_LEN)) == BLOCKS_PER_READ*BLOCK_LEN + && + (frames = afReadFrames(refhandle, AF_DEFAULT_TRACK, ref_amp, BLOCKS_PER_READ*BLOCK_LEN)) == BLOCKS_PER_READ*BLOCK_LEN) + { + lpc10_encode(lpc10_enc_state, lpc10_data, pre_amp, BLOCKS_PER_READ); + if (compress) + write(compress_file, lpc10_data, BLOCKS_PER_READ*7); + lpc10_decode(lpc10_dec_state, post_amp, lpc10_data, BLOCKS_PER_READ); + for (i = 0; i < BLOCK_LEN; i++) + { + pre_energy += (double) pre_amp[i]*(double) pre_amp[i]; + post_energy += (double) post_amp[i]*(double) post_amp[i]; + ref_energy += (double) ref_amp[i]*(double) ref_amp[i]; + /* The reference file has some odd clipping, so eliminate this from the + energy measurement. */ + if (ref_amp[i] == 32767 || ref_amp[i] == -32768) + xx = 0.0; + else + xx = post_amp[i] - ref_amp[i]; + diff_energy += (double) xx*(double) xx; + log_amp[i] = xx; + } + block_no++; + if (log_error) + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, log_amp, frames); + else + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_amp, frames); + } + if (afCloseFile(inhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", in_file_name); + exit(2); + } + if (afCloseFile(refhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", REF_FILE_NAME); + exit(2); + } + } + + if (afCloseFile(outhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + if (compress) + close(compress_file); + if (decompress) + close(decompress_file); + lpc10_encode_release(lpc10_enc_state); + lpc10_decode_release(lpc10_dec_state); + + if (!decompress) + { + printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy); + printf("Difference energy is %f%% of the total.\n", 100.0*diff_energy/ref_energy); + if (fabs(1.0 - post_energy/pre_energy) > 0.05 + || + fabs(diff_energy/post_energy) > 0.03) + { + printf("Tests failed.\n"); + exit(2); + } + printf("Tests passed.\n"); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/oki_adpcm_tests.c b/libs/voipcodecs/tests/oki_adpcm_tests.c new file mode 100644 index 0000000000..eb1cc3ecf4 --- /dev/null +++ b/libs/voipcodecs/tests/oki_adpcm_tests.c @@ -0,0 +1,239 @@ +/* + * VoIPcodecs - a series of DSP components for telephony + * + * oki_adpcm_tests.c - Test the Oki (Dialogic) ADPCM encode and decode + * software at 24kbps and 32kbps. + * + * Written by Steve Underwood + * + * Copyright (C) 2004 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: oki_adpcm_tests.c,v 1.24 2007/11/10 11:14:58 steveu Exp $ + */ + +/*! \file */ + +/*! \page oki_adpcm_tests_page OKI (Dialogic) ADPCM tests +\section oki_adpcm_tests_page_sec_1 What does it do? +To perform a general audio quality test, oki_adpcm_tests should be run. The test file +../localtests/short_nb_voice.wav will be compressed to the specified bit rate, +decompressed, and the resulting audio stored in post_oki_adpcm.wav. A simple SNR test +is automatically performed. Listening tests may be used for a more detailed evaluation +of the degradation in quality caused by the compression. Both 32k bps and 24k bps +compression may be tested. + +\section oki_adpcm_tests_page_sec_2 How is it used? +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "voipcodecs.h" + +#define IN_FILE_NAME "../localtests/short_nb_voice.wav" +#define OUT_FILE_NAME "post_oki_adpcm.wav" + +#define HIST_LEN 1000 + +int main(int argc, char *argv[]) +{ + int i; + AFfilehandle inhandle; + AFfilehandle outhandle; + AFfilesetup filesetup; + int frames; + int dec_frames; + int outframes; + int oki_bytes; + int bit_rate; + float x; + double pre_energy; + double post_energy; + double diff_energy; + int16_t pre_amp[HIST_LEN]; + int16_t post_amp[HIST_LEN]; + uint8_t oki_data[HIST_LEN]; + int16_t history[HIST_LEN]; + int hist_in; + int hist_out; + oki_adpcm_state_t *oki_enc_state; + oki_adpcm_state_t *oki_dec_state; + int xx; + int total_pre_samples; + int total_compressed_bytes; + int total_post_samples; + const char *in_file_name; + + bit_rate = 32000; + in_file_name = IN_FILE_NAME; + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-2") == 0) + { + bit_rate = 24000; + continue; + } + if (strcmp(argv[i], "-i") == 0) + { + in_file_name = argv[++i]; + continue; + } + fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]); + exit(2); + } + + if ((inhandle = afOpenFile(in_file_name, "r", 0)) == AF_NULL_FILEHANDLE) + { + printf(" Cannot open wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate in wave file '%s'\n", in_file_name); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", in_file_name); + exit(2); + } + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + + outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup); + if (outhandle == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + + if ((oki_enc_state = oki_adpcm_init(NULL, bit_rate)) == NULL) + { + fprintf(stderr, " Cannot create encoder\n"); + exit(2); + } + + if ((oki_dec_state = oki_adpcm_init(NULL, bit_rate)) == NULL) + { + fprintf(stderr, " Cannot create decoder\n"); + exit(2); + } + + hist_in = 0; + if (bit_rate == 32000) + hist_out = 0; + else + hist_out = HIST_LEN - 27; + memset(history, 0, sizeof(history)); + pre_energy = 0.0; + post_energy = 0.0; + diff_energy = 0.0; + total_pre_samples = 0; + total_compressed_bytes = 0; + total_post_samples = 0; + while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, 159))) + { + total_pre_samples +=frames; + oki_bytes = oki_adpcm_encode(oki_enc_state, oki_data, pre_amp, frames); + total_compressed_bytes += oki_bytes; + dec_frames = oki_adpcm_decode(oki_dec_state, post_amp, oki_data, oki_bytes); + total_post_samples += dec_frames; + for (i = 0; i < frames; i++) + { + history[hist_in++] = pre_amp[i]; + if (hist_in >= HIST_LEN) + hist_in = 0; + pre_energy += (double) pre_amp[i] * (double) pre_amp[i]; + } + for (i = 0; i < dec_frames; i++) + { + post_energy += (double) post_amp[i] * (double) post_amp[i]; + xx = post_amp[i] - history[hist_out++]; + if (hist_out >= HIST_LEN) + hist_out = 0; + diff_energy += (double) xx * (double) xx; + //post_amp[i] = xx; + } + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_amp, dec_frames); + } + if (afCloseFile(inhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", in_file_name); + exit(2); + } + if (afCloseFile(outhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + oki_adpcm_release(oki_enc_state); + oki_adpcm_release(oki_dec_state); + + printf("Pre samples: %d\n", total_pre_samples); + printf("Compressed bytes: %d\n", total_compressed_bytes); + printf("Post samples: %d\n", total_post_samples); + + printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy); + printf("Residual energy is %f%% of the total.\n", 100.0*diff_energy/post_energy); + if (bit_rate == 32000) + { + if (fabs(1.0 - post_energy/pre_energy) > 0.05 + || + fabs(diff_energy/post_energy) > 0.03) + { + printf("Tests failed.\n"); + exit(2); + } + } + else + { + if (fabs(1.0 - post_energy/pre_energy) > 0.20 + || + fabs(diff_energy/post_energy) > 0.10) + { + printf("Tests failed.\n"); + exit(2); + } + } + + printf("Tests passed.\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/voipcodecs/tests/regression_tests.sh b/libs/voipcodecs/tests/regression_tests.sh new file mode 100755 index 0000000000..9d5817ac3d --- /dev/null +++ b/libs/voipcodecs/tests/regression_tests.sh @@ -0,0 +1,93 @@ +#!/bin/sh +# +# VoIPcodecs - a series of DSP components for telephony +# +# regression_tests.sh +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# $Id: regression_tests.sh,v 1.47 2007/12/22 12:37:22 steveu Exp $ +# + +STDOUT_DEST=xyzzy +STDERR_DEST=xyzzy2 + +echo Performing basic VoIP codecs regression tests +echo + +./g711_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo g711_tests failed! + exit $RETVAL +fi +echo g711_tests completed OK + +./g722_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo g722_tests failed! + exit $RETVAL +fi +echo g722_tests completed OK + +./g726_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo g726_tests failed! + exit $RETVAL +fi +echo g726_tests completed OK + +./gsm0610_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo gsm0610_tests failed! + exit $RETVAL +fi +echo gsm0610_tests completed OK + +./ima_adpcm_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo ima_adpcm_tests failed! + exit $RETVAL +fi +echo ima_adpcm_tests completed OK + +./lpc10_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo lpc10_tests failed! + exit $RETVAL +fi +echo lpc10_tests completed OK + +./oki_adpcm_tests >$STDOUT_DEST 2>$STDERR_DEST +RETVAL=$? +if [ $RETVAL != 0 ] +then + echo oki_adpcm_tests failed! + exit $RETVAL +fi +echo oki_adpcm_tests completed OK + +echo +echo All regression tests successfully completed diff --git a/libs/voipcodecs/voipcodecs.spec.in b/libs/voipcodecs/voipcodecs.spec.in new file mode 100644 index 0000000000..ac69fe9393 --- /dev/null +++ b/libs/voipcodecs/voipcodecs.spec.in @@ -0,0 +1,65 @@ +Summary: VoIPcodecs is a library of unencumbered codecs commonly used for VoIP +Name: @PACKAGE@ +Version: @VERSION@ +Release: 1 +License: GPL +Group: System Environment/Libraries +URL: http://www.soft-switch.org/voipcodecs +BuildRoot: %{_tmppath}/%{name}-%{version}-root +Source: http://www.soft-switch.org/downloads/voipcodecs/@PACKAGE@-@VERSION@.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +Docdir: %{_prefix}/doc + +BuildRequires: audiofile-devel +BuildRequires: doxygen + +%description +VoIPcodecs is a library of unencumbered codecs commonly used for VoIP. + +%package devel +Summary: VoIPcodecs development files +Group: Development/Libraries +Requires: voipcodecs = %{version} +PreReq: /sbin/install-info + +%description devel +VoIPcodecs development files. + +%prep +%setup -q + +%build +%configure --enable-doc --disable-static --disable-rpath +make + +%install +rm -rf %{buildroot} +make install DESTDIR=%{buildroot} +rm %{buildroot}%{_libdir}/libvoipcodecs.la + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root,-) +%doc ChangeLog AUTHORS COPYING NEWS README + +%{_libdir}/libvoipcodecs.so.* + +%{_datadir}/voipcodecs + +%files devel +%defattr(-,root,root,-) +%doc doc/api +%{_includedir}/voipcodecs.h +%{_includedir}/voipcodecs +%{_libdir}/libvoipcodecs.so + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%changelog +* Thu Feb 7 2008 Steve Underwood 0.0.1 +- First pass diff --git a/libs/voipcodecs/wrapper.xsl b/libs/voipcodecs/wrapper.xsl new file mode 100644 index 0000000000..89e314d781 --- /dev/null +++ b/libs/voipcodecs/wrapper.xsl @@ -0,0 +1,5 @@ + + + css.css + \ No newline at end of file