summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2005-02-16 11:02:11 +0000
committerDave Chapman <dave@dchapman.com>2005-02-16 11:02:11 +0000
commit3bd167771d23edbfcf11ea4d5f0f75faf53af0c9 (patch)
tree8caa153a8c30654e7488cbc50eaa650e6c43fe72
parent1f9610d43cefc10a1e47924ad65ce0f78c63bc66 (diff)
downloadrockbox-3bd167771d23edbfcf11ea4d5f0f75faf53af0c9.tar.gz
rockbox-3bd167771d23edbfcf11ea4d5f0f75faf53af0c9.zip
Initial import of the unmodified version of liba52-0.7.5-cvs, checked out of the Sourceforge CVS repository today.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5970 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/liba52/AUTHORS23
-rw-r--r--apps/codecs/liba52/COPYING340
-rw-r--r--apps/codecs/liba52/ChangeLog97
-rw-r--r--apps/codecs/liba52/HISTORY28
-rw-r--r--apps/codecs/liba52/INSTALL58
-rw-r--r--apps/codecs/liba52/Makefile47
-rw-r--r--apps/codecs/liba52/NEWS46
-rw-r--r--apps/codecs/liba52/README180
-rw-r--r--apps/codecs/liba52/README.rockbox27
-rw-r--r--apps/codecs/liba52/SOURCES5
-rw-r--r--apps/codecs/liba52/TODO17
-rw-r--r--apps/codecs/liba52/a52.h67
-rw-r--r--apps/codecs/liba52/a52_internal.h160
-rw-r--r--apps/codecs/liba52/attributes.h37
-rw-r--r--apps/codecs/liba52/bit_allocate.c265
-rw-r--r--apps/codecs/liba52/bitstream.c97
-rw-r--r--apps/codecs/liba52/bitstream.h77
-rw-r--r--apps/codecs/liba52/config.h21
-rw-r--r--apps/codecs/liba52/downmix.c685
-rw-r--r--apps/codecs/liba52/imdct.c429
-rw-r--r--apps/codecs/liba52/mm_accel.h37
-rw-r--r--apps/codecs/liba52/parse.c946
-rw-r--r--apps/codecs/liba52/tables.h246
-rw-r--r--apps/codecs/liba52/tendra.h35
24 files changed, 3970 insertions, 0 deletions
diff --git a/apps/codecs/liba52/AUTHORS b/apps/codecs/liba52/AUTHORS
new file mode 100644
index 0000000000..b9ded1bc4d
--- /dev/null
+++ b/apps/codecs/liba52/AUTHORS
@@ -0,0 +1,23 @@
+Aaron Holtzman <aholtzma@ess.engr.uvic.ca> started the project and
+made the initial working implementation.
+
+Michel Lespinasse <walken@zoy.org> did major changes for speed and
+conformance and is the current maintainer.
+
+Other contributors include:
+ Gildas Bazin <gbazin@netcourrier.com> - mingw32 port
+ Billy Biggs <vektor@div8.net> - most of liba52.txt
+ Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com> - fixed point version
+ Eduard Hasenleithner <eduardh@aon.at> - gcc 3.0 fixes
+ Håkan Hjort <d95hjort@dtek.chalmers.se> - Solaris output, mlib code
+ Charles M. Hannum <root@ihack.net> - fixes
+ Chris Hodges <hodges@stradis.com> - made the library reentrant
+ Michael Holzt <kju@flummi.de> - OSS output.c and misc errata
+ Angelos Keromytis <angelos@dsl.cis.upenn.edu> - OpenBSD fixes
+ David I. Lehn <dlehn@vt.edu> - API cleanup suggestion
+ Don Mahurin <dmahurin@dma.org> - stdin support for extract_a52
+ Jim Miller <jmiller@heli.engr.sgi.com> - IRIX output.c
+ Takefumi Sayo <stake@niagara.shiojiri.ne.jp> - FreeBSD tweak
+ Shoji Tokunaga <toku@mac.com> - aif file output
+
+(let me know if I forgot anyone)
diff --git a/apps/codecs/liba52/COPYING b/apps/codecs/liba52/COPYING
new file mode 100644
index 0000000000..60549be514
--- /dev/null
+++ b/apps/codecs/liba52/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <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) 19yy 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.
diff --git a/apps/codecs/liba52/ChangeLog b/apps/codecs/liba52/ChangeLog
new file mode 100644
index 0000000000..4adac364eb
--- /dev/null
+++ b/apps/codecs/liba52/ChangeLog
@@ -0,0 +1,97 @@
+a52dec-0.7.4 Sat Jul 27 20:44:00 PDT 2002
+-The library is now fully reentrant.
+-Added win32 output module, al file output, gain control.
+-A few additional portability enhancements.
+
+a52dec-0.7.3 Wed Feb 20 23:38:22 PST 2002
+-rewrite of the imdct code, making a52dec 40% to 80% faster than version 0.7.2
+-fixed one memory corruption problem in parse.c
+-small liba52 portability fixes
+-byte order and CRLF bugfixes in wav file output
+-aif file output
+-IRIX al sound output (untested, tell us if it works)
+
+a52dec-0.7.2 Sun Dec 16 14:39:56 PST 2001
+-demuxer improvements, with support for TS streams.
+-smaller demux buffer, making it easier to use a52dec as a pipe
+-wav output
+-avoid -fPIC when possible (-prefer-non-pic)
+-support for vc++ and TenDRA
+-portability fixes
+
+a52dec-0.7.1b Fri Aug 31 02:37:23 PDT 2001
+-removed an #include <stdint.h> that was only breaking libc5 builds
+
+a52dec-0.7.1 Thu Aug 30 02:13:23 PDT 2001
+-gcc 3.0 fixes
+-mlib fixes (now passes the test suite)
+-in a52dec.c, made sample_data and flags static
+-removed a few statics in liba52/parse.c (still not reentrant, but closer)
+
+a52dec-0.7.0 Thu Aug 23 23:18:00 PDT 2001
+-Downmix to arbitrary speaker configurations
+-Dynamic range compression
+-Major speedups: 2x for 2.0 streams with 2.0 output,
+ 3x for 5.1 streams with 2.0 output.
+-New library interface
+-Rematrixing bugfix
+-Higher precision
+
+ac3dec-0.6.1 Mon Mar 27 20:27:06 EST 2000
+-Fix another 2.0 problem (rematrix was wrong).
+-Fix the never resync on a bad crc bug.
+
+ac3dec-0.6.0 Sat Mar 18 19:43:25 EST 2000
+-New library interface
+-Fix bug wrt coupling channels that was causing sound quality problems.
+-Fix 2.0 mode problems (aka the I forgot to implement the phase flags bug).
+-All around speed improvements (almost twice as fast)
+-Improved robustness when fed bad data. The entire frame is checksummed before playback.
+
+ac3dec-0.5.6 Tue Nov 16 00:37:34 EST 1999
+-Irix support
+-Alpha fixes
+-Minor performance enhancements to downmix and imdct
+-OpenBSD fixes
+-extract_ac3 can now read from stdin
+-Change output_linux to block on write instead of using the
+ ring buffer. Let me know if this causes/fixes any problems
+
+ac3dec-0.5.5 Wed Aug 25 15:36:44 EDT 1999
+-Fixed a cut and paste bug (argh!) in parse.c which potentially
+ screwed up delta bit allocation info.
+-Martin Mueller <mamueller@topmail.de> informed me that I was missing
+ some corrections from the AC-3 errata document. It turns out that
+ I used an earlier version of the errata when I initially wrote ac3dec.
+ Fortunately the errata fix the outstanding bugs that I was pulling
+ my hair out on for a long time. Woohoo! Thanks Martin. Kudos to Dolby
+ Labs for keeping their documentation up to date as well.
+-stereo downmixing (downmix.c) is now in. Matrix encoded surround
+ (Dolby Prologic Surround) should work too.
+-clipping due to high level signals has been fixed. We normalize a
+ block of samples by its maximum absolute value if the max exceeds
+ the %100 digital level. This shouldn't be a problem, but for some
+ reason some channels have a dynamic range that exceeds [-1.0,1.0].
+ I blame the encoder :)
+-Multiple track support in extract_ac3. Simply just give it the track
+ number you want [1,8] after the filename.
+
+ac3dec-0.5.4 Thu Jul 29 16:55:10 PDT 1999
+-Fixed a stupid bug with the coupling channel that was causing
+ high frequencies to be attenuated.
+-Re-wrote the extract_ac3 tool.
+-Added to a tool to verify the checksums on a given AC3 stream.
+ (tools/verify_ac3)
+
+ac3dec-0.5.3 Mon Jul 12 10:45:56 PDT 1999
+-Fixed problems related to streams with coupling channel enabled.
+-Minor performance enhancements
+
+ac3dec-0.5.2 Sun Jul 4 12:00:25 PDT 1999
+-output_linux.c patch provided by Michael Holzt <kju@flummi.de>
+
+ac3dec-0.5.1 Wed Jun 30 17:48:52 PDT 1999
+-Compiles and dies gracefully under Linux now.
+
+ac3dec-0.5.0 Wed Jun 23 11:06:06 EDT 1999
+-First public release of ac3dec.
diff --git a/apps/codecs/liba52/HISTORY b/apps/codecs/liba52/HISTORY
new file mode 100644
index 0000000000..c2b9d02ee1
--- /dev/null
+++ b/apps/codecs/liba52/HISTORY
@@ -0,0 +1,28 @@
+changes that affected the PCM output:
+
+2001/05/14 05:48:59 - aaron's 0.6.1 was cutting before the end
+
+2001/06/04 01:42:47 - slightly adjusted some values (volume, downmix adjustemtn, clev/slev tables)
+2001/06/04 05:48:31 - added adjust_level to the downmix
+
+2001/06/12
+2001/06/13 - changed the order of the dither() calls
+ also introduced bug with thx_2_0 stream
+
+2001/06/22 08:23:37 - fixed bug with thx_2_0 stream (see parse.c)
+
+2001/07/02 08:44:55 - changed float-to-int conversion (+ added saturation)
+
+2001/07/06 06:53:01 - more precise imdct init, more precise q_* coefficients
+
+2001/07/06 08:52:30 - rematrixing fixes
+
+2001/07/26 21:31:39 - do 3dB dither reduction in coeff_get() not dither_gen()
+
+2001/08/09 08:11:31 - implemented dynamic range compression
+
+2002/02/24 08:54:49 - window function computed at runtime, with more precision
+
+2003/01/28 06.57:37 - switched to integer q_* coefficients
+
+2003/01/28 07:39:35 - use level of 0.75 for dithering instead of 0.707
diff --git a/apps/codecs/liba52/INSTALL b/apps/codecs/liba52/INSTALL
new file mode 100644
index 0000000000..30a07fecff
--- /dev/null
+++ b/apps/codecs/liba52/INSTALL
@@ -0,0 +1,58 @@
+Unix build instructions
+-----------------------
+
+./configure
+make
+make install
+
+If you install from CVS you'll have to run ./bootstrap first
+
+
+Building for win32
+------------------
+
+There are at least three ways to do it:
+
+- natively on Windows using Microsoft VC++ and the vc++ project
+ included in this distribution.
+
+- natively on Windows using MSYS + MINGW (www.mingw.org) (MSYS is a
+ minimal build environnement to compile unixish projects under
+ windows. It provides all the common unix tools like sh, gmake...)
+
+- or on Linux, using the mingw32 cross-compiler
+
+
+Building using MSYS + MINGW on windows
+--------------------------------------
+
+First you will need to download and install the latest MSYS (version
+1.0.7 as of now) and MINGW. The installation is really easy. Begin
+with the MSYS auto-installer and once this is done, extract MINGW into
+c:\msys\1.0\mingw. You also have to remember to remove the make
+utility included with MINGW as it conflicts with the one from MSYS
+(just rename or remove c:\msys\1.0\mingw\bin\make.exe).
+
+http://prdownloads.sourceforge.net/mingw/MSYS-1.0.7-i686-2002.04.24-1.exe
+http://prdownloads.sourceforge.net/mingw/MinGW-1.1.tar.gz
+
+Then you can build the package using:
+# ./configure
+# make
+
+
+Building using the mingw32 cross-compiler
+-----------------------------------------
+
+You need to install mingw32 first. For Debian GNU/Linux users, there
+is a mingw32 package. Otherwise you might get it from the mingw site
+at http://www.mingw.org/download.shtml.
+
+The videolan project also keeps precompiled mingw32 binaries at
+http://www.videolan.org/vlc/windows.html . If you install these,
+you'll have to set your PATH accordingly to include
+/usr/local/cross-tools/bin too.
+
+The build should then proceed using something like:
+# CC=i586-mingw32msvc-gcc ./configure --host=i586-mingw32msvc
+# make
diff --git a/apps/codecs/liba52/Makefile b/apps/codecs/liba52/Makefile
new file mode 100644
index 0000000000..53e6d24dde
--- /dev/null
+++ b/apps/codecs/liba52/Makefile
@@ -0,0 +1,47 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+# ../.. for the plugin.h in the apps dir
+# .. for stuff in the plugins dir
+# . for stuff in the pluginlib dir
+INCLUDES=-I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
+ -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(APPSDIR)/plugins/liba52/
+
+ifdef APPEXTRA
+INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
+endif
+
+A52OPTS =
+CFLAGS = $(GCCOPTS) $(A52OPTS) $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) -DMEM=${MEMORYSIZE}
+
+SRC := $(shell cat SOURCES | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P -include "config.h" - )
+SOURCES = $(SRC)
+OBJS := $(SRC:%.c=$(OBJDIR)/liba52/%.o)
+DEPFILE = $(OBJDIR)/dep-liba52
+DIRS =
+
+OUTPUT = $(OBJDIR)/liba52.a
+
+all: $(OUTPUT)
+
+$(OUTPUT): $(OBJS)
+ @echo "AR $@"
+ @$(AR) ruv $@ $+ >/dev/null 2>&1
+
+$(OBJDIR)/liba52/%.o: $(APPSDIR)/plugins/liba52/%.c
+ mkdir -p $(OBJDIR)/liba52
+ $(CC) -c -O2 $(CFLAGS) -I$(APPSDIR)/plugins/liba52/ $< -o $@
+
+include $(TOOLSDIR)/make.inc
+
+clean:
+ @echo "cleaning liba52"
+ @rm -f $(OBJS) $(OUTPUT) $(DEPFILE)
+
+-include $(DEPFILE)
diff --git a/apps/codecs/liba52/NEWS b/apps/codecs/liba52/NEWS
new file mode 100644
index 0000000000..4bee9cac8d
--- /dev/null
+++ b/apps/codecs/liba52/NEWS
@@ -0,0 +1,46 @@
+a52dec-0.7.4 Sat Jul 27 20:44:00 PDT 2002
+
+The library is now fully reentrant.
+
+Added win32 output module, al file output, gain control.
+
+A few additional portability enhancements.
+
+
+a52dec-0.7.3 Wed Feb 20 23:38:22 PST 2002
+
+Performance enhancements, from 40% to 80% depending on streams.
+
+Fixed a few embarassing bugs in liba52: one memory corruption issue
+and a few minor portability problems.
+
+Several new output modules, and fixes in the existing .wav file output.
+
+
+a52dec-0.7.2 Sun Dec 16 14:39:56 PST 2001
+
+Minor bugfixes, performance and portability enhancements.
+
+Also added wav format output, and reduced the demux buffer size which
+makes it easier to use a52dec as a pipe.
+
+
+a52dec-0.7.1 Thu Aug 30 02:13:23 PDT 2001
+
+Minor release for bugfixes. Looks like 0.7.0 was a bit rushed out.
+
+Now compiles with gcc 3.0, made sure mlib implementation works, and
+fixed a small bug in the a52dec test program.
+
+
+a52dec-0.7.0 Thu Aug 23 23:18:00 PDT 2001
+
+First release since more than one year !
+
+The most user-noticeable additions are the downmix to arbitrary
+speaker configurations, and the implementation of dynamic range
+compression.
+
+The speed has been improved by a factor of 2 to 3, the conformance and
+precision should be higher, and we also fixed a small bug when playing
+stereo rematrixed streams.
diff --git a/apps/codecs/liba52/README b/apps/codecs/liba52/README
new file mode 100644
index 0000000000..eb6c64df84
--- /dev/null
+++ b/apps/codecs/liba52/README
@@ -0,0 +1,180 @@
+
+
+ABOUT LIBA52
+
+liba52 is a free library for decoding ATSC A/52 streams. It is
+released under the terms of the GPL license. The A/52 standard is used
+in a variety of applications, including digital television and DVD. It
+is also known as AC-3.
+
+The main goals in liba52 development are:
+
+ * Portability - Currently all of the code is written in C, and
+ when we write platform-specific optimizations we will always
+ keep a generic C routine to fall back on.
+
+ * Reuseability - we do not want liba52 to include any
+ project-specific code, but it should still include enough
+ features to be used by very diverse projects.
+
+ * Precision - We are trying to implement all of the A/52
+ standard, and to have a very precise output by doing all the
+ calculations in floating point. We have a test suite that
+ detects any deviation in the output when compared to previous
+ versions. We do not have access to official A/52 test vectors
+ though, so we have to use our judgement to ensure that such
+ deviations are only intruduced when we fix bugs !
+
+ * Speed - liba52 is really fast, on any modern PC it should take
+ only a few percent of CPU time.
+
+The project homepage is at http://liba52.sourceforge.net/
+
+
+A52DEC
+
+a52dec is a test program for liba52. It decodes ATSC A/52 streams, and
+also includes a demultiplexer for mpeg-1 and mpeg-2 program streams.
+
+The liba52 source code is always distributed in the a52dec package, to
+make sure it easier for people to test it.
+
+The basic usage is to just type "a52dec file" where file is an ATSC
+A/52 file.
+
+The "-s" option must be used for multiplexed (audio and video) mpeg-2
+files. These files are usualy found on the internet or on unencrypted
+DVDs.
+
+The "-o" option is used to select a given output layer. By default
+a52dec does a stereo downmix and outputs to your speakers, but you can
+try other choices using this option. This is also used for performance
+testing and conformance testing.
+
+The "-c" option is used to disable all optimizations (currently only djbfft).
+
+The "-r" option is used to disable the dynamic range compression.
+
+
+OTHER PROJECTS USING LIBA52
+
+liba52 (and its ancestor libac3) is being used by various other
+projects, including:
+
+ * xine (http://xine.sourceforge.net/) - started as a simple
+ mpeg-2 audio and video decoder, but it since became a
+ full-featured DVD and video media player.
+
+ * VideoLAN (http://www.videolan.org/) - video streaming over an
+ ethernet network, can also be used as a standalone player.
+
+ * MPlayer (http://www.MPlayerHQ.hu) - another good player, it is
+ also very robust against damaged streams.
+
+ * movietime (http://movietime.sourceforge.net/) - still quite
+ young, but it looks very promising !
+
+ * ffmpeg (http://ffmpeg.sourceforge.net/) - a nice audio/video
+ encoder and transcoder, uses liba52 for decoding A/52 streams.
+
+ * Ogle (http://www.dtek.chalmers.se/groups/dvd/) - a good DVD
+ player with menu support
+
+ * a52decX (http://homepage1.nifty.com/~toku/software_en.html) -
+ a graphical interface for a52dec in macintosh osX.
+
+ * TCVP (http://tcvp.sf.net) - video and music player for unix.
+
+ * bd4go (http://denisx.dyndns.org/bd4go/) - another graphical
+ interface for macintosh osX.
+
+ * drip (http://drip.sourceforge.net/) - a DVD to DIVX transcoder.
+
+ * OMS (http://www.linuxvideo.org/oms/)
+
+ * XMPS (http://xmps.sourceforge.net/)
+
+ * GStreamer (http://www.gstreamer.net/) - a framework for
+ streaming media; it has an A/52 decoding plugin based on liba52.
+
+ * mpeglib (http://mpeglib.sourceforge.net/) - a video decoding
+ library that usess liba52 when decoding A/52 streams.
+
+If you use liba52 in another project, let us know !
+
+
+TASKS
+
+There are several places where we could easily use some help:
+
+ * Web design: This site sucks ! at the very least, we'd like to
+ come up with a nicer background picture and a logo.
+
+ * Testing: If you find any stream that does not decode right
+ with liba52, let us know ! The best thing would be to mail to
+ the liba52-devel mailing list. Also if you have access to
+ encoders, we'd love to get test streams that would be free of
+ rights - so that we can put them on this server.
+
+ * Coding: you can have a look in the TODO file first ! The most
+ important item is probably to make the code fully reentrant.
+
+ * Porting: If you're porting to a new architecture, you might
+ want to experiment with the compile flags defined in
+ configure.in . When you figure out whats fastest on your
+ platform, send us a patch !
+
+
+REFERENCES
+
+The A/52 standard, as published by the ATSC, is available at
+http://www.atsc.org/standards/a_52a.pdf
+
+
+CVS SNAPSHOTS
+
+A daily snapshot is created using "make distcheck" every night and
+uploaded to http://liba52.sourceforge.net/files/a52dec-snapshot.tar.gz .
+It is easier to use than the CVS repository, because you do not need
+to have the right versions of automake, autoconf and libtool
+installed. It might be convenient when working on a liba52 port for
+example.
+
+
+CVS REPOSITORY
+
+The latest liba52 and a52dec source code can always be found by
+anonymous CVS:
+
+# export CVSROOT=:pserver:anonymous@cvs.liba52.sourceforge.net:/cvsroot/liba52
+# cvs login (Just press Return when prompted for a password)
+# cvs checkout a52dec
+
+You can also browse the latest changes online at
+http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/liba52/a52dec/
+
+The other CVS modules are ac3dec-livid for the CVS history of the
+project while it was still hosted on the linuxvideo.org servers, and
+ac3dec for the CVS history of the project while the linuxvideo.org
+servers were down and before the library switched its name to liba52.
+
+
+MAILING LISTS
+
+See the subscription information at http://liba52.sourceforge.net/lists.html
+
+liba52-devel
+
+This is the main mailing list for technical discussion about
+liba52. Anyone wanting to work on liba52, or maybe just stay informed
+about the development process, should probably subscribe to this list.
+
+liba52-checkins
+
+All liba52 checkins are announced there. This is a good way to keep
+track of what goes into CVS.
+
+liba52-announce
+
+This is a very low traffic mailing list, only for announcements of new
+versions of liba52. Only project administrators can post there.
diff --git a/apps/codecs/liba52/README.rockbox b/apps/codecs/liba52/README.rockbox
new file mode 100644
index 0000000000..79768c5d72
--- /dev/null
+++ b/apps/codecs/liba52/README.rockbox
@@ -0,0 +1,27 @@
+Library: liba52-0.7.5 (CVS version 2005-02-16)
+Imported: 2005-02-16 by Dave Chapman
+
+
+This directory contains a local version of liba52 for decoding ATSC
+A/52 (aka AC-3) audio streams. A/52 is commonly used in digital TV and
+on DVDs.
+
+LICENSING INFORMATION
+
+liba52 is released under the GNU General Public License as described
+in the COPYING file in this directory.
+
+
+IMPORT DETAILS
+
+The base version first imported into Rockbox was the CVS version of
+liba52-0.7.5 (0.7.4 was at the time the latest official) which was
+checked out of sourceforge on 2005-02-16.
+
+The .[ch] files from a52dec/liba52/ and a52dec/include/ as well as the
+documentation files in a52dec/ were imported into Rockbox. The other
+files in the archive relate to the test player (a52dec) and were not
+imported.
+
+A simple config.h file was added to enable liba52's fixed-point
+integer-only mode and to specify the endianness of the target CPU.
diff --git a/apps/codecs/liba52/SOURCES b/apps/codecs/liba52/SOURCES
new file mode 100644
index 0000000000..733b95e8a6
--- /dev/null
+++ b/apps/codecs/liba52/SOURCES
@@ -0,0 +1,5 @@
+bit_allocate.c
+bitstream.c
+downmix.c
+imdct.c
+parse.c
diff --git a/apps/codecs/liba52/TODO b/apps/codecs/liba52/TODO
new file mode 100644
index 0000000000..dc5fb84203
--- /dev/null
+++ b/apps/codecs/liba52/TODO
@@ -0,0 +1,17 @@
+* look at possible overflow/precision issues in integer port
+
+* redo all bit allocation if previous frame had zero_snr_offsets
+* make dynrng work in dual-channel streams
+
+* implement A/52a downmix extensions
+* reduce size of delay buffer by 50%
+* include float->s16 conversion in liba52 API ?
+* include up/downsampling 44100<->48000 in liba52 API ?
+* include audio dithering in liba52 API ?
+* API extensions might be at a different level (base vs. extended)
+
+* use restrict pointers where appropriate
+* avoid overflows, including reading the a52 stream !!!
+* faster bitstream parsing ?
+* make dither code faster (generate dither table in advance ?)
+* SIMD optimizations
diff --git a/apps/codecs/liba52/a52.h b/apps/codecs/liba52/a52.h
new file mode 100644
index 0000000000..aa4e7f6243
--- /dev/null
+++ b/apps/codecs/liba52/a52.h
@@ -0,0 +1,67 @@
+/*
+ * a52.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#ifndef A52_H
+#define A52_H
+
+#if defined(LIBA52_FIXED)
+typedef int32_t sample_t;
+typedef int32_t level_t;
+#elif defined(LIBA52_DOUBLE)
+typedef double sample_t;
+typedef double level_t;
+#else
+typedef float sample_t;
+typedef float level_t;
+#endif
+
+typedef struct a52_state_s a52_state_t;
+
+#define A52_CHANNEL 0
+#define A52_MONO 1
+#define A52_STEREO 2
+#define A52_3F 3
+#define A52_2F1R 4
+#define A52_3F1R 5
+#define A52_2F2R 6
+#define A52_3F2R 7
+#define A52_CHANNEL1 8
+#define A52_CHANNEL2 9
+#define A52_DOLBY 10
+#define A52_CHANNEL_MASK 15
+
+#define A52_LFE 16
+#define A52_ADJUST_LEVEL 32
+
+a52_state_t * a52_init (uint32_t mm_accel);
+sample_t * a52_samples (a52_state_t * state);
+int a52_syncinfo (uint8_t * buf, int * flags,
+ int * sample_rate, int * bit_rate);
+int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
+ level_t * level, sample_t bias);
+void a52_dynrng (a52_state_t * state,
+ level_t (* call) (level_t, void *), void * data);
+int a52_block (a52_state_t * state);
+void a52_free (a52_state_t * state);
+
+#endif /* A52_H */
diff --git a/apps/codecs/liba52/a52_internal.h b/apps/codecs/liba52/a52_internal.h
new file mode 100644
index 0000000000..a158227699
--- /dev/null
+++ b/apps/codecs/liba52/a52_internal.h
@@ -0,0 +1,160 @@
+/*
+ * a52_internal.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+typedef struct {
+ uint8_t bai; /* fine SNR offset, fast gain */
+ uint8_t deltbae; /* delta bit allocation exists */
+ int8_t deltba[50]; /* per-band delta bit allocation */
+} ba_t;
+
+typedef struct {
+ uint8_t exp[256]; /* decoded channel exponents */
+ int8_t bap[256]; /* derived channel bit allocation */
+} expbap_t;
+
+struct a52_state_s {
+ uint8_t fscod; /* sample rate */
+ uint8_t halfrate; /* halfrate factor */
+ uint8_t acmod; /* coded channels */
+ uint8_t lfeon; /* coded lfe channel */
+ level_t clev; /* centre channel mix level */
+ level_t slev; /* surround channels mix level */
+
+ int output; /* type of output */
+ level_t level; /* output level */
+ sample_t bias; /* output bias */
+
+ int dynrnge; /* apply dynamic range */
+ level_t dynrng; /* dynamic range */
+ void * dynrngdata; /* dynamic range callback funtion and data */
+ level_t (* dynrngcall) (level_t range, void * dynrngdata);
+
+ uint8_t chincpl; /* channel coupled */
+ uint8_t phsflginu; /* phase flags in use (stereo only) */
+ uint8_t cplstrtmant; /* coupling channel start mantissa */
+ uint8_t cplendmant; /* coupling channel end mantissa */
+ uint32_t cplbndstrc; /* coupling band structure */
+ level_t cplco[5][18]; /* coupling coordinates */
+
+ /* derived information */
+ uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */
+ uint8_t ncplbnd; /* number of coupling bands */
+
+ uint8_t rematflg; /* stereo rematrixing */
+
+ uint8_t endmant[5]; /* channel end mantissa */
+
+ uint16_t bai; /* bit allocation information */
+
+ uint32_t * buffer_start;
+ uint16_t lfsr_state; /* dither state */
+ uint32_t bits_left;
+ uint32_t current_word;
+
+ uint8_t csnroffst; /* coarse SNR offset */
+ ba_t cplba; /* coupling bit allocation parameters */
+ ba_t ba[5]; /* channel bit allocation parameters */
+ ba_t lfeba; /* lfe bit allocation parameters */
+
+ uint8_t cplfleak; /* coupling fast leak init */
+ uint8_t cplsleak; /* coupling slow leak init */
+
+ expbap_t cpl_expbap;
+ expbap_t fbw_expbap[5];
+ expbap_t lfe_expbap;
+
+ sample_t * samples;
+ int downmixed;
+};
+
+#define LEVEL_PLUS6DB 2.0
+#define LEVEL_PLUS3DB 1.4142135623730951
+#define LEVEL_3DB 0.7071067811865476
+#define LEVEL_45DB 0.5946035575013605
+#define LEVEL_6DB 0.5
+
+#define EXP_REUSE (0)
+#define EXP_D15 (1)
+#define EXP_D25 (2)
+#define EXP_D45 (3)
+
+#define DELTA_BIT_REUSE (0)
+#define DELTA_BIT_NEW (1)
+#define DELTA_BIT_NONE (2)
+#define DELTA_BIT_RESERVED (3)
+
+void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
+ int start, int end, int fastleak, int slowleak,
+ expbap_t * expbap);
+
+int a52_downmix_init (int input, int flags, level_t * level,
+ level_t clev, level_t slev);
+int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
+ level_t clev, level_t slev);
+void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
+ level_t clev, level_t slev);
+void a52_upmix (sample_t * samples, int acmod, int output);
+
+void a52_imdct_init (uint32_t mm_accel);
+void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias);
+void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias);
+
+#define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5)))
+
+#ifndef LIBA52_FIXED
+
+typedef sample_t quantizer_t;
+#define SAMPLE(x) (x)
+#define LEVEL(x) (x)
+#define MUL(a,b) ((a) * (b))
+#define MUL_L(a,b) ((a) * (b))
+#define MUL_C(a,b) ((a) * (b))
+#define DIV(a,b) ((a) / (b))
+#define BIAS(x) ((x) + bias)
+
+#else /* LIBA52_FIXED */
+
+typedef int16_t quantizer_t;
+#define SAMPLE(x) (sample_t)((x) * (1 << 30))
+#define LEVEL(x) (level_t)((x) * (1 << 26))
+
+#if 0
+#define MUL(a,b) ((int)(((int64_t)(a) * (b) + (1 << 29)) >> 30))
+#define MUL_L(a,b) ((int)(((int64_t)(a) * (b) + (1 << 25)) >> 26))
+#elif 1
+#define MUL(a,b) \
+({ int32_t _ta=(a), _tb=(b), _tc; \
+ _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)(((_tc >> 14))+ (((_ta >> 16)*(_tb >> 16)) << 2 )); })
+#define MUL_L(a,b) \
+({ int32_t _ta=(a), _tb=(b), _tc; \
+ _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)((_tc >> 10) + (((_ta >> 16)*(_tb >> 16)) << 6)); })
+#else
+#define MUL(a,b) (((a) >> 15) * ((b) >> 15))
+#define MUL_L(a,b) (((a) >> 13) * ((b) >> 13))
+#endif
+
+#define MUL_C(a,b) MUL_L (a, LEVEL (b))
+#define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b))
+#define BIAS(x) (x)
+
+#endif
diff --git a/apps/codecs/liba52/attributes.h b/apps/codecs/liba52/attributes.h
new file mode 100644
index 0000000000..988abc0311
--- /dev/null
+++ b/apps/codecs/liba52/attributes.h
@@ -0,0 +1,37 @@
+/*
+ * attributes.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+/* use gcc attribs to align critical data structures */
+#ifdef ATTRIBUTE_ALIGNED_MAX
+#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
+#else
+#define ATTR_ALIGN(align)
+#endif
+
+#ifdef HAVE_BUILTIN_EXPECT
+#define likely(x) __builtin_expect ((x) != 0, 1)
+#define unlikely(x) __builtin_expect ((x) != 0, 0)
+#else
+#define likely(x) (x)
+#define unlikely(x) (x)
+#endif
diff --git a/apps/codecs/liba52/bit_allocate.c b/apps/codecs/liba52/bit_allocate.c
new file mode 100644
index 0000000000..c8da24e9e6
--- /dev/null
+++ b/apps/codecs/liba52/bit_allocate.c
@@ -0,0 +1,265 @@
+/*
+ * bit_allocate.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "a52.h"
+#include "a52_internal.h"
+
+static int hthtab[3][50] = {
+ {0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
+ 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890,
+ 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900,
+ 0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0,
+ 0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0},
+ {0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860,
+ 0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880,
+ 0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0,
+ 0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820,
+ 0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0},
+ {0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850,
+ 0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860,
+ 0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0,
+ 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0,
+ 0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720}
+};
+
+static int8_t baptab[305] = {
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, /* 93 padding elems */
+
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14,
+ 14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
+ 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5,
+ 5, 4, 4, -3, -3, 3, 3, 3, -2, -2, -1, -1, -1, -1, -1, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0 /* 148 padding elems */
+};
+
+static int bndtab[30] = {21, 22, 23, 24, 25, 26, 27, 28, 31, 34,
+ 37, 40, 43, 46, 49, 55, 61, 67, 73, 79,
+ 85, 97, 109, 121, 133, 157, 181, 205, 229, 253};
+
+static int8_t latab[256] = {
+ -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53,
+ -52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44,
+ -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35,
+ -35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28,
+ -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22,
+ -22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18,
+ -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14,
+ -13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11,
+ -10, -10, -10, -10, -10, -9, -9, -9, -9, -9, -8, -8,
+ -8, -8, -8, -8, -7, -7, -7, -7, -7, -7, -6, -6,
+ -6, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5,
+ -5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
+ -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
+ -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+#define UPDATE_LEAK() \
+do { \
+ fastleak += fdecay; \
+ if (fastleak > psd + fgain) \
+ fastleak = psd + fgain; \
+ slowleak += sdecay; \
+ if (slowleak > psd + sgain) \
+ slowleak = psd + sgain; \
+} while (0)
+
+#define COMPUTE_MASK() \
+do { \
+ if (psd > dbknee) \
+ mask -= (psd - dbknee) >> 2; \
+ if (mask > hth [i >> halfrate]) \
+ mask = hth [i >> halfrate]; \
+ mask -= snroffset + 128 * deltba[i]; \
+ mask = (mask > 0) ? 0 : ((-mask) >> 5); \
+ mask -= floor; \
+} while (0)
+
+void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
+ int start, int end, int fastleak, int slowleak,
+ expbap_t * expbap)
+{
+ static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
+ static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100};
+ static int floortab[8] = {0x910, 0x950, 0x990, 0x9d0,
+ 0xa10, 0xa90, 0xb10, 0x1400};
+
+ int i, j;
+ uint8_t * exp;
+ int8_t * bap;
+ int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset;
+ int psd, mask;
+ int8_t * deltba;
+ int * hth;
+ int halfrate;
+
+ halfrate = state->halfrate;
+ fdecay = (63 + 20 * ((state->bai >> 7) & 3)) >> halfrate; /* fdcycod */
+ fgain = 128 + 128 * (ba->bai & 7); /* fgaincod */
+ sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate; /* sdcycod */
+ sgain = slowgain[(state->bai >> 5) & 3]; /* sgaincod */
+ dbknee = dbpbtab[(state->bai >> 3) & 3]; /* dbpbcod */
+ hth = hthtab[state->fscod];
+ /*
+ * if there is no delta bit allocation, make deltba point to an area
+ * known to contain zeroes. baptab+156 here.
+ */
+ deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
+ floor = floortab[state->bai & 7]; /* floorcod */
+ snroffset = 960 - 64 * state->csnroffst - 4 * (ba->bai >> 3) + floor;
+ floor >>= 5;
+
+ exp = expbap->exp;
+ bap = expbap->bap;
+
+ i = bndstart;
+ j = start;
+ if (start == 0) { /* not the coupling channel */
+ int lowcomp;
+
+ lowcomp = 0;
+ j = end - 1;
+ do {
+ if (i < j) {
+ if (exp[i+1] == exp[i] - 2)
+ lowcomp = 384;
+ else if (lowcomp && (exp[i+1] > exp[i]))
+ lowcomp -= 64;
+ }
+ psd = 128 * exp[i];
+ mask = psd + fgain + lowcomp;
+ COMPUTE_MASK ();
+ bap[i] = (baptab+156)[mask + 4 * exp[i]];
+ i++;
+ } while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1])));
+ fastleak = psd + fgain;
+ slowleak = psd + sgain;
+
+ while (i < 7) {
+ if (i < j) {
+ if (exp[i+1] == exp[i] - 2)
+ lowcomp = 384;
+ else if (lowcomp && (exp[i+1] > exp[i]))
+ lowcomp -= 64;
+ }
+ psd = 128 * exp[i];
+ UPDATE_LEAK ();
+ mask = ((fastleak + lowcomp < slowleak) ?
+ fastleak + lowcomp : slowleak);
+ COMPUTE_MASK ();
+ bap[i] = (baptab+156)[mask + 4 * exp[i]];
+ i++;
+ }
+
+ if (end == 7) /* lfe channel */
+ return;
+
+ do {
+ if (exp[i+1] == exp[i] - 2)
+ lowcomp = 320;
+ else if (lowcomp && (exp[i+1] > exp[i]))
+ lowcomp -= 64;
+ psd = 128 * exp[i];
+ UPDATE_LEAK ();
+ mask = ((fastleak + lowcomp < slowleak) ?
+ fastleak + lowcomp : slowleak);
+ COMPUTE_MASK ();
+ bap[i] = (baptab+156)[mask + 4 * exp[i]];
+ i++;
+ } while (i < 20);
+
+ while (lowcomp > 128) { /* two iterations maximum */
+ lowcomp -= 128;
+ psd = 128 * exp[i];
+ UPDATE_LEAK ();
+ mask = ((fastleak + lowcomp < slowleak) ?
+ fastleak + lowcomp : slowleak);
+ COMPUTE_MASK ();
+ bap[i] = (baptab+156)[mask + 4 * exp[i]];
+ i++;
+ }
+ j = i;
+ }
+
+ do {
+ int startband, endband;
+
+ startband = j;
+ endband = (bndtab[i-20] < end) ? bndtab[i-20] : end;
+ psd = 128 * exp[j++];
+ while (j < endband) {
+ int next, delta;
+
+ next = 128 * exp[j++];
+ delta = next - psd;
+ switch (delta >> 9) {
+ case -6: case -5: case -4: case -3: case -2:
+ psd = next;
+ break;
+ case -1:
+ psd = next + latab[(-delta) >> 1];
+ break;
+ case 0:
+ psd += latab[delta >> 1];
+ break;
+ }
+ }
+ /* minpsd = -289 */
+ UPDATE_LEAK ();
+ mask = (fastleak < slowleak) ? fastleak : slowleak;
+ COMPUTE_MASK ();
+ i++;
+ j = startband;
+ do {
+ /* max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp */
+ /* min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 */
+ bap[j] = (baptab+156)[mask + 4 * exp[j]];
+ } while (++j < endband);
+ } while (j < end);
+}
diff --git a/apps/codecs/liba52/bitstream.c b/apps/codecs/liba52/bitstream.c
new file mode 100644
index 0000000000..05e4940dc4
--- /dev/null
+++ b/apps/codecs/liba52/bitstream.c
@@ -0,0 +1,97 @@
+/*
+ * bitstream.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "a52.h"
+#include "a52_internal.h"
+#include "bitstream.h"
+
+#define BUFFER_SIZE 4096
+
+void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf)
+{
+ int align;
+
+ align = (long)buf & 3;
+ state->buffer_start = (uint32_t *) (buf - align);
+ state->bits_left = 0;
+ state->current_word = 0;
+ bitstream_get (state, align * 8);
+ bitstream_get_2 (state, 0); /* pretend function is used - keep gcc happy */
+}
+
+static inline void bitstream_fill_current (a52_state_t * state)
+{
+ uint32_t tmp;
+
+ tmp = *(state->buffer_start++);
+ state->current_word = swab32 (tmp);
+}
+
+/*
+ * The fast paths for _get is in the
+ * bitstream.h header file so it can be inlined.
+ *
+ * The "bottom half" of this routine is suffixed _bh
+ *
+ * -ah
+ */
+
+uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits)
+{
+ uint32_t result;
+
+ num_bits -= state->bits_left;
+ result = ((state->current_word << (32 - state->bits_left)) >>
+ (32 - state->bits_left));
+
+ bitstream_fill_current (state);
+
+ if (num_bits != 0)
+ result = (result << num_bits) | (state->current_word >> (32 - num_bits));
+
+ state->bits_left = 32 - num_bits;
+
+ return result;
+}
+
+int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits)
+{
+ int32_t result;
+
+ num_bits -= state->bits_left;
+ result = ((((int32_t)state->current_word) << (32 - state->bits_left)) >>
+ (32 - state->bits_left));
+
+ bitstream_fill_current(state);
+
+ if (num_bits != 0)
+ result = (result << num_bits) | (state->current_word >> (32 - num_bits));
+
+ state->bits_left = 32 - num_bits;
+
+ return result;
+}
diff --git a/apps/codecs/liba52/bitstream.h b/apps/codecs/liba52/bitstream.h
new file mode 100644
index 0000000000..f559fbf833
--- /dev/null
+++ b/apps/codecs/liba52/bitstream.h
@@ -0,0 +1,77 @@
+/*
+ * bitstream.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+/* (stolen from the kernel) */
+#ifdef WORDS_BIGENDIAN
+
+# define swab32(x) (x)
+
+#else
+
+# if 0 && defined (__i386__)
+
+# define swab32(x) __i386_swab32(x)
+ static inline const uint32_t __i386_swab32(uint32_t x)
+ {
+ __asm__("bswap %0" : "=r" (x) : "0" (x));
+ return x;
+ }
+
+# else
+
+# define swab32(x)\
+((((uint8_t*)&x)[0] << 24) | (((uint8_t*)&x)[1] << 16) | \
+ (((uint8_t*)&x)[2] << 8) | (((uint8_t*)&x)[3]))
+
+# endif
+#endif
+
+void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf);
+uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits);
+int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits);
+
+static inline uint32_t bitstream_get (a52_state_t * state, uint32_t num_bits)
+{
+ uint32_t result;
+
+ if (num_bits < state->bits_left) {
+ result = (state->current_word << (32 - state->bits_left)) >> (32 - num_bits);
+ state->bits_left -= num_bits;
+ return result;
+ }
+
+ return a52_bitstream_get_bh (state, num_bits);
+}
+
+static inline int32_t bitstream_get_2 (a52_state_t * state, uint32_t num_bits)
+{
+ int32_t result;
+
+ if (num_bits < state->bits_left) {
+ result = (((int32_t)state->current_word) << (32 - state->bits_left)) >> (32 - num_bits);
+ state->bits_left -= num_bits;
+ return result;
+ }
+
+ return a52_bitstream_get_bh_2 (state, num_bits);
+}
diff --git a/apps/codecs/liba52/config.h b/apps/codecs/liba52/config.h
new file mode 100644
index 0000000000..dc8515971c
--- /dev/null
+++ b/apps/codecs/liba52/config.h
@@ -0,0 +1,21 @@
+/* a52dec profiling */
+/* #undef A52DEC_GPROF */
+
+/* Define to 1 if you have the `memalign' function. */
+/* #undef HAVE_MEMALIGN 1 */
+
+/* liba52 djbfft support */
+/* #undef LIBA52_DJBFFT */
+
+/* a52 sample precision */
+/* #undef LIBA52_DOUBLE */
+
+/* use fixed-point arithmetic */
+#define LIBA52_FIXED
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+
+/* Used in bitstream.h */
+
+#define WORDS_BIGENDIAN 1
diff --git a/apps/codecs/liba52/downmix.c b/apps/codecs/liba52/downmix.c
new file mode 100644
index 0000000000..5660951486
--- /dev/null
+++ b/apps/codecs/liba52/downmix.c
@@ -0,0 +1,685 @@
+/*
+ * downmix.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "a52.h"
+#include "a52_internal.h"
+
+#define CONVERT(acmod,output) (((output) << 3) + (acmod))
+
+int a52_downmix_init (int input, int flags, level_t * level,
+ level_t clev, level_t slev)
+{
+ static uint8_t table[11][8] = {
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO},
+ {A52_MONO, A52_MONO, A52_MONO, A52_MONO,
+ A52_MONO, A52_MONO, A52_MONO, A52_MONO},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
+ A52_STEREO, A52_3F, A52_STEREO, A52_3F},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_2F1R, A52_2F1R, A52_2F1R, A52_2F1R},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
+ A52_2F1R, A52_3F1R, A52_2F1R, A52_3F1R},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
+ A52_2F2R, A52_2F2R, A52_2F2R, A52_2F2R},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
+ A52_2F2R, A52_3F2R, A52_2F2R, A52_3F2R},
+ {A52_CHANNEL1, A52_MONO, A52_MONO, A52_MONO,
+ A52_MONO, A52_MONO, A52_MONO, A52_MONO},
+ {A52_CHANNEL2, A52_MONO, A52_MONO, A52_MONO,
+ A52_MONO, A52_MONO, A52_MONO, A52_MONO},
+ {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_DOLBY,
+ A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY}
+ };
+ int output;
+
+ output = flags & A52_CHANNEL_MASK;
+ if (output > A52_DOLBY)
+ return -1;
+
+ output = table[output][input & 7];
+
+ if (output == A52_STEREO &&
+ (input == A52_DOLBY || (input == A52_3F && clev == LEVEL (LEVEL_3DB))))
+ output = A52_DOLBY;
+
+ if (flags & A52_ADJUST_LEVEL) {
+ level_t adjust;
+
+ switch (CONVERT (input & 7, output)) {
+
+ case CONVERT (A52_3F, A52_MONO):
+ adjust = DIV (LEVEL_3DB, LEVEL (1) + clev);
+ break;
+
+ case CONVERT (A52_STEREO, A52_MONO):
+ case CONVERT (A52_2F2R, A52_2F1R):
+ case CONVERT (A52_3F2R, A52_3F1R):
+ level_3db:
+ adjust = LEVEL (LEVEL_3DB);
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F1R):
+ if (clev < LEVEL (LEVEL_PLUS3DB - 1))
+ goto level_3db;
+ /* break thru */
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_2F1R):
+ case CONVERT (A52_3F1R, A52_2F2R):
+ case CONVERT (A52_3F2R, A52_2F2R):
+ adjust = DIV (1, LEVEL (1) + clev);
+ break;
+
+ case CONVERT (A52_2F1R, A52_MONO):
+ adjust = DIV (LEVEL_PLUS3DB, LEVEL (2) + slev);
+ break;
+
+ case CONVERT (A52_2F1R, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_3F):
+ adjust = DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB));
+ break;
+
+ case CONVERT (A52_3F1R, A52_MONO):
+ adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5));
+ break;
+
+ case CONVERT (A52_3F1R, A52_STEREO):
+ adjust = DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB));
+ break;
+
+ case CONVERT (A52_2F2R, A52_MONO):
+ adjust = DIV (LEVEL_3DB, LEVEL (1) + slev);
+ break;
+
+ case CONVERT (A52_2F2R, A52_STEREO):
+ case CONVERT (A52_3F2R, A52_3F):
+ adjust = DIV (1, LEVEL (1) + slev);
+ break;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + slev);
+ break;
+
+ case CONVERT (A52_3F2R, A52_STEREO):
+ adjust = DIV (1, LEVEL (1) + clev + slev);
+ break;
+
+ case CONVERT (A52_MONO, A52_DOLBY):
+ adjust = LEVEL (LEVEL_PLUS3DB);
+ break;
+
+ case CONVERT (A52_3F, A52_DOLBY):
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ adjust = LEVEL (1 / (1 + LEVEL_3DB));
+ break;
+
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ adjust = LEVEL (1 / (1 + 2 * LEVEL_3DB));
+ break;
+
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ adjust = LEVEL (1 / (1 + 3 * LEVEL_3DB));
+ break;
+
+ default:
+ return output;
+ }
+
+ *level = MUL_L (*level, adjust);
+ }
+
+ return output;
+}
+
+int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
+ level_t clev, level_t slev)
+{
+ level_t level_3db;
+
+ level_3db = MUL_C (level, LEVEL_3DB);
+
+ switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL):
+ case CONVERT (A52_MONO, A52_MONO):
+ case CONVERT (A52_STEREO, A52_STEREO):
+ case CONVERT (A52_3F, A52_3F):
+ case CONVERT (A52_2F1R, A52_2F1R):
+ case CONVERT (A52_3F1R, A52_3F1R):
+ case CONVERT (A52_2F2R, A52_2F2R):
+ case CONVERT (A52_3F2R, A52_3F2R):
+ case CONVERT (A52_STEREO, A52_DOLBY):
+ coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level;
+ return 0;
+
+ case CONVERT (A52_CHANNEL, A52_MONO):
+ coeff[0] = coeff[1] = MUL_C (level, LEVEL_6DB);
+ return 3;
+
+ case CONVERT (A52_STEREO, A52_MONO):
+ coeff[0] = coeff[1] = level_3db;
+ return 3;
+
+ case CONVERT (A52_3F, A52_MONO):
+ coeff[0] = coeff[2] = level_3db;
+ coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB);
+ return 7;
+
+ case CONVERT (A52_2F1R, A52_MONO):
+ coeff[0] = coeff[1] = level_3db;
+ coeff[2] = MUL_L (level_3db, slev);
+ return 7;
+
+ case CONVERT (A52_2F2R, A52_MONO):
+ coeff[0] = coeff[1] = level_3db;
+ coeff[2] = coeff[3] = MUL_L (level_3db, slev);
+ return 15;
+
+ case CONVERT (A52_3F1R, A52_MONO):
+ coeff[0] = coeff[2] = level_3db;
+ coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB);
+ coeff[3] = MUL_L (level_3db, slev);
+ return 15;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ coeff[0] = coeff[2] = level_3db;
+ coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB);
+ coeff[3] = coeff[4] = MUL_L (level_3db, slev);
+ return 31;
+
+ case CONVERT (A52_MONO, A52_DOLBY):
+ coeff[0] = level_3db;
+ return 0;
+
+ case CONVERT (A52_3F, A52_DOLBY):
+ coeff[0] = coeff[2] = coeff[3] = coeff[4] = level;
+ coeff[1] = level_3db;
+ return 7;
+
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_2F1R):
+ case CONVERT (A52_3F2R, A52_2F2R):
+ coeff[0] = coeff[2] = coeff[3] = coeff[4] = level;
+ coeff[1] = MUL_L (level, clev);
+ return 7;
+
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = level_3db;
+ return 7;
+
+ case CONVERT (A52_2F1R, A52_STEREO):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = MUL_L (level_3db, slev);
+ return 7;
+
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = coeff[3] = level_3db;
+ return 15;
+
+ case CONVERT (A52_3F1R, A52_STEREO):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = MUL_L (level, clev);
+ coeff[3] = MUL_L (level_3db, slev);
+ return 15;
+
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = coeff[3] = level_3db;
+ return 15;
+
+ case CONVERT (A52_2F2R, A52_STEREO):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = coeff[3] = MUL_L (level, slev);
+ return 15;
+
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = coeff[3] = coeff[4] = level_3db;
+ return 31;
+
+ case CONVERT (A52_3F2R, A52_2F1R):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = MUL_L (level, clev);
+ coeff[3] = coeff[4] = level_3db;
+ return 31;
+
+ case CONVERT (A52_3F2R, A52_STEREO):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = MUL_L (level, clev);
+ coeff[3] = coeff[4] = MUL_L (level, slev);
+ return 31;
+
+ case CONVERT (A52_3F1R, A52_3F):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = MUL_L (level_3db, slev);
+ return 13;
+
+ case CONVERT (A52_3F2R, A52_3F):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = coeff[4] = MUL_L (level, slev);
+ return 29;
+
+ case CONVERT (A52_2F2R, A52_2F1R):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = coeff[3] = level_3db;
+ return 12;
+
+ case CONVERT (A52_3F2R, A52_3F1R):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = coeff[4] = level_3db;
+ return 24;
+
+ case CONVERT (A52_2F1R, A52_2F2R):
+ coeff[0] = coeff[1] = level;
+ coeff[2] = level_3db;
+ return 0;
+
+ case CONVERT (A52_3F1R, A52_2F2R):
+ coeff[0] = coeff[2] = level;
+ coeff[1] = MUL_L (level, clev);
+ coeff[3] = level_3db;
+ return 7;
+
+ case CONVERT (A52_3F1R, A52_3F2R):
+ coeff[0] = coeff[1] = coeff[2] = level;
+ coeff[3] = level_3db;
+ return 0;
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL1):
+ coeff[0] = level;
+ coeff[1] = 0;
+ return 0;
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL2):
+ coeff[0] = 0;
+ coeff[1] = level;
+ return 0;
+ }
+
+ return -1; /* NOTREACHED */
+}
+
+static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dest[i] += BIAS (src[i]);
+}
+
+static void mix3to1 (sample_t * samples, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] += BIAS (samples[i + 256] + samples[i + 512]);
+}
+
+static void mix4to1 (sample_t * samples, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] += BIAS (samples[i + 256] + samples[i + 512] +
+ samples[i + 768]);
+}
+
+static void mix5to1 (sample_t * samples, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] += BIAS (samples[i + 256] + samples[i + 512] +
+ samples[i + 768] + samples[i + 1024]);
+}
+
+static void mix3to2 (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i + 256]);
+ samples[i] += common;
+ samples[i + 256] = samples[i + 512] + common;
+ }
+}
+
+static void mix21to2 (sample_t * left, sample_t * right, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (right[i + 256]);
+ left[i] += common;
+ right[i] += common;
+ }
+}
+
+static void mix21toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t surround;
+
+ for (i = 0; i < 256; i++) {
+ surround = samples[i + 512];
+ samples[i] += BIAS (-surround);
+ samples[i + 256] += BIAS (surround);
+ }
+}
+
+static void mix31to2 (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i + 256] + samples[i + 768]);
+ samples[i] += common;
+ samples[i + 256] = samples[i + 512] + common;
+ }
+}
+
+static void mix31toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common, surround;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i + 256]);
+ surround = samples[i + 768];
+ samples[i] += common - surround;
+ samples[i + 256] = samples[i + 512] + common + surround;
+ }
+}
+
+static void mix22toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t surround;
+
+ for (i = 0; i < 256; i++) {
+ surround = samples[i + 512] + samples[i + 768];
+ samples[i] += BIAS (-surround);
+ samples[i + 256] += BIAS (surround);
+ }
+}
+
+static void mix32to2 (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i + 256]);
+ samples[i] += common + samples[i + 768];
+ samples[i + 256] = common + samples[i + 512] + samples[i + 1024];
+ }
+}
+
+static void mix32toS (sample_t * samples, sample_t bias)
+{
+ int i;
+ sample_t common, surround;
+
+ for (i = 0; i < 256; i++) {
+ common = BIAS (samples[i + 256]);
+ surround = samples[i + 768] + samples[i + 1024];
+ samples[i] += common - surround;
+ samples[i + 256] = samples[i + 512] + common + surround;
+ }
+}
+
+static void move2to1 (sample_t * src, sample_t * dest, sample_t bias)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dest[i] = BIAS (src[i] + src[i + 256]);
+}
+
+static void zero (sample_t * samples)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ samples[i] = 0;
+}
+
+void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
+ level_t clev, level_t slev)
+{
+ switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL2):
+ memcpy (samples, samples + 256, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_CHANNEL, A52_MONO):
+ case CONVERT (A52_STEREO, A52_MONO):
+ mix_2to1:
+ mix2to1 (samples, samples + 256, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_MONO):
+ if (slev == 0)
+ goto mix_2to1;
+ case CONVERT (A52_3F, A52_MONO):
+ mix_3to1:
+ mix3to1 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_MONO):
+ if (slev == 0)
+ goto mix_3to1;
+ case CONVERT (A52_2F2R, A52_MONO):
+ if (slev == 0)
+ goto mix_2to1;
+ mix4to1 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ if (slev == 0)
+ goto mix_3to1;
+ mix5to1 (samples, bias);
+ break;
+
+ case CONVERT (A52_MONO, A52_DOLBY):
+ memcpy (samples + 256, samples, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F, A52_DOLBY):
+ mix_3to2:
+ mix3to2 (samples, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_STEREO):
+ if (slev == 0)
+ break;
+ mix21to2 (samples, samples + 256, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ mix21toS (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_STEREO):
+ if (slev == 0)
+ goto mix_3to2;
+ mix31to2 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ mix31toS (samples, bias);
+ break;
+
+ case CONVERT (A52_2F2R, A52_STEREO):
+ if (slev == 0)
+ break;
+ mix2to1 (samples, samples + 512, bias);
+ mix2to1 (samples + 256, samples + 768, bias);
+ break;
+
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ mix22toS (samples, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_STEREO):
+ if (slev == 0)
+ goto mix_3to2;
+ mix32to2 (samples, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ mix32toS (samples, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_3F):
+ if (slev == 0)
+ break;
+ mix21to2 (samples, samples + 512, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F):
+ if (slev == 0)
+ break;
+ mix2to1 (samples, samples + 768, bias);
+ mix2to1 (samples + 512, samples + 1024, bias);
+ break;
+
+ case CONVERT (A52_3F1R, A52_2F1R):
+ mix3to2 (samples, bias);
+ memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_2F2R, A52_2F1R):
+ mix2to1 (samples + 512, samples + 768, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F1R):
+ mix3to2 (samples, bias);
+ move2to1 (samples + 768, samples + 512, bias);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F1R):
+ mix2to1 (samples + 768, samples + 1024, bias);
+ break;
+
+ case CONVERT (A52_2F1R, A52_2F2R):
+ memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F1R, A52_2F2R):
+ mix3to2 (samples, bias);
+ memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F2R):
+ mix3to2 (samples, bias);
+ memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
+ memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F1R, A52_3F2R):
+ memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
+ break;
+ }
+}
+
+void a52_upmix (sample_t * samples, int acmod, int output)
+{
+ switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
+
+ case CONVERT (A52_CHANNEL, A52_CHANNEL2):
+ memcpy (samples + 256, samples, 256 * sizeof (sample_t));
+ break;
+
+ case CONVERT (A52_3F2R, A52_MONO):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_MONO):
+ case CONVERT (A52_2F2R, A52_MONO):
+ zero (samples + 768);
+ case CONVERT (A52_3F, A52_MONO):
+ case CONVERT (A52_2F1R, A52_MONO):
+ zero (samples + 512);
+ case CONVERT (A52_CHANNEL, A52_MONO):
+ case CONVERT (A52_STEREO, A52_MONO):
+ zero (samples + 256);
+ break;
+
+ case CONVERT (A52_3F2R, A52_STEREO):
+ case CONVERT (A52_3F2R, A52_DOLBY):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_STEREO):
+ case CONVERT (A52_3F1R, A52_DOLBY):
+ zero (samples + 768);
+ case CONVERT (A52_3F, A52_STEREO):
+ case CONVERT (A52_3F, A52_DOLBY):
+ mix_3to2:
+ memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t));
+ zero (samples + 256);
+ break;
+
+ case CONVERT (A52_2F2R, A52_STEREO):
+ case CONVERT (A52_2F2R, A52_DOLBY):
+ zero (samples + 768);
+ case CONVERT (A52_2F1R, A52_STEREO):
+ case CONVERT (A52_2F1R, A52_DOLBY):
+ zero (samples + 512);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_3F):
+ case CONVERT (A52_2F2R, A52_2F1R):
+ zero (samples + 768);
+ break;
+
+ case CONVERT (A52_3F2R, A52_3F1R):
+ zero (samples + 1024);
+ break;
+
+ case CONVERT (A52_3F2R, A52_2F1R):
+ zero (samples + 1024);
+ case CONVERT (A52_3F1R, A52_2F1R):
+ mix_31to21:
+ memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
+ goto mix_3to2;
+
+ case CONVERT (A52_3F2R, A52_2F2R):
+ memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
+ goto mix_31to21;
+ }
+}
diff --git a/apps/codecs/liba52/imdct.c b/apps/codecs/liba52/imdct.c
new file mode 100644
index 0000000000..1cb3814907
--- /dev/null
+++ b/apps/codecs/liba52/imdct.c
@@ -0,0 +1,429 @@
+/*
+ * imdct.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * The ifft algorithms in this file have been largely inspired by Dan
+ * Bernstein's work, djbfft, available at http://cr.yp.to/djbfft.html
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdio.h>
+#ifdef LIBA52_DJBFFT
+#include <fftc4.h>
+#include <fftc8.h>
+#endif
+#ifndef M_PI
+#define M_PI 3.1415926535897932384626433832795029
+#endif
+#include <inttypes.h>
+
+#include "a52.h"
+#include "a52_internal.h"
+#include "mm_accel.h"
+
+typedef struct complex_s {
+ sample_t real;
+ sample_t imag;
+} complex_t;
+
+static uint8_t fftorder[] = {
+ 0,128, 64,192, 32,160,224, 96, 16,144, 80,208,240,112, 48,176,
+ 8,136, 72,200, 40,168,232,104,248,120, 56,184, 24,152,216, 88,
+ 4,132, 68,196, 36,164,228,100, 20,148, 84,212,244,116, 52,180,
+ 252,124, 60,188, 28,156,220, 92, 12,140, 76,204,236,108, 44,172,
+ 2,130, 66,194, 34,162,226, 98, 18,146, 82,210,242,114, 50,178,
+ 10,138, 74,202, 42,170,234,106,250,122, 58,186, 26,154,218, 90,
+ 254,126, 62,190, 30,158,222, 94, 14,142, 78,206,238,110, 46,174,
+ 6,134, 70,198, 38,166,230,102,246,118, 54,182, 22,150,214, 86
+};
+
+/* Root values for IFFT */
+static sample_t roots16[3];
+static sample_t roots32[7];
+static sample_t roots64[15];
+static sample_t roots128[31];
+
+/* Twiddle factors for IMDCT */
+static complex_t pre1[128];
+static complex_t post1[64];
+static complex_t pre2[64];
+static complex_t post2[32];
+
+static sample_t a52_imdct_window[256];
+
+static void (* ifft128) (complex_t * buf);
+static void (* ifft64) (complex_t * buf);
+
+static inline void ifft2 (complex_t * buf)
+{
+ sample_t r, i;
+
+ r = buf[0].real;
+ i = buf[0].imag;
+ buf[0].real += buf[1].real;
+ buf[0].imag += buf[1].imag;
+ buf[1].real = r - buf[1].real;
+ buf[1].imag = i - buf[1].imag;
+}
+
+static inline void ifft4 (complex_t * buf)
+{
+ sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+
+ tmp1 = buf[0].real + buf[1].real;
+ tmp2 = buf[3].real + buf[2].real;
+ tmp3 = buf[0].imag + buf[1].imag;
+ tmp4 = buf[2].imag + buf[3].imag;
+ tmp5 = buf[0].real - buf[1].real;
+ tmp6 = buf[0].imag - buf[1].imag;
+ tmp7 = buf[2].imag - buf[3].imag;
+ tmp8 = buf[3].real - buf[2].real;
+
+ buf[0].real = tmp1 + tmp2;
+ buf[0].imag = tmp3 + tmp4;
+ buf[2].real = tmp1 - tmp2;
+ buf[2].imag = tmp3 - tmp4;
+ buf[1].real = tmp5 + tmp7;
+ buf[1].imag = tmp6 + tmp8;
+ buf[3].real = tmp5 - tmp7;
+ buf[3].imag = tmp6 - tmp8;
+}
+
+/* basic radix-2 ifft butterfly */
+
+#define BUTTERFLY_0(t0,t1,W0,W1,d0,d1) do { \
+ t0 = MUL (W1, d1) + MUL (W0, d0); \
+ t1 = MUL (W0, d1) - MUL (W1, d0); \
+} while (0)
+
+/* radix-2 ifft butterfly with bias */
+
+#define BUTTERFLY_B(t0,t1,W0,W1,d0,d1) do { \
+ t0 = BIAS (MUL (d1, W1) + MUL (d0, W0)); \
+ t1 = BIAS (MUL (d1, W0) - MUL (d0, W1)); \
+} while (0)
+
+/* the basic split-radix ifft butterfly */
+
+#define BUTTERFLY(a0,a1,a2,a3,wr,wi) do { \
+ BUTTERFLY_0 (tmp5, tmp6, wr, wi, a2.real, a2.imag); \
+ BUTTERFLY_0 (tmp8, tmp7, wr, wi, a3.imag, a3.real); \
+ tmp1 = tmp5 + tmp7; \
+ tmp2 = tmp6 + tmp8; \
+ tmp3 = tmp6 - tmp8; \
+ tmp4 = tmp7 - tmp5; \
+ a2.real = a0.real - tmp1; \
+ a2.imag = a0.imag - tmp2; \
+ a3.real = a1.real - tmp3; \
+ a3.imag = a1.imag - tmp4; \
+ a0.real += tmp1; \
+ a0.imag += tmp2; \
+ a1.real += tmp3; \
+ a1.imag += tmp4; \
+} while (0)
+
+/* split-radix ifft butterfly, specialized for wr=1 wi=0 */
+
+#define BUTTERFLY_ZERO(a0,a1,a2,a3) do { \
+ tmp1 = a2.real + a3.real; \
+ tmp2 = a2.imag + a3.imag; \
+ tmp3 = a2.imag - a3.imag; \
+ tmp4 = a3.real - a2.real; \
+ a2.real = a0.real - tmp1; \
+ a2.imag = a0.imag - tmp2; \
+ a3.real = a1.real - tmp3; \
+ a3.imag = a1.imag - tmp4; \
+ a0.real += tmp1; \
+ a0.imag += tmp2; \
+ a1.real += tmp3; \
+ a1.imag += tmp4; \
+} while (0)
+
+/* split-radix ifft butterfly, specialized for wr=wi */
+
+#define BUTTERFLY_HALF(a0,a1,a2,a3,w) do { \
+ tmp5 = MUL (a2.real + a2.imag, w); \
+ tmp6 = MUL (a2.imag - a2.real, w); \
+ tmp7 = MUL (a3.real - a3.imag, w); \
+ tmp8 = MUL (a3.imag + a3.real, w); \
+ tmp1 = tmp5 + tmp7; \
+ tmp2 = tmp6 + tmp8; \
+ tmp3 = tmp6 - tmp8; \
+ tmp4 = tmp7 - tmp5; \
+ a2.real = a0.real - tmp1; \
+ a2.imag = a0.imag - tmp2; \
+ a3.real = a1.real - tmp3; \
+ a3.imag = a1.imag - tmp4; \
+ a0.real += tmp1; \
+ a0.imag += tmp2; \
+ a1.real += tmp3; \
+ a1.imag += tmp4; \
+} while (0)
+
+static inline void ifft8 (complex_t * buf)
+{
+ sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+
+ ifft4 (buf);
+ ifft2 (buf + 4);
+ ifft2 (buf + 6);
+ BUTTERFLY_ZERO (buf[0], buf[2], buf[4], buf[6]);
+ BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], roots16[1]);
+}
+
+static void ifft_pass (complex_t * buf, sample_t * weight, int n)
+{
+ complex_t * buf1;
+ complex_t * buf2;
+ complex_t * buf3;
+ sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+ int i;
+
+ buf++;
+ buf1 = buf + n;
+ buf2 = buf + 2 * n;
+ buf3 = buf + 3 * n;
+
+ BUTTERFLY_ZERO (buf[-1], buf1[-1], buf2[-1], buf3[-1]);
+
+ i = n - 1;
+
+ do {
+ BUTTERFLY (buf[0], buf1[0], buf2[0], buf3[0],
+ weight[0], weight[2*i-n]);
+ buf++;
+ buf1++;
+ buf2++;
+ buf3++;
+ weight++;
+ } while (--i);
+}
+
+static void ifft16 (complex_t * buf)
+{
+ ifft8 (buf);
+ ifft4 (buf + 8);
+ ifft4 (buf + 12);
+ ifft_pass (buf, roots16, 4);
+}
+
+static void ifft32 (complex_t * buf)
+{
+ ifft16 (buf);
+ ifft8 (buf + 16);
+ ifft8 (buf + 24);
+ ifft_pass (buf, roots32, 8);
+}
+
+static void ifft64_c (complex_t * buf)
+{
+ ifft32 (buf);
+ ifft16 (buf + 32);
+ ifft16 (buf + 48);
+ ifft_pass (buf, roots64, 16);
+}
+
+static void ifft128_c (complex_t * buf)
+{
+ ifft32 (buf);
+ ifft16 (buf + 32);
+ ifft16 (buf + 48);
+ ifft_pass (buf, roots64, 16);
+
+ ifft32 (buf + 64);
+ ifft32 (buf + 96);
+ ifft_pass (buf, roots128, 32);
+}
+
+void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias)
+{
+ int i, k;
+ sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2;
+ const sample_t * window = a52_imdct_window;
+ complex_t buf[128];
+
+ for (i = 0; i < 128; i++) {
+ k = fftorder[i];
+ t_r = pre1[i].real;
+ t_i = pre1[i].imag;
+ BUTTERFLY_0 (buf[i].real, buf[i].imag, t_r, t_i, data[k], data[255-k]);
+ }
+
+ ifft128 (buf);
+
+ /* Post IFFT complex multiply plus IFFT complex conjugate*/
+ /* Window and convert to real valued signal */
+ for (i = 0; i < 64; i++) {
+ /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
+ t_r = post1[i].real;
+ t_i = post1[i].imag;
+ BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf[i].imag, buf[i].real);
+ BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf[127-i].imag, buf[127-i].real);
+
+ w_1 = window[2*i];
+ w_2 = window[255-2*i];
+ BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]);
+ delay[2*i] = a_i;
+
+ w_1 = window[2*i+1];
+ w_2 = window[254-2*i];
+ BUTTERFLY_B (data[2*i+1], data[254-2*i], w_1, w_2, b_r, delay[2*i+1]);
+ delay[2*i+1] = b_i;
+ }
+}
+
+void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias)
+{
+ int i, k;
+ sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2;
+ const sample_t * window = a52_imdct_window;
+ complex_t buf1[64], buf2[64];
+
+ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
+ for (i = 0; i < 64; i++) {
+ k = fftorder[i];
+ t_r = pre2[i].real;
+ t_i = pre2[i].imag;
+ BUTTERFLY_0 (buf1[i].real, buf1[i].imag, t_r, t_i, data[k], data[254-k]);
+ BUTTERFLY_0 (buf2[i].real, buf2[i].imag, t_r, t_i, data[k+1], data[255-k]);
+ }
+
+ ifft64 (buf1);
+ ifft64 (buf2);
+
+ /* Post IFFT complex multiply */
+ /* Window and convert to real valued signal */
+ for (i = 0; i < 32; i++) {
+ /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
+ t_r = post2[i].real;
+ t_i = post2[i].imag;
+ BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf1[i].imag, buf1[i].real);
+ BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf1[63-i].imag, buf1[63-i].real);
+ BUTTERFLY_0 (c_r, c_i, t_i, t_r, buf2[i].imag, buf2[i].real);
+ BUTTERFLY_0 (d_r, d_i, t_r, t_i, buf2[63-i].imag, buf2[63-i].real);
+
+ w_1 = window[2*i];
+ w_2 = window[255-2*i];
+ BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]);
+ delay[2*i] = c_i;
+
+ w_1 = window[128+2*i];
+ w_2 = window[127-2*i];
+ BUTTERFLY_B (data[128+2*i], data[127-2*i], w_1, w_2, a_i, delay[127-2*i]);
+ delay[127-2*i] = c_r;
+
+ w_1 = window[2*i+1];
+ w_2 = window[254-2*i];
+ BUTTERFLY_B (data[254-2*i], data[2*i+1], w_2, w_1, b_i, delay[2*i+1]);
+ delay[2*i+1] = d_r;
+
+ w_1 = window[129+2*i];
+ w_2 = window[126-2*i];
+ BUTTERFLY_B (data[129+2*i], data[126-2*i], w_1, w_2, b_r, delay[126-2*i]);
+ delay[126-2*i] = d_i;
+ }
+}
+
+static double besselI0 (double x)
+{
+ double bessel = 1;
+ int i = 100;
+
+ do
+ bessel = bessel * x / (i * i) + 1;
+ while (--i);
+ return bessel;
+}
+
+void a52_imdct_init (uint32_t mm_accel)
+{
+ int i, k;
+ double sum;
+ double local_imdct_window[256];
+
+ /* compute imdct window - kaiser-bessel derived window, alpha = 5.0 */
+ sum = 0;
+ for (i = 0; i < 256; i++) {
+ sum += besselI0 (i * (256 - i) * (5 * M_PI / 256) * (5 * M_PI / 256));
+ local_imdct_window[i] = sum;
+ }
+ sum++;
+ for (i = 0; i < 256; i++)
+ a52_imdct_window[i] = SAMPLE (sqrt (local_imdct_window[i] / sum));
+
+ for (i = 0; i < 3; i++)
+ roots16[i] = SAMPLE (cos ((M_PI / 8) * (i + 1)));
+
+ for (i = 0; i < 7; i++)
+ roots32[i] = SAMPLE (cos ((M_PI / 16) * (i + 1)));
+
+ for (i = 0; i < 15; i++)
+ roots64[i] = SAMPLE (cos ((M_PI / 32) * (i + 1)));
+
+ for (i = 0; i < 31; i++)
+ roots128[i] = SAMPLE (cos ((M_PI / 64) * (i + 1)));
+
+ for (i = 0; i < 64; i++) {
+ k = fftorder[i] / 2 + 64;
+ pre1[i].real = SAMPLE (cos ((M_PI / 256) * (k - 0.25)));
+ pre1[i].imag = SAMPLE (sin ((M_PI / 256) * (k - 0.25)));
+ }
+
+ for (i = 64; i < 128; i++) {
+ k = fftorder[i] / 2 + 64;
+ pre1[i].real = SAMPLE (-cos ((M_PI / 256) * (k - 0.25)));
+ pre1[i].imag = SAMPLE (-sin ((M_PI / 256) * (k - 0.25)));
+ }
+
+ for (i = 0; i < 64; i++) {
+ post1[i].real = SAMPLE (cos ((M_PI / 256) * (i + 0.5)));
+ post1[i].imag = SAMPLE (sin ((M_PI / 256) * (i + 0.5)));
+ }
+
+ for (i = 0; i < 64; i++) {
+ k = fftorder[i] / 4;
+ pre2[i].real = SAMPLE (cos ((M_PI / 128) * (k - 0.25)));
+ pre2[i].imag = SAMPLE (sin ((M_PI / 128) * (k - 0.25)));
+ }
+
+ for (i = 0; i < 32; i++) {
+ post2[i].real = SAMPLE (cos ((M_PI / 128) * (i + 0.5)));
+ post2[i].imag = SAMPLE (sin ((M_PI / 128) * (i + 0.5)));
+ }
+
+#ifdef LIBA52_DJBFFT
+ if (mm_accel & MM_ACCEL_DJBFFT) {
+#ifndef LIBA52_DOUBLE
+ ifft128 = (void (*) (complex_t *)) fftc4_un128;
+ ifft64 = (void (*) (complex_t *)) fftc4_un64;
+#else
+ ifft128 = (void (*) (complex_t *)) fftc8_un128;
+ ifft64 = (void (*) (complex_t *)) fftc8_un64;
+#endif
+ } else
+#endif
+ {
+ ifft128 = ifft128_c;
+ ifft64 = ifft64_c;
+ }
+}
diff --git a/apps/codecs/liba52/mm_accel.h b/apps/codecs/liba52/mm_accel.h
new file mode 100644
index 0000000000..f569787aec
--- /dev/null
+++ b/apps/codecs/liba52/mm_accel.h
@@ -0,0 +1,37 @@
+/*
+ * mm_accel.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#ifndef MM_ACCEL_H
+#define MM_ACCEL_H
+
+/* generic accelerations */
+#define MM_ACCEL_DJBFFT 0x00000001
+
+/* x86 accelerations */
+#define MM_ACCEL_X86_MMX 0x80000000
+#define MM_ACCEL_X86_3DNOW 0x40000000
+#define MM_ACCEL_X86_MMXEXT 0x20000000
+
+uint32_t mm_accel (void);
+
+#endif /* MM_ACCEL_H */
diff --git a/apps/codecs/liba52/parse.c b/apps/codecs/liba52/parse.c
new file mode 100644
index 0000000000..505a335f09
--- /dev/null
+++ b/apps/codecs/liba52/parse.c
@@ -0,0 +1,946 @@
+/*
+ * parse.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "a52.h"
+#include "a52_internal.h"
+#include "bitstream.h"
+#include "tables.h"
+
+#if defined(HAVE_MEMALIGN) && !defined(__cplusplus)
+/* some systems have memalign() but no declaration for it */
+void * memalign (size_t align, size_t size);
+#else
+/* assume malloc alignment is sufficient */
+#define memalign(align,size) malloc (size)
+#endif
+
+typedef struct {
+ quantizer_t q1[2];
+ quantizer_t q2[2];
+ quantizer_t q4;
+ int q1_ptr;
+ int q2_ptr;
+ int q4_ptr;
+} quantizer_set_t;
+
+static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
+
+a52_state_t * a52_init (uint32_t mm_accel)
+{
+ a52_state_t * state;
+ int i;
+
+ state = (a52_state_t *) malloc (sizeof (a52_state_t));
+ if (state == NULL)
+ return NULL;
+
+ state->samples = (sample_t *) memalign (16, 256 * 12 * sizeof (sample_t));
+ if (state->samples == NULL) {
+ free (state);
+ return NULL;
+ }
+
+ for (i = 0; i < 256 * 12; i++)
+ state->samples[i] = 0;
+
+ state->downmixed = 1;
+
+ state->lfsr_state = 1;
+
+ a52_imdct_init (mm_accel);
+
+ return state;
+}
+
+sample_t * a52_samples (a52_state_t * state)
+{
+ return state->samples;
+}
+
+int a52_syncinfo (uint8_t * buf, int * flags,
+ int * sample_rate, int * bit_rate)
+{
+ static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384, 448,
+ 512, 576, 640};
+ static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01};
+ int frmsizecod;
+ int bitrate;
+ int half;
+ int acmod;
+
+ if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */
+ return 0;
+
+ if (buf[5] >= 0x60) /* bsid >= 12 */
+ return 0;
+ half = halfrate[buf[5] >> 3];
+
+ /* acmod, dsurmod and lfeon */
+ acmod = buf[6] >> 5;
+ *flags = ((((buf[6] & 0xf8) == 0x50) ? A52_DOLBY : acmod) |
+ ((buf[6] & lfeon[acmod]) ? A52_LFE : 0));
+
+ frmsizecod = buf[4] & 63;
+ if (frmsizecod >= 38)
+ return 0;
+ bitrate = rate [frmsizecod >> 1];
+ *bit_rate = (bitrate * 1000) >> half;
+
+ switch (buf[4] & 0xc0) {
+ case 0:
+ *sample_rate = 48000 >> half;
+ return 4 * bitrate;
+ case 0x40:
+ *sample_rate = 44100 >> half;
+ return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
+ case 0x80:
+ *sample_rate = 32000 >> half;
+ return 6 * bitrate;
+ default:
+ return 0;
+ }
+}
+
+int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
+ level_t * level, sample_t bias)
+{
+ static level_t clev[4] = { LEVEL (LEVEL_3DB), LEVEL (LEVEL_45DB),
+ LEVEL (LEVEL_6DB), LEVEL (LEVEL_45DB) };
+ static level_t slev[4] = { LEVEL (LEVEL_3DB), LEVEL (LEVEL_6DB),
+ 0, LEVEL (LEVEL_6DB) };
+ int chaninfo;
+ int acmod;
+
+ state->fscod = buf[4] >> 6;
+ state->halfrate = halfrate[buf[5] >> 3];
+ state->acmod = acmod = buf[6] >> 5;
+
+ a52_bitstream_set_ptr (state, buf + 6);
+ bitstream_get (state, 3); /* skip acmod we already parsed */
+
+ if ((acmod == 2) && (bitstream_get (state, 2) == 2)) /* dsurmod */
+ acmod = A52_DOLBY;
+
+ state->clev = state->slev = 0;
+
+ if ((acmod & 1) && (acmod != 1))
+ state->clev = clev[bitstream_get (state, 2)]; /* cmixlev */
+
+ if (acmod & 4)
+ state->slev = slev[bitstream_get (state, 2)]; /* surmixlev */
+
+ state->lfeon = bitstream_get (state, 1);
+
+ state->output = a52_downmix_init (acmod, *flags, level,
+ state->clev, state->slev);
+ if (state->output < 0)
+ return 1;
+ if (state->lfeon && (*flags & A52_LFE))
+ state->output |= A52_LFE;
+ *flags = state->output;
+ /* the 2* compensates for differences in imdct */
+ state->dynrng = state->level = MUL_C (*level, 2);
+ state->bias = bias;
+ state->dynrnge = 1;
+ state->dynrngcall = NULL;
+ state->cplba.deltbae = DELTA_BIT_NONE;
+ state->ba[0].deltbae = state->ba[1].deltbae = state->ba[2].deltbae =
+ state->ba[3].deltbae = state->ba[4].deltbae = DELTA_BIT_NONE;
+
+ chaninfo = !acmod;
+ do {
+ bitstream_get (state, 5); /* dialnorm */
+ if (bitstream_get (state, 1)) /* compre */
+ bitstream_get (state, 8); /* compr */
+ if (bitstream_get (state, 1)) /* langcode */
+ bitstream_get (state, 8); /* langcod */
+ if (bitstream_get (state, 1)) /* audprodie */
+ bitstream_get (state, 7); /* mixlevel + roomtyp */
+ } while (chaninfo--);
+
+ bitstream_get (state, 2); /* copyrightb + origbs */
+
+ if (bitstream_get (state, 1)) /* timecod1e */
+ bitstream_get (state, 14); /* timecod1 */
+ if (bitstream_get (state, 1)) /* timecod2e */
+ bitstream_get (state, 14); /* timecod2 */
+
+ if (bitstream_get (state, 1)) { /* addbsie */
+ int addbsil;
+
+ addbsil = bitstream_get (state, 6);
+ do {
+ bitstream_get (state, 8); /* addbsi */
+ } while (addbsil--);
+ }
+
+ return 0;
+}
+
+void a52_dynrng (a52_state_t * state,
+ level_t (* call) (level_t, void *), void * data)
+{
+ state->dynrnge = 0;
+ if (call) {
+ state->dynrnge = 1;
+ state->dynrngcall = call;
+ state->dynrngdata = data;
+ }
+}
+
+static int parse_exponents (a52_state_t * state, int expstr, int ngrps,
+ uint8_t exponent, uint8_t * dest)
+{
+ int exps;
+
+ while (ngrps--) {
+ exps = bitstream_get (state, 7);
+
+ exponent += exp_1[exps];
+ if (exponent > 24)
+ return 1;
+
+ switch (expstr) {
+ case EXP_D45:
+ *(dest++) = exponent;
+ *(dest++) = exponent;
+ case EXP_D25:
+ *(dest++) = exponent;
+ case EXP_D15:
+ *(dest++) = exponent;
+ }
+
+ exponent += exp_2[exps];
+ if (exponent > 24)
+ return 1;
+
+ switch (expstr) {
+ case EXP_D45:
+ *(dest++) = exponent;
+ *(dest++) = exponent;
+ case EXP_D25:
+ *(dest++) = exponent;
+ case EXP_D15:
+ *(dest++) = exponent;
+ }
+
+ exponent += exp_3[exps];
+ if (exponent > 24)
+ return 1;
+
+ switch (expstr) {
+ case EXP_D45:
+ *(dest++) = exponent;
+ *(dest++) = exponent;
+ case EXP_D25:
+ *(dest++) = exponent;
+ case EXP_D15:
+ *(dest++) = exponent;
+ }
+ }
+
+ return 0;
+}
+
+static int parse_deltba (a52_state_t * state, int8_t * deltba)
+{
+ int deltnseg, deltlen, delta, j;
+
+ memset (deltba, 0, 50);
+
+ deltnseg = bitstream_get (state, 3);
+ j = 0;
+ do {
+ j += bitstream_get (state, 5);
+ deltlen = bitstream_get (state, 4);
+ delta = bitstream_get (state, 3);
+ delta -= (delta >= 4) ? 3 : 4;
+ if (!deltlen)
+ continue;
+ if (j + deltlen >= 50)
+ return 1;
+ while (deltlen--)
+ deltba[j++] = delta;
+ } while (deltnseg--);
+
+ return 0;
+}
+
+static inline int zero_snr_offsets (int nfchans, a52_state_t * state)
+{
+ int i;
+
+ if ((state->csnroffst) ||
+ (state->chincpl && state->cplba.bai >> 3) || /* cplinu, fsnroffst */
+ (state->lfeon && state->lfeba.bai >> 3)) /* fsnroffst */
+ return 0;
+ for (i = 0; i < nfchans; i++)
+ if (state->ba[i].bai >> 3) /* fsnroffst */
+ return 0;
+ return 1;
+}
+
+static inline int16_t dither_gen (a52_state_t * state)
+{
+ int16_t nstate;
+
+ nstate = dither_lut[state->lfsr_state >> 8] ^ (state->lfsr_state << 8);
+
+ state->lfsr_state = (uint16_t) nstate;
+
+ return (3 * nstate) >> 2;
+}
+
+#ifndef LIBA52_FIXED
+#define COEFF(c,t,l,s,e) (c) = (t) * (s)[e]
+#else
+#define COEFF(c,_t,_l,s,e) do { \
+ quantizer_t t = (_t); \
+ level_t l = (_l); \
+ int shift = e - 5; \
+ sample_t tmp = t * (l >> 16) + ((t * (l & 0xffff)) >> 16); \
+ if (shift >= 0) \
+ (c) = tmp >> shift; \
+ else \
+ (c) = tmp << -shift; \
+} while (0)
+#endif
+
+static void coeff_get (a52_state_t * state, sample_t * coeff,
+ expbap_t * expbap, quantizer_set_t * quant,
+ level_t level, int dither, int end)
+{
+ int i;
+ uint8_t * exp;
+ int8_t * bap;
+
+#ifndef LIBA52_FIXED
+ sample_t factor[25];
+
+ for (i = 0; i <= 24; i++)
+ factor[i] = scale_factor[i] * level;
+#endif
+
+ exp = expbap->exp;
+ bap = expbap->bap;
+
+ for (i = 0; i < end; i++) {
+ int bapi;
+
+ bapi = bap[i];
+ switch (bapi) {
+ case 0:
+ if (dither) {
+ COEFF (coeff[i], dither_gen (state), level, factor, exp[i]);
+ continue;
+ } else {
+ coeff[i] = 0;
+ continue;
+ }
+
+ case -1:
+ if (quant->q1_ptr >= 0) {
+ COEFF (coeff[i], quant->q1[quant->q1_ptr--], level,
+ factor, exp[i]);
+ continue;
+ } else {
+ int code;
+
+ code = bitstream_get (state, 5);
+
+ quant->q1_ptr = 1;
+ quant->q1[0] = q_1_2[code];
+ quant->q1[1] = q_1_1[code];
+ COEFF (coeff[i], q_1_0[code], level, factor, exp[i]);
+ continue;
+ }
+
+ case -2:
+ if (quant->q2_ptr >= 0) {
+ COEFF (coeff[i], quant->q2[quant->q2_ptr--], level,
+ factor, exp[i]);
+ continue;
+ } else {
+ int code;
+
+ code = bitstream_get (state, 7);
+
+ quant->q2_ptr = 1;
+ quant->q2[0] = q_2_2[code];
+ quant->q2[1] = q_2_1[code];
+ COEFF (coeff[i], q_2_0[code], level, factor, exp[i]);
+ continue;
+ }
+
+ case 3:
+ COEFF (coeff[i], q_3[bitstream_get (state, 3)], level,
+ factor, exp[i]);
+ continue;
+
+ case -3:
+ if (quant->q4_ptr == 0) {
+ quant->q4_ptr = -1;
+ COEFF (coeff[i], quant->q4, level, factor, exp[i]);
+ continue;
+ } else {
+ int code;
+
+ code = bitstream_get (state, 7);
+
+ quant->q4_ptr = 0;
+ quant->q4 = q_4_1[code];
+ COEFF (coeff[i], q_4_0[code], level, factor, exp[i]);
+ continue;
+ }
+
+ case 4:
+ COEFF (coeff[i], q_5[bitstream_get (state, 4)], level,
+ factor, exp[i]);
+ continue;
+
+ default:
+ COEFF (coeff[i], bitstream_get_2 (state, bapi) << (16 - bapi),
+ level, factor, exp[i]);
+ }
+ }
+}
+
+static void coeff_get_coupling (a52_state_t * state, int nfchans,
+ level_t * coeff, sample_t (* samples)[256],
+ quantizer_set_t * quant, uint8_t dithflag[5])
+{
+ int cplbndstrc, bnd, i, i_end, ch;
+ uint8_t * exp;
+ int8_t * bap;
+ level_t cplco[5];
+
+ exp = state->cpl_expbap.exp;
+ bap = state->cpl_expbap.bap;
+ bnd = 0;
+ cplbndstrc = state->cplbndstrc;
+ i = state->cplstrtmant;
+ while (i < state->cplendmant) {
+ i_end = i + 12;
+ while (cplbndstrc & 1) {
+ cplbndstrc >>= 1;
+ i_end += 12;
+ }
+ cplbndstrc >>= 1;
+ for (ch = 0; ch < nfchans; ch++)
+ cplco[ch] = MUL_L (state->cplco[ch][bnd], coeff[ch]);
+ bnd++;
+
+ while (i < i_end) {
+ quantizer_t cplcoeff;
+ int bapi;
+
+ bapi = bap[i];
+ switch (bapi) {
+ case 0:
+ for (ch = 0; ch < nfchans; ch++)
+ if ((state->chincpl >> ch) & 1) {
+ if (dithflag[ch])
+#ifndef LIBA52_FIXED
+ samples[ch][i] = (scale_factor[exp[i]] *
+ cplco[ch] * dither_gen (state));
+#else
+ COEFF (samples[ch][i], dither_gen (state),
+ cplco[ch], scale_factor, exp[i]);
+#endif
+ else
+ samples[ch][i] = 0;
+ }
+ i++;
+ continue;
+
+ case -1:
+ if (quant->q1_ptr >= 0) {
+ cplcoeff = quant->q1[quant->q1_ptr--];
+ break;
+ } else {
+ int code;
+
+ code = bitstream_get (state, 5);
+
+ quant->q1_ptr = 1;
+ quant->q1[0] = q_1_2[code];
+ quant->q1[1] = q_1_1[code];
+ cplcoeff = q_1_0[code];
+ break;
+ }
+
+ case -2:
+ if (quant->q2_ptr >= 0) {
+ cplcoeff = quant->q2[quant->q2_ptr--];
+ break;
+ } else {
+ int code;
+
+ code = bitstream_get (state, 7);
+
+ quant->q2_ptr = 1;
+ quant->q2[0] = q_2_2[code];
+ quant->q2[1] = q_2_1[code];
+ cplcoeff = q_2_0[code];
+ break;
+ }
+
+ case 3:
+ cplcoeff = q_3[bitstream_get (state, 3)];
+ break;
+
+ case -3:
+ if (quant->q4_ptr == 0) {
+ quant->q4_ptr = -1;
+ cplcoeff = quant->q4;
+ break;
+ } else {
+ int code;
+
+ code = bitstream_get (state, 7);
+
+ quant->q4_ptr = 0;
+ quant->q4 = q_4_1[code];
+ cplcoeff = q_4_0[code];
+ break;
+ }
+
+ case 4:
+ cplcoeff = q_5[bitstream_get (state, 4)];
+ break;
+
+ default:
+ cplcoeff = bitstream_get_2 (state, bapi) << (16 - bapi);
+ }
+#ifndef LIBA52_FIXED
+ cplcoeff *= scale_factor[exp[i]];
+#endif
+ for (ch = 0; ch < nfchans; ch++)
+ if ((state->chincpl >> ch) & 1)
+#ifndef LIBA52_FIXED
+ samples[ch][i] = cplcoeff * cplco[ch];
+#else
+ COEFF (samples[ch][i], cplcoeff, cplco[ch],
+ scale_factor, exp[i]);
+#endif
+ i++;
+ }
+ }
+}
+
+int a52_block (a52_state_t * state)
+{
+ static const uint8_t nfchans_tbl[] = {2, 1, 2, 3, 3, 4, 4, 5, 1, 1, 2};
+ static int rematrix_band[4] = {25, 37, 61, 253};
+ int i, nfchans, chaninfo;
+ uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc, done_cpl;
+ uint8_t blksw[5], dithflag[5];
+ level_t coeff[5];
+ int chanbias;
+ quantizer_set_t quant;
+ sample_t * samples;
+
+ nfchans = nfchans_tbl[state->acmod];
+
+ for (i = 0; i < nfchans; i++)
+ blksw[i] = bitstream_get (state, 1);
+
+ for (i = 0; i < nfchans; i++)
+ dithflag[i] = bitstream_get (state, 1);
+
+ chaninfo = !state->acmod;
+ do {
+ if (bitstream_get (state, 1)) { /* dynrnge */
+ int dynrng;
+
+ dynrng = bitstream_get_2 (state, 8);
+ if (state->dynrnge) {
+ level_t range;
+
+#if !defined(LIBA52_FIXED)
+ range = ((((dynrng & 0x1f) | 0x20) << 13) *
+ scale_factor[3 - (dynrng >> 5)]);
+#else
+ range = ((dynrng & 0x1f) | 0x20) << (21 + (dynrng >> 5));
+#endif
+ if (state->dynrngcall)
+ range = state->dynrngcall (range, state->dynrngdata);
+ state->dynrng = MUL_L (state->level, range);
+ }
+ }
+ } while (chaninfo--);
+
+ if (bitstream_get (state, 1)) { /* cplstre */
+ state->chincpl = 0;
+ if (bitstream_get (state, 1)) { /* cplinu */
+ static uint8_t bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44,
+ 45, 45, 46, 46, 47, 47, 48, 48};
+ int cplbegf;
+ int cplendf;
+ int ncplsubnd;
+
+ for (i = 0; i < nfchans; i++)
+ state->chincpl |= bitstream_get (state, 1) << i;
+ switch (state->acmod) {
+ case 0: case 1:
+ return 1;
+ case 2:
+ state->phsflginu = bitstream_get (state, 1);
+ }
+ cplbegf = bitstream_get (state, 4);
+ cplendf = bitstream_get (state, 4);
+
+ if (cplendf + 3 - cplbegf < 0)
+ return 1;
+ state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf;
+ state->cplstrtbnd = bndtab[cplbegf];
+ state->cplstrtmant = cplbegf * 12 + 37;
+ state->cplendmant = cplendf * 12 + 73;
+
+ state->cplbndstrc = 0;
+ for (i = 0; i < ncplsubnd - 1; i++)
+ if (bitstream_get (state, 1)) {
+ state->cplbndstrc |= 1 << i;
+ state->ncplbnd--;
+ }
+ }
+ }
+
+ if (state->chincpl) { /* cplinu */
+ int j, cplcoe;
+
+ cplcoe = 0;
+ for (i = 0; i < nfchans; i++)
+ if ((state->chincpl) >> i & 1)
+ if (bitstream_get (state, 1)) { /* cplcoe */
+ int mstrcplco, cplcoexp, cplcomant;
+
+ cplcoe = 1;
+ mstrcplco = 3 * bitstream_get (state, 2);
+ for (j = 0; j < state->ncplbnd; j++) {
+ cplcoexp = bitstream_get (state, 4);
+ cplcomant = bitstream_get (state, 4);
+ if (cplcoexp == 15)
+ cplcomant <<= 14;
+ else
+ cplcomant = (cplcomant | 0x10) << 13;
+#ifndef LIBA52_FIXED
+ state->cplco[i][j] =
+ cplcomant * scale_factor[cplcoexp + mstrcplco];
+#else
+ state->cplco[i][j] = (cplcomant << 11) >> (cplcoexp + mstrcplco);
+#endif
+
+ }
+ }
+ if ((state->acmod == 2) && state->phsflginu && cplcoe)
+ for (j = 0; j < state->ncplbnd; j++)
+ if (bitstream_get (state, 1)) /* phsflg */
+ state->cplco[1][j] = -state->cplco[1][j];
+ }
+
+ if ((state->acmod == 2) && (bitstream_get (state, 1))) { /* rematstr */
+ int end;
+
+ state->rematflg = 0;
+ end = (state->chincpl) ? state->cplstrtmant : 253; /* cplinu */
+ i = 0;
+ do
+ state->rematflg |= bitstream_get (state, 1) << i;
+ while (rematrix_band[i++] < end);
+ }
+
+ cplexpstr = EXP_REUSE;
+ lfeexpstr = EXP_REUSE;
+ if (state->chincpl) /* cplinu */
+ cplexpstr = bitstream_get (state, 2);
+ for (i = 0; i < nfchans; i++)
+ chexpstr[i] = bitstream_get (state, 2);
+ if (state->lfeon)
+ lfeexpstr = bitstream_get (state, 1);
+
+ for (i = 0; i < nfchans; i++)
+ if (chexpstr[i] != EXP_REUSE) {
+ if ((state->chincpl >> i) & 1)
+ state->endmant[i] = state->cplstrtmant;
+ else {
+ int chbwcod;
+
+ chbwcod = bitstream_get (state, 6);
+ if (chbwcod > 60)
+ return 1;
+ state->endmant[i] = chbwcod * 3 + 73;
+ }
+ }
+
+ do_bit_alloc = 0;
+
+ if (cplexpstr != EXP_REUSE) {
+ int cplabsexp, ncplgrps;
+
+ do_bit_alloc = 64;
+ ncplgrps = ((state->cplendmant - state->cplstrtmant) /
+ (3 << (cplexpstr - 1)));
+ cplabsexp = bitstream_get (state, 4) << 1;
+ if (parse_exponents (state, cplexpstr, ncplgrps, cplabsexp,
+ state->cpl_expbap.exp + state->cplstrtmant))
+ return 1;
+ }
+ for (i = 0; i < nfchans; i++)
+ if (chexpstr[i] != EXP_REUSE) {
+ int grp_size, nchgrps;
+
+ do_bit_alloc |= 1 << i;
+ grp_size = 3 << (chexpstr[i] - 1);
+ nchgrps = (state->endmant[i] + grp_size - 4) / grp_size;
+ state->fbw_expbap[i].exp[0] = bitstream_get (state, 4);
+ if (parse_exponents (state, chexpstr[i], nchgrps,
+ state->fbw_expbap[i].exp[0],
+ state->fbw_expbap[i].exp + 1))
+ return 1;
+ bitstream_get (state, 2); /* gainrng */
+ }
+ if (lfeexpstr != EXP_REUSE) {
+ do_bit_alloc |= 32;
+ state->lfe_expbap.exp[0] = bitstream_get (state, 4);
+ if (parse_exponents (state, lfeexpstr, 2, state->lfe_expbap.exp[0],
+ state->lfe_expbap.exp + 1))
+ return 1;
+ }
+
+ if (bitstream_get (state, 1)) { /* baie */
+ do_bit_alloc = 127;
+ state->bai = bitstream_get (state, 11);
+ }
+ if (bitstream_get (state, 1)) { /* snroffste */
+ do_bit_alloc = 127;
+ state->csnroffst = bitstream_get (state, 6);
+ if (state->chincpl) /* cplinu */
+ state->cplba.bai = bitstream_get (state, 7);
+ for (i = 0; i < nfchans; i++)
+ state->ba[i].bai = bitstream_get (state, 7);
+ if (state->lfeon)
+ state->lfeba.bai = bitstream_get (state, 7);
+ }
+ if ((state->chincpl) && (bitstream_get (state, 1))) { /* cplleake */
+ do_bit_alloc |= 64;
+ state->cplfleak = 9 - bitstream_get (state, 3);
+ state->cplsleak = 9 - bitstream_get (state, 3);
+ }
+
+ if (bitstream_get (state, 1)) { /* deltbaie */
+ do_bit_alloc = 127;
+ if (state->chincpl) /* cplinu */
+ state->cplba.deltbae = bitstream_get (state, 2);
+ for (i = 0; i < nfchans; i++)
+ state->ba[i].deltbae = bitstream_get (state, 2);
+ if (state->chincpl && /* cplinu */
+ (state->cplba.deltbae == DELTA_BIT_NEW) &&
+ parse_deltba (state, state->cplba.deltba))
+ return 1;
+ for (i = 0; i < nfchans; i++)
+ if ((state->ba[i].deltbae == DELTA_BIT_NEW) &&
+ parse_deltba (state, state->ba[i].deltba))
+ return 1;
+ }
+
+ if (do_bit_alloc) {
+ if (zero_snr_offsets (nfchans, state)) {
+ memset (state->cpl_expbap.bap, 0, sizeof (state->cpl_expbap.bap));
+ for (i = 0; i < nfchans; i++)
+ memset (state->fbw_expbap[i].bap, 0,
+ sizeof (state->fbw_expbap[i].bap));
+ memset (state->lfe_expbap.bap, 0, sizeof (state->lfe_expbap.bap));
+ } else {
+ if (state->chincpl && (do_bit_alloc & 64)) /* cplinu */
+ a52_bit_allocate (state, &state->cplba, state->cplstrtbnd,
+ state->cplstrtmant, state->cplendmant,
+ state->cplfleak << 8, state->cplsleak << 8,
+ &state->cpl_expbap);
+ for (i = 0; i < nfchans; i++)
+ if (do_bit_alloc & (1 << i))
+ a52_bit_allocate (state, state->ba + i, 0, 0,
+ state->endmant[i], 0, 0,
+ state->fbw_expbap +i);
+ if (state->lfeon && (do_bit_alloc & 32)) {
+ state->lfeba.deltbae = DELTA_BIT_NONE;
+ a52_bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0,
+ &state->lfe_expbap);
+ }
+ }
+ }
+
+ if (bitstream_get (state, 1)) { /* skiple */
+ i = bitstream_get (state, 9); /* skipl */
+ while (i--)
+ bitstream_get (state, 8);
+ }
+
+ samples = state->samples;
+ if (state->output & A52_LFE)
+ samples += 256; /* shift for LFE channel */
+
+ chanbias = a52_downmix_coeff (coeff, state->acmod, state->output,
+ state->dynrng, state->clev, state->slev);
+
+ quant.q1_ptr = quant.q2_ptr = quant.q4_ptr = -1;
+ done_cpl = 0;
+
+ for (i = 0; i < nfchans; i++) {
+ int j;
+
+ coeff_get (state, samples + 256 * i, state->fbw_expbap +i, &quant,
+ coeff[i], dithflag[i], state->endmant[i]);
+
+ if ((state->chincpl >> i) & 1) {
+ if (!done_cpl) {
+ done_cpl = 1;
+ coeff_get_coupling (state, nfchans, coeff,
+ (sample_t (*)[256])samples, &quant,
+ dithflag);
+ }
+ j = state->cplendmant;
+ } else
+ j = state->endmant[i];
+ do
+ (samples + 256 * i)[j] = 0;
+ while (++j < 256);
+ }
+
+ if (state->acmod == 2) {
+ int j, end, band, rematflg;
+
+ end = ((state->endmant[0] < state->endmant[1]) ?
+ state->endmant[0] : state->endmant[1]);
+
+ i = 0;
+ j = 13;
+ rematflg = state->rematflg;
+ do {
+ if (! (rematflg & 1)) {
+ rematflg >>= 1;
+ j = rematrix_band[i++];
+ continue;
+ }
+ rematflg >>= 1;
+ band = rematrix_band[i++];
+ if (band > end)
+ band = end;
+ do {
+ sample_t tmp0, tmp1;
+
+ tmp0 = samples[j];
+ tmp1 = (samples+256)[j];
+ samples[j] = tmp0 + tmp1;
+ (samples+256)[j] = tmp0 - tmp1;
+ } while (++j < band);
+ } while (j < end);
+ }
+
+ if (state->lfeon) {
+ if (state->output & A52_LFE) {
+ coeff_get (state, samples - 256, &state->lfe_expbap, &quant,
+ state->dynrng, 0, 7);
+ for (i = 7; i < 256; i++)
+ (samples-256)[i] = 0;
+ a52_imdct_512 (samples - 256, samples + 1536 - 256, state->bias);
+ } else {
+ /* just skip the LFE coefficients */
+ coeff_get (state, samples + 1280, &state->lfe_expbap, &quant,
+ 0, 0, 7);
+ }
+ }
+
+ i = 0;
+ if (nfchans_tbl[state->output & A52_CHANNEL_MASK] < nfchans)
+ for (i = 1; i < nfchans; i++)
+ if (blksw[i] != blksw[0])
+ break;
+
+ if (i < nfchans) {
+ if (state->downmixed) {
+ state->downmixed = 0;
+ a52_upmix (samples + 1536, state->acmod, state->output);
+ }
+
+ for (i = 0; i < nfchans; i++) {
+ sample_t bias;
+
+ bias = 0;
+ if (!(chanbias & (1 << i)))
+ bias = state->bias;
+
+ if (coeff[i]) {
+ if (blksw[i])
+ a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
+ bias);
+ else
+ a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
+ bias);
+ } else {
+ int j;
+
+ for (j = 0; j < 256; j++)
+ (samples + 256 * i)[j] = bias;
+ }
+ }
+
+ a52_downmix (samples, state->acmod, state->output, state->bias,
+ state->clev, state->slev);
+ } else {
+ nfchans = nfchans_tbl[state->output & A52_CHANNEL_MASK];
+
+ a52_downmix (samples, state->acmod, state->output, 0,
+ state->clev, state->slev);
+
+ if (!state->downmixed) {
+ state->downmixed = 1;
+ a52_downmix (samples + 1536, state->acmod, state->output, 0,
+ state->clev, state->slev);
+ }
+
+ if (blksw[0])
+ for (i = 0; i < nfchans; i++)
+ a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
+ state->bias);
+ else
+ for (i = 0; i < nfchans; i++)
+ a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
+ state->bias);
+ }
+
+ return 0;
+}
+
+void a52_free (a52_state_t * state)
+{
+ free (state->samples);
+ free (state);
+}
diff --git a/apps/codecs/liba52/tables.h b/apps/codecs/liba52/tables.h
new file mode 100644
index 0000000000..b067c63f69
--- /dev/null
+++ b/apps/codecs/liba52/tables.h
@@ -0,0 +1,246 @@
+/*
+ * tables.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+static const int8_t exp_1[128] = {
+ -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 25,25,25
+};
+static const int8_t exp_2[128] = {
+ -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+ -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+ -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+ -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+ -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+ 25,25,25
+};
+static const int8_t exp_3[128] = {
+ -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
+ -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
+ -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
+ -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
+ -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
+ 25,25,25
+};
+
+#define Q(x) ROUND (32768.0 * x)
+
+#define Q0 Q (-2/3)
+#define Q1 Q (0)
+#define Q2 Q (2/3)
+
+static const quantizer_t q_1_0[32] = {
+ Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
+ Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
+ Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
+ 0, 0, 0, 0, 0
+};
+
+static const quantizer_t q_1_1[32] = {
+ Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2,
+ Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2,
+ Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2,
+ 0, 0, 0, 0, 0
+};
+
+static const quantizer_t q_1_2[32] = {
+ Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2,
+ Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2,
+ Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2,
+ 0, 0, 0, 0, 0
+};
+
+#undef Q0
+#undef Q1
+#undef Q2
+
+#define Q0 Q (-4/5)
+#define Q1 Q (-2/5)
+#define Q2 Q (0)
+#define Q3 Q (2/5)
+#define Q4 Q (4/5)
+
+static const quantizer_t q_2_0[128] = {
+ Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
+ Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
+ Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
+ Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,
+ Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,
+ 0,0,0
+};
+
+static const quantizer_t q_2_1[128] = {
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
+ 0,0,0
+};
+
+static const quantizer_t q_2_2[128] = {
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ 0,0,0
+};
+
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+#undef Q4
+
+static const quantizer_t q_3[8] = {
+ Q (-6/7), Q (-4/7), Q (-2/7), Q (0), Q (2/7), Q (4/7), Q (6/7), 0
+};
+
+#define Q0 Q (-10/11)
+#define Q1 Q (-8/11)
+#define Q2 Q (-6/11)
+#define Q3 Q (-4/11)
+#define Q4 Q (-2/11)
+#define Q5 Q (0)
+#define Q6 Q (2/11)
+#define Q7 Q (4/11)
+#define Q8 Q (6/11)
+#define Q9 Q (8/11)
+#define QA Q (10/11)
+
+static const quantizer_t q_4_0[128] = {
+ Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
+ Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
+ Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
+ Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3,
+ Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4,
+ Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5,
+ Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6,
+ Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7,
+ Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8,
+ Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9,
+ QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static const quantizer_t q_4_1[128] = {
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+#undef Q4
+#undef Q5
+#undef Q6
+#undef Q7
+#undef Q8
+#undef Q9
+#undef QA
+
+static const quantizer_t q_5[16] = {
+ Q (-14/15), Q (-12/15), Q (-10/15), Q (-8/15), Q (-6/15),
+ Q (-4/15), Q (-2/15), Q (0), Q (2/15), Q (4/15),
+ Q (6/15), Q (8/15), Q (10/15), Q (12/15), Q (14/15), 0
+};
+
+#ifndef LIBA52_FIXED
+static const sample_t scale_factor[25] = {
+ 0.000030517578125,
+ 0.0000152587890625,
+ 0.00000762939453125,
+ 0.000003814697265625,
+ 0.0000019073486328125,
+ 0.00000095367431640625,
+ 0.000000476837158203125,
+ 0.0000002384185791015625,
+ 0.00000011920928955078125,
+ 0.000000059604644775390625,
+ 0.0000000298023223876953125,
+ 0.00000001490116119384765625,
+ 0.000000007450580596923828125,
+ 0.0000000037252902984619140625,
+ 0.00000000186264514923095703125,
+ 0.000000000931322574615478515625,
+ 0.0000000004656612873077392578125,
+ 0.00000000023283064365386962890625,
+ 0.000000000116415321826934814453125,
+ 0.0000000000582076609134674072265625,
+ 0.00000000002910383045673370361328125,
+ 0.000000000014551915228366851806640625,
+ 0.0000000000072759576141834259033203125,
+ 0.00000000000363797880709171295166015625,
+ 0.000000000001818989403545856475830078125
+};
+#endif
+
+static const uint16_t dither_lut[256] = {
+ 0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055,
+ 0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb,
+ 0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198,
+ 0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176,
+ 0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf,
+ 0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321,
+ 0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202,
+ 0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec,
+ 0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761,
+ 0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f,
+ 0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac,
+ 0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642,
+ 0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb,
+ 0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415,
+ 0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536,
+ 0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8,
+ 0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c,
+ 0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2,
+ 0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1,
+ 0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f,
+ 0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6,
+ 0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58,
+ 0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b,
+ 0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95,
+ 0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918,
+ 0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6,
+ 0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5,
+ 0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b,
+ 0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82,
+ 0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c,
+ 0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f,
+ 0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1
+};
diff --git a/apps/codecs/liba52/tendra.h b/apps/codecs/liba52/tendra.h
new file mode 100644
index 0000000000..cc740fceeb
--- /dev/null
+++ b/apps/codecs/liba52/tendra.h
@@ -0,0 +1,35 @@
+/*
+ * tendra.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of a52dec, a free ATSC A-52 stream decoder.
+ * See http://liba52.sourceforge.net/ for updates.
+ *
+ * a52dec 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.
+ *
+ * a52dec 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
+ */
+
+#pragma TenDRA begin
+#pragma TenDRA longlong type warning
+
+#ifdef TenDRA_check
+
+#pragma TenDRA conversion analysis (pointer-int explicit) off
+#pragma TenDRA implicit function declaration off
+
+/* avoid the "No declarations in translation unit" problem */
+int TenDRA;
+
+#endif /* TenDRA_check */