[Freeswitch-svn] [commit] r7544 - in freeswitch/trunk/libs/voipcodecs: . config debian doc etsitests itutests localtests src src/msvc src/msvc/sys src/voipcodecs tests
Freeswitch SVN
mikej at freeswitch.org
Thu Feb 7 17:00:11 EST 2008
Author: mikej
Date: Thu Feb 7 17:00:10 2008
New Revision: 7544
Added:
freeswitch/trunk/libs/voipcodecs/
freeswitch/trunk/libs/voipcodecs/AUTHORS
freeswitch/trunk/libs/voipcodecs/COPYING
freeswitch/trunk/libs/voipcodecs/ChangeLog
freeswitch/trunk/libs/voipcodecs/INSTALL
freeswitch/trunk/libs/voipcodecs/Makefile.am
freeswitch/trunk/libs/voipcodecs/NEWS
freeswitch/trunk/libs/voipcodecs/README
freeswitch/trunk/libs/voipcodecs/config/
freeswitch/trunk/libs/voipcodecs/config-h.in
freeswitch/trunk/libs/voipcodecs/configure.ac
freeswitch/trunk/libs/voipcodecs/debian/
freeswitch/trunk/libs/voipcodecs/debian/changelog
freeswitch/trunk/libs/voipcodecs/debian/compat
freeswitch/trunk/libs/voipcodecs/debian/control
freeswitch/trunk/libs/voipcodecs/debian/copyright
freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs-dev.install
freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs-doc.install
freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs.install
freeswitch/trunk/libs/voipcodecs/debian/rules (contents, props changed)
freeswitch/trunk/libs/voipcodecs/debian/watch
freeswitch/trunk/libs/voipcodecs/doc/
freeswitch/trunk/libs/voipcodecs/doc/Makefile.am
freeswitch/trunk/libs/voipcodecs/doc/css.css
freeswitch/trunk/libs/voipcodecs/doc/libvoipcodecs-doxygen
freeswitch/trunk/libs/voipcodecs/doc/wrapper.xsl
freeswitch/trunk/libs/voipcodecs/etsitests/
freeswitch/trunk/libs/voipcodecs/etsitests/Makefile.am
freeswitch/trunk/libs/voipcodecs/itutests/
freeswitch/trunk/libs/voipcodecs/itutests/Makefile.am
freeswitch/trunk/libs/voipcodecs/libvoipcodecs.vcproj
freeswitch/trunk/libs/voipcodecs/localtests/
freeswitch/trunk/libs/voipcodecs/localtests/Makefile.am
freeswitch/trunk/libs/voipcodecs/localtests/dam9.wav (contents, props changed)
freeswitch/trunk/libs/voipcodecs/localtests/dam9_lpc55.wav (contents, props changed)
freeswitch/trunk/libs/voipcodecs/localtests/short_nb_voice.wav (contents, props changed)
freeswitch/trunk/libs/voipcodecs/localtests/short_wb_voice.wav (contents, props changed)
freeswitch/trunk/libs/voipcodecs/src/
freeswitch/trunk/libs/voipcodecs/src/Makefile.am
freeswitch/trunk/libs/voipcodecs/src/bitstream.c
freeswitch/trunk/libs/voipcodecs/src/float_fudge.h
freeswitch/trunk/libs/voipcodecs/src/g711.c
freeswitch/trunk/libs/voipcodecs/src/g722_decode.c
freeswitch/trunk/libs/voipcodecs/src/g722_encode.c
freeswitch/trunk/libs/voipcodecs/src/g726.c
freeswitch/trunk/libs/voipcodecs/src/gsm0610_decode.c
freeswitch/trunk/libs/voipcodecs/src/gsm0610_encode.c
freeswitch/trunk/libs/voipcodecs/src/gsm0610_local.h
freeswitch/trunk/libs/voipcodecs/src/gsm0610_long_term.c
freeswitch/trunk/libs/voipcodecs/src/gsm0610_lpc.c
freeswitch/trunk/libs/voipcodecs/src/gsm0610_preprocess.c
freeswitch/trunk/libs/voipcodecs/src/gsm0610_rpe.c
freeswitch/trunk/libs/voipcodecs/src/gsm0610_short_term.c
freeswitch/trunk/libs/voipcodecs/src/ima_adpcm.c
freeswitch/trunk/libs/voipcodecs/src/libvoipcodecs.dsp
freeswitch/trunk/libs/voipcodecs/src/libvoipcodecs.sln
freeswitch/trunk/libs/voipcodecs/src/lpc10_analyse.c
freeswitch/trunk/libs/voipcodecs/src/lpc10_decode.c
freeswitch/trunk/libs/voipcodecs/src/lpc10_encdecs.h
freeswitch/trunk/libs/voipcodecs/src/lpc10_encode.c
freeswitch/trunk/libs/voipcodecs/src/lpc10_placev.c
freeswitch/trunk/libs/voipcodecs/src/lpc10_voicing.c
freeswitch/trunk/libs/voipcodecs/src/msvc/
freeswitch/trunk/libs/voipcodecs/src/msvc/gettimeofday.c
freeswitch/trunk/libs/voipcodecs/src/msvc/inttypes.h
freeswitch/trunk/libs/voipcodecs/src/msvc/msvcproj.foot
freeswitch/trunk/libs/voipcodecs/src/msvc/msvcproj.head
freeswitch/trunk/libs/voipcodecs/src/msvc/sys/
freeswitch/trunk/libs/voipcodecs/src/msvc/sys/time.h
freeswitch/trunk/libs/voipcodecs/src/msvc/tgmath.h
freeswitch/trunk/libs/voipcodecs/src/msvc/unistd.h
freeswitch/trunk/libs/voipcodecs/src/msvc/vc8proj.foot
freeswitch/trunk/libs/voipcodecs/src/msvc/vc8proj.head
freeswitch/trunk/libs/voipcodecs/src/msvc/voipcodecs.def
freeswitch/trunk/libs/voipcodecs/src/oki_adpcm.c
freeswitch/trunk/libs/voipcodecs/src/vector_int.c
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/
freeswitch/trunk/libs/voipcodecs/src/voipcodecs.h.in
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/bit_operations.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/bitstream.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/dc_restore.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g711.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g722.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g726.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/gsm0610.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/ima_adpcm.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/lpc10.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/oki_adpcm.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/telephony.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/vector_int.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/version.h
freeswitch/trunk/libs/voipcodecs/src/voipcodecs/version.h.in
freeswitch/trunk/libs/voipcodecs/tests/
freeswitch/trunk/libs/voipcodecs/tests/Makefile.am
freeswitch/trunk/libs/voipcodecs/tests/g711_tests.c
freeswitch/trunk/libs/voipcodecs/tests/g722_tests.c
freeswitch/trunk/libs/voipcodecs/tests/g726_tests.c
freeswitch/trunk/libs/voipcodecs/tests/gsm0610_tests.c
freeswitch/trunk/libs/voipcodecs/tests/ima_adpcm_tests.c
freeswitch/trunk/libs/voipcodecs/tests/lpc10_tests.c
freeswitch/trunk/libs/voipcodecs/tests/oki_adpcm_tests.c
freeswitch/trunk/libs/voipcodecs/tests/regression_tests.sh (contents, props changed)
freeswitch/trunk/libs/voipcodecs/voipcodecs.spec.in
freeswitch/trunk/libs/voipcodecs/wrapper.xsl
Log:
inital checkin of voipcodecs library version 0.0.1 from http://www.soft-switch.org/downloads/voipcodecs/ thank you Steve
Added: freeswitch/trunk/libs/voipcodecs/AUTHORS
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/AUTHORS Thu Feb 7 17:00:10 2008
@@ -0,0 +1 @@
+Steve Underwood <steveu at coppice.org>
Added: freeswitch/trunk/libs/voipcodecs/COPYING
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/COPYING Thu Feb 7 17:00:10 2008
@@ -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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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.
+
+ <signature of Ty Coon>, 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.
Added: freeswitch/trunk/libs/voipcodecs/ChangeLog
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/ChangeLog Thu Feb 7 17:00:10 2008
@@ -0,0 +1,3 @@
+08.02.08 - 0.0.1 - Steve Underwood <steveu at coppice.org>
+ - The first version.
+
Added: freeswitch/trunk/libs/voipcodecs/INSTALL
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/INSTALL Thu Feb 7 17:00:10 2008
@@ -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.
Added: freeswitch/trunk/libs/voipcodecs/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/Makefile.am Thu Feb 7 17:00:10 2008
@@ -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 at -@VERSION at .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 >voipcodecs.spec.new; \
+ mv voipcodecs.spec.new voipcodecs.spec
Added: freeswitch/trunk/libs/voipcodecs/NEWS
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/NEWS Thu Feb 7 17:00:10 2008
@@ -0,0 +1 @@
+No news is good news!
\ No newline at end of file
Added: freeswitch/trunk/libs/voipcodecs/README
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/README Thu Feb 7 17:00:10 2008
@@ -0,0 +1,4 @@
+VoIPcodecs 0.0.1 - A set of commonly used, unencumbered, codecs for VoIP
+------------------------------------------------------------------------
+
+Steve Underwood <steveu at coppice.org>
Added: freeswitch/trunk/libs/voipcodecs/config-h.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/config-h.in Thu Feb 7 17:00:10 2008
@@ -0,0 +1,235 @@
+/* config-h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <audiofile.h> header file. */
+#undef HAVE_AUDIOFILE_H
+
+/* Define to 1 if you have the <dlfcn.h> 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 <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <fftw3.h> header file. */
+#undef HAVE_FFTW3_H
+
+/* Define to 1 if you have the <fftw.h> header file. */
+#undef HAVE_FFTW_H
+
+/* Define to 1 if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
+/* Define to 1 if you have the <FL/Fl_Audio_Meter.H> header file. */
+#undef HAVE_FL_FL_AUDIO_METER_H
+
+/* Define to 1 if you have the <FL/Fl_Cartesian.H> header file. */
+#undef HAVE_FL_FL_CARTESIAN_H
+
+/* Define to 1 if you have the <FL/fl_draw.H> header file. */
+#undef HAVE_FL_FL_DRAW_H
+
+/* Define to 1 if you have the <FL/Fl.H> header file. */
+#undef HAVE_FL_FL_H
+
+/* Define to 1 if you have the <FL/Fl_Light_Button.H> header file. */
+#undef HAVE_FL_FL_LIGHT_BUTTON_H
+
+/* Define to 1 if you have the <FL/Fl_Overlay_Window.H> 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 <inttypes.h> 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 <libxml/parser.h> header file. */
+#undef HAVE_LIBXML_PARSER_H
+
+/* Define to 1 if you have the <libxml/xinclude.h> header file. */
+#undef HAVE_LIBXML_XINCLUDE_H
+
+/* Define to 1 if you have the <libxml/xmlmemory.h> 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 <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <math.h> 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 <memory.h> 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 <pthread.h> 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 <socket.h> header file. */
+#undef HAVE_SOCKET_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> 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 <sys/fcntl.h> header file. */
+#undef HAVE_SYS_FCNTL_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <tgmath.h> header file. */
+#undef HAVE_TGMATH_H
+
+/* Define to 1 if you have the <tiffio.h> header file. */
+#undef HAVE_TIFFIO_H
+
+/* Define to 1 if you have the <unicall.h> header file. */
+#undef HAVE_UNICALL_H
+
+/* Define to 1 if you have the <unistd.h> 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 <X11/X.h> 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 <sys/time.h> and <time.h>. */
+#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
Added: freeswitch/trunk/libs/voipcodecs/configure.ac
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/configure.ac Thu Feb 7 17:00:10 2008
@@ -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 <inttypes.h>"])
+AC_CHECK_HEADERS([stdint.h], [INSERT_STDINT_HEADER="#include <stdint.h>"])
+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 <tgmath.h>"])
+AC_CHECK_HEADERS([math.h], [INSERT_MATH_HEADER="#include <math.h>"])
+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 <libxml/xmlmemory.h>], [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 <libxml/xmlmemory.h>], [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 <FL/Fl.H>
+]])
+AC_CHECK_HEADERS([FL/Fl_Audio_Meter.H], [], [], [],[[#include <FL/Fl.H>
+]])
+
+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
Added: freeswitch/trunk/libs/voipcodecs/debian/changelog
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/changelog Thu Feb 7 17:00:10 2008
@@ -0,0 +1,6 @@
+voipcodecs (0.0.1) unstable; urgency=low
+
+ [ Steve Underwood ]
+ * Begun
+
+ -- Steve Underwood <steveu at coppice.org> Thu, 7 Feb 2008 09:53:06 +0300
Added: freeswitch/trunk/libs/voipcodecs/debian/compat
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/compat Thu Feb 7 17:00:10 2008
@@ -0,0 +1 @@
+4
Added: freeswitch/trunk/libs/voipcodecs/debian/control
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/control Thu Feb 7 17:00:10 2008
@@ -0,0 +1,42 @@
+Source: voipcodecs
+Section: libs
+Priority: optional
+Maintainer: Debian VoIP Team <pkg-voip-maintainers at lists.alioth.debian.org>
+Uploaders: Jose Carlos Garcia Sogo <jsogo at debian.org>, Kilian Krause <kilian at debian.org>, Santiago Garcia Mantinan <manty at debian.org>, Mark Purcell <msp at debian.org>, Tzafrir Cohen <tzafrir.cohen at xorcom.com>, Santiago Ruano Rincón <santiago at debian.org>
+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.
Added: freeswitch/trunk/libs/voipcodecs/debian/copyright
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/copyright Thu Feb 7 17:00:10 2008
@@ -0,0 +1,25 @@
+This package was debianized by Steve Underwood <steveu at coppice.org> on
+Thu, 7 Feb 2008 15:22:58 +0100.
+
+It was downloaded from http://soft-switch.org/downloads/voipcodecs/
+
+Copyright: Steve Underwood <steveu at coppice.org>
+
+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'.
Added: freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs-dev.install
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs-dev.install Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs-doc.install
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs-doc.install Thu Feb 7 17:00:10 2008
@@ -0,0 +1 @@
+doc/api/html usr/share/doc/libvoipcodecs-doc/api/
Added: freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs.install
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/libvoipcodecs.install Thu Feb 7 17:00:10 2008
@@ -0,0 +1,2 @@
+debian/tmp/usr/lib/libvoipcodecs.so.0.*
+debian/tmp/usr/lib/libvoipcodecs.so.0
Added: freeswitch/trunk/libs/voipcodecs/debian/rules
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/rules Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/debian/watch
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/debian/watch Thu Feb 7 17:00:10 2008
@@ -0,0 +1,7 @@
+# See uscan(1) for format
+
+# Compulsory line, this is a version 3 file
+version=3
+
+# <Webpage URL> <string match>
+http://soft-switch.org/downloads/voipcodecs/ voipcodecs-(.*)\.tgz debian svn-upgrade
Added: freeswitch/trunk/libs/voipcodecs/doc/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/doc/Makefile.am Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/doc/css.css
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/doc/css.css Thu Feb 7 17:00:10 2008
@@ -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;
+}
Added: freeswitch/trunk/libs/voipcodecs/doc/libvoipcodecs-doxygen
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/doc/libvoipcodecs-doxygen Thu Feb 7 17:00:10 2008
@@ -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 <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> 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 <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> 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
Added: freeswitch/trunk/libs/voipcodecs/doc/wrapper.xsl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/doc/wrapper.xsl Thu Feb 7 17:00:10 2008
@@ -0,0 +1,5 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/>
+ <xsl:param name="html.stylesheet">css.css</xsl:param>
+</xsl:stylesheet>
\ No newline at end of file
Added: freeswitch/trunk/libs/voipcodecs/etsitests/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/etsitests/Makefile.am Thu Feb 7 17:00:10 2008
@@ -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:
Added: freeswitch/trunk/libs/voipcodecs/itutests/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/itutests/Makefile.am Thu Feb 7 17:00:10 2008
@@ -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:
+
Added: freeswitch/trunk/libs/voipcodecs/libvoipcodecs.vcproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/libvoipcodecs.vcproj Thu Feb 7 17:00:10 2008
@@ -0,0 +1,657 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libvoipcodecs"
+ ProjectGUID="{CF70F278-3364-4395-A2E1-23501C9B8AD2}"
+ RootNamespace="libvoipcodecs"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="src; src\voipcodecs; src\msvc"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBvoipcodecs_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ ModuleDefinitionFile="src/msvc/voipcodecs.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="src; src\voipcodecs; src\msvc"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBvoipcodecs_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ ModuleDefinitionFile="src/msvc/voipcodecs.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\src\adsi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\async.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\awgn.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bert.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\complex_dds.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\complex_filters.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\dds.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\ec_disable_tone.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\echo.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\fax.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\fsk.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\g722_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\g722_encode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\g726.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\msvc\gettimeofday.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\hdlc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\ima_adpcm.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\logging.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\modem_echo.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\noise.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\oki_adpcm.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\playout.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\plc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\power_meter.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\queue.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\schedule.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\sig_tone.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\super_tone_rx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\super_tone_tx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t30.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t31.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t35.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t38_gateway.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t38_ifppacket.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t38_terminal.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t4.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\testcpuid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\time_scale.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\tone_detect.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\tone_generate.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v17rx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v17tx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v22bis_rx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v22bis_tx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v27ter_rx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v27ter_tx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v29rx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v29tx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v42.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v42bis.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\v8.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\src\voipcodecs\adsi.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\alaw_ulaw.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\arctan2.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\async.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\awgn.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\bert.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\biquad.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\complex.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\complex_filters.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\dc_restore.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\dds.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\ec_disable_detector.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\ec_disable_tone.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\echo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\fax.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\faxfont.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\fir.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\fsk.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\g168models.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\g722.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\g726.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\hdlc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\ima_adpcm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\msvc\inttypes.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\logging.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\modem_echo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\noise.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\oki_adpcm.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\oss.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\playout.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\plc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\power_meter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\queue.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\schedule.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\sig_tone.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\super_tone_rx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\super_tone_tx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\t30.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\t30_fcf.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\t31.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\t35.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\t38.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\t4.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\t4states.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\telephony.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\msvc\tgmath.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\msvc\sys\time.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\time_scale.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\timing.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\tone_detect.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\tone_generate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\msvc\unistd.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v17rx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v17tx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v22bis.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v27ter_rx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v27ter_tx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v29rx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v29tx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v42.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v42bis.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\v8.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\voipcodecs\vector.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: freeswitch/trunk/libs/voipcodecs/localtests/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/localtests/Makefile.am Thu Feb 7 17:00:10 2008
@@ -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:
Added: freeswitch/trunk/libs/voipcodecs/localtests/dam9.wav
==============================================================================
Binary file. No diff available.
Added: freeswitch/trunk/libs/voipcodecs/localtests/dam9_lpc55.wav
==============================================================================
Binary file. No diff available.
Added: freeswitch/trunk/libs/voipcodecs/localtests/short_nb_voice.wav
==============================================================================
Binary file. No diff available.
Added: freeswitch/trunk/libs/voipcodecs/localtests/short_wb_voice.wav
==============================================================================
Binary file. No diff available.
Added: freeswitch/trunk/libs/voipcodecs/src/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/Makefile.am Thu Feb 7 17:00:10 2008
@@ -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 "<File RelativePath=\""$$file"\"></File>" $(VCPROJOUT); \
+ done; \
+ echo "</Filter><Filter Name=\"Header Files\">" $(VCPROJOUT); \
+ for file in $(WIN32HEADERS); do \
+ echo "<File RelativePath=\""$$file"\"></File>" $(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.in >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.in >voipcodecs/version.h
Added: freeswitch/trunk/libs/voipcodecs/src/bitstream.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/bitstream.c Thu Feb 7 17:00:10 2008
@@ -0,0 +1,137 @@
+/*
+ * VoIPcodecs - a series of DSP components for telephony
+ *
+ * bitstream.c - Bitstream composition and decomposition routines.
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/float_fudge.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/float_fudge.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/g711.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/g711.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <assert.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/g722_decode.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/g722_decode.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <inttypes.h>
+#include <memory.h>
+#include <stdlib.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/g722_encode.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/g722_encode.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <inttypes.h>
+#include <memory.h>
+#include <stdlib.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/g726.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/g726.c Thu Feb 7 17:00:10 2008
@@ -0,0 +1,1178 @@
+/*
+ * VoIPcodecs - a series of DSP components for telephony
+ *
+ * g726.c - The ITU G.726 codec.
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <inttypes.h>
+#include <memory.h>
+#include <stdlib.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_decode.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_decode.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+#include <memory.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_encode.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_encode.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+#include <memory.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_local.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_local.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ---------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_long_term.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_long_term.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_lpc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_lpc.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_preprocess.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_preprocess.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_rpe.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_rpe.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/gsm0610_short_term.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/gsm0610_short_term.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/ima_adpcm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/ima_adpcm.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/libvoipcodecs.dsp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/libvoipcodecs.dsp Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/src/libvoipcodecs.sln
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/libvoipcodecs.sln Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/src/lpc10_analyse.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/lpc10_analyse.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <memory.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/lpc10_decode.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/lpc10_decode.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <memory.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/lpc10_encdecs.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/lpc10_encdecs.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/lpc10_encode.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/lpc10_encode.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <memory.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/lpc10_placev.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/lpc10_placev.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <memory.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/lpc10_voicing.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/lpc10_voicing.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <memory.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/gettimeofday.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/gettimeofday.c Thu Feb 7 17:00:10 2008
@@ -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;
+}
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/inttypes.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/inttypes.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <windows.h>
+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
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/msvcproj.foot
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/msvcproj.foot Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/msvcproj.head
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/msvcproj.head Thu Feb 7 17:00:10 2008
@@ -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"
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/sys/time.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/sys/time.h Thu Feb 7 17:00:10 2008
@@ -0,0 +1 @@
+extern void gettimeofday(struct timeval *tv, void *tz);
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/tgmath.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/tgmath.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * Copyright (C) 2006 Michael Jerris
+ *
+ *
+ * This file is released in the public domain.
+ *
+ */
+
+#if !defined(_TGMATH_H_)
+#define _TGMATH_H_
+
+#include <math.h>
+
+#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
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/unistd.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/unistd.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/vc8proj.foot
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/vc8proj.foot Thu Feb 7 17:00:10 2008
@@ -0,0 +1,11 @@
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/vc8proj.head
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/vc8proj.head Thu Feb 7 17:00:10 2008
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libvoipcodecs"
+ ProjectGUID="{CF70F278-3364-4395-A2E1-23501C9B8AD2}"
+ RootNamespace="libvoipcodecs"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="src; src\voipcodecs; src\msvc"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBSPANDSP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;HAVE_TGMATH_H"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ ModuleDefinitionFile="src/msvc/voipcodecs.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="src; src\voipcodecs; src\msvc"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBSPANDSP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;HAVE_TGMATH_H"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ ModuleDefinitionFile="src/msvc/voipcodecs.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
Added: freeswitch/trunk/libs/voipcodecs/src/msvc/voipcodecs.def
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/msvc/voipcodecs.def Thu Feb 7 17:00:10 2008
@@ -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
+
Added: freeswitch/trunk/libs/voipcodecs/src/oki_adpcm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/oki_adpcm.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/vector_int.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/vector_int.c Thu Feb 7 17:00:10 2008
@@ -0,0 +1,347 @@
+/*
+ * VoIPcodecs - a series of DSP components for telephony
+ *
+ * vector_int.c - Integer vector arithmetic
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <assert.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs.h.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs.h.in Thu Feb 7 17:00:10 2008
@@ -0,0 +1,54 @@
+/*
+ * VoIPcodecs - a series of DSP components for telephony
+ *
+ * voipcodecs.h - The head guy amongst the headers
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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_
+
+ at VOIPCODECS_USE_FIXED_POINT@
+
+#include <stdlib.h>
+ at INSERT_INTTYPES_HEADER@
+#include <string.h>
+#include <limits.h>
+#include <time.h>
+ at INSERT_MATH_HEADER@
+
+#include <voipcodecs/telephony.h>
+#include <voipcodecs/bit_operations.h>
+#include <voipcodecs/bitstream.h>
+#include <voipcodecs/g711.h>
+#include <voipcodecs/g722.h>
+#include <voipcodecs/g726.h>
+#include <voipcodecs/gsm0610.h>
+#include <voipcodecs/ima_adpcm.h>
+#include <voipcodecs/lpc10.h>
+#include <voipcodecs/oki_adpcm.h>
+
+#endif
+/*- End of file ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/bit_operations.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/bit_operations.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/bitstream.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/bitstream.h Thu Feb 7 17:00:10 2008
@@ -0,0 +1,89 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * bitstream.h - Bitstream composition and decomposition routines.
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/dc_restore.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/dc_restore.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g711.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g711.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g722.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g722.h Thu Feb 7 17:00:10 2008
@@ -0,0 +1,180 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g722.h - The ITU G.722 codec.
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g726.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/g726.h Thu Feb 7 17:00:10 2008
@@ -0,0 +1,195 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g726.h - ITU G.726 codec.
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/gsm0610.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/gsm0610.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ---------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/ima_adpcm.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/ima_adpcm.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/lpc10.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/lpc10.h Thu Feb 7 17:00:10 2008
@@ -0,0 +1,213 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * lpc10.h - LPC10 low bit rate speech codec.
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 ---------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/oki_adpcm.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/oki_adpcm.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/telephony.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/telephony.h Thu Feb 7 17:00:10 2008
@@ -0,0 +1,67 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * telephony.h - some very basic telephony definitions
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/vector_int.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/vector_int.h Thu Feb 7 17:00:10 2008
@@ -0,0 +1,99 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * vector_int.h
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/version.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/version.h Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/src/voipcodecs/version.h.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/src/voipcodecs/version.h.in Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/Makefile.am
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/Makefile.am Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/tests/g711_tests.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/g711_tests.c Thu Feb 7 17:00:10 2008
@@ -0,0 +1,287 @@
+/*
+ * VoIPcodecs - a series of DSP components for telephony
+ *
+ * g711_tests.c
+ *
+ * Written by Steve Underwood <steveu at coppice.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <audiofile.h>
+
+#include "voipcodecs.h"
+#include <spandsp/power_meter.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/g722_tests.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/g722_tests.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <memory.h>
+#include <ctype.h>
+#include <audiofile.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/g726_tests.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/g726_tests.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <memory.h>
+#include <ctype.h>
+#include <audiofile.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/gsm0610_tests.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/gsm0610_tests.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <audiofile.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/ima_adpcm_tests.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/ima_adpcm_tests.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include <audiofile.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/lpc10_tests.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/lpc10_tests.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <audiofile.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/oki_adpcm_tests.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/oki_adpcm_tests.c Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include <audiofile.h>
+
+#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 ------------------------------------------------------------*/
Added: freeswitch/trunk/libs/voipcodecs/tests/regression_tests.sh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/tests/regression_tests.sh Thu Feb 7 17:00:10 2008
@@ -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
Added: freeswitch/trunk/libs/voipcodecs/voipcodecs.spec.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/voipcodecs.spec.in Thu Feb 7 17:00:10 2008
@@ -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 <steveu at coppice.org> 0.0.1
+- First pass
Added: freeswitch/trunk/libs/voipcodecs/wrapper.xsl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/voipcodecs/wrapper.xsl Thu Feb 7 17:00:10 2008
@@ -0,0 +1,5 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/>
+ <xsl:param name="html.stylesheet">css.css</xsl:param>
+</xsl:stylesheet>
\ No newline at end of file
More information about the Freeswitch-svn
mailing list