Showing preview only (1,089K chars total). Download the full file or copy to clipboard to get everything.
Repository: foo86/dcadec
Branch: master
Commit: b93deed1a231
Files: 62
Total size: 1.0 MB
Directory structure:
gitextract_4euf4kon/
├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── COPYING.LGPLv2.1
├── Makefile
├── README.md
├── dcacut.c
├── dcadec.c
├── dcadec.pc.in
├── getopt.c
├── getopt.h
├── libdcadec/
│ ├── bitstream.c
│ ├── bitstream.h
│ ├── common.h
│ ├── compiler.h
│ ├── core_decoder.c
│ ├── core_decoder.h
│ ├── core_huffman.h
│ ├── core_tables.h
│ ├── core_vectors.h
│ ├── dca_context.c
│ ├── dca_context.h
│ ├── dca_frame.c
│ ├── dca_frame.h
│ ├── dca_stream.c
│ ├── dca_stream.h
│ ├── dca_waveout.c
│ ├── dca_waveout.h
│ ├── dmix_tables.c
│ ├── dmix_tables.h
│ ├── exss_parser.c
│ ├── exss_parser.h
│ ├── fir_fixed.h
│ ├── fir_float.h
│ ├── fixed_math.h
│ ├── huffman.h
│ ├── idct.h
│ ├── idct_fixed.c
│ ├── idct_float.c
│ ├── interpolator.c
│ ├── interpolator.h
│ ├── interpolator_fixed.c
│ ├── interpolator_float.c
│ ├── lbr_bitstream.h
│ ├── lbr_decoder.c
│ ├── lbr_decoder.h
│ ├── lbr_huffman.h
│ ├── lbr_tables.h
│ ├── ta.c
│ ├── ta.h
│ ├── xll_decoder.c
│ ├── xll_decoder.h
│ └── xll_tables.h
├── msvc/
│ ├── dcadec/
│ │ ├── dcadec.vcxproj
│ │ └── dcadec.vcxproj.filters
│ ├── dcadec.sln
│ └── libdcadec/
│ ├── libdcadec.vcxproj
│ └── libdcadec.vcxproj.filters
└── test/
├── checksum.txt
├── stddev.c
├── stddev.txt
└── test.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.d
*.o
*.dll
*.so
*.a
/dcadec
/dcacut
*.exe
*.pc
/test/decoded/
/test/stddev
================================================
FILE: .gitmodules
================================================
[submodule "test/samples"]
path = test/samples
url = https://github.com/foo86/dcadec-samples.git
================================================
FILE: CHANGELOG.md
================================================
v0.2.0 - Jan 04, 2016
=====================
- Fixed installation of shared library symlink.
- Switched LFE channel interpolation to FIR filter by default.
- Added command line option and context flag to select IIR filter for LFE
channel interpolation.
- Fixed two bugs that could cause decoder to crash when processing invalid
input.
- Fixed handling of sync loss when decoding MA streams with multiple frequency
bands.
- Fixed decoding of MA streams with multiple frequency bands when sampling
frequency of the first band is not 96 kHz.
- Fixed decoding to standard output on Windows causing junk to be appended
after normal PCM data.
v0.1.0 - Nov 27, 2015
=====================
- Initial public release.
================================================
FILE: COPYING.LGPLv2.1
================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
================================================
FILE: Makefile
================================================
VERSION = 0.2.0
API_MAJOR = 0
API_MINOR = 1
API_PATCH = 0
CFLAGS := -std=gnu99 -D_FILE_OFFSET_BITS=64 -Wall -Wextra -O3 -ffast-math -g -MMD $(CFLAGS)
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
LIBDIR ?= $(PREFIX)/lib
INCLUDEDIR ?= $(PREFIX)/include
SRC_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
vpath %.c $(SRC_DIR)
vpath %.h $(SRC_DIR)
vpath %.pc.in $(SRC_DIR)
-include .config
ifdef CONFIG_DEBUG
CFLAGS += -D_DEBUG
else
CFLAGS += -DNDEBUG
endif
ifdef CONFIG_WINDOWS
EXESUF ?= .exe
DLLSUF ?= .dll
LIBSUF ?= .a
else
DLLSUF ?= .so
LIBSUF ?= .a
LIBS ?= -lm
ifdef CONFIG_SHARED
SONAMESUF ?= .$(API_MAJOR).$(API_MINOR).$(API_PATCH)
SONAMESUF_MAJOR ?= .$(API_MAJOR)
SONAME ?= libdcadec$(DLLSUF)$(SONAMESUF_MAJOR)
endif
endif
ifdef CONFIG_SHARED
OUT_LIB ?= libdcadec/libdcadec$(DLLSUF)$(SONAMESUF)
else
OUT_LIB ?= libdcadec/libdcadec$(LIBSUF)
endif
OUT_DEC ?= dcadec$(EXESUF)
OUT_CUT ?= dcacut$(EXESUF)
OUT_DEV ?= test/stddev$(EXESUF)
SRC_DEV ?= test/stddev.c
CFLAGS_DEV ?= -O2 -Wall -Wextra
SRC_LIB = \
libdcadec/bitstream.c \
libdcadec/core_decoder.c \
libdcadec/dca_context.c \
libdcadec/dmix_tables.c \
libdcadec/exss_parser.c \
libdcadec/idct_fixed.c \
libdcadec/idct_float.c \
libdcadec/interpolator.c \
libdcadec/interpolator_fixed.c \
libdcadec/interpolator_float.c \
libdcadec/lbr_decoder.c \
libdcadec/ta.c \
libdcadec/xll_decoder.c
INC_LIB = \
libdcadec/dca_context.h
ifndef CONFIG_SMALL
SRC_LIB += libdcadec/dca_frame.c
SRC_LIB += libdcadec/dca_stream.c
SRC_LIB += libdcadec/dca_waveout.c
INC_LIB += libdcadec/dca_frame.h
INC_LIB += libdcadec/dca_stream.h
INC_LIB += libdcadec/dca_waveout.h
endif
OBJ_LIB = $(SRC_LIB:.c=.o)
DEP_LIB = $(SRC_LIB:.c=.d)
SRC_DEC = dcadec.c
OBJ_DEC = $(SRC_DEC:.c=.o)
DEP_DEC = $(SRC_DEC:.c=.d)
SRC_CUT = dcacut.c
OBJ_CUT = $(SRC_CUT:.c=.o)
DEP_CUT = $(SRC_CUT:.c=.d)
default: $(OUT_LIB) $(OUT_DEC)
lib: $(OUT_LIB)
all: $(OUT_LIB) $(OUT_DEC) $(OUT_CUT)
-include $(DEP_LIB) $(DEP_DEC) $(DEP_CUT)
$(OBJ_LIB): | objdir
$(OBJ_DEC): | objdir
$(OBJ_CUT): | objdir
objdir:
mkdir -p libdcadec
ifdef CONFIG_SHARED
CFLAGS_DLL = $(CFLAGS) -DDCADEC_SHARED -DDCADEC_INTERNAL
LDFLAGS_DLL = $(LDFLAGS) -shared
ifdef CONFIG_WINDOWS
IMP_LIB = libdcadec/libdcadec$(DLLSUF)$(LIBSUF)
IMP_DEF = libdcadec/libdcadec.def
EXTRA_LIB = $(IMP_LIB) $(IMP_DEF)
LDFLAGS_DLL += -static-libgcc
LDFLAGS_DLL += -Wl,--nxcompat,--dynamicbase
LDFLAGS_DLL += -Wl,--output-def,$(IMP_DEF)
LDFLAGS_DLL += -Wl,--out-implib,$(IMP_LIB)
else
CFLAGS_DLL += -fPIC -fvisibility=hidden
ifdef SONAME
LDFLAGS_DLL += -Wl,-soname,$(SONAME)
EXTRA_LIB += libdcadec/libdcadec$(DLLSUF)
EXTRA_LIB += libdcadec/libdcadec$(DLLSUF)$(SONAMESUF_MAJOR)
endif
IMP_LIB = -Llibdcadec -ldcadec
endif
libdcadec/%.o: libdcadec/%.c
$(CC) -c $(CFLAGS_DLL) -o $@ $<
$(OUT_LIB): $(OBJ_LIB)
$(CC) $(LDFLAGS_DLL) -o $@ $(OBJ_LIB) $(LIBS)
ifdef SONAME
ln -sf $(@F) libdcadec/libdcadec$(DLLSUF)
ln -sf $(@F) libdcadec/libdcadec$(DLLSUF)$(SONAMESUF_MAJOR)
endif
$(OUT_DEC): $(OBJ_DEC) $(OUT_LIB)
$(CC) $(LDFLAGS) -o $@ $(OBJ_DEC) $(IMP_LIB) $(LIBS)
$(OUT_CUT): $(OBJ_CUT) $(OUT_LIB)
$(CC) $(LDFLAGS) -o $@ $(OBJ_CUT) $(IMP_LIB) $(LIBS)
else
$(OUT_LIB): $(OBJ_LIB)
$(AR) crsu $@ $(OBJ_LIB)
$(OUT_DEC): $(OBJ_DEC) $(OUT_LIB)
$(CC) $(LDFLAGS) -o $@ $(OBJ_DEC) $(OUT_LIB) $(LIBS)
$(OUT_CUT): $(OBJ_CUT) $(OUT_LIB)
$(CC) $(LDFLAGS) -o $@ $(OBJ_CUT) $(OUT_LIB) $(LIBS)
endif
$(OUT_DEV): $(SRC_DEV)
$(CC) $(LDFLAGS) -o $@ $(CFLAGS_DEV) $< $(LIBS)
check: $(OUT_DEC) $(OUT_DEV)
cd test && ./test.sh
clean:
$(RM) $(OUT_LIB) $(OBJ_LIB) $(DEP_LIB) $(EXTRA_LIB)
$(RM) $(OUT_DEC) $(OBJ_DEC) $(DEP_DEC)
$(RM) $(OUT_CUT) $(OBJ_CUT) $(DEP_CUT)
$(RM) dcadec.pc
$(RM) $(OUT_DEV)
$(RM) -r test/decoded
.PHONY: dcadec.pc
dcadec.pc: dcadec.pc.in
sed 's,%PREFIX%,$(PREFIX),;s,%LIBDIR%,$(LIBDIR),;s,%INCLUDEDIR%,$(INCLUDEDIR),;s,%VERSION%,$(VERSION),' $< > $@
install-lib: $(OUT_LIB) dcadec.pc
install -d -m 755 $(DESTDIR)$(LIBDIR) $(DESTDIR)$(LIBDIR)/pkgconfig $(DESTDIR)$(INCLUDEDIR)/libdcadec
install -m 644 $(OUT_LIB) $(DESTDIR)$(LIBDIR)
install -m 644 $(addprefix $(SRC_DIR)/, $(INC_LIB)) $(DESTDIR)$(INCLUDEDIR)/libdcadec
install -m 644 dcadec.pc $(DESTDIR)$(LIBDIR)/pkgconfig
ifdef SONAME
ln -sf libdcadec$(DLLSUF)$(SONAMESUF) $(DESTDIR)$(LIBDIR)/libdcadec$(DLLSUF)
ln -sf libdcadec$(DLLSUF)$(SONAMESUF) $(DESTDIR)$(LIBDIR)/libdcadec$(DLLSUF)$(SONAMESUF_MAJOR)
endif
install-dec: $(OUT_DEC)
install -d -m 755 $(DESTDIR)$(BINDIR)
install -m 755 $(OUT_DEC) $(DESTDIR)$(BINDIR)
install: install-lib install-dec
================================================
FILE: README.md
================================================
dcadec
======
dcadec is a free DTS Coherent Acoustics decoder with support for HD extensions.
Supported features:
* Decoding of standard DTS core streams with up to 5.1 channels
* Decoding of DTS-ES streams with discrete back channel
* Decoding of High Resolution streams with up to 7.1 channels and extended bitrate
* Decoding of 96/24 core streams
* Lossless decoding of Master Audio streams with up to 7.1 channels, 192 kHz
* Downmixing to stereo and 5.1 using embedded coefficients
__This program is deprecated!__
This decoder has been fully integrated into FFmpeg master branch and further
development will continue there. Using [FFmpeg](https://ffmpeg.org/) for DTS
decoding is now recommended.
Usage
-----
Help screen of the program is reproduced below.
```
Usage: ./dcadec [-26bcfhlmnPqSx] <input.dts> [output.wav]
dcadec is a free DTS Coherent Acoustics decoder. Supported options:
-2 Extract embedded 2.0 downmix if present, otherwise extract 5.1 downmix.
-6 Extract embedded 5.1 downmix.
-b Force fixed point DTS core interpolation. Developer option, degrades sound
quality.
-c Force decoding of DTS core only without extensions.
-f Use FIR filter for floating point DTS core LFE channel interpolation.
-h Show this help message.
-i Use IIR filter for floating point DTS core LFE channel interpolation.
-l Enable lenient decoding mode. Attempt to recover from errors by skipping
non-decodable parts of the stream.
-m Write a mono WAV file for each native DTS channel. Output file name must
include `%s' sub-string that will be replaced with DTS channel name.
-n No-act mode. Parse DTS bitstream without writing WAV file(s).
-P Disable progress indicator.
-q Be quiet. Disables informational messages and progress indicator. Warnings
and errors are still printed.
-S Don't strip padding samples for streams within DTS-HD container.
-x Force use of X96 synthesis filter for DTS core interpolation. Developer
option, degrades sound quality.
When run without output file name argument, prints information about DTS file
to stdout and exits.
Single dash in place of input or output file name argument means to read from
stdin or write to stdout, respectively.
dcadec comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
welcome to redistribute it under certain conditions; see GNU Lesser General
Public License version 2.1 for details.
```
Examples
--------
Some dcadec usage examples follow.
* Decode DTS file to WAV:
```
$ ./dcadec input.dts output.wav
```
* Decode DTS file to multiple mono WAVs:
```
$ ./dcadec -m input.dts output_%s.wav
```
* Decode DTS file and play with mpv:
```
$ ./dcadec input.dts - | mpv -
```
* Decode DTS file and re-encode to FLAC:
```
$ ./dcadec input.dts - | flac --ignore-chunk-sizes -o output.flac -
```
* Demux DTS track #1 from MKV file, decode and re-encode to FLAC:
```
$ mkvextract tracks input.mkv -r /dev/null 1:/dev/stdout | \
./dcadec - - | flac --ignore-chunk-sizes -o output.flac -
```
================================================
FILE: dcacut.c
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "libdcadec/dca_stream.h"
int main(int argc, char **argv)
{
if (argc < 3) {
fprintf(stderr, "Usage: %s <input.dts> <output.dts> [first] [last]\n", argv[0]);
return 1;
}
unsigned long first_packet = 0;
unsigned long last_packet = ULONG_MAX;
if (argc > 3)
first_packet = strtoul(argv[3], NULL, 0);
if (argc > 4)
last_packet = strtoul(argv[4], NULL, 0);
if (last_packet < first_packet) {
fprintf(stderr, "Invalid packet range\n");
return 1;
}
struct dcadec_stream *stream = dcadec_stream_open(argv[1], 0);
if (!stream) {
fprintf(stderr, "Couldn't open input file\n");
return 1;
}
FILE *fp = fopen(argv[2], "wb");
if (!fp) {
fprintf(stderr, "Couldn't open output file\n");
dcadec_stream_close(stream);
return 1;
}
unsigned long packet_in = 0;
unsigned long packet_out = 0;
int ret;
while (true) {
uint8_t *packet;
size_t size;
ret = dcadec_stream_read(stream, &packet, &size);
if (ret < 0) {
fprintf(stderr, "Error %d reading packet\n", ret);
break;
}
if (ret == 0)
break;
if (packet_in >= first_packet) {
if (fwrite(packet, size, 1, fp) != 1) {
fprintf(stderr, "Error %d writing packet\n", errno);
ret = -1;
break;
}
packet_out++;
}
if (++packet_in > last_packet)
break;
}
if (packet_out) {
fprintf(stderr, "Wrote %lu packets\n", packet_out);
} else {
fprintf(stderr, "Didn't write a single packet!\n");
ret = -1;
}
fclose(fp);
dcadec_stream_close(stream);
return !!ret;
}
================================================
FILE: dcadec.c
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#ifdef _MSC_VER
#include "getopt.h"
#else
#include <unistd.h>
#endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <signal.h>
#endif
#include "libdcadec/dca_stream.h"
#include "libdcadec/dca_context.h"
#include "libdcadec/dca_waveout.h"
static void print_help(const char *name)
{
fprintf(stderr,
"Usage: %s [-26bcfhilmnPqSx] <input.dts> [output.wav]\n"
"dcadec is a free DTS Coherent Acoustics decoder. Supported options:\n"
"\n"
"-2 Extract embedded 2.0 downmix if present, otherwise extract 5.1 downmix.\n"
"\n"
"-6 Extract embedded 5.1 downmix.\n"
"\n"
"-b Force fixed point DTS core interpolation. Developer option, degrades sound\n"
" quality.\n"
"\n"
"-c Force decoding of DTS core only without extensions.\n"
"\n"
"-f Use FIR filter for floating point DTS core LFE channel interpolation.\n"
"\n"
"-h Show this help message.\n"
"\n"
"-i Use IIR filter for floating point DTS core LFE channel interpolation.\n"
"\n"
"-l Enable lenient decoding mode. Attempt to recover from errors by skipping\n"
" non-decodable parts of the stream.\n"
"\n"
"-m Write a mono WAV file for each native DTS channel. Output file name must\n"
" include `%%s' sub-string that will be replaced with DTS channel name.\n"
"\n"
"-n No-act mode. Parse DTS bitstream without writing WAV file(s).\n"
"\n"
"-P Disable progress indicator.\n"
"\n"
"-q Be quiet. Disables informational messages and progress indicator. Warnings\n"
" and errors are still printed.\n"
"\n"
"-S Don't strip padding samples for streams within DTS-HD container.\n"
"\n"
"-x Force use of X96 synthesis filter for DTS core interpolation. Developer\n"
" option, degrades sound quality.\n"
"\n"
"When run without output file name argument, prints information about DTS file\n"
"to stdout and exits.\n"
"\n"
"Single dash in place of input or output file name argument means to read from\n"
"stdin or write to stdout, respectively.\n"
"\n"
"dcadec comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n"
"welcome to redistribute it under certain conditions; see GNU Lesser General\n"
"Public License version 2.1 for details.\n", name);
}
static const char * const spkr_pair_names[] = {
"C", "LR", "LsRs", "LFE",
"Cs", "LhRh", "LsrRsr", "Ch",
"Oh", "LcRc", "LwRw", "LssRss",
"LFE2", "LhsRhs", "Chr", "LhrRhr"
};
static char *make_spkr_mask_str(int mask)
{
static char buf[128];
if (!mask)
return "???";
buf[0] = 0;
for (size_t i = 0; i < sizeof(spkr_pair_names) / sizeof(spkr_pair_names[0]); i++) {
if (mask & (1 << i)) {
if (buf[0])
strcat(buf, " ");
strcat(buf, spkr_pair_names[i]);
}
}
return buf;
}
static void print_info(struct dcadec_context *context, FILE *fp)
{
struct dcadec_exss_info *exss = dcadec_context_get_exss_info(context);
if (exss && exss->profile == DCADEC_PROFILE_DS) {
dcadec_context_free_exss_info(exss);
exss = NULL;
}
if (exss) {
if (exss->profile & DCADEC_PROFILE_HD_MA)
fprintf(fp, "DTS-HD Master Audio");
else if (exss->profile & DCADEC_PROFILE_HD_HRA)
fprintf(fp, "DTS-HD High Resolution Audio");
else if (exss->profile & DCADEC_PROFILE_DS_ES)
fprintf(fp, "DTS-ES Discrete");
else if (exss->profile & DCADEC_PROFILE_DS_96_24)
fprintf(fp, "DTS 96/24");
else if (exss->profile & DCADEC_PROFILE_EXPRESS)
fprintf(fp, "DTS Express");
else
fprintf(fp, "Unknown Extension Profile");
fprintf(fp, ": %d ch (%s), %.f kHz, %d bit\n",
exss->nchannels, make_spkr_mask_str(exss->spkr_mask),
exss->sample_rate / 1000.0f, exss->bits_per_sample);
dcadec_context_free_exss_info(exss);
}
struct dcadec_core_info *core = dcadec_context_get_core_info(context);
if (core) {
if (exss)
fprintf(fp, "(");
fprintf(fp, "DTS Core Audio: %d.%d ch, %.f kHz, %d bit",
core->nchannels, !!core->lfe_present, core->sample_rate / 1000.f,
core->source_pcm_res);
if (core->es_format)
fprintf(fp, ", ES");
if (core->bit_rate > 0)
fprintf(fp, ", %.f kbps", core->bit_rate / 1000.0f);
if (exss)
fprintf(fp, ")");
fprintf(fp, "\n");
dcadec_context_free_core_info(core);
}
}
static bool interrupted;
#ifdef _WIN32
static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
{
(void)dwCtrlType;
interrupted = true;
return TRUE;
}
#else
static void signal_handler(int sig)
{
(void)sig;
interrupted = true;
}
#endif
static void my_log_cb(int level, const char *file, int line,
const char *message, void *cbarg)
{
(void)cbarg;
if (level > DCADEC_LOG_WARNING)
return;
const char *prefix = "UNKNOWN";
switch (level) {
case DCADEC_LOG_ERROR:
prefix = "ERROR";
break;
case DCADEC_LOG_WARNING:
prefix = "WARNING";
break;
}
fprintf(stderr, "%s: %s+%d: %s\n", prefix, file, line, message);
}
int main(int argc, char **argv)
{
int flags = DCADEC_FLAG_STRICT;
int wave_flags = 0;
bool parse_only = false;
bool no_progress = false;
bool quiet = false;
bool no_strip = false;
int opt;
while ((opt = getopt(argc, argv, "26bcfhilmnPqSsx")) != -1) {
switch (opt) {
case '2':
flags |= DCADEC_FLAG_KEEP_DMIX_2CH;
break;
case '6':
flags |= DCADEC_FLAG_KEEP_DMIX_6CH;
break;
case 'b':
flags |= DCADEC_FLAG_CORE_BIT_EXACT;
break;
case 'c':
flags |= DCADEC_FLAG_CORE_ONLY;
break;
case 'f':
flags &= ~DCADEC_FLAG_CORE_LFE_IIR;
flags |= DCADEC_FLAG_CORE_LFE_FIR;
break;
case 'h':
print_help(argv[0]);
return 0;
case 'i':
flags &= ~DCADEC_FLAG_CORE_LFE_FIR;
flags |= DCADEC_FLAG_CORE_LFE_IIR;
break;
case 'l':
flags &= ~DCADEC_FLAG_STRICT;
break;
case 'm':
flags |= DCADEC_FLAG_NATIVE_LAYOUT;
wave_flags |= DCADEC_WAVEOUT_FLAG_MONO;
break;
case 'n':
parse_only = true;
break;
case 'P':
no_progress = true;
break;
case 'q':
quiet = true;
break;
case 'S':
no_strip = true;
break;
case 'x':
flags |= DCADEC_FLAG_CORE_SYNTH_X96;
break;
default:
print_help(argv[0]);
return 1;
}
}
no_progress |= quiet;
if (optind >= argc) {
print_help(argv[0]);
return 1;
}
char *fn = argv[optind];
struct dcadec_stream *stream = dcadec_stream_open(strcmp(fn, "-") ? fn : NULL, 0);
if (!stream) {
fprintf(stderr, "Couldn't open input file\n");
return 1;
}
uint8_t *packet;
size_t size;
int ret;
if ((ret = dcadec_stream_read(stream, &packet, &size)) < 0) {
fprintf(stderr, "Error reading packet: %s\n", dcadec_strerror(ret));
dcadec_stream_close(stream);
return 1;
}
if (ret == 0) {
fprintf(stderr, "This doesn't look like a valid DTS bit stream\n");
dcadec_stream_close(stream);
return 1;
}
struct dcadec_context *context = dcadec_context_create(flags);
if (!context) {
fprintf(stderr, "Couldn't create decoder context\n");
dcadec_stream_close(stream);
return 1;
}
dcadec_context_set_log_cb(context, my_log_cb, NULL);
if ((ret = dcadec_context_parse(context, packet, size)) < 0) {
fprintf(stderr, "Error parsing packet: %s\n", dcadec_strerror(ret));
dcadec_context_destroy(context);
dcadec_stream_close(stream);
return 1;
}
if (ret > 0)
fprintf(stderr, "WARNING: %s at frame 0\n", dcadec_strerror(ret));
if (!quiet)
print_info(context, optind + 1 >= argc ? stdout : stderr);
struct dcadec_waveout *waveout = NULL;
if (!parse_only) {
if (optind + 1 >= argc) {
dcadec_context_destroy(context);
dcadec_stream_close(stream);
return 0;
}
fn = argv[optind + 1];
waveout = dcadec_waveout_open(strcmp(fn, "-") ? fn : NULL, wave_flags);
if (!waveout) {
fprintf(stderr, "Couldn't open output file\n");
dcadec_context_destroy(context);
dcadec_stream_close(stream);
return 1;
}
}
int last_progress = -1;
#ifdef _WIN32
SetConsoleCtrlHandler(&console_ctrl_handler, TRUE);
#else
signal(SIGINT, &signal_handler);
#endif
uint32_t ndelayframes = 0;
uint64_t npcmsamples = UINT64_MAX;
uint64_t ntotalframes = 0;
uint64_t nskippedframes = 0;
uint64_t nlossyframes = 0;
if (!parse_only && !no_strip) {
struct dcadec_stream_info *info = dcadec_stream_get_info(stream);
if (info) {
if (info->nframesamples)
ndelayframes = info->ndelaysamples / info->nframesamples;
if (info->npcmsamples)
npcmsamples = info->npcmsamples;
dcadec_stream_free_info(info);
}
}
if (!quiet) {
const bool core_only = (flags & DCADEC_FLAG_CORE_ONLY);
fprintf(stderr, "%s%s...\n",
waveout ? "Decoding" : "Parsing",
core_only ? " (core only)" : "");
}
while (!interrupted) {
if (waveout) {
int **samples, nsamples, channel_mask, sample_rate, bits_per_sample;
if ((ret = dcadec_context_filter(context, &samples, &nsamples,
&channel_mask, &sample_rate,
&bits_per_sample, NULL)) < 0) {
fprintf(stderr, "Error filtering frame: %s\n", dcadec_strerror(ret));
if (flags & DCADEC_FLAG_STRICT) {
break;
} else {
nskippedframes++;
goto next_packet;
}
}
if (ndelayframes) {
ndelayframes--;
goto next_packet;
}
if (ret > 0) {
fprintf(stderr, "WARNING: %s at frame %" PRIu64 "\n", dcadec_strerror(ret), ntotalframes);
nlossyframes++;
}
if ((uint64_t)nsamples > npcmsamples)
nsamples = (int)npcmsamples;
if ((ret = dcadec_waveout_write(waveout, samples, nsamples,
channel_mask, sample_rate,
bits_per_sample)) < 0) {
fprintf(stderr, "Error writing WAV file: %s\n", dcadec_strerror(ret));
if ((flags & DCADEC_FLAG_STRICT) || ret != -DCADEC_EOUTCHG) {
break;
} else {
nskippedframes++;
goto next_packet;
}
}
npcmsamples -= nsamples;
}
next_packet:
ntotalframes++;
if ((ret = dcadec_stream_read(stream, &packet, &size)) < 0) {
fprintf(stderr, "Error reading packet: %s\n", dcadec_strerror(ret));
break;
}
if (!no_progress) {
int progress = dcadec_stream_progress(stream);
if (progress != last_progress) {
fprintf(stderr, "Progress: %d%%\r", progress);
last_progress = progress;
}
}
if (ret == 0)
break;
if ((ret = dcadec_context_parse(context, packet, size)) < 0) {
fprintf(stderr, "Error parsing packet: %s\n", dcadec_strerror(ret));
if (flags & DCADEC_FLAG_STRICT) {
break;
} else {
nskippedframes++;
goto next_packet;
}
}
if (ret > 0)
fprintf(stderr, "WARNING: %s at frame %" PRIu64 "\n", dcadec_strerror(ret), ntotalframes);
}
if (!quiet) {
if (last_progress != -1)
fprintf(stderr, "\n");
if (interrupted)
fprintf(stderr, "Interrupted.\n");
else if (ret == 0)
fprintf(stderr, "Completed.\n");
if (nskippedframes)
fprintf(stderr, "*** %" PRIu64 " frames skipped ***\n", nskippedframes);
if (nlossyframes)
fprintf(stderr, "*** %" PRIu64 " frames not lossless ***\n", nlossyframes);
}
dcadec_waveout_close(waveout);
dcadec_context_destroy(context);
dcadec_stream_close(stream);
return !!ret;
}
================================================
FILE: dcadec.pc.in
================================================
prefix=%PREFIX%
libdir=%LIBDIR%
includedir=%INCLUDEDIR%
Name: dcadec
Description: a free DTS Coherent Acoustics decoder with support for HD extensions
Version: %VERSION%
Libs: -L${libdir} -ldcadec
Cflags: -I${includedir}
================================================
FILE: getopt.c
================================================
/*
* Copyright © 2005-2014 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "getopt.h"
char *optarg;
int optind = 1, opterr = 1, optopt;
static int optpos;
int getopt(int argc, char * const argv[], const char *optstring)
{
if (optind < 1) {
optpos = 0;
optind = 1;
}
if (optind >= argc || !argv[optind])
return -1;
if (argv[optind][0] != '-') {
if (optstring[0] == '-') {
optarg = argv[optind++];
return 1;
}
return -1;
}
if (!argv[optind][1])
return -1;
if (argv[optind][1] == '-' && !argv[optind][2]) {
optind++;
return -1;
}
if (!optpos)
optpos++;
optopt = argv[optind][optpos++];
if (!argv[optind][optpos]) {
optind++;
optpos = 0;
}
if (optstring[0] == '-' || optstring[0] == '+')
optstring++;
char *p = strchr(optstring, optopt);
if (!p) {
if (optstring[0] != ':' && opterr)
fprintf(stderr, "%s: unrecognized option: %c\n", argv[0], optopt);
return '?';
}
if (p[1] == ':') {
if (p[2] == ':') {
optarg = NULL;
} else if (optind >= argc) {
if (optstring[0] == ':')
return ':';
if (opterr)
fprintf(stderr, "%s: option requires an argument: %c\n", argv[0], optopt);
return '?';
}
if (p[2] != ':' || optpos) {
optarg = argv[optind++] + optpos;
optpos = 0;
}
}
return optopt;
}
================================================
FILE: getopt.h
================================================
/*
* Copyright © 2005-2014 Rich Felker, et al.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef GETOPT_H
#define GETOPT_H
extern char *optarg;
extern int optind, opterr, optopt;
int getopt(int argc, char * const argv[], const char *optstring);
#endif
================================================
FILE: libdcadec/bitstream.c
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "common.h"
#include "bitstream.h"
static inline uint32_t bits_peek(struct bitstream *bits)
{
if (bits->index >= bits->total)
return 0;
int pos = bits->index >> 5;
int shift = bits->index & 31;
uint32_t v = DCA_32BE(bits->data[pos]);
if (shift) {
v <<= shift;
v |= DCA_32BE(bits->data[pos + 1]) >> (32 - shift);
}
return v;
}
bool bits_get1(struct bitstream *bits)
{
if (bits->index >= bits->total)
return false;
uint32_t v = DCA_32BE(bits->data[bits->index >> 5]);
v <<= bits->index & 31;
v >>= 32 - 1;
bits->index++;
return v;
}
int bits_get(struct bitstream *bits, int n)
{
uint32_t v = bits_peek(bits);
v >>= 32 - n;
bits->index += n;
return v;
}
int bits_get_signed(struct bitstream *bits, int n)
{
int32_t v = bits_peek(bits);
v >>= 32 - n;
bits->index += n;
return v;
}
int bits_get_signed_linear(struct bitstream *bits, int n)
{
if (n == 0)
return 0;
unsigned int v = bits_get(bits, n);
return (v >> 1) ^ -(v & 1);
}
static int bits_get_unsigned_rice(struct bitstream *bits, int k)
{
unsigned int unary = 0;
while (bits->index < bits->total) {
uint32_t v = bits_peek(bits);
if (v) {
int z = dca_clz(v);
bits->index += z + 1;
unary += z;
break;
}
bits->index += 32;
unary += 32;
}
return k > 0 ? (unary << k) | bits_get(bits, k) : unary;
}
int bits_get_signed_rice(struct bitstream *bits, int k)
{
unsigned int v = bits_get_unsigned_rice(bits, k);
return (v >> 1) ^ -(v & 1);
}
int bits_get_unsigned_vlc(struct bitstream *bits, const struct huffman *h)
{
uint32_t v = bits_peek(bits);
for (int i = 0; i < h->size; i++) {
if (v >> (32 - h->len[i]) == h->code[i]) {
bits->index += h->len[i];
return i;
}
}
return BITS_INVALID_VLC_UN;
}
int bits_get_signed_vlc(struct bitstream *bits, const struct huffman *h)
{
unsigned int v = bits_get_unsigned_vlc(bits, h);
return ((v >> 1) ^ ((v & 1) - 1)) + 1;
}
static uint16_t crc16(const uint8_t *data, int size)
{
static const uint16_t crctab[16] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};
uint16_t res = 0xffff;
for (int i = 0; i < size; i++) {
res = (res << 4) ^ crctab[(data[i] >> 4) ^ (res >> 12)];
res = (res << 4) ^ crctab[(data[i] & 15) ^ (res >> 12)];
}
return res;
}
int bits_check_crc(struct bitstream *bits, int p1, int p2)
{
if (((p1 | p2) & 7) || p1 < 0 || p2 > bits->total || p2 - p1 < 16)
return -DCADEC_EBADREAD;
if (crc16((uint8_t *)bits->data + p1 / 8, (p2 - p1) / 8))
return -DCADEC_EBADCRC;
return 0;
}
void bits_get_array(struct bitstream *bits, int *array, int size, int n)
{
for (int i = 0; i < size; i++)
array[i] = bits_get(bits, n);
}
void bits_get_signed_array(struct bitstream *bits, int *array, int size, int n)
{
for (int i = 0; i < size; i++)
array[i] = bits_get_signed(bits, n);
}
void bits_get_signed_linear_array(struct bitstream *bits, int *array, int size, int n)
{
if (n == 0)
memset(array, 0, sizeof(*array) * size);
else for (int i = 0; i < size; i++)
array[i] = bits_get_signed_linear(bits, n);
}
void bits_get_signed_rice_array(struct bitstream *bits, int *array, int size, int k)
{
for (int i = 0; i < size; i++)
array[i] = bits_get_signed_rice(bits, k);
}
int bits_get_signed_vlc_array(struct bitstream *bits, int *array, int size, const struct huffman *h)
{
for (int i = 0; i < size; i++)
if ((array[i] = bits_get_signed_vlc(bits, h)) == BITS_INVALID_VLC_SI)
return -DCADEC_EBADDATA;
return 0;
}
================================================
FILE: libdcadec/bitstream.h
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BITSTREAM_H
#define BITSTREAM_H
#include "huffman.h"
#define BITS_INVALID_VLC_UN 32768
#define BITS_INVALID_VLC_SI -16384
struct bitstream {
uint32_t *data;
int total;
int index;
};
static inline void bits_init(struct bitstream *bits, uint8_t *data, int size)
{
assert(data && !((uintptr_t)data & 3));
assert(size > 0 && size < INT_MAX / 8);
bits->data = (uint32_t *)data;
bits->total = size * 8;
bits->index = 0;
}
bool bits_get1(struct bitstream *bits);
int bits_get(struct bitstream *bits, int n);
int bits_get_signed(struct bitstream *bits, int n);
int bits_get_signed_linear(struct bitstream *bits, int n);
int bits_get_signed_rice(struct bitstream *bits, int k);
int bits_get_unsigned_vlc(struct bitstream *bits, const struct huffman *h);
int bits_get_signed_vlc(struct bitstream *bits, const struct huffman *h);
static inline void bits_skip(struct bitstream *bits, int n)
{
assert(n >= 0);
bits->index += n;
}
static inline void bits_skip1(struct bitstream *bits)
{
bits->index++;
}
static inline int bits_seek(struct bitstream *bits, int n)
{
if (n < bits->index || n > bits->total)
return -DCADEC_EBADREAD;
bits->index = n;
return 0;
}
static inline int bits_align1(struct bitstream *bits)
{
bits->index = DCA_ALIGN(bits->index, 8);
return bits->index;
}
static inline int bits_align4(struct bitstream *bits)
{
bits->index = DCA_ALIGN(bits->index, 32);
return bits->index;
}
int bits_check_crc(struct bitstream *bits, int p1, int p2);
void bits_get_array(struct bitstream *bits, int *array, int size, int n);
void bits_get_signed_array(struct bitstream *bits, int *array, int size, int n);
void bits_get_signed_linear_array(struct bitstream *bits, int *array, int size, int n);
void bits_get_signed_rice_array(struct bitstream *bits, int *array, int size, int k);
int bits_get_signed_vlc_array(struct bitstream *bits, int *array, int size, const struct huffman *h);
#endif
================================================
FILE: libdcadec/common.h
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMMON_H
#define COMMON_H
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#include <assert.h>
#include <limits.h>
#include "compiler.h"
#include "dca_context.h"
#include "ta.h"
#if AT_LEAST_GCC(3, 4)
#define dca_clz(x) __builtin_clz(x)
#else
static inline int dca_clz(uint32_t x)
{
int r = 0;
assert(x);
if (x & 0xffff0000) { x >>= 16; r |= 16; }
if (x & 0x0000ff00) { x >>= 8; r |= 8; }
if (x & 0x000000f0) { x >>= 4; r |= 4; }
if (x & 0x0000000c) { x >>= 2; r |= 2; }
if (x & 0x00000002) { x >>= 1; r |= 1; }
return 31 - r;
}
#endif
#if (defined __GNUC__) && (defined __POPCNT__)
#define dca_popcount(x) __builtin_popcount(x)
#else
static inline int dca_popcount(uint32_t x)
{
x -= (x >> 1) & 0x55555555;
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0f0f0f0f;
x += x >> 8;
return (x + (x >> 16)) & 0x3f;
}
#endif
#define dca_countof(x) (sizeof(x) / sizeof((x)[0]))
#if AT_LEAST_GCC(4, 8)
#define dca_bswap16(x) __builtin_bswap16(x)
#else
static inline uint16_t dca_bswap16(uint16_t x)
{
return (x << 8) | (x >> 8);
}
#endif
#if AT_LEAST_GCC(4, 3)
#define dca_bswap32(x) __builtin_bswap32(x)
#define dca_bswap64(x) __builtin_bswap64(x)
#else
static inline uint32_t dca_bswap32(uint32_t x)
{
x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
return (x << 16) | (x >> 16);
}
static inline uint64_t dca_bswap64(uint64_t x)
{
x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8);
x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);
return (x << 32) | (x >> 32);
}
#endif
#define DCA_BSWAP16_C(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8))
#define DCA_BSWAP32_C(x) ((DCA_BSWAP16_C(x) << 16) | (DCA_BSWAP16_C(x >> 16)))
#define DCA_BSWAP64_C(x) ((DCA_BSWAP32_C(x) << 32) | (DCA_BSWAP32_C(x >> 32)))
#if HAVE_BIGENDIAN
#define DCA_16LE(x) dca_bswap16(x)
#define DCA_32LE(x) dca_bswap32(x)
#define DCA_64LE(x) dca_bswap64(x)
#define DCA_16BE(x) ((uint16_t)(x))
#define DCA_32BE(x) ((uint32_t)(x))
#define DCA_64BE(x) ((uint64_t)(x))
#define DCA_16LE_C(x) DCA_BSWAP16_C(x)
#define DCA_32LE_C(x) DCA_BSWAP32_C(x)
#define DCA_64LE_C(x) DCA_BSWAP64_C(x)
#define DCA_16BE_C(x) (x)
#define DCA_32BE_C(x) (x)
#define DCA_64BE_C(x) (x)
#else
#define DCA_16LE(x) ((uint16_t)(x))
#define DCA_32LE(x) ((uint32_t)(x))
#define DCA_64LE(x) ((uint64_t)(x))
#define DCA_16BE(x) dca_bswap16(x)
#define DCA_32BE(x) dca_bswap32(x)
#define DCA_64BE(x) dca_bswap64(x)
#define DCA_16LE_C(x) (x)
#define DCA_32LE_C(x) (x)
#define DCA_64LE_C(x) (x)
#define DCA_16BE_C(x) DCA_BSWAP16_C(x)
#define DCA_32BE_C(x) DCA_BSWAP32_C(x)
#define DCA_64BE_C(x) DCA_BSWAP64_C(x)
#endif
#define DCA_MIN(a, b) ((a) < (b) ? (a) : (b))
#define DCA_MAX(a, b) ((a) > (b) ? (a) : (b))
#define DCA_ALIGN(value, align) \
(((value) + (align) - 1) & ~((align) - 1))
#define DCA_SET_BIT(map, bit) \
((map)[(bit) >> 3] |= 1 << ((bit) & 7))
#define DCA_TEST_BIT(map, bit) \
((map)[(bit) >> 3] >> ((bit) & 7) & 1)
#define DCA_MEM16BE(data) \
(((uint32_t)(data)[0] << 8) | (data)[1])
#define DCA_MEM24BE(data) \
(((uint32_t)(data)[0] << 16) | DCA_MEM16BE(&(data)[1]))
#define DCA_MEM32BE(data) \
(((uint32_t)(data)[0] << 24) | DCA_MEM24BE(&(data)[1]))
#define DCA_MEM40BE(data) \
(((uint64_t)(data)[0] << 32) | DCA_MEM32BE(&(data)[1]))
#define DCA_MEM16LE(data) \
(((uint32_t)(data)[1] << 8) | (data)[0])
#define DCA_MEM24LE(data) \
(((uint32_t)(data)[2] << 16) | DCA_MEM16LE(data))
#define DCA_MEM32LE(data) \
(((uint32_t)(data)[3] << 24) | DCA_MEM24LE(data))
#define DCA_MEM40LE(data) \
(((uint64_t)(data)[4] << 32) | DCA_MEM32LE(data))
static inline uint32_t DCA_MEM32NE(const void *data)
{
uint32_t res;
memcpy(&res, data, sizeof(res));
return res;
}
void dca_format_log(struct dcadec_context *dca, int level,
const char *file, int line, const char *fmt, ...)
__attribute__((format(printf, 5, 6)));
#define DCADEC_LOG_ONCE 0x80000000
#define dca_log(obj, lvl, ...) \
dca_format_log((obj)->ctx, DCADEC_LOG_##lvl, __FILE__, __LINE__, __VA_ARGS__)
#define dca_log_once(obj, lvl, ...) \
dca_format_log((obj)->ctx, DCADEC_LOG_##lvl | DCADEC_LOG_ONCE, __FILE__, __LINE__, __VA_ARGS__)
#define DCADEC_FLAG_KEEP_DMIX_MASK \
(DCADEC_FLAG_KEEP_DMIX_2CH | DCADEC_FLAG_KEEP_DMIX_6CH)
#define SPEAKER_LAYOUT_MONO (SPEAKER_MASK_C)
#define SPEAKER_LAYOUT_STEREO (SPEAKER_MASK_L | SPEAKER_MASK_R)
#define SPEAKER_LAYOUT_2POINT1 (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_LFE1)
#define SPEAKER_LAYOUT_3_0 (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_C)
#define SPEAKER_LAYOUT_2_1 (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_Cs)
#define SPEAKER_LAYOUT_3_1 (SPEAKER_LAYOUT_3_0 | SPEAKER_MASK_Cs)
#define SPEAKER_LAYOUT_2_2 (SPEAKER_LAYOUT_STEREO | SPEAKER_MASK_Ls | SPEAKER_MASK_Rs)
#define SPEAKER_LAYOUT_5POINT0 (SPEAKER_LAYOUT_3_0 | SPEAKER_MASK_Ls | SPEAKER_MASK_Rs)
#define SPEAKER_LAYOUT_7POINT0_WIDE (SPEAKER_LAYOUT_5POINT0 | SPEAKER_MASK_Lw | SPEAKER_MASK_Rw)
#define SPEAKER_LAYOUT_7POINT1_WIDE (SPEAKER_LAYOUT_7POINT0_WIDE | SPEAKER_MASK_LFE1)
enum WaveTag {
TAG_RIFF = 0x46464952,
TAG_WAVE = 0x45564157,
TAG_data = 0x61746164,
TAG_fmt = 0x20746d66
};
// WAVEFORMATEXTENSIBLE speakers
enum WaveSpeaker {
WAVESPKR_FL, WAVESPKR_FR, WAVESPKR_FC, WAVESPKR_LFE,
WAVESPKR_BL, WAVESPKR_BR, WAVESPKR_FLC, WAVESPKR_FRC,
WAVESPKR_BC, WAVESPKR_SL, WAVESPKR_SR, WAVESPKR_TC,
WAVESPKR_TFL, WAVESPKR_TFC, WAVESPKR_TFR, WAVESPKR_TBL,
WAVESPKR_TBC, WAVESPKR_TBR,
WAVESPKR_COUNT
};
// Table 6-22: Loudspeaker masks
enum SpeakerMask {
SPEAKER_MASK_C = 0x00000001,
SPEAKER_MASK_L = 0x00000002,
SPEAKER_MASK_R = 0x00000004,
SPEAKER_MASK_Ls = 0x00000008,
SPEAKER_MASK_Rs = 0x00000010,
SPEAKER_MASK_LFE1 = 0x00000020,
SPEAKER_MASK_Cs = 0x00000040,
SPEAKER_MASK_Lsr = 0x00000080,
SPEAKER_MASK_Rsr = 0x00000100,
SPEAKER_MASK_Lss = 0x00000200,
SPEAKER_MASK_Rss = 0x00000400,
SPEAKER_MASK_Lc = 0x00000800,
SPEAKER_MASK_Rc = 0x00001000,
SPEAKER_MASK_Lh = 0x00002000,
SPEAKER_MASK_Ch = 0x00004000,
SPEAKER_MASK_Rh = 0x00008000,
SPEAKER_MASK_LFE2 = 0x00010000,
SPEAKER_MASK_Lw = 0x00020000,
SPEAKER_MASK_Rw = 0x00040000,
SPEAKER_MASK_Oh = 0x00080000,
SPEAKER_MASK_Lhs = 0x00100000,
SPEAKER_MASK_Rhs = 0x00200000,
SPEAKER_MASK_Chr = 0x00400000,
SPEAKER_MASK_Lhr = 0x00800000,
SPEAKER_MASK_Rhr = 0x01000000,
SPEAKER_MASK_Cl = 0x02000000,
SPEAKER_MASK_Ll = 0x04000000,
SPEAKER_MASK_Rl = 0x08000000,
SPEAKER_MASK_RSV1 = 0x10000000,
SPEAKER_MASK_RSV2 = 0x20000000,
SPEAKER_MASK_RSV3 = 0x40000000,
SPEAKER_MASK_RSV4 = 0x80000000
};
// Table 6-22: Loudspeaker masks
enum Speaker {
SPEAKER_C, SPEAKER_L, SPEAKER_R, SPEAKER_Ls,
SPEAKER_Rs, SPEAKER_LFE1, SPEAKER_Cs, SPEAKER_Lsr,
SPEAKER_Rsr, SPEAKER_Lss, SPEAKER_Rss, SPEAKER_Lc,
SPEAKER_Rc, SPEAKER_Lh, SPEAKER_Ch, SPEAKER_Rh,
SPEAKER_LFE2, SPEAKER_Lw, SPEAKER_Rw, SPEAKER_Oh,
SPEAKER_Lhs, SPEAKER_Rhs, SPEAKER_Chr, SPEAKER_Lhr,
SPEAKER_Rhr, SPEAKER_Cl, SPEAKER_Ll, SPEAKER_Rl,
SPEAKER_RSV1, SPEAKER_RSV2, SPEAKER_RSV3, SPEAKER_RSV4,
SPEAKER_COUNT
};
// Table 7-1: Sync words
enum SyncWord {
SYNC_WORD_CORE = 0x7ffe8001,
SYNC_WORD_CORE_LE = 0xfe7f0180,
SYNC_WORD_CORE_LE14 = 0xff1f00e8,
SYNC_WORD_CORE_BE14 = 0x1fffe800,
SYNC_WORD_REV1AUX = 0x9a1105a0,
SYNC_WORD_REV2AUX = 0x7004c070,
SYNC_WORD_XCH = 0x5a5a5a5a,
SYNC_WORD_XXCH = 0x47004a03,
SYNC_WORD_X96 = 0x1d95f262,
SYNC_WORD_XBR = 0x655e315e,
SYNC_WORD_LBR = 0x0a801921,
SYNC_WORD_XLL = 0x41a29547,
SYNC_WORD_EXSS = 0x64582025,
SYNC_WORD_EXSS_LE = 0x58642520,
SYNC_WORD_CORE_EXSS = 0x02b09261,
};
// Table 7-10: Loudspeaker bit mask for speaker activity
enum SpeakerPair {
SPEAKER_PAIR_C = 0x0001,
SPEAKER_PAIR_LR = 0x0002,
SPEAKER_PAIR_LsRs = 0x0004,
SPEAKER_PAIR_LFE1 = 0x0008,
SPEAKER_PAIR_Cs = 0x0010,
SPEAKER_PAIR_LhRh = 0x0020,
SPEAKER_PAIR_LsrRsr = 0x0040,
SPEAKER_PAIR_Ch = 0x0080,
SPEAKER_PAIR_Oh = 0x0100,
SPEAKER_PAIR_LcRc = 0x0200,
SPEAKER_PAIR_LwRw = 0x0400,
SPEAKER_PAIR_LssRss = 0x0800,
SPEAKER_PAIR_LFE2 = 0x1000,
SPEAKER_PAIR_LhsRhs = 0x2000,
SPEAKER_PAIR_Chr = 0x4000,
SPEAKER_PAIR_LhrRhr = 0x8000,
SPEAKER_PAIR_ALL_1 = 0x5199,
SPEAKER_PAIR_ALL_2 = 0xae66
};
static inline int count_chs_for_mask(int mask)
{
return dca_popcount(mask) + dca_popcount(mask & SPEAKER_PAIR_ALL_2);
}
// Table 7-11: Representation type
enum RepresentationType {
REPR_TYPE_LtRt = 2,
REPR_TYPE_LhRh = 3
};
// Table 7-15: Core/extension mask
enum ExtensionMask {
CSS_CORE = 0x001,
CSS_XXCH = 0x002,
CSS_X96 = 0x004,
CSS_XCH = 0x008,
EXSS_CORE = 0x010,
EXSS_XBR = 0x020,
EXSS_XXCH = 0x040,
EXSS_X96 = 0x080,
EXSS_LBR = 0x100,
EXSS_XLL = 0x200,
EXSS_RSV1 = 0x400,
EXSS_RSV2 = 0x800
};
// Table 8-8: Downmix type
enum DownMixType {
DMIX_TYPE_1_0,
DMIX_TYPE_LoRo,
DMIX_TYPE_LtRt,
DMIX_TYPE_3_0,
DMIX_TYPE_2_1,
DMIX_TYPE_2_2,
DMIX_TYPE_3_1,
DMIX_TYPE_COUNT
};
#endif
================================================
FILE: libdcadec/compiler.h
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPILER_H
#define COMPILER_H
#ifdef _MSC_VER
#define inline __inline
#define restrict __restrict
#define fseeko _fseeki64
#define ftello _ftelli64
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
typedef __int64 off_t;
#endif
#ifndef __GNUC__
#define __attribute__(x)
#endif
#define AT_LEAST_GCC(major, minor) \
(defined __GNUC__) && ((__GNUC__ > (major)) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#ifndef HAVE_BIGENDIAN
# if (defined __GNUC__)
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define HAVE_BIGENDIAN 0
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define HAVE_BIGENDIAN 1
# else
# error Unsupported byte order
# endif
# elif (defined _MSC_VER)
# define HAVE_BIGENDIAN 0
# else
# error Unsupported compiler. Define HAVE_BIGENDIAN macro to specify endianness.
# endif
#endif
#endif
================================================
FILE: libdcadec/core_decoder.c
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "common.h"
#include "bitstream.h"
#include "interpolator.h"
#include "idct.h"
#include "fixed_math.h"
#include "core_decoder.h"
#include "exss_parser.h"
#include "dmix_tables.h"
#include "core_tables.h"
#include "core_huffman.h"
#include "core_vectors.h"
enum HeaderType {
HEADER_CORE,
HEADER_XCH,
HEADER_XXCH
};
enum AudioMode {
AMODE_MONO, // Mode 0: A (mono)
AMODE_MONO_DUAL, // Mode 1: A + B (dual mono)
AMODE_STEREO, // Mode 2: L + R (stereo)
AMODE_STEREO_SUMDIFF, // Mode 3: (L+R) + (L-R) (sum-diff)
AMODE_STEREO_TOTAL, // Mode 4: LT + RT (left and right total)
AMODE_3F, // Mode 5: C + L + R
AMODE_2F1R, // Mode 6: L + R + S
AMODE_3F1R, // Mode 7: C + L + R + S
AMODE_2F2R, // Mode 8: L + R + SL + SR
AMODE_3F2R, // Mode 9: C + L + R + SL + SR
AMODE_COUNT
};
enum ExtAudioType {
EXT_AUDIO_XCH = 0,
EXT_AUDIO_X96 = 2,
EXT_AUDIO_XXCH = 6
};
enum LFEFlag {
LFE_FLAG_NONE,
LFE_FLAG_128,
LFE_FLAG_64,
LFE_FLAG_INVALID
};
static const int8_t prm_ch_to_spkr_map[AMODE_COUNT][5] = {
{ SPEAKER_C, -1, -1, -1, -1 },
{ SPEAKER_L, SPEAKER_R, -1, -1, -1 },
{ SPEAKER_L, SPEAKER_R, -1, -1, -1 },
{ SPEAKER_L, SPEAKER_R, -1, -1, -1 },
{ SPEAKER_L, SPEAKER_R, -1, -1, -1 },
{ SPEAKER_C, SPEAKER_L, SPEAKER_R , -1, -1 },
{ SPEAKER_L, SPEAKER_R, SPEAKER_Cs, -1 -1 },
{ SPEAKER_C, SPEAKER_L, SPEAKER_R , SPEAKER_Cs, -1 },
{ SPEAKER_L, SPEAKER_R, SPEAKER_Ls, SPEAKER_Rs, -1 },
{ SPEAKER_C, SPEAKER_L, SPEAKER_R, SPEAKER_Ls, SPEAKER_Rs }
};
static const uint8_t audio_mode_ch_mask[AMODE_COUNT] = {
SPEAKER_LAYOUT_MONO,
SPEAKER_LAYOUT_STEREO,
SPEAKER_LAYOUT_STEREO,
SPEAKER_LAYOUT_STEREO,
SPEAKER_LAYOUT_STEREO,
SPEAKER_LAYOUT_3_0,
SPEAKER_LAYOUT_2_1,
SPEAKER_LAYOUT_3_1,
SPEAKER_LAYOUT_2_2,
SPEAKER_LAYOUT_5POINT0
};
// 5.3.1 - Bit stream header
static int parse_frame_header(struct core_decoder *core)
{
// Frame type
bool normal_frame = bits_get1(&core->bits);
// Deficit sample count
if (bits_get(&core->bits, 5) != NUM_PCMBLOCK_SAMPLES - 1) {
core_err("Invalid deficit sample count");
return normal_frame ? -DCADEC_EBADDATA : -DCADEC_ENOSUP;
}
// CRC present flag
core->crc_present = bits_get1(&core->bits);
// Number of PCM sample blocks
core->npcmblocks = bits_get(&core->bits, 7) + 1;
if (core->npcmblocks & (NUM_SUBBAND_SAMPLES - 1)) {
core_err("Invalid number of PCM sample blocks (%d)", core->npcmblocks);
return (core->npcmblocks < 6 || normal_frame) ? -DCADEC_EBADDATA : -DCADEC_ENOSUP;
}
// Primary frame byte size
core->frame_size = bits_get(&core->bits, 14) + 1;
if (core->frame_size < 96) {
core_err("Invalid core frame size");
return -DCADEC_EBADDATA;
}
// Audio channel arrangement
core->audio_mode = bits_get(&core->bits, 6);
if (core->audio_mode >= AMODE_COUNT) {
core_err("Unsupported audio channel arrangement (%d)", core->audio_mode);
return -DCADEC_ENOSUP;
}
// Core audio sampling frequency
core->sample_rate = sample_rates[bits_get(&core->bits, 4)];
if (!core->sample_rate) {
core_err("Invalid core audio sampling frequency");
return -DCADEC_EBADDATA;
}
// Transmission bit rate
core->bit_rate = bit_rates[bits_get(&core->bits, 5)];
if (core->bit_rate == -1) {
core_err("Invalid transmission bit rate");
return -DCADEC_EBADDATA;
}
// Reserved field
bits_skip1(&core->bits);
// Embedded dynamic range flag
core->drc_present = bits_get1(&core->bits);
// Embedded time stamp flag
core->ts_present = bits_get1(&core->bits);
// Auxiliary data flag
core->aux_present = bits_get1(&core->bits);
// HDCD mastering flag
bits_skip1(&core->bits);
// Extension audio descriptor flag
core->ext_audio_type = bits_get(&core->bits, 3);
// Extended coding flag
core->ext_audio_present = bits_get1(&core->bits);
// Audio sync word insertion flag
core->sync_ssf = bits_get1(&core->bits);
// Low frequency effects flag
core->lfe_present = bits_get(&core->bits, 2);
if (core->lfe_present == LFE_FLAG_INVALID) {
core_err("Invalid low frequency effects flag");
return -DCADEC_EBADDATA;
}
// Predictor history flag switch
core->predictor_history = bits_get1(&core->bits);
// Header CRC check bytes
if (core->crc_present)
bits_skip(&core->bits, 16);
// Multirate interpolator switch
core->filter_perfect = bits_get1(&core->bits);
// Encoder software revision
bits_skip(&core->bits, 4);
// Copy history
bits_skip(&core->bits, 2);
// Source PCM resolution
int pcmr_index = bits_get(&core->bits, 3);
core->source_pcm_res = sample_res[pcmr_index];
if (!core->source_pcm_res) {
core_err("Invalid source PCM resolution");
return -DCADEC_EBADDATA;
}
core->es_format = !!(pcmr_index & 1);
// Front sum/difference flag
core->sumdiff_front = bits_get1(&core->bits);
// Surround sum/difference flag
core->sumdiff_surround = bits_get1(&core->bits);
// Dialog normalization / unspecified
bits_skip(&core->bits, 4);
return 0;
}
// 5.3.2 - Primary audio coding header
static int parse_coding_header(struct core_decoder *core, enum HeaderType header, int xch_base)
{
int ch, n, ret, header_size = 0, header_pos = core->bits.index;
switch (header) {
case HEADER_CORE:
// Number of subframes
core->nsubframes = bits_get(&core->bits, 4) + 1;
// Number of primary audio channels
core->nchannels = bits_get(&core->bits, 3) + 1;
if (core->nchannels != audio_mode_nch[core->audio_mode]) {
core_err("Invalid number of primary audio channels (%d) for audio "
"channel arrangement (%d)", core->nchannels, core->audio_mode);
return -DCADEC_EBADDATA;
}
assert(core->nchannels <= MAX_CHANNELS - 2);
core->ch_mask = audio_mode_ch_mask[core->audio_mode];
// Add LFE channel if present
if (core->lfe_present)
core->ch_mask |= SPEAKER_MASK_LFE1;
break;
case HEADER_XCH:
core->nchannels = audio_mode_nch[core->audio_mode] + 1;
assert(core->nchannels <= MAX_CHANNELS - 1);
core->ch_mask |= SPEAKER_MASK_Cs;
break;
case HEADER_XXCH:
// Channel set header length
header_size = bits_get(&core->bits, 7) + 1;
// Check CRC
if (core->xxch_crc_present && (ret = bits_check_crc(&core->bits, header_pos, header_pos + header_size * 8)) < 0) {
core_err("Invalid XXCH channel set header checksum");
return ret;
}
// Number of channels in a channel set
int nchannels = bits_get(&core->bits, 3) + 1;
if (nchannels > MAX_CHANNELS_XXCH) {
core_err_once("Unsupported number of XXCH channels (%d)", nchannels);
return -DCADEC_ENOSUP;
}
core->nchannels = audio_mode_nch[core->audio_mode] + nchannels;
assert(core->nchannels <= MAX_CHANNELS);
// Loudspeaker layout mask
unsigned int mask = bits_get(&core->bits, core->xxch_mask_nbits - SPEAKER_Cs);
core->xxch_spkr_mask = mask << SPEAKER_Cs;
if (dca_popcount(core->xxch_spkr_mask) != nchannels) {
core_err("Invalid XXCH speaker layout mask (%#x)", core->xxch_spkr_mask);
return -DCADEC_EBADDATA;
}
if (core->xxch_core_mask & core->xxch_spkr_mask) {
core_err("XXCH speaker layout mask (%#x) overlaps with core (%#x)",
core->xxch_spkr_mask, core->xxch_core_mask);
return -DCADEC_EBADDATA;
}
// Combine core and XXCH masks together
core->ch_mask = core->xxch_core_mask | core->xxch_spkr_mask;
// Downmix coefficients present in stream
if (bits_get1(&core->bits)) {
// Downmix already performed by encoder
core->xxch_dmix_embedded = bits_get1(&core->bits);
// Downmix scale factor
unsigned int index = bits_get(&core->bits, 6) * 4 - 44;
if (index >= dca_countof(dmix_table_inv)) {
core_err("Invalid XXCH downmix scale index");
return -DCADEC_EBADDATA;
}
core->xxch_dmix_scale_inv = dmix_table_inv[index];
// Downmix channel mapping mask
for (ch = 0; ch < nchannels; ch++) {
mask = bits_get(&core->bits, core->xxch_mask_nbits);
if ((mask & core->xxch_core_mask) != mask) {
core_err("Invalid XXCH downmix channel mapping mask (%#x)", mask);
return -DCADEC_EBADDATA;
}
core->xxch_dmix_mask[ch] = mask;
}
// Downmix coefficients
int *coeff_ptr = core->xxch_dmix_coeff;
for (ch = 0; ch < nchannels; ch++) {
for (n = 0; n < core->xxch_mask_nbits; n++) {
if (core->xxch_dmix_mask[ch] & (1U << n)) {
int code = bits_get(&core->bits, 7);
int sign = (code >> 6) - 1;
if (code &= 63) {
unsigned int index = code * 4 - 4;
if (index >= dca_countof(dmix_table)) {
core_err("Invalid XXCH downmix coefficient index");
return -DCADEC_EBADDATA;
}
*coeff_ptr++ = (dmix_table[index] ^ sign) - sign;
} else {
*coeff_ptr++ = 0;
}
}
}
}
} else {
core->xxch_dmix_embedded = false;
}
break;
}
// Subband activity count
for (ch = xch_base; ch < core->nchannels; ch++) {
core->nsubbands[ch] = bits_get(&core->bits, 5) + 2;
if (core->nsubbands[ch] > MAX_SUBBANDS) {
core_err("Invalid subband activity count");
return -DCADEC_EBADDATA;
}
}
// High frequency VQ start subband
for (ch = xch_base; ch < core->nchannels; ch++)
core->subband_vq_start[ch] = bits_get(&core->bits, 5) + 1;
// Joint intensity coding index
for (ch = xch_base; ch < core->nchannels; ch++) {
if ((n = bits_get(&core->bits, 3)) && header == HEADER_XXCH)
n += xch_base - 1;
if (n > core->nchannels) {
core_err("Invalid joint intensity coding index");
return -DCADEC_EBADDATA;
}
core->joint_intensity_index[ch] = n;
}
// Transient mode code book
for (ch = xch_base; ch < core->nchannels; ch++)
core->transition_mode_sel[ch] = bits_get(&core->bits, 2);
// Scale factor code book
for (ch = xch_base; ch < core->nchannels; ch++) {
core->scale_factor_sel[ch] = bits_get(&core->bits, 3);
if (core->scale_factor_sel[ch] == 7) {
core_err("Invalid scale factor code book");
return -DCADEC_EBADDATA;
}
}
// Bit allocation quantizer select
for (ch = xch_base; ch < core->nchannels; ch++) {
core->bit_allocation_sel[ch] = bits_get(&core->bits, 3);
if (core->bit_allocation_sel[ch] == 7) {
core_err("Invalid bit allocation quantizer select");
return -DCADEC_EBADDATA;
}
}
// Quantization index codebook select
for (n = 0; n < NUM_CODE_BOOKS; n++)
for (ch = xch_base; ch < core->nchannels; ch++)
core->quant_index_sel[ch][n] = bits_get(&core->bits, quant_index_sel_nbits[n]);
// Scale factor adjustment index
for (n = 0; n < NUM_CODE_BOOKS; n++)
for (ch = xch_base; ch < core->nchannels; ch++)
if (core->quant_index_sel[ch][n] < quant_index_group_size[n])
core->scale_factor_adj[ch][n] = scale_factor_adj[bits_get(&core->bits, 2)];
if (header == HEADER_XXCH) {
// Reserved
// Byte align
// CRC16 of channel set header
if ((ret = bits_seek(&core->bits, header_pos + header_size * 8)) < 0) {
core_err("Read past end of XXCH channel set header");
return ret;
}
} else {
// Audio header CRC check word
if (core->crc_present)
bits_skip(&core->bits, 16);
}
return 0;
}
static int parse_scale(struct core_decoder *core, int *scale_index, int sel)
{
// Select the root square table
const int32_t *scale_table;
size_t scale_size;
if (sel > 5) {
scale_table = scale_factors_7bit;
scale_size = dca_countof(scale_factors_7bit);
} else {
scale_table = scale_factors_6bit;
scale_size = dca_countof(scale_factors_6bit);
}
if (sel < 5)
// If Huffman code was used, the difference of scales was encoded
*scale_index += bits_get_signed_vlc(&core->bits, &scale_factor_huff[sel]);
else
*scale_index = bits_get(&core->bits, sel + 1);
// Look up scale factor from the root square table
if ((unsigned int)*scale_index >= scale_size) {
core_err("Invalid scale factor index");
return -DCADEC_EBADDATA;
}
return scale_table[*scale_index];
}
static int parse_joint_scale(struct core_decoder *core, int sel)
{
int scale_index;
if (sel < 5)
scale_index = bits_get_signed_vlc(&core->bits, &scale_factor_huff[sel]);
else
scale_index = bits_get(&core->bits, sel + 1);
// Bias by 64
scale_index += 64;
// Look up joint scale factor
if ((unsigned int)scale_index >= dca_countof(joint_scale_factors)) {
core_err("Invalid joint scale factor index");
return -DCADEC_EBADDATA;
}
return joint_scale_factors[scale_index];
}
// 5.4.1 - Primary audio coding side information
static int parse_subframe_header(struct core_decoder *core, int sf,
enum HeaderType header, int xch_base)
{
int ch, band, ret;
if (header == HEADER_CORE) {
// Subsubframe count
core->nsubsubframes[sf] = bits_get(&core->bits, 2) + 1;
// Partial subsubframe sample count
bits_skip(&core->bits, 3);
}
// Prediction mode
for (ch = xch_base; ch < core->nchannels; ch++)
for (band = 0; band < core->nsubbands[ch]; band++)
core->prediction_mode[ch][band] = bits_get1(&core->bits);
// Prediction coefficients VQ address
for (ch = xch_base; ch < core->nchannels; ch++)
for (band = 0; band < core->nsubbands[ch]; band++)
if (core->prediction_mode[ch][band])
core->prediction_vq_index[ch][band] = bits_get(&core->bits, 12);
// Bit allocation index
for (ch = xch_base; ch < core->nchannels; ch++) {
// Select codebook
int sel = core->bit_allocation_sel[ch];
// Not high frequency VQ subbands
for (band = 0; band < core->subband_vq_start[ch]; band++) {
int abits;
if (sel < 5)
abits = bits_get_unsigned_vlc(&core->bits, &bit_allocation_huff[sel]) + 1;
else
abits = bits_get(&core->bits, sel - 1);
if (abits >= 27) {
core_err("Invalid bit allocation index");
return -DCADEC_EBADDATA;
}
core->bit_allocation[ch][band] = abits;
}
}
// Transition mode
for (ch = xch_base; ch < core->nchannels; ch++) {
// Clear transition mode for all subbands
memset(core->transition_mode[sf][ch], 0, sizeof(core->transition_mode[0][0]));
// Transient possible only if more than one subsubframe
if (core->nsubsubframes[sf] > 1) {
// Select codebook
int sel = core->transition_mode_sel[ch];
// Not high frequency VQ subbands
for (band = 0; band < core->subband_vq_start[ch]; band++) {
// Present only if bits allocated
if (core->bit_allocation[ch][band]) {
int trans_ssf = bits_get_unsigned_vlc(&core->bits, &transition_mode_huff[sel]);
if (trans_ssf >= 4) {
core_err("Invalid transition mode index");
return -DCADEC_EBADDATA;
}
core->transition_mode[sf][ch][band] = trans_ssf;
}
}
}
}
// Scale factors
for (ch = xch_base; ch < core->nchannels; ch++) {
// Select codebook
int sel = core->scale_factor_sel[ch];
// Clear accumulation
int scale_index = 0;
// Extract scales for subbands up to VQ
for (band = 0; band < core->subband_vq_start[ch]; band++) {
if (core->bit_allocation[ch][band]) {
if ((ret = parse_scale(core, &scale_index, sel)) < 0)
return ret;
core->scale_factors[ch][band][0] = ret;
if (core->transition_mode[sf][ch][band]) {
if ((ret = parse_scale(core, &scale_index, sel)) < 0)
return ret;
core->scale_factors[ch][band][1] = ret;
}
} else {
core->scale_factors[ch][band][0] = 0;
}
}
// High frequency VQ subbands
for (band = core->subband_vq_start[ch]; band < core->nsubbands[ch]; band++) {
if ((ret = parse_scale(core, &scale_index, sel)) < 0)
return ret;
core->scale_factors[ch][band][0] = ret;
}
}
// Joint subband codebook select
for (ch = xch_base; ch < core->nchannels; ch++) {
// Only if joint subband coding is enabled
if (core->joint_intensity_index[ch]) {
core->joint_scale_sel[ch] = bits_get(&core->bits, 3);
if (core->joint_scale_sel[ch] == 7) {
core_err("Invalid joint scale factor code book");
return -DCADEC_EBADDATA;
}
}
}
// Scale factors for joint subband coding
for (ch = xch_base; ch < core->nchannels; ch++) {
// Only if joint subband coding is enabled
if (core->joint_intensity_index[ch]) {
// Select codebook
int sel = core->joint_scale_sel[ch];
// Get source channel
int src_ch = core->joint_intensity_index[ch] - 1;
for (band = core->nsubbands[ch]; band < core->nsubbands[src_ch]; band++) {
if ((ret = parse_joint_scale(core, sel)) < 0)
return ret;
core->joint_scale_factors[ch][band] = ret;
}
}
}
// Dynamic range coefficient
if (core->drc_present && header == HEADER_CORE)
bits_skip(&core->bits, 8);
// Side information CRC check word
if (core->crc_present)
bits_skip(&core->bits, 16);
return 0;
}
static int parse_block_codes(struct core_decoder *core, int *audio, int abits)
{
// Extract the block code indices from the bit stream
int code1 = bits_get(&core->bits, block_code_nbits[abits]);
int code2 = bits_get(&core->bits, block_code_nbits[abits]);
int levels = quant_levels[abits];
int offset = (levels - 1) / 2;
int n;
// Look up samples from the block code book
for (n = 0; n < NUM_SUBBAND_SAMPLES / 2; n++) {
audio[n] = (code1 % levels) - offset;
code1 /= levels;
}
for (; n < NUM_SUBBAND_SAMPLES; n++) {
audio[n] = (code2 % levels) - offset;
code2 /= levels;
}
if (code1 || code2) {
core_err("Failed to decode block codes");
return -DCADEC_EBADDATA;
}
return 0;
}
static int parse_huffman_codes(struct core_decoder *core, int *audio, int abits, int sel)
{
int ret;
// Extract Huffman codes from the bit stream
if ((ret = bits_get_signed_vlc_array(&core->bits, audio, NUM_SUBBAND_SAMPLES,
&quant_index_group_huff[abits - 1][sel])) < 0) {
core_err("Failed to decode huffman codes");
return ret;
}
return 1;
}
static inline int extract_audio(struct core_decoder *core, int *audio, int abits, int ch)
{
assert(abits >= 0 && abits < 27);
if (abits == 0) {
// No bits allocated
memset(audio, 0, NUM_SUBBAND_SAMPLES * sizeof(*audio));
return 0;
}
if (abits <= NUM_CODE_BOOKS) {
int sel = core->quant_index_sel[ch][abits - 1];
if (sel < quant_index_group_size[abits - 1]) {
// Huffman codes
return parse_huffman_codes(core, audio, abits, sel);
}
if (abits <= 7) {
// Block codes
return parse_block_codes(core, audio, abits);
}
}
// No further encoding
bits_get_signed_array(&core->bits, audio, NUM_SUBBAND_SAMPLES, abits - 3);
return 0;
}
static inline void dequantize(int *output, const int *input, int step_size,
int scale, bool residual)
{
// Account for quantizer step size
int64_t step_scale = (int64_t)step_size * scale;
int shift = 0;
// Limit scale factor resolution to 22 bits
if (step_scale > (1 << 23)) {
shift = 32 - dca_clz(step_scale >> 23);
step_scale >>= shift;
}
// Scale the samples
if (residual) {
for (int n = 0; n < NUM_SUBBAND_SAMPLES; n++)
output[n] += clip23(norm__(input[n] * step_scale, 22 - shift));
} else {
for (int n = 0; n < NUM_SUBBAND_SAMPLES; n++)
output[n] = clip23(norm__(input[n] * step_scale, 22 - shift));
}
}
// 5.5 - Primary audio data arrays
static int parse_subframe_audio(struct core_decoder *core, int sf, enum HeaderType header,
int xch_base, int *sub_pos, int *lfe_pos)
{
int ssf, ch, band, ofs;
// Number of subband samples in this subframe
int nsamples = core->nsubsubframes[sf] * NUM_SUBBAND_SAMPLES;
if (*sub_pos + nsamples > core->npcmblocks) {
core_err("Subband sample buffer overflow");
return -DCADEC_EBADDATA;
}
// VQ encoded subbands
for (ch = xch_base; ch < core->nchannels; ch++) {
for (band = core->subband_vq_start[ch]; band < core->nsubbands[ch]; band++) {
// Extract the VQ address from the bit stream
int vq_index = bits_get(&core->bits, 10);
// Get the scale factor
int scale = core->scale_factors[ch][band][0];
// Look up the VQ code book for 32 subband samples
const int8_t *vq_samples = high_freq_samples[vq_index];
// Scale and take the samples
int *samples = core->subband_samples[ch][band] + *sub_pos;
for (int n = 0; n < nsamples; n++)
samples[n] = clip23(mul4(scale, vq_samples[n]));
}
}
// Low frequency effect data
if (core->lfe_present && header == HEADER_CORE) {
// Number of LFE samples in this subframe
int nlfesamples = 2 * core->lfe_present * core->nsubsubframes[sf];
assert(nlfesamples <= MAX_LFE_SAMPLES);
// Extract LFE samples from the bit stream
int audio[MAX_LFE_SAMPLES];
bits_get_signed_array(&core->bits, audio, nlfesamples, 8);
// Extract scale factor index from the bit stream
unsigned int scale_index = bits_get(&core->bits, 8);
if (scale_index >= dca_countof(scale_factors_7bit)) {
core_err("Invalid LFE scale factor index");
return -DCADEC_EBADDATA;
}
// Look up the 7-bit root square quantization table
int scale = scale_factors_7bit[scale_index];
// Account for quantizer step size which is 0.035
int step_scale = mul23(4697620, scale);
// Scale the LFE samples
int *samples = core->lfe_samples + *lfe_pos;
for (int n = 0; n < nlfesamples; n++)
samples[n] = clip23((audio[n] * step_scale) >> 4);
// Advance LFE sample pointer for the next subframe
*lfe_pos += nlfesamples;
}
// Audio data
for (ssf = 0, ofs = *sub_pos; ssf < core->nsubsubframes[sf]; ssf++) {
for (ch = xch_base; ch < core->nchannels; ch++) {
// Not high frequency VQ subbands
for (band = 0; band < core->subband_vq_start[ch]; band++) {
int abits = core->bit_allocation[ch][band];
int audio[NUM_SUBBAND_SAMPLES];
int ret, step_size, trans_ssf, scale;
// Extract bits from the bit stream
if ((ret = extract_audio(core, audio, abits, ch)) < 0)
return ret;
// Select quantization step size table
// Look up quantization step size
if (core->bit_rate == -2)
step_size = step_size_lossless[abits];
else
step_size = step_size_lossy[abits];
// Identify transient location
trans_ssf = core->transition_mode[sf][ch][band];
// Determine proper scale factor
if (trans_ssf == 0 || ssf < trans_ssf)
scale = core->scale_factors[ch][band][0];
else
scale = core->scale_factors[ch][band][1];
// Adjustment of scale factor
// Only when SEL indicates Huffman code
if (ret > 0) {
int64_t adj = core->scale_factor_adj[ch][abits - 1];
scale = clip23((adj * scale) >> 22);
}
dequantize(core->subband_samples[ch][band] + ofs,
audio, step_size, scale, false);
}
}
// DSYNC
if ((ssf == core->nsubsubframes[sf] - 1 || core->sync_ssf)
&& bits_get(&core->bits, 16) != 0xffff) {
core_err("DSYNC check failed");
return -DCADEC_EBADDATA;
}
ofs += NUM_SUBBAND_SAMPLES;
}
// Inverse ADPCM
for (ch = xch_base; ch < core->nchannels; ch++) {
for (band = 0; band < core->nsubbands[ch]; band++) {
// Only if prediction mode is on
if (core->prediction_mode[ch][band]) {
int *samples = core->subband_samples[ch][band] + *sub_pos;
// Extract the VQ index
int vq_index = core->prediction_vq_index[ch][band];
// Look up the VQ table for prediction coefficients
const int16_t *vq_coeffs = adpcm_coeffs[vq_index];
for (int m = 0; m < nsamples; m++) {
int64_t err = INT64_C(0);
for (int n = 0; n < NUM_ADPCM_COEFFS; n++)
err += (int64_t)samples[m - n - 1] * vq_coeffs[n];
samples[m] = clip23(samples[m] + clip23(norm13(err)));
}
}
}
}
// Joint subband coding
for (ch = xch_base; ch < core->nchannels; ch++) {
// Only if joint subband coding is enabled
if (core->joint_intensity_index[ch]) {
// Get source channel
int src_ch = core->joint_intensity_index[ch] - 1;
for (band = core->nsubbands[ch]; band < core->nsubbands[src_ch]; band++) {
int *src = core->subband_samples[src_ch][band] + *sub_pos;
int *dst = core->subband_samples[ ch][band] + *sub_pos;
int scale = core->joint_scale_factors[ch][band];
for (int n = 0; n < nsamples; n++)
dst[n] = clip23(mul17(src[n], scale));
}
}
}
// Advance subband sample pointer for the next subframe
*sub_pos += nsamples;
return 0;
}
static void erase_adpcm_history(struct core_decoder *core)
{
// Erase ADPCM history from previous frame if
// predictor history switch was disabled
for (int ch = 0; ch < MAX_CHANNELS; ch++)
for (int band = 0; band < MAX_SUBBANDS; band++)
memset(core->subband_samples[ch][band] - NUM_ADPCM_COEFFS, 0, NUM_ADPCM_COEFFS * sizeof(int));
}
static int alloc_sample_buffer(struct core_decoder *core)
{
int nchsamples = NUM_ADPCM_COEFFS + core->npcmblocks;
int nframesamples = nchsamples * MAX_CHANNELS * MAX_SUBBANDS;
int nlfesamples = MAX_LFE_HISTORY + core->npcmblocks / 2;
// Reallocate subband sample buffer
int ret;
if ((ret = ta_zalloc_fast(core, &core->subband_buffer, nframesamples + nlfesamples, sizeof(int))) < 0)
return -DCADEC_ENOMEM;
if (ret > 0) {
for (int ch = 0; ch < MAX_CHANNELS; ch++)
for (int band = 0; band < MAX_SUBBANDS; band++)
core->subband_samples[ch][band] = core->subband_buffer +
(ch * MAX_SUBBANDS + band) * nchsamples + NUM_ADPCM_COEFFS;
core->lfe_samples = core->subband_buffer + nframesamples;
}
if (!core->predictor_history)
erase_adpcm_history(core);
return 0;
}
static int parse_frame_data(struct core_decoder *core, enum HeaderType header, int xch_base)
{
int ret;
if ((ret = parse_coding_header(core, header, xch_base)) < 0)
return ret;
int sub_pos = 0;
int lfe_pos = MAX_LFE_HISTORY;
for (int sf = 0; sf < core->nsubframes; sf++) {
if ((ret = parse_subframe_header(core, sf, header, xch_base)) < 0)
return ret;
if ((ret = parse_subframe_audio(core, sf, header, xch_base, &sub_pos, &lfe_pos)) < 0)
return ret;
}
for (int ch = xch_base; ch < core->nchannels; ch++) {
// Number of active subbands for this channel
int nsubbands = core->nsubbands[ch];
if (core->joint_intensity_index[ch])
nsubbands = DCA_MAX(nsubbands, core->nsubbands[core->joint_intensity_index[ch] - 1]);
// Update history for ADPCM
for (int band = 0; band < nsubbands; band++) {
int *samples = core->subband_samples[ch][band] - NUM_ADPCM_COEFFS;
memcpy(samples, samples + core->npcmblocks, NUM_ADPCM_COEFFS * sizeof(int));
}
// Clear inactive subbands
for (int band = nsubbands; band < MAX_SUBBANDS; band++) {
int *samples = core->subband_samples[ch][band] - NUM_ADPCM_COEFFS;
memset(samples, 0, (NUM_ADPCM_COEFFS + core->npcmblocks) * sizeof(int));
}
}
return 0;
}
static int map_prm_ch_to_spkr(struct core_decoder *core, int ch)
{
// Try to map this channel to core first
int pos = audio_mode_nch[core->audio_mode];
if (ch < pos) {
int spkr = prm_ch_to_spkr_map[core->audio_mode][ch];
if (core->ext_audio_mask & (CSS_XXCH | EXSS_XXCH)) {
if (core->xxch_core_mask & (1U << spkr))
return spkr;
if (spkr == SPEAKER_Ls && (core->xxch_core_mask & SPEAKER_MASK_Lss))
return SPEAKER_Lss;
if (spkr == SPEAKER_Rs && (core->xxch_core_mask & SPEAKER_MASK_Rss))
return SPEAKER_Rss;
return -1;
}
return spkr;
}
// Then XCH
if ((core->ext_audio_mask & CSS_XCH) && ch == pos)
return SPEAKER_Cs;
// Then XXCH
if (core->ext_audio_mask & (CSS_XXCH | EXSS_XXCH))
for (int spkr = SPEAKER_Cs; spkr < core->xxch_mask_nbits; spkr++)
if (core->xxch_spkr_mask & (1U << spkr))
if (pos++ == ch)
return spkr;
// No mapping
return -1;
}
int core_filter(struct core_decoder *core, int flags)
{
int x96_nchannels = 0;
// Externally set CORE_SYNTH_X96 flags implies that X96 synthesis should be
// enabled, yet actual X96 subband data should be discarded. This is a special
// case for lossless residual decoder that apparently ignores X96 data.
if (!(flags & DCADEC_FLAG_CORE_SYNTH_X96) && (core->ext_audio_mask & (CSS_X96 | EXSS_X96))) {
x96_nchannels = core->x96_nchannels;
flags |= DCADEC_FLAG_CORE_SYNTH_X96;
}
// X96 synthesis enabled flag
bool synth_x96 = !!(flags & DCADEC_FLAG_CORE_SYNTH_X96);
// Output sample rate
core->output_rate = core->sample_rate << synth_x96;
// Number of PCM samples in this frame
core->npcmsamples = (core->npcmblocks * NUM_PCMBLOCK_SAMPLES) << synth_x96;
// Reallocate PCM output buffer
if (ta_zalloc_fast(core, &core->output_buffer, core->npcmsamples * dca_popcount(core->ch_mask), sizeof(int)) < 0)
return -DCADEC_ENOMEM;
int *ptr = core->output_buffer;
for (int spkr = 0; spkr < SPEAKER_COUNT; spkr++) {
if (core->ch_mask & (1U << spkr)) {
core->output_samples[spkr] = ptr;
ptr += core->npcmsamples;
} else {
core->output_samples[spkr] = NULL;
}
}
// Handle change of certain filtering parameters
int diff = core->filter_flags ^ flags;
if (diff & (DCADEC_FLAG_CORE_BIT_EXACT | DCADEC_FLAG_CORE_SYNTH_X96)) {
for (int ch = 0; ch < MAX_CHANNELS; ch++) {
ta_free(core->subband_dsp[ch]);
core->subband_dsp[ch] = NULL;
}
}
if (diff & (DCADEC_FLAG_CORE_BIT_EXACT | DCADEC_FLAG_CORE_LFE_IIR))
memset(core->lfe_samples, 0, MAX_LFE_HISTORY * sizeof(int));
if (diff & DCADEC_FLAG_CORE_SYNTH_X96)
core->output_history_lfe = 0;
core->filter_flags = flags;
if (!core->subband_dsp_idct[synth_x96] && !(core->subband_dsp_idct[synth_x96] = idct_init(core, 5 + synth_x96, 0.25)))
return -DCADEC_ENOMEM;
// Filter primary channels
for (int ch = 0; ch < core->nchannels; ch++) {
// Allocate subband DSP
if (!core->subband_dsp[ch] && !(core->subband_dsp[ch] = interpolator_create(core->subband_dsp_idct[synth_x96], flags)))
return -DCADEC_ENOMEM;
// Map this primary channel to speaker
int spkr = map_prm_ch_to_spkr(core, ch);
if (spkr < 0)
return -DCADEC_EINVAL;
// Get the pointer to high frequency subbands for this channel, if present
int **subband_samples_hi;
if (ch < x96_nchannels)
subband_samples_hi = core->x96_subband_samples[ch];
else
subband_samples_hi = NULL;
// Filter bank reconstruction
core->subband_dsp[ch]->interpolate(core->subband_dsp[ch],
core->output_samples[spkr],
core->subband_samples[ch],
subband_samples_hi,
core->npcmblocks,
core->filter_perfect);
}
// Filter LFE channel
if (core->lfe_present) {
bool dec_select = (core->lfe_present == LFE_FLAG_128);
interpolate_lfe_cb interpolate;
// Select LFE DSP
if (flags & DCADEC_FLAG_CORE_BIT_EXACT) {
if (dec_select) {
core_err("Fixed point mode doesn't support LFF=1");
return -DCADEC_EINVAL;
}
interpolate = interpolate_lfe_fixed_fir;
} else if (flags & DCADEC_FLAG_CORE_LFE_IIR) {
interpolate = interpolate_lfe_float_iir;
} else if (dec_select) {
interpolate = interpolate_lfe_float_fir_2x;
} else {
interpolate = interpolate_lfe_float_fir;
}
// Offset output buffer for X96
int *samples = core->output_samples[SPEAKER_LFE1];
if (synth_x96)
samples += core->npcmsamples / 2;
// Interpolation of LFE channel
interpolate(samples, core->lfe_samples, core->npcmblocks, dec_select);
if (synth_x96) {
// Filter 96 kHz oversampled LFE PCM to attenuate high frequency
// (47.6 - 48.0 kHz) components of interpolation image
int history = core->output_history_lfe;
int *samples2 = core->output_samples[SPEAKER_LFE1];
int nsamples = core->npcmsamples / 2;
for (int n = 0; n < nsamples; n++) {
int64_t res1 = INT64_C(2097471) * samples[n] + INT64_C(6291137) * history;
int64_t res2 = INT64_C(6291137) * samples[n] + INT64_C(2097471) * history;
history = samples[n];
samples2[2 * n ] = clip23(norm23(res1));
samples2[2 * n + 1] = clip23(norm23(res2));
}
// Update LFE PCM history
core->output_history_lfe = history;
}
}
if (!(flags & DCADEC_FLAG_KEEP_DMIX_MASK)) {
int nsamples = core->npcmsamples;
// Undo embedded XCH downmix
if (core->es_format && (core->ext_audio_mask & CSS_XCH) && core->audio_mode >= AMODE_2F2R) {
int *samples_ls = core->output_samples[SPEAKER_Ls];
int *samples_rs = core->output_samples[SPEAKER_Rs];
int *samples_cs = core->output_samples[SPEAKER_Cs];
for (int n = 0; n < nsamples; n++) {
int cs = mul23(samples_cs[n], 5931520);
samples_ls[n] = clip23(samples_ls[n] - cs);
samples_rs[n] = clip23(samples_rs[n] - cs);
}
}
// Undo embedded XXCH downmix
if ((core->ext_audio_mask & (CSS_XXCH | EXSS_XXCH)) && core->xxch_dmix_embedded) {
int xch_base = audio_mode_nch[core->audio_mode];
assert(core->nchannels - xch_base <= MAX_CHANNELS_XXCH);
// Undo embedded core downmix pre-scaling
int scale_inv = core->xxch_dmix_scale_inv;
if (scale_inv != (1 << 16)) {
for (int spkr = 0; spkr < core->xxch_mask_nbits; spkr++) {
if (core->xxch_core_mask & (1U << spkr)) {
int *samples = core->output_samples[spkr];
for (int n = 0; n < nsamples; n++)
samples[n] = mul16(samples[n], scale_inv);
}
}
}
// Undo downmix
int *coeff_ptr = core->xxch_dmix_coeff;
for (int ch = xch_base; ch < core->nchannels; ch++) {
int spkr1 = map_prm_ch_to_spkr(core, ch);
if (spkr1 < 0)
return -DCADEC_EINVAL;
for (int spkr2 = 0; spkr2 < core->xxch_mask_nbits; spkr2++) {
if (core->xxch_dmix_mask[ch - xch_base] & (1U << spkr2)) {
int coeff = mul16(*coeff_ptr++, scale_inv);
if (coeff) {
int *src = core->output_samples[spkr1];
int *dst = core->output_samples[spkr2];
for (int n = 0; n < nsamples; n++)
dst[n] -= mul15(src[n], coeff);
}
}
}
}
// Clip core channels
for (int spkr = 0; spkr < core->xxch_mask_nbits; spkr++) {
if (core->xxch_core_mask & (1U << spkr)) {
int *samples = core->output_samples[spkr];
for (int n = 0; n < nsamples; n++)
samples[n] = clip23(samples[n]);
}
}
}
}
if (!(core->ext_audio_mask & (CSS_XXCH | CSS_XCH | EXSS_XXCH))) {
int nsamples = core->npcmsamples;
// Front sum/difference decoding
if ((core->sumdiff_front && core->audio_mode > AMODE_MONO)
|| core->audio_mode == AMODE_STEREO_SUMDIFF) {
int *samples_l = core->output_samples[SPEAKER_L];
int *samples_r = core->output_samples[SPEAKER_R];
for (int n = 0; n < nsamples; n++) {
int res1 = samples_l[n] + samples_r[n];
int res2 = samples_l[n] - samples_r[n];
samples_l[n] = clip23(res1);
samples_r[n] = clip23(res2);
}
}
// Surround sum/difference decoding
if (core->sumdiff_surround && core->audio_mode >= AMODE_2F2R) {
int *samples_ls = core->output_samples[SPEAKER_Ls];
int *samples_rs = core->output_samples[SPEAKER_Rs];
for (int n = 0; n < nsamples; n++) {
int res1 = samples_ls[n] + samples_rs[n];
int res2 = samples_ls[n] - samples_rs[n];
samples_ls[n] = clip23(res1);
samples_rs[n] = clip23(res2);
}
}
}
return 0;
}
static int parse_xch_frame(struct core_decoder *core)
{
if (core->ch_mask & SPEAKER_MASK_Cs) {
core_err("XCH with Cs speaker already present");
return -DCADEC_EBADDATA;
}
int ret;
if ((ret = parse_frame_data(core, HEADER_XCH, core->nchannels)) < 0)
return ret;
// Seek to the end of core frame, don't trust XCH frame size
return bits_seek(&core->bits, core->frame_size * 8);
}
static int parse_xxch_frame(struct core_decoder *core)
{
int header_pos = core->bits.index;
// XXCH sync word
if (bits_get(&core->bits, 32) != SYNC_WORD_XXCH) {
core_err("Invalid XXCH sync word");
return -DCADEC_ENOSYNC;
}
// XXCH frame header length
int header_size = bits_get(&core->bits, 6) + 1;
// Check XXCH frame header CRC
int ret;
if ((ret = bits_check_crc(&core->bits, header_pos + 32, header_pos + header_size * 8)) < 0) {
core_err("Invalid XXCH frame header checksum");
return ret;
}
// CRC presence flag for channel set header
core->xxch_crc_present = bits_get1(&core->bits);
// Number of bits for loudspeaker mask
core->xxch_mask_nbits = bits_get(&core->bits, 5) + 1;
if (core->xxch_mask_nbits <= SPEAKER_Cs) {
core_err("Invalid number of bits for XXCH speaker mask (%d)", core->xxch_mask_nbits);
return -DCADEC_EBADDATA;
}
// Number of channel sets
int xxch_nchsets = bits_get(&core->bits, 2) + 1;
if (xxch_nchsets > 1) {
core_err_once("Unsupported number of XXCH channel sets (%d)", xxch_nchsets);
return -DCADEC_ENOSUP;
}
// Channel set 0 data byte size
int xxch_frame_size = bits_get(&core->bits, 14) + 1;
// Core loudspeaker activity mask
core->xxch_core_mask = bits_get(&core->bits, core->xxch_mask_nbits);
// Validate the core mask
int mask = core->ch_mask;
if ((mask & SPEAKER_MASK_Ls) && (core->xxch_core_mask & SPEAKER_MASK_Lss))
mask = (mask & ~SPEAKER_MASK_Ls) | SPEAKER_MASK_Lss;
if ((mask & SPEAKER_MASK_Rs) && (core->xxch_core_mask & SPEAKER_MASK_Rss))
mask = (mask & ~SPEAKER_MASK_Rs) | SPEAKER_MASK_Rss;
if (mask != core->xxch_core_mask) {
core_err("XXCH core speaker activity mask (%#x) disagrees "
"with core (%#x)", core->xxch_core_mask, mask);
return -DCADEC_EBADDATA;
}
// Reserved
// Byte align
// CRC16 of XXCH frame header
if ((ret = bits_seek(&core->bits, header_pos + header_size * 8)) < 0) {
core_err("Read past end of XXCH frame header");
return ret;
}
// Parse XXCH channel set 0
if ((ret = parse_frame_data(core, HEADER_XXCH, core->nchannels)) < 0)
return ret;
if ((ret = bits_seek(&core->bits, header_pos + header_size * 8 + xxch_frame_size * 8)) < 0)
core_err("Read past end of XXCH channel set");
return ret;
}
static int parse_xbr_subframe(struct core_decoder *core, int xbr_base_ch, int xbr_nchannels,
int *xbr_nsubbands, bool xbr_transition_mode, int sf, int *sub_pos)
{
int xbr_nabits[MAX_CHANNELS];
int xbr_bit_allocation[MAX_CHANNELS][MAX_SUBBANDS];
int xbr_scale_nbits[MAX_CHANNELS];
int xbr_scale_factors[MAX_CHANNELS][MAX_SUBBANDS][2];
int ssf, ch, band, ofs;
// Number of subband samples in this subframe
int nsamples = core->nsubsubframes[sf] * NUM_SUBBAND_SAMPLES;
if (*sub_pos + nsamples > core->npcmblocks) {
core_err("Subband sample buffer overflow");
return -DCADEC_EBADDATA;
}
// Number of bits for XBR bit allocation index
for (ch = xbr_base_ch; ch < xbr_nchannels; ch++)
xbr_nabits[ch] = bits_get(&core->bits, 2) + 2;
// XBR bit allocation index
for (ch = xbr_base_ch; ch < xbr_nchannels; ch++)
for (band = 0; band < xbr_nsubbands[ch]; band++)
xbr_bit_allocation[ch][band] = bits_get(&core->bits, xbr_nabits[ch]);
// Number of bits for scale indices
for (ch = xbr_base_ch; ch < xbr_nchannels; ch++) {
xbr_scale_nbits[ch] = bits_get(&core->bits, 3);
if (!xbr_scale_nbits[ch]) {
core_err("Invalid number of bits for XBR scale factor index");
return -DCADEC_EBADDATA;
}
}
// XBR scale factors
for (ch = xbr_base_ch; ch < xbr_nchannels; ch++) {
// Select the root square table
const int32_t *scale_table;
size_t scale_size;
if (core->scale_factor_sel[ch] > 5) {
scale_table = scale_factors_7bit;
scale_size = dca_countof(scale_factors_7bit);
} else {
scale_table = scale_factors_6bit;
scale_size = dca_countof(scale_factors_6bit);
}
// Parse scale factor indices
// Look up scale factors from the root square table
for (band = 0; band < xbr_nsubbands[ch]; band++) {
if (xbr_bit_allocation[ch][band] > 0) {
unsigned int scale_index = bits_get(&core->bits, xbr_scale_nbits[ch]);
if (scale_index >= scale_size) {
core_err("Invalid XBR scale factor index");
return -DCADEC_EBADDATA;
}
xbr_scale_factors[ch][band][0] = scale_table[scale_index];
if (xbr_transition_mode && core->transition_mode[sf][ch][band]) {
scale_index = bits_get(&core->bits, xbr_scale_nbits[ch]);
if (scale_index >= scale_size) {
core_err("Invalid XBR scale factor index");
return -DCADEC_EBADDATA;
}
xbr_scale_factors[ch][band][1] = scale_table[scale_index];
}
}
}
}
// Audio data
for (ssf = 0, ofs = *sub_pos; ssf < core->nsubsubframes[sf]; ssf++) {
for (ch = xbr_base_ch; ch < xbr_nchannels; ch++) {
for (band = 0; band < xbr_nsubbands[ch]; band++) {
int abits = xbr_bit_allocation[ch][band];
int audio[NUM_SUBBAND_SAMPLES];
int ret, step_size, trans_ssf, scale;
// Extract bits from the bit stream
if (abits > 7) {
// No further encoding
bits_get_signed_array(&core->bits, audio, NUM_SUBBAND_SAMPLES, abits - 3);
} else if (abits > 0) {
// Block codes
if ((ret = parse_block_codes(core, audio, abits)) < 0)
return ret;
} else {
// No bits allocated
continue;
}
// Look up quantization step size
step_size = step_size_lossless[abits];
// Identify transient location
if (xbr_transition_mode)
trans_ssf = core->transition_mode[sf][ch][band];
else
trans_ssf = 0;
// Determine proper scale factor
if (trans_ssf == 0 || ssf < trans_ssf)
scale = xbr_scale_factors[ch][band][0];
else
scale = xbr_scale_factors[ch][band][1];
dequantize(core->subband_samples[ch][band] + ofs,
audio, step_size, scale, true);
}
}
// DSYNC
if ((ssf == core->nsubsubframes[sf] - 1 || core->sync_ssf)
&& bits_get(&core->bits, 16) != 0xffff) {
core_err("XBR-DSYNC check failed");
return -DCADEC_EBADDATA;
}
ofs += NUM_SUBBAND_SAMPLES;
}
// Advance subband sample pointer for the next subframe
*sub_pos += nsamples;
return 0;
}
static int parse_xbr_frame(struct core_decoder *core)
{
int xbr_frame_size[MAX_EXSS_CHSETS];
int xbr_nchannels[MAX_EXSS_CHSETS];
int xbr_nsubbands[MAX_EXSS_CHSETS * MAX_CHANNELS_CHSET];
int header_pos = core->bits.index;
// XBR sync word
if (bits_get(&core->bits, 32) != SYNC_WORD_XBR) {
core_err("Invalid XBR sync word");
return -DCADEC_ENOSYNC;
}
// XBR frame header length
int header_size = bits_get(&core->bits, 6) + 1;
// Check XBR frame header CRC
int ret;
if ((ret = bits_check_crc(&core->bits, header_pos + 32, header_pos + header_size * 8)) < 0) {
core_err("Invalid XBR frame header checksum");
return ret;
}
// Number of channel sets
int xbr_nchsets = bits_get(&core->bits, 2) + 1;
// Channel set data byte size
for (int i = 0; i < xbr_nchsets; i++)
xbr_frame_size[i] = bits_get(&core->bits, 14) + 1;
// Transition mode flag
bool xbr_transition_mode = bits_get1(&core->bits);
// Channel set headers
for (int i = 0, ch2 = 0; i < xbr_nchsets; i++) {
xbr_nchannels[i] = bits_get(&core->bits, 3) + 1;
int xbr_band_nbits = bits_get(&core->bits, 2) + 5;
for (int ch1 = 0; ch1 < xbr_nchannels[i]; ch1++, ch2++) {
xbr_nsubbands[ch2] = bits_get(&core->bits, xbr_band_nbits) + 1;
if (xbr_nsubbands[ch2] > MAX_SUBBANDS) {
core_err("Invalid number of active XBR subbands (%d)", xbr_nsubbands[ch2]);
return -DCADEC_EBADDATA;
}
}
}
// Reserved
// Byte align
// CRC16 of XBR frame header
if ((ret = bits_seek(&core->bits, header_pos + header_size * 8)) < 0) {
core_err("Read past end of XBR frame header");
return ret;
}
// Channel set data
int xbr_base_ch = 0;
for (int i = 0; i < xbr_nchsets; i++) {
header_pos = core->bits.index;
if (xbr_base_ch + xbr_nchannels[i] <= core->nchannels) {
int sub_pos = 0;
for (int sf = 0; sf < core->nsubframes; sf++) {
if ((ret = parse_xbr_subframe(core, xbr_base_ch,
xbr_base_ch + xbr_nchannels[i],
xbr_nsubbands, xbr_transition_mode,
sf, &sub_pos)) < 0)
return ret;
}
}
xbr_base_ch += xbr_nchannels[i];
if ((ret = bits_seek(&core->bits, header_pos + xbr_frame_size[i] * 8)) < 0) {
core_err("Read past end of XBR channel set");
return ret;
}
}
return 0;
}
// Modified ISO/IEC 9899 linear congruential generator
// Returns pseudorandom integer in range [-2^30, 2^30 - 1]
static int rand_x96(struct core_decoder *core)
{
core->x96_rand = 1103515245U * core->x96_rand + 12345U;
return (core->x96_rand & 0x7fffffff) - 0x40000000;
}
static int parse_x96_subframe_audio(struct core_decoder *core, int sf, int xch_base, int *sub_pos)
{
int ssf, ch, band, ofs;
// Number of subband samples in this subframe
int nsamples = core->nsubsubframes[sf] * NUM_SUBBAND_SAMPLES;
if (*sub_pos + nsamples > core->npcmblocks) {
core_err("Subband sample buffer overflow");
return -DCADEC_EBADDATA;
}
// VQ encoded or unallocated subbands
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
for (band = core->x96_subband_start; band < core->nsubbands[ch]; band++) {
// Get the sample pointer
int *samples = core->x96_subband_samples[ch][band] + *sub_pos;
// Get the scale factor
int scale = core->x96_scale_factors[ch][band];
int abits = core->bit_allocation[ch][band];
if (abits == 0) { // No bits allocated for subband
if (scale <= 1) {
memset(samples, 0, nsamples * sizeof(int));
} else {
// Generate scaled random samples as required by specification
for (int n = 0; n < nsamples; n++)
samples[n] = mul31(rand_x96(core), scale);
}
} else if (abits == 1) { // VQ encoded subband
for (ssf = 0; ssf < (core->nsubsubframes[sf] + 1) / 2; ssf++) {
// Extract the VQ address from the bit stream
int vq_index = bits_get(&core->bits, 10);
// Look up the VQ code book for up to 16 subband samples
const int8_t *vq_samples = high_freq_samples[vq_index];
// Number of VQ samples to look up
int vq_nsamples = DCA_MIN(nsamples - ssf * 16, 16);
// Scale and take the samples
for (int n = 0; n < vq_nsamples; n++)
*samples++ = clip23(mul4(scale, vq_samples[n]));
}
}
}
}
// Audio data
for (ssf = 0, ofs = *sub_pos; ssf < core->nsubsubframes[sf]; ssf++) {
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
for (band = core->x96_subband_start; band < core->nsubbands[ch]; band++) {
int abits = core->bit_allocation[ch][band] - 1;
int audio[NUM_SUBBAND_SAMPLES];
int ret, step_size, scale;
// Not VQ encoded or unallocated subbands
if (abits < 1)
continue;
// Extract bits from the bit stream
if ((ret = extract_audio(core, audio, abits, ch)) < 0)
return ret;
// Select quantization step size table
// Look up quantization step size
if (core->bit_rate == -2)
step_size = step_size_lossless[abits];
else
step_size = step_size_lossy[abits];
// Determine proper scale factor
scale = core->x96_scale_factors[ch][band];
dequantize(core->x96_subband_samples[ch][band] + ofs,
audio, step_size, scale, false);
}
}
// DSYNC
if ((ssf == core->nsubsubframes[sf] - 1 || core->sync_ssf)
&& bits_get(&core->bits, 16) != 0xffff) {
core_err("X96-DSYNC check failed");
return -DCADEC_EBADDATA;
}
ofs += NUM_SUBBAND_SAMPLES;
}
// Inverse ADPCM
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
for (band = core->x96_subband_start; band < core->nsubbands[ch]; band++) {
// Only if prediction mode is on
if (core->prediction_mode[ch][band]) {
int *samples = core->x96_subband_samples[ch][band] + *sub_pos;
// Extract the VQ index
int vq_index = core->prediction_vq_index[ch][band];
// Look up the VQ table for prediction coefficients
const int16_t *vq_coeffs = adpcm_coeffs[vq_index];
for (int m = 0; m < nsamples; m++) {
int64_t err = INT64_C(0);
for (int n = 0; n < NUM_ADPCM_COEFFS; n++)
err += (int64_t)samples[m - n - 1] * vq_coeffs[n];
samples[m] = clip23(samples[m] + clip23(norm13(err)));
}
}
}
}
// Joint subband coding
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
// Only if joint subband coding is enabled
if (core->joint_intensity_index[ch]) {
// Get source channel
int src_ch = core->joint_intensity_index[ch] - 1;
for (band = core->nsubbands[ch]; band < core->nsubbands[src_ch]; band++) {
int *src = core->x96_subband_samples[src_ch][band] + *sub_pos;
int *dst = core->x96_subband_samples[ ch][band] + *sub_pos;
int scale = core->joint_scale_factors[ch][band];
for (int n = 0; n < nsamples; n++)
dst[n] = clip23(mul17(src[n], scale));
}
}
}
// Advance subband sample pointer for the next subframe
*sub_pos += nsamples;
return 0;
}
static void erase_x96_adpcm_history(struct core_decoder *core)
{
// Erase ADPCM history from previous frame if
// predictor history switch was disabled
for (int ch = 0; ch < MAX_CHANNELS; ch++)
for (int band = 0; band < MAX_SUBBANDS_X96; band++)
memset(core->x96_subband_samples[ch][band] - NUM_ADPCM_COEFFS, 0, NUM_ADPCM_COEFFS * sizeof(int));
}
static int alloc_x96_sample_buffer(struct core_decoder *core)
{
int nchsamples = NUM_ADPCM_COEFFS + core->npcmblocks;
int nframesamples = nchsamples * MAX_CHANNELS * MAX_SUBBANDS_X96;
// Reallocate subband sample buffer
int ret;
if ((ret = ta_zalloc_fast(core, &core->x96_subband_buffer, nframesamples, sizeof(int))) < 0)
return -DCADEC_ENOMEM;
if (ret > 0) {
for (int ch = 0; ch < MAX_CHANNELS; ch++)
for (int band = 0; band < MAX_SUBBANDS_X96; band++)
core->x96_subband_samples[ch][band] = core->x96_subband_buffer +
(ch * MAX_SUBBANDS_X96 + band) * nchsamples + NUM_ADPCM_COEFFS;
}
if (!core->predictor_history)
erase_x96_adpcm_history(core);
return 0;
}
static int parse_x96_subframe_header(struct core_decoder *core, int xch_base)
{
int ch, band, ret;
// Prediction mode
for (ch = xch_base; ch < core->x96_nchannels; ch++)
for (band = core->x96_subband_start; band < core->nsubbands[ch]; band++)
core->prediction_mode[ch][band] = bits_get1(&core->bits);
// Prediction coefficients VQ address
for (ch = xch_base; ch < core->x96_nchannels; ch++)
for (band = core->x96_subband_start; band < core->nsubbands[ch]; band++)
if (core->prediction_mode[ch][band])
core->prediction_vq_index[ch][band] = bits_get(&core->bits, 12);
// Bit allocation index
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
// Select codebook
int sel = core->bit_allocation_sel[ch];
const struct huffman *huff;
unsigned int abits_max;
// Reuse quantization index code books for bit allocation index
if (core->x96_high_res) {
huff = &quant_index_huff_7[sel];
abits_max = 15;
} else {
huff = &quant_index_huff_5[sel];
abits_max = 7;
}
// Clear accumulation
int abits = 0;
for (band = core->x96_subband_start; band < core->nsubbands[ch]; band++) {
if (sel < 7)
// If Huffman code was used, the difference of abits was encoded
abits += bits_get_signed_vlc(&core->bits, huff);
else
abits = bits_get(&core->bits, 3 + core->x96_high_res);
if ((unsigned int)abits > abits_max) {
core_err("Invalid X96 bit allocation index");
return -DCADEC_EBADDATA;
}
core->bit_allocation[ch][band] = abits;
}
}
// Scale factors
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
// Select codebook
int sel = core->scale_factor_sel[ch];
// Clear accumulation
int scale_index = 0;
// Extract scales for subbands
// Transmitted even for unallocated subbands
for (band = core->x96_subband_start; band < core->nsubbands[ch]; band++) {
if ((ret = parse_scale(core, &scale_index, sel)) < 0)
return ret;
core->x96_scale_factors[ch][band] = ret;
}
}
// Joint subband codebook select
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
// Only if joint subband coding is enabled
if (core->joint_intensity_index[ch]) {
core->joint_scale_sel[ch] = bits_get(&core->bits, 3);
if (core->joint_scale_sel[ch] == 7) {
core_err("Invalid X96 joint scale factor code book");
return -DCADEC_EBADDATA;
}
}
}
// Scale factors for joint subband coding
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
// Only if joint subband coding is enabled
if (core->joint_intensity_index[ch]) {
// Select codebook
int sel = core->joint_scale_sel[ch];
// Get source channel
int src_ch = core->joint_intensity_index[ch] - 1;
for (band = core->nsubbands[ch]; band < core->nsubbands[src_ch]; band++) {
if ((ret = parse_joint_scale(core, sel)) < 0)
return ret;
core->joint_scale_factors[ch][band] = ret;
}
}
}
// Side information CRC check word
if (core->crc_present)
bits_skip(&core->bits, 16);
return 0;
}
static int parse_x96_coding_header(struct core_decoder *core, bool exss, int xch_base)
{
int ch, n, ret, header_size = 0, header_pos = core->bits.index;
if (exss) {
// Channel set header length
header_size = bits_get(&core->bits, 7) + 1;
// Check CRC
if (core->x96_crc_present && (ret = bits_check_crc(&core->bits, header_pos, header_pos + header_size * 8)) < 0) {
core_err("Invalid X96 channel set header checksum");
return ret;
}
}
// High resolution flag
core->x96_high_res = bits_get1(&core->bits);
// First encoded subband
if (core->x96_rev_no < 8) {
core->x96_subband_start = bits_get(&core->bits, 5);
if (core->x96_subband_start > 27) {
core_err("Invalid X96 subband start index (%d)", core->x96_subband_start);
return -DCADEC_EBADDATA;
}
} else {
core->x96_subband_start = MAX_SUBBANDS;
}
// Subband activity count
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
core->nsubbands[ch] = bits_get(&core->bits, 6) + 1;
if (core->nsubbands[ch] < MAX_SUBBANDS) {
core_err("Invalid X96 subband activity count (%d)", core->nsubbands[ch]);
return -DCADEC_EBADDATA;
}
}
// Joint intensity coding index
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
if ((n = bits_get(&core->bits, 3)) && xch_base)
n += xch_base - 1;
if (n > core->x96_nchannels) {
core_err("Invalid X96 joint intensity coding index");
return -DCADEC_EBADDATA;
}
core->joint_intensity_index[ch] = n;
}
// Scale factor code book
for (ch = xch_base; ch < core->x96_nchannels; ch++) {
core->scale_factor_sel[ch] = bits_get(&core->bits, 3);
if (core->scale_factor_sel[ch] >= 6) {
core_err("Invalid X96 scale factor code book");
return -DCADEC_EBADDATA;
}
}
// Bit allocation quantizer select
for (ch = xch_base; ch < core->x96_nchannels; ch++)
core->bit_allocation_sel[ch] = bits_get(&core->bits, 3);
// Quantization index codebook select
for (n = 0; n < 6 + 4 * core->x96_high_res; n++)
for (ch = xch_base; ch < core->x96_nchannels; ch++)
core->quant_index_sel[ch][n] = bits_get(&core->bits, quant_index_sel_nbits[n]);
if (exss) {
// Reserved
// Byte align
// CRC16 of channel set header
if ((ret = bits_seek(&core->bits, header_pos + header_size * 8)) < 0) {
core_err("Read past end of X96 channel set header");
return ret;
}
} else {
if (core->crc_present)
bits_skip(&core->bits, 16);
}
return 0;
}
static int parse_x96_frame_data(struct core_decoder *core, bool exss, int xch_base)
{
int ret;
if ((ret = parse_x96_coding_header(core, exss, xch_base)) < 0)
return ret;
int sub_pos = 0;
for (int sf = 0; sf < core->nsubframes; sf++) {
if ((ret = parse_x96_subframe_header(core, xch_base)) < 0)
return ret;
if ((ret = parse_x96_subframe_audio(core, sf, xch_base, &sub_pos)) < 0)
return ret;
}
for (int ch = xch_base; ch < core->x96_nchannels; ch++) {
// Number of active subbands for this channel
int nsubbands = core->nsubbands[ch];
if (core->joint_intensity_index[ch])
nsubbands = DCA_MAX(nsubbands, core->nsubbands[core->joint_intensity_index[ch] - 1]);
// Update history for ADPCM
// Clear inactive subbands
for (int band = 0; band < MAX_SUBBANDS_X96; band++) {
int *samples = core->x96_subband_samples[ch][band] - NUM_ADPCM_COEFFS;
if (band >= core->x96_subband_start && band < nsubbands)
memcpy(samples, samples + core->npcmblocks, NUM_ADPCM_COEFFS * sizeof(int));
else
memset(samples, 0, (NUM_ADPCM_COEFFS + core->npcmblocks) * sizeof(int));
}
}
return 0;
}
static int parse_x96_frame(struct core_decoder *core)
{
// Revision number
core->x96_rev_no = bits_get(&core->bits, 4);
if (core->x96_rev_no < 1 || core->x96_rev_no > 8) {
core_err_once("Unsupported X96 revision (%d)", core->x96_rev_no);
return -DCADEC_ENOSUP;
}
core->x96_crc_present = false;
core->x96_nchannels = core->nchannels;
int ret;
if ((ret = alloc_x96_sample_buffer(core)) < 0)
return ret;
if ((ret = parse_x96_frame_data(core, false, 0)) < 0)
return ret;
// Seek to the end of core frame
return bits_seek(&core->bits, core->frame_size * 8);
}
static int parse_x96_frame_exss(struct core_decoder *core)
{
int x96_frame_size[MAX_EXSS_CHSETS];
int x96_nchannels[MAX_EXSS_CHSETS];
int header_pos = core->bits.index;
// X96 sync word
if (bits_get(&core->bits, 32) != SYNC_WORD_X96) {
core_err("Invalid X96 sync word");
return -DCADEC_ENOSYNC;
}
// X96 frame header length
int header_size = bits_get(&core->bits, 6) + 1;
// Check X96 frame header CRC
int ret;
if ((ret = bits_check_crc(&core->bits, header_pos + 32, header_pos + header_size * 8)) < 0) {
core_err("Invalid X96 frame header checksum");
return ret;
}
// Revision number
core->x96_rev_no = bits_get(&core->bits, 4);
if (core->x96_rev_no < 1 || core->x96_rev_no > 8) {
core_err_once("Unsupported X96 revision (%d)", core->x96_rev_no);
return -DCADEC_ENOSUP;
}
// CRC presence flag for channel set header
core->x96_crc_present = bits_get1(&core->bits);
// Number of channel sets
int x96_nchsets = bits_get(&core->bits, 2) + 1;
// Channel set data byte size
for (int i = 0; i < x96_nchsets; i++)
x96_frame_size[i] = bits_get(&core->bits, 12) + 1;
// Number of channels in channel set
for (int i = 0; i < x96_nchsets; i++)
x96_nchannels[i] = bits_get(&core->bits, 3) + 1;
// Reserved
// Byte align
// CRC16 of X96 frame header
if ((ret = bits_seek(&core->bits, header_pos + header_size * 8)) < 0) {
core_err("Read past end of X96 frame header");
return ret;
}
if ((ret = alloc_x96_sample_buffer(core)) < 0)
return ret;
core->x96_nchannels = 0;
// Channel set data
int x96_base_ch = 0;
for (int i = 0; i < x96_nchsets; i++) {
header_pos = core->bits.index;
if (x96_base_ch + x96_nchannels[i] <= core->nchannels) {
core->x96_nchannels = x96_base_ch + x96_nchannels[i];
if ((ret = parse_x96_frame_data(core, true, x96_base_ch)) < 0)
return ret;
}
x96_base_ch += x96_nchannels[i];
if ((ret = bits_seek(&core->bits, header_pos + x96_frame_size[i] * 8)) < 0) {
core_err("Read past end of X96 channel set");
return ret;
}
}
return 0;
}
static int parse_aux_data(struct core_decoder *core)
{
// Auxiliary data byte count (can't be trusted)
bits_skip(&core->bits, 6);
// 4-byte align
int aux_pos = bits_align4(&core->bits);
// Auxiliary data sync word
uint32_t sync = bits_get(&core->bits, 32);
if (sync != SYNC_WORD_REV1AUX) {
core_err("Invalid auxiliary data sync word (%#x)", sync);
return -DCADEC_ENOSYNC;
}
// Auxiliary decode time stamp flag
if (bits_get1(&core->bits)) {
bits_skip(&core->bits, 3); // 4-bit align
bits_skip(&core->bits, 8); // MSB
bits_skip(&core->bits, 4); // Marker
bits_skip(&core->bits, 28); // LSB
bits_skip(&core->bits, 4); // Marker
}
// Auxiliary dynamic downmix flag
core->prim_dmix_embedded = bits_get1(&core->bits);
if (core->prim_dmix_embedded) {
// Auxiliary primary channel downmix type
core->prim_dmix_type = bits_get(&core->bits, 3);
if (core->prim_dmix_type >= DMIX_TYPE_COUNT) {
core_err("Invalid primary channel set downmix type");
return -DCADEC_EBADDATA;
}
// Size of downmix coefficients matrix
int m = dmix_primary_nch[core->prim_dmix_type];
int n = audio_mode_nch[core->audio_mode] + !!core->lfe_present;
// Dynamic downmix code coefficients
int *coeff_ptr = core->prim_dmix_coeff;
for (int i = 0; i < m * n; i++) {
int code = bits_get(&core->bits, 9);
int sign = (code >> 8) - 1;
if (code &= 0xff) {
unsigned int index = code - 1;
if (index >= dca_countof(dmix_table)) {
core_err("Invalid downmix coefficient index");
return -DCADEC_EBADDATA;
}
*coeff_ptr++ = (dmix_table[index] ^ sign) - sign;
} else {
*coeff_ptr++ = 0;
}
}
}
// Byte align
bits_align1(&core->bits);
// CRC16 of auxiliary data
bits_skip(&core->bits, 16);
// Check CRC
int ret;
if ((ret = bits_check_crc(&core->bits, aux_pos + 32, core->bits.index)) < 0)
core_err("Invalid auxiliary data checksum");
return ret;
}
#define CHECK_SYNC(pos, msg) \
if (!pos) { \
if (flags & DCADEC_FLAG_STRICT) { \
core_err(msg); \
return -DCADEC_ENOSYNC; \
} \
core_warn_once(msg); \
status = DCADEC_WCOREEXTFAILED; \
}
static int parse_optional_info(struct core_decoder *core, int flags)
{
int status = 0;
// Time code stamp
if (core->ts_present)
bits_skip(&core->bits, 32);
// Auxiliary data
if (core->aux_present && (flags & DCADEC_FLAG_KEEP_DMIX_2CH)) {
int ret;
if ((ret = parse_aux_data(core)) < 0) {
if (flags & DCADEC_FLAG_STRICT)
return ret;
status = DCADEC_WCOREAUXFAILED;
core->prim_dmix_embedded = false;
}
} else {
core->prim_dmix_embedded = false;
}
// Core extensions
if (core->ext_audio_present && !(flags & DCADEC_FLAG_CORE_ONLY)) {
int sync_pos = DCA_MIN(core->frame_size / 4, core->bits.total / 32) - 1;
int last_pos = core->bits.index / 32;
// Search for extension sync words aligned on 4-byte boundary
switch (core->ext_audio_type) {
case EXT_AUDIO_XCH:
if (flags & DCADEC_FLAG_KEEP_DMIX_MASK)
break;
// The distance between XCH sync word and end of the core frame
// must be equal to XCH frame size. Off by one error is allowed for
// compatibility with legacy bitstreams. Minimum XCH frame size is
// 96 bytes. AMODE and PCHS are further checked to reduce
// probability of alias sync detection.
for (; sync_pos >= last_pos; sync_pos--) {
if (core->bits.data[sync_pos] == DCA_32BE_C(SYNC_WORD_XCH)) {
core->bits.index = (sync_pos + 1) * 32;
int frame_size = bits_get(&core->bits, 10) + 1;
int dist = core->frame_size - sync_pos * 4;
if (frame_size >= 96
&& (frame_size == dist || frame_size - 1 == dist)
&& bits_get(&core->bits, 7) == 0x08) {
core->xch_pos = core->bits.index;
break;
}
}
}
CHECK_SYNC(core->xch_pos, "XCH sync word not found")
break;
case EXT_AUDIO_X96:
// The distance between X96 sync word and end of the core frame
// must be equal to X96 frame size. Minimum X96 frame size is 96
// bytes.
for (; sync_pos >= last_pos; sync_pos--) {
if (core->bits.data[sync_pos] == DCA_32BE_C(SYNC_WORD_X96)) {
core->bits.index = (sync_pos + 1) * 32;
int frame_size = bits_get(&core->bits, 12) + 1;
int dist = core->frame_size - sync_pos * 4;
if (frame_size >= 96 && frame_size == dist) {
core->x96_pos = core->bits.index;
break;
}
}
}
CHECK_SYNC(core->x96_pos, "X96 sync word not found")
break;
case EXT_AUDIO_XXCH:
if (flags & DCADEC_FLAG_KEEP_DMIX_MASK)
break;
// XXCH frame header CRC must be valid. Minimum XXCH frame header
// size is 11 bytes.
for (; sync_pos >= last_pos; sync_pos--) {
if (core->bits.data[sync_pos] == DCA_32BE_C(SYNC_WORD_XXCH)) {
core->bits.index = (sync_pos + 1) * 32;
int hdr_size = bits_get(&core->bits, 6) + 1;
if (hdr_size >= 11 &&
!bits_check_crc(&core->bits, (sync_pos + 1) * 32,
sync_pos * 32 + hdr_size * 8)) {
core->xxch_pos = sync_pos * 32;
break;
}
}
}
CHECK_SYNC(core->xxch_pos, "XXCH sync word not found")
break;
default:
core_warn_once("Stream with unknown extended audio type (%d)",
core->ext_audio_type);
break;
}
}
return status;
}
int core_parse(struct core_decoder *core, uint8_t *data, int size,
int flags, struct exss_asset *asset)
{
core->ext_audio_mask = 0;
core->xch_pos = core->xxch_pos = core->x96_pos = 0;
if (asset) {
bits_init(&core->bits, data + asset->core_offset, asset->core_size);
if (bits_get(&core->bits, 32) != SYNC_WORD_CORE_EXSS)
return -DCADEC_ENOSYNC;
} else {
bits_init(&core->bits, data, size);
bits_skip(&core->bits, 32);
}
int status = 0, ret;
if ((ret = parse_frame_header(core)) < 0)
return ret;
if ((ret = alloc_sample_buffer(core)) < 0)
return ret;
if ((ret = parse_frame_data(core, HEADER_CORE, 0)) < 0)
return ret;
if ((ret = parse_optional_info(core, flags)) < 0)
return ret;
if (ret > 0)
status = ret;
// Workaround for DTS in WAV
if (!asset && core->frame_size > size && core->frame_size < size + 4) {
core_warn_once("Stream with excessive core frame size");
core->frame_size = size;
}
if ((ret = bits_seek(&core->bits, core->frame_size * 8)) < 0)
return ret;
return status;
}
int core_parse_exss(struct core_decoder *core, uint8_t *data,
int flags, struct exss_asset *asset)
{
struct bitstream temp = core->bits;
int exss_mask = asset ? asset->extension_mask : 0;
int status = 0, ret = 0, ext = 0;
// Parse (X)XCH unless downmixing
if (!(flags & DCADEC_FLAG_KEEP_DMIX_MASK)) {
if (exss_mask & EXSS_XXCH) {
bits_init(&core->bits, data + asset->xxch_offset, asset->xxch_size);
ret = parse_xxch_frame(core);
ext = EXSS_XXCH;
} else if (core->xxch_pos) {
core->bits.index = core->xxch_pos;
ret = parse_xxch_frame(core);
ext = CSS_XXCH;
} else if (core->xch_pos) {
core->bits.index = core->xch_pos;
ret = parse_xch_frame(core);
ext = CSS_XCH;
}
// Revert to primary channel set in case (X)XCH parsing fails
if (ret < 0) {
if (flags & DCADEC_FLAG_STRICT)
return ret;
status = DCADEC_WCOREEXTFAILED;
core->nchannels = audio_mode_nch[core->audio_mode];
core->ch_mask = audio_mode_ch_mask[core->audio_mode];
if (core->lfe_present)
core->ch_mask |= SPEAKER_MASK_LFE1;
} else {
core->ext_audio_mask |= ext;
}
}
// Parse XBR
if (exss_mask & EXSS_XBR) {
bits_init(&core->bits, data + asset->xbr_offset, asset->xbr_size);
if ((ret = parse_xbr_frame(core)) < 0) {
if (flags & DCADEC_FLAG_STRICT)
return ret;
status = DCADEC_WCOREEXTFAILED;
} else {
core->ext_audio_mask |= EXSS_XBR;
}
}
// Parse X96
if (exss_mask & EXSS_X96) {
bits_init(&core->bits, data + asset->x96_offset, asset->x96_size);
if ((ret = parse_x96_frame_exss(core)) < 0) {
if (flags & DCADEC_FLAG_STRICT)
return ret;
status = DCADEC_WCOREEXTFAILED;
} else {
core->ext_audio_mask |= EXSS_X96;
}
} else if (core->x96_pos) {
core->bits = temp;
core->bits.index = core->x96_pos;
if ((ret = parse_x96_frame(core)) < 0) {
if (flags & DCADEC_FLAG_STRICT)
return ret;
status = DCADEC_WCOREEXTFAILED;
} else {
core->ext_audio_mask |= CSS_X96;
}
}
return status;
}
void core_clear(struct core_decoder *core)
{
if (core) {
if (core->subband_buffer) {
erase_adpcm_history(core);
memset(core->lfe_samples, 0, MAX_LFE_HISTORY * sizeof(int));
}
if (core->x96_subband_buffer)
erase_x96_adpcm_history(core);
for (int ch = 0; ch < MAX_CHANNELS; ch++)
interpolator_clear(core->subband_dsp[ch]);
core->output_history_lfe = 0;
}
}
struct dcadec_core_info *core_get_info(struct core_decoder *core)
{
struct dcadec_core_info *info = ta_znew(NULL, struct dcadec_core_info);
if (!info)
return NULL;
info->nchannels = audio_mode_nch[core->audio_mode];
info->audio_mode = core->audio_mode;
info->lfe_present = core->lfe_present;
info->sample_rate = core->sample_rate;
info->source_pcm_res = core->source_pcm_res;
info->es_format = core->es_format;
info->bit_rate = core->bit_rate;
info->npcmblocks = core->npcmblocks;
info->ext_audio_present = core->ext_audio_present;
info->ext_audio_type = core->ext_audio_type;
return info;
}
static int make_spkr_pair_mask(int mask1)
{
int mask2 = 0;
#define MAP(m1, m2) if ((mask1 & (m1)) == (m1)) mask2 |= (m2);
MAP(SPEAKER_MASK_C, SPEAKER_PAIR_C)
MAP(SPEAKER_MASK_L | SPEAKER_MASK_R, SPEAKER_PAIR_LR)
MAP(SPEAKER_MASK_Ls | SPEAKER_MASK_Rs, SPEAKER_PAIR_LsRs)
MAP(SPEAKER_MASK_LFE1, SPEAKER_PAIR_LFE1)
MAP(SPEAKER_MASK_Cs, SPEAKER_PAIR_Cs)
MAP(SPEAKER_MASK_Lh | SPEAKER_MASK_Rh, SPEAKER_PAIR_LhRh)
MAP(SPEAKER_MASK_Lsr | SPEAKER_MASK_Rsr, SPEAKER_PAIR_LsrRsr)
MAP(SPEAKER_MASK_Ch, SPEAKER_PAIR_Ch)
MAP(SPEAKER_MASK_Oh, SPEAKER_PAIR_Oh)
MAP(SPEAKER_MASK_Lc | SPEAKER_MASK_Rc, SPEAKER_PAIR_LcRc)
MAP(SPEAKER_MASK_Lw | SPEAKER_MASK_Rw, SPEAKER_PAIR_LwRw)
MAP(SPEAKER_MASK_Lss | SPEAKER_MASK_Rss, SPEAKER_PAIR_LssRss)
MAP(SPEAKER_MASK_LFE2, SPEAKER_PAIR_LFE2)
MAP(SPEAKER_MASK_Lhs | SPEAKER_MASK_Rhs, SPEAKER_PAIR_LhsRhs)
MAP(SPEAKER_MASK_Chr, SPEAKER_PAIR_Chr)
MAP(SPEAKER_MASK_Lhr | SPEAKER_MASK_Rhr, SPEAKER_PAIR_LhrRhr)
#undef MAP
return mask2;
}
struct dcadec_exss_info *core_get_info_exss(struct core_decoder *core)
{
struct dcadec_exss_info *info = ta_znew(NULL, struct dcadec_exss_info);
if (!info)
return NULL;
info->nchannels = core->nchannels + !!core->lfe_present;
info->sample_rate = core->sample_rate << !!(core->ext_audio_mask & CSS_X96);
info->bits_per_sample = core->source_pcm_res;
if (core->ext_audio_mask & (CSS_XXCH | CSS_XCH))
info->profile = DCADEC_PROFILE_DS_ES;
else if (core->ext_audio_mask & CSS_X96)
info->profile = DCADEC_PROFILE_DS_96_24;
else
info->profile = DCADEC_PROFILE_DS;
info->embedded_6ch = !!(core->ext_audio_mask & (CSS_XXCH | CSS_XCH));
info->spkr_mask = make_spkr_pair_mask(core->ch_mask);
if (core->audio_mode == AMODE_STEREO_TOTAL)
info->matrix_encoding = DCADEC_MATRIX_ENCODING_SURROUND;
return info;
}
================================================
FILE: libdcadec/core_decoder.h
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CORE_DECODER_H
#define CORE_DECODER_H
#include "bitstream.h"
#define MAX_CHANNELS 7
#define MAX_SUBBANDS 32
#define MAX_LFE_SAMPLES 16
#define MAX_SUBFRAMES 16
#define NUM_SUBBAND_SAMPLES 8
#define NUM_PCMBLOCK_SAMPLES 32
#define NUM_ADPCM_COEFFS 4
#define NUM_CODE_BOOKS 10
#define MAX_SUBBANDS_X96 64
#define MAX_CHANNELS_CORE 6
#define MAX_CHANNELS_DMIX 4
#define MAX_CHANNELS_XXCH 2
#define MAX_CHANNELS_CHSET 8
#define MAX_EXSS_CHSETS 4
#define core_err(...) dca_log(core, ERROR, __VA_ARGS__)
#define core_warn(...) dca_log(core, WARNING, __VA_ARGS__)
#define core_err_once(...) dca_log_once(core, ERROR, __VA_ARGS__)
#define core_warn_once(...) dca_log_once(core, WARNING, __VA_ARGS__)
struct exss_asset;
struct core_decoder {
struct dcadec_context *ctx; ///< Parent context
struct bitstream bits; ///< Bitstream reader
// Bit stream header
bool crc_present; ///< CRC present flag
int npcmblocks; ///< Number of PCM sample blocks
int frame_size; ///< Primary frame byte size
int audio_mode; ///< Audio channel arrangement
int sample_rate; ///< Core audio sampling frequency
int bit_rate; ///< Transmission bit rate
bool drc_present; ///< Embedded dynamic range flag
bool ts_present; ///< Embedded time stamp flag
bool aux_present; ///< Auxiliary data flag
int ext_audio_type; ///< Extension audio descriptor flag
bool ext_audio_present; ///< Extended coding flag
bool sync_ssf; ///< Audio sync word insertion flag
int lfe_present; ///< Low frequency effects flag
bool predictor_history; ///< Predictor history flag switch
bool filter_perfect; ///< Multirate interpolator switch
int source_pcm_res; ///< Source PCM resolution
bool es_format; ///< Extended surround (ES) mastering flag
bool sumdiff_front; ///< Front sum/difference flag
bool sumdiff_surround; ///< Surround sum/difference flag
// Primary audio coding header
int nsubframes; ///< Number of subframes
int nchannels; ///< Number of primary audio channels (incl. extension channels)
int ch_mask; ///< Speaker layout mask (incl. LFE and extension channels)
int8_t nsubbands[MAX_CHANNELS]; ///< Subband activity count
int8_t subband_vq_start[MAX_CHANNELS]; ///< High frequency VQ start subband
int8_t joint_intensity_index[MAX_CHANNELS]; ///< Joint intensity coding index
int8_t transition_mode_sel[MAX_CHANNELS]; ///< Transient mode code book
int8_t scale_factor_sel[MAX_CHANNELS]; ///< Scale factor code book
int8_t bit_allocation_sel[MAX_CHANNELS]; ///< Bit allocation quantizer select
int8_t quant_index_sel[MAX_CHANNELS][NUM_CODE_BOOKS]; ///< Quantization index codebook select
int32_t scale_factor_adj[MAX_CHANNELS][NUM_CODE_BOOKS]; ///< Scale factor adjustment
// Primary audio coding side information
int8_t nsubsubframes[MAX_SUBFRAMES]; ///< Subsubframe count for each subframe
int8_t prediction_mode[MAX_CHANNELS][MAX_SUBBANDS_X96]; ///< Prediction mode
int16_t prediction_vq_index[MAX_CHANNELS][MAX_SUBBANDS_X96]; ///< Prediction coefficients VQ address
int8_t bit_allocation[MAX_CHANNELS][MAX_SUBBANDS_X96]; ///< Bit allocation index
int8_t transition_mode[MAX_SUBFRAMES][MAX_CHANNELS][MAX_SUBBANDS]; ///< Transition mode
union {
int32_t scale_factors[MAX_CHANNELS][MAX_SUBBANDS][2]; ///< Scale factors (2x for transients)
int32_t x96_scale_factors[MAX_CHANNELS][MAX_SUBBANDS_X96]; ///< X96 scale factors
};
int8_t joint_scale_sel[MAX_CHANNELS]; ///< Joint subband codebook select
int32_t joint_scale_factors[MAX_CHANNELS][MAX_SUBBANDS_X96]; ///< Scale factors for joint subband coding
// Auxiliary data
bool prim_dmix_embedded; ///< Auxiliary dynamic downmix flag
int prim_dmix_type; ///< Auxiliary primary channel downmix type
int prim_dmix_coeff[MAX_CHANNELS_DMIX * MAX_CHANNELS_CORE]; ///< Dynamic downmix code coefficients
// Core extensions
int ext_audio_mask; ///< Bit mask of fully decoded core extensions
// XCH extension data
int xch_pos; ///< Bit position of XCH frame in core substream
// XXCH extension data
bool xxch_crc_present; ///< CRC presence flag for XXCH channel set header
int xxch_mask_nbits; ///< Number of bits for loudspeaker mask
int xxch_core_mask; ///< Core loudspeaker activity mask
int xxch_spkr_mask; ///< Loudspeaker layout mask
bool xxch_dmix_embedded; ///< Downmix already performed by encoder
int xxch_dmix_scale_inv; ///< Downmix scale factor
int xxch_dmix_mask[MAX_CHANNELS_XXCH]; ///< Downmix channel mapping mask
int xxch_dmix_coeff[MAX_CHANNELS_XXCH * MAX_CHANNELS_CORE]; ///< Downmix coefficients
int xxch_pos; ///< Bit position of XXCH frame in core substream
// X96 extension data
int x96_rev_no; ///< X96 revision number
bool x96_crc_present; ///< CRC presence flag for X96 channel set header
int x96_nchannels; ///< Number of primary channels in X96 extension
bool x96_high_res; ///< X96 high resolution flag
int x96_subband_start; ///< First encoded subband in X96 extension
int x96_rand; ///< Random seed for generating samples for unallocated X96 subbands
int x96_pos; ///< Bit position of X96 frame in core substream
int *x96_subband_buffer; ///< X96 subband sample buffer base
int *x96_subband_samples[MAX_CHANNELS][MAX_SUBBANDS_X96]; ///< X96 subband samples
// Core subband buffer and filter banks
int *subband_buffer; ///< Subband sample buffer base
int *subband_samples[MAX_CHANNELS][MAX_SUBBANDS]; ///< Subband samples
struct interpolator *subband_dsp[MAX_CHANNELS]; ///< Filter banks
struct idct_context *subband_dsp_idct[2]; ///< IDCT context
int *lfe_samples; ///< Buffer for decimated LFE samples
// PCM output data
int *output_buffer; ///< PCM output buffer base
int *output_samples[SPEAKER_COUNT]; ///< PCM output speaker map
int output_history_lfe; ///< LFE PCM history for X96 filter
int npcmsamples; ///< Number of PCM samples per channel
int output_rate; ///< Output sample rate (1x or 2x header rate)
int filter_flags; ///< Previous filtering flags for detecting changes
};
int core_parse(struct core_decoder *core, uint8_t *data, int size,
int flags, struct exss_asset *asset);
int core_parse_exss(struct core_decoder *core, uint8_t *data,
int flags, struct exss_asset *asset);
int core_filter(struct core_decoder *core, int flags);
void core_clear(struct core_decoder *core) __attribute__((cold));
struct dcadec_core_info *core_get_info(struct core_decoder *core) __attribute__((cold));
struct dcadec_exss_info *core_get_info_exss(struct core_decoder *core) __attribute__((cold));
#endif
================================================
FILE: libdcadec/core_huffman.h
================================================
/*
* This file is part of libdcadec.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
//
// Table A3
//
static const uint8_t A3_len[] = {
1, 2, 2
};
static const uint16_t A3_code[] = {
0x0000, 0x0002, 0x0003
};
//
// Table A4
//
static const uint8_t A4_len[] = {
1, 2, 3, 3
};
static const uint16_t A4_code[] = {
0x0000, 0x0002, 0x0006, 0x0007
};
//
// Table B4
//
static const uint8_t B4_len[] = {
2, 3, 3, 1
};
static const uint16_t B4_code[] = {
0x0002, 0x0006, 0x0007, 0x0000
};
//
// Table C4
//
static const uint8_t C4_len[] = {
3, 3, 1, 2
};
static const uint16_t C4_code[] = {
0x0006, 0x0007, 0x0000, 0x0002
};
//
// Table D4
//
static const uint8_t D4_len[] = {
2, 2, 2, 2
};
static const uint16_t D4_code[] = {
0x0000, 0x0001, 0x0002, 0x0003
};
//
// Table A5
//
static const uint8_t A5_len[] = {
1, 2, 3, 4, 4
};
static const uint16_t A5_code[] = {
0x0000, 0x0002, 0x0006, 0x000e, 0x000f
};
//
// Table B5
//
static const uint8_t B5_len[] = {
2, 2, 2, 3, 3
};
static const uint16_t B5_code[] = {
0x0002, 0x0000, 0x0001, 0x0006, 0x0007
};
//
// Table C5
//
static const uint8_t C5_len[] = {
1, 3, 3, 3, 3
};
static const uint16_t C5_code[] = {
0x0000, 0x0004, 0x0005, 0x0006, 0x0007
};
//
// Table A7
//
static const uint8_t A7_len[] = {
1, 3, 3, 3, 4, 5, 5
};
static const uint16_t A7_code[] = {
0x0000, 0x0006, 0x0005, 0x0004, 0x000e, 0x001f, 0x001e
};
//
// Table B7
//
static const uint8_t B7_len[] = {
2, 2, 2, 3, 4, 5, 5
};
static const uint16_t B7_code[] = {
0x0003, 0x0001, 0x0000, 0x0004, 0x000b, 0x0015, 0x0014
};
//
// Table C7
//
static const uint8_t C7_len[] = {
2, 2, 2, 4, 4, 4, 4
};
static const uint16_t C7_code[] = {
0x0003, 0x0002, 0x0001, 0x0003, 0x0002, 0x0001, 0x0000
};
//
// Table A9
//
static const uint8_t A9_len[] = {
1, 3, 3, 4, 4, 4, 5, 6, 6
};
static const uint16_t A9_code[] = {
0x0000, 0x0007, 0x0005, 0x000d, 0x0009, 0x0008, 0x0019, 0x0031, 0x0030
};
//
// Table B9
//
static const uint8_t B9_len[] = {
2, 2, 3, 3, 3, 5, 5, 5, 5
};
static const uint16_t B9_code[] = {
0x0002, 0x0000, 0x0007, 0x0003, 0x0002, 0x001b, 0x001a, 0x0019, 0x0018
};
//
// Table C9
//
static const uint8_t C9_len[] = {
2, 2, 3, 3, 3, 4, 5, 6, 6
};
static const uint16_t C9_code[] = {
0x0002, 0x0000, 0x0007, 0x0006, 0x0002, 0x0006, 0x000f, 0x001d, 0x001c
};
//
// Table A12
//
static const uint8_t A12_len[] = {
1, 2, 3, 4, 5, 6, 8, 8, 9,
9, 9, 9
};
static const uint16_t A12_code[] = {
0x0000, 0x0002, 0x0006, 0x000e, 0x001e, 0x003e, 0x00ff, 0x00fe, 0x01fb,
0x01fa, 0x01f9, 0x01f8
};
//
// Table B12
//
static const uint8_t B12_len[] = {
1, 2, 3, 5, 5, 6, 7, 7, 7,
7, 7, 7
};
static const uint16_t B12_code[] = {
0x0001, 0x0000, 0x0002, 0x000f, 0x000c, 0x001d, 0x0039, 0x0038, 0x0037,
0x0036, 0x0035, 0x0034
};
//
// Table C12
//
static const uint8_t C12_len[] = {
2, 3, 3, 3, 3, 4, 4, 4, 5,
6, 7, 7
};
static const uint16_t C12_code[] = {
0x0000, 0x0007, 0x0005, 0x0004, 0x0002, 0x000d, 0x000c, 0x0006, 0x000f,
0x001d, 0x0039, 0x0038
};
//
// Table D12
//
static const uint8_t D12_len[] = {
2, 2, 2, 3, 4, 5, 6, 7, 8,
9, 10, 10
};
static const uint16_t D12_code[] = {
0x0003, 0x0002, 0x0000, 0x0002, 0x0006, 0x000e, 0x001e, 0x003e, 0x007e,
0x00fe, 0x01ff, 0x01fe
};
//
// Table E12
//
static const uint8_t E12_len[] = {
1, 2, 3, 4, 5, 7, 7, 8, 8,
8, 9, 9
};
static const uint16_t E12_code[] = {
0x0001, 0x0000, 0x0002, 0x0006, 0x000e, 0x003f, 0x003d, 0x007c, 0x0079,
0x0078, 0x00fb, 0x00fa
};
//
// Table A13
//
static const uint8_t A13_len[] = {
1, 3, 4, 4, 4, 4, 5, 5, 6,
6, 6, 7, 7
};
static const uint16_t A13_code[] = {
0x0000, 0x0004, 0x000f, 0x000d, 0x000c, 0x000a, 0x001d, 0x0016, 0x0039,
0x002f, 0x002e, 0x0071, 0x0070
};
//
// Table B13
//
static const uint8_t B13_len[] = {
2, 3, 3, 3, 4, 4, 4, 4, 5,
5, 5, 6, 6
};
static const uint16_t B13_code[] = {
0x0000, 0x0006, 0x0005, 0x0002, 0x000f, 0x0009, 0x0007, 0x0006, 0x001d,
0x0011, 0x0010, 0x0039, 0x0038
};
//
// Table C13
//
static const uint8_t C13_len[] = {
3, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5
};
static const uint16_t C13_code[] = {
0x0005, 0x0004, 0x0003, 0x0002, 0x0000, 0x000f, 0x000e, 0x000c, 0x0003,
0x001b, 0x001a, 0x0005, 0x0004
};
//
// Table A17
//
static const uint8_t A17_len[] = {
2, 3, 3, 3, 3, 4, 4, 4, 5,
6, 7, 8, 9, 10, 11, 12, 12
};
static const uint16_t A17_code[] = {
0x0001, 0x0007, 0x0006, 0x0004, 0x0001, 0x000b, 0x000a, 0x0000, 0x0003,
0x0004, 0x000b, 0x0014, 0x002b, 0x0054, 0x00ab, 0x0155, 0x0154
};
//
// Table B17
//
static const uint8_t B17_len[] = {
2, 3, 3, 3, 4, 4, 4, 5, 5,
5, 5, 6, 6, 6, 7, 8, 8
};
static const uint16_t B17_code[] = {
0x0000, 0x0006, 0x0005, 0x0002, 0x000f, 0x0009, 0x0008, 0x001d, 0x001c,
0x000e, 0x000d, 0x001e, 0x0019, 0x0018, 0x003f, 0x007d, 0x007c
};
//
// Table C17
//
static const uint8_t C17_len[] = {
3, 3, 3, 3, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 6, 7, 7
};
static const uint16_t C17_code[] = {
0x0006, 0x0004, 0x0003, 0x0000, 0x000f, 0x000b, 0x000a, 0x0004, 0x0003,
0x001d, 0x001c, 0x000a, 0x0005, 0x0004, 0x0017, 0x002d, 0x002c
};
//
// Table D17
//
static const uint8_t D17_len[] = {
1, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 9, 9
};
static const uint16_t D17_code[] = {
0x0000, 0x0007, 0x0006, 0x000b, 0x000a, 0x0013, 0x0012, 0x0023, 0x0022,
0x0043, 0x0042, 0x0083, 0x0082, 0x0103, 0x0102, 0x0101, 0x0100
};
//
// Table E17
//
static const uint8_t E17_len[] = {
1, 3, 3, 4, 5, 5, 5, 6, 6,
6, 6, 7, 7, 8, 8, 8, 8
};
static const uint16_t E17_code[] = {
0x0000, 0x0005, 0x0004, 0x000c, 0x001f, 0x001c, 0x001b, 0x003c, 0x003b,
0x0035, 0x0034, 0x007a, 0x0075, 0x00f7, 0x00f6, 0x00e9, 0x00e8
};
//
// Table F17
//
static const uint8_t F17_len[] = {
3, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 6, 6, 6, 7, 8, 8
};
static const uint16_t F17_code[] = {
0x0006, 0x0005, 0x0004, 0x0002, 0x0001, 0x000f, 0x000e, 0x0006, 0x0001,
0x000e, 0x0001, 0x001f, 0x001e, 0x0000, 0x0003, 0x0005, 0x0004
};
//
// Table G17
//
static const uint8_t G17_len[] = {
2, 3, 3, 3, 3, 4, 4, 5, 5,
6, 6, 7, 7, 8, 8, 8, 8
};
static const uint16_t G17_code[] = {
0x0002, 0x0007, 0x0006, 0x0001, 0x0000, 0x0005, 0x0004, 0x000e, 0x000d,
0x001e, 0x0019, 0x003e, 0x0031, 0x007f, 0x007e, 0x0061, 0x0060
};
//
// Table A25
//
static const uint8_t A25_len[] = {
3, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 6, 6, 7, 7, 8, 8, 8,
9, 10, 11, 12, 13, 14, 14
};
static const uint16_t A25_code[] = {
0x0006, 0x0004, 0x0003, 0x0001, 0x0000, 0x000f, 0x000e, 0x0005, 0x0004,
0x0016, 0x0015, 0x002f, 0x002e, 0x0053, 0x0052, 0x00a3, 0x00a2, 0x00a0,
0x0143, 0x0284, 0x050b, 0x0a14, 0x142b, 0x2855, 0x2854
};
//
// Table B25
//
static const uint8_t B25_len[] = {
3, 3, 3, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 6, 6, 6, 6, 6,
6, 7, 7, 7, 8, 9, 9
};
static const uint16_t B25_code[] = {
0x0005, 0x0002, 0x0001, 0x000f, 0x000e, 0x0009, 0x0008, 0x0006, 0x0001,
0x001a, 0x0019, 0x000f, 0x000e, 0x0037, 0x0036, 0x0031, 0x0030, 0x0001,
0x0000, 0x0006, 0x0005, 0x0004, 0x000f, 0x001d, 0x001c
};
//
// Table C25
//
static const uint8_t C25_len[] = {
3, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 6, 6,
6, 6, 7, 7, 7, 8, 8
};
static const uint16_t C25_code[] = {
0x0001, 0x000f, 0x000e, 0x000c, 0x000b, 0x0009, 0x0008, 0x0006, 0x0005,
0x0001, 0x0000, 0x001a, 0x0015, 0x000f, 0x000e, 0x0008, 0x0037, 0x0029,
0x0028, 0x0012, 0x006d, 0x006c, 0x0027, 0x004d, 0x004c
};
//
// Table D25
//
static const uint8_t D25_len[] = {
2, 3, 3, 3, 3, 4, 4, 5, 5,
6, 6, 7, 7, 8, 8, 9, 9, 10,
10, 11, 11, 12, 12, 12, 12
};
static const uint16_t D25_code[] = {
0x0002, 0x0007, 0x0006, 0x0001, 0x0000, 0x0005, 0x0004, 0x000d, 0x000c,
0x001d, 0x001c, 0x003e, 0x003d, 0x007e, 0x0079, 0x00ff, 0x00fe, 0x01e3,
0x01e2, 0x03c3, 0x03c2, 0x0783, 0x0782, 0x0781, 0x0780
};
//
// Table E25
//
static const uint8_t E25_len[] = {
2, 3, 3, 4, 4, 4, 4, 5, 5,
5, 5, 6, 6, 6, 6, 7, 7, 7,
7, 7, 7, 8, 8, 8, 8
};
static const uint16_t E25_code[] = {
0x0003, 0x0003, 0x0002, 0x000b, 0x000a, 0x0001, 0x0000, 0x0011, 0x0010,
0x0005, 0x0004, 0x0026, 0x0025, 0x000e, 0x000d, 0x004f, 0x004e, 0x0048,
0x001f, 0x0019, 0x0018, 0x0093, 0x0092, 0x003d, 0x003c
};
//
// Table F25
//
static const uint8_t F25_len[] = {
3, 3, 4, 4, 4, 4, 4, 4, 4,
4, 4, 5, 5, 5, 5, 6, 6, 7,
7, 8, 8, 8, 9, 10, 10
};
static const uint16_t F25_code[] = {
0x0001, 0x0000, 0x000f, 0x000e, 0x000d, 0x000b, 0x000a, 0x0008, 0x0007,
0x0005, 0x0004, 0x0018, 0x0013, 0x000d, 0x000c, 0x0025, 0x0024, 0x0066,
0x0065, 0x00cf, 0x00ce, 0x00c8, 0x0193, 0x0325, 0x0324
};
//
// Table G25
//
static const uint8_t G25_len[] = {
2, 3, 3, 3, 4, 4, 4, 5, 5,
5, 6, 6, 6, 7, 7, 7, 7, 8,
8, 9, 9, 10, 10, 10, 10
};
static const uint16_t G25_code[] = {
0x0001, 0x0006, 0x0005, 0x0000, 0x000f, 0x0008, 0x0003, 0x001c, 0x0013,
0x0004, 0x003b, 0x0024, 0x000b, 0x0074, 0x004b, 0x0015, 0x0014, 0x0095,
0x0094, 0x01d6, 0x01d5, 0x03af, 0x03ae, 0x03a9, 0x03a8
};
//
// Table A33
//
static const uint8_t A33_len[] = {
3, 3, 3, 4, 4, 4, 4, 4, 4,
4, 5, 5, 5, 6, 6, 6, 6, 7,
7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13, 13, 13
};
static const uint16_t A33_code[] = {
0x0002, 0x0001, 0x0000, 0x000e, 0x000d, 0x000c, 0x000b, 0x0009, 0x0008,
0x0006, 0x001f, 0x0014, 0x000f, 0x003d, 0x003c, 0x001d, 0x001c, 0x0055,
0x0054, 0x00ae, 0x00ad, 0x015f, 0x015e, 0x02b3, 0x02b2, 0x0563, 0x0562,
0x0ac3, 0x0ac2, 0x1583, 0x1582, 0x1581, 0x1580
};
//
// Table B33
//
static const uint8_t B33_len[] = {
3, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 6,
6, 6, 6, 7, 7, 7, 7, 7, 7,
8, 8, 8, 9, 10, 10
};
static const uint16_t B33_code[] = {
0x0001, 0x000f, 0x000e, 0x000b, 0x000a, 0x0008, 0x0007, 0x0004, 0x0001,
0x001b, 0x001a, 0x0013, 0x0012, 0x000c, 0x000b, 0x0001, 0x0000, 0x0032,
0x0031, 0x001a, 0x0015, 0x0067, 0x0066, 0x0060, 0x0037, 0x0029, 0x0028,
0x00c2, 0x006d, 0x006c, 0x0187, 0x030d, 0x030c
};
//
// Table C33
//
static const uint8_t C33_len[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 8, 9, 9
};
static const uint16_t C33_code[] = {
0x000d, 0x000b, 0x000a, 0x0008, 0x0007, 0x0004, 0x0003, 0x0002, 0x0001,
0x001e, 0x001d, 0x0019, 0x0018, 0x0013, 0x0012, 0x000b, 0x000a, 0x0000,
0x003f, 0x003e, 0x0039, 0x001b, 0x001a, 0x0018, 0x0003, 0x0071, 0x0070,
0x0032, 0x0005, 0x0004, 0x0067, 0x00cd, 0x00cc
};
//
// Table D33
//
static const uint8_t D33_len[] = {
2, 3, 3, 3, 4, 4, 4, 5, 5,
5, 6, 6, 6, 7, 7, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 12, 12,
13, 13, 14, 14, 14, 14
};
static const uint16_t D33_code[] = {
0x0001, 0x0006, 0x0005, 0x0000, 0x000f, 0x0008, 0x0003, 0x001c, 0x0013,
0x0004, 0x003b, 0x0024, 0x000b, 0x0074, 0x004b, 0x0015, 0x0014, 0x0095,
0x0094, 0x01d5, 0x01d4, 0x03ad, 0x03ac, 0x075d, 0x075c, 0x0ebd, 0x0ebc,
0x1d7f, 0x1d7e, 0x3afb, 0x3afa, 0x3af9, 0x3af8
};
//
// Table E33
//
static const uint8_t E33_len[] = {
2, 3, 3, 4, 4, 4, 5, 5, 5,
5, 5, 6, 6, 6, 6, 7, 7, 7,
7, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 9, 9, 9, 9
};
static const uint16_t E33_code[] = {
0x0002, 0x0002, 0x0001, 0x000c, 0x0007, 0x0000, 0x001f, 0x001b, 0x001a,
0x0003, 0x0002, 0x003b, 0x003a, 0x001b, 0x001a, 0x007b, 0x007a, 0x0078,
0x0073, 0x0070, 0x0033, 0x0031, 0x0030, 0x00f2, 0x00e5, 0x00e3, 0x00e2,
0x0065, 0x0064, 0x01e7, 0x01e6, 0x01c9, 0x01c8
};
//
// Table F33
//
static const uint8_t F33_len[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 5, 6,
6, 6, 6, 6, 6, 7, 7, 8, 8,
9, 9, 9, 10, 11, 11
};
static const uint16_t F33_code[] = {
0x000d, 0x000c, 0x000b, 0x0009, 0x0008, 0x0007, 0x0006, 0x0004, 0x0003,
0x0001, 0x0000, 0x001e, 0x001d, 0x0015, 0x0014, 0x000a, 0x0005, 0x003f,
0x003e, 0x0038, 0x0017, 0x0009, 0x0008, 0x002d, 0x002c, 0x00e6, 0x00e5,
0x01cf, 0x01ce, 0x01c8, 0x0393, 0x0725, 0x0724
};
//
// Table G33
//
static const uint8_t G33_len[] = {
3, 3, 3, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 6, 6, 6, 6, 7,
7, 7, 7, 8, 8, 8, 8, 8, 9,
9, 9, 9, 9, 10, 10
};
static const uint16_t G33_code[] = {
0x0006, 0x0003, 0x0002, 0x000f, 0x000e, 0x0009, 0x0008, 0x0001, 0x0000,
0x0016, 0x0015, 0x0006, 0x0005, 0x002e, 0x0029, 0x000e, 0x0009, 0x005e,
0x0051, 0x001e, 0x0011, 0x00bf, 0x00be, 0x003f, 0x003e, 0x0020, 0x0143,
0x0141, 0x0140, 0x0043, 0x0042, 0x0285, 0x0284
};
//
// Table A65
//
static const uint8_t A65_len[] = {
4, 4, 4, 4, 4, 4, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 8, 8, 8,
8, 9, 9, 9, 9, 10, 10, 10, 10,
11, 11, 11, 11, 11, 12, 12, 12, 13,
13, 13, 13, 14, 14, 15, 15, 16, 16,
16, 16
};
static const uint16_t A65_code[] = {
0x0006, 0x0005, 0x0004, 0x0002, 0x0001, 0x0000, 0x001f, 0x001d, 0x001c,
0x001b, 0x001a, 0x0018, 0x0017, 0x0015, 0x0014, 0x0012, 0x0011, 0x000e,
0x0007, 0x0006, 0x003d, 0x0032, 0x002d, 0x0026, 0x0021, 0x001f, 0x001e,
0x0078, 0x0067, 0x0059, 0x0058, 0x0041, 0x0040, 0x00cd, 0x00cc, 0x009d,
0x009c, 0x01e6, 0x01e5, 0x013e, 0x013d, 0x03cf, 0x03ce, 0x027f, 0x027e,
0x0793, 0x0792, 0x0790, 0x04f3, 0x04f0, 0x0f23, 0x09e4, 0x09e3, 0x1e45,
0x1e44, 0x13c5, 0x13c4, 0x2795, 0x2794, 0x4f2d, 0x4f2c, 0x9e5f, 0x9e5e,
0x9e5d, 0x9e5c
};
//
// Table B65
//
static const uint8_t B65_len[] = {
4, 4, 4, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 9,
9, 9, 9, 9, 9, 10, 10, 10, 11,
12, 12
};
static const uint16_t B65_code[] = {
0x0004, 0x0002, 0x0001, 0x001e, 0x001d, 0x001a, 0x0019, 0x0017, 0x0016,
0x0013, 0x0012, 0x0010, 0x000f, 0x000c, 0x000b, 0x0007, 0x0006, 0x003f,
0x003e, 0x0038, 0x0037, 0x0031, 0x0030, 0x0029, 0x0028, 0x0022, 0x001d,
0x001a, 0x0015, 0x0014, 0x0003, 0x0000, 0x0073, 0x006d, 0x006c, 0x0056,
0x0055, 0x0046, 0x0039, 0x0038, 0x0037, 0x0004, 0x0003, 0x00e5, 0x00e4,
0x00af, 0x00ae, 0x008f, 0x008e, 0x006c, 0x000b, 0x000a, 0x0005, 0x0153,
0x0152, 0x0150, 0x00db, 0x0009, 0x0008, 0x02a2, 0x01b5, 0x01b4, 0x0547,
0x0a8d, 0x0a8c
};
//
// Table C65
//
static const uint8_t C65_len[] = {
5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 8, 8, 8, 8, 8,
8, 8, 9, 9, 9, 9, 10, 10, 10,
11, 11
};
static const uint16_t C65_code[] = {
0x001c, 0x0019, 0x0018, 0x0017, 0x0016, 0x0013, 0x0012, 0x0010, 0x000f,
0x000d, 0x000c, 0x000a, 0x0009, 0x0007, 0x0006, 0x0004, 0x0003, 0x0001,
0x0000, 0x003e, 0x003d, 0x003b, 0x003a, 0x0036, 0x0035, 0x002b, 0x002a,
0x0028, 0x0023, 0x001d, 0x001c, 0x0011, 0x0010, 0x000b, 0x000a, 0x0004,
0x007f, 0x0079, 0x0078, 0x006e, 0x0069, 0x0053, 0x0052, 0x0044, 0x002f,
0x002e, 0x002d, 0x000b, 0x000a, 0x00fc, 0x00df, 0x00d1, 0x00d0, 0x008a,
0x0059, 0x0058, 0x01fb, 0x01bd, 0x01bc, 0x0116, 0x03f5, 0x03f4, 0x022f,
0x045d, 0x045c
};
//
// Table D65
//
static const uint8_t D65_len[] = {
3, 3, 3, 4, 4, 4, 4, 5, 5,
5, 5, 5, 5, 6, 6, 6, 6, 6,
6, 7, 7, 7, 7, 7, 7, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 9,
9, 10, 10, 10, 10, 10, 10, 11, 11,
11, 11, 12, 12, 12, 12, 13, 13, 13,
13, 13, 14, 14, 14, 15, 15, 15, 15,
15, 15
};
static const uint16_t D65_code[] = {
0x0004, 0x0001, 0x0000, 0x000d, 0x000c, 0x0007, 0x0006, 0x001f, 0x001e,
0x0017, 0x0016, 0x000b, 0x000a, 0x003b, 0x003a, 0x002b, 0x002a, 0x0013,
0x0012, 0x0073, 0x0072, 0x0053, 0x0052, 0x0023, 0x0022, 0x00e3, 0x00e2,
0x00a3, 0x00a2, 0x00a0, 0x0043, 0x0040, 0x01c3, 0x01c0, 0x0143, 0x0084,
0x0083, 0x0384, 0x0383, 0x0284, 0x010b, 0x0105, 0x0104, 0x0705, 0x0704,
0x0215, 0x0214, 0x0e15, 0x0e14, 0x0a16, 0x0a15, 0x1c2f, 0x1c2e, 0x142f,
0x142e, 0x1428, 0x385b, 0x2853, 0x2852, 0x70b5, 0x70b4, 0x70b3, 0x70b2,
0x70b1, 0x70b0
};
//
// Table E65
//
static const uint8_t E65_len[] = {
3, 3, 4, 4, 4, 5, 5, 5, 5,
5, 5, 5, 5, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 10, 10, 10, 10, 10, 10,
10, 10
};
static const uint16_t E65_code[] = {
0x0004, 0x0000, 0x000f, 0x0007, 0x0006, 0x001d, 0x001c, 0x0017, 0x0016,
0x000a, 0x0009, 0x0006, 0x0005, 0x0036, 0x0035, 0x0030, 0x002b, 0x0028,
0x0017, 0x0010, 0x000f, 0x0009, 0x0008, 0x0069, 0x0068, 0x0064, 0x0063,
0x0054, 0x0053, 0x002d, 0x002c, 0x001d, 0x001c, 0x00dd, 0x00dc, 0x00ce,
0x00cd, 0x00ca, 0x00c5, 0x00ab, 0x00aa, 0x00a4, 0x0047, 0x0045, 0x0044,
0x01be, 0x01bd, 0x019f, 0x019e, 0x0198, 0x0197, 0x0189, 0x0188, 0x014b,
0x014a, 0x008d, 0x008c, 0x037f, 0x037e, 0x0379, 0x0378, 0x0333, 0x0332,
0x032d, 0x032c
};
//
// Table F65
//
static const uint8_t F65_len[] = {
3, 3, 3, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 6, 6, 6, 6, 7,
7, 7, 7, 8, 8, 8, 8, 9, 9,
9, 9, 10, 10, 10, 11, 11, 11, 11,
12, 12, 12, 12, 12, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14
};
static const uint16_t F65_code[] = {
0x0006, 0x0003, 0x0002, 0x000f, 0x000e, 0x0009, 0x0008, 0x0001, 0x0000,
0x0015, 0x0014, 0x0005, 0x0004, 0x002d, 0x002c, 0x000d, 0x000c, 0x005d,
0x005c, 0x001d, 0x001c, 0x00bd, 0x00bc, 0x003d, 0x003c, 0x017d, 0x017c,
0x007d, 0x007c, 0x02fd, 0x02fc, 0x00fc, 0x05ff, 0x05fc, 0x01ff, 0x01fa,
0x0bfd, 0x0bfb, 0x0bfa, 0x03f7, 0x03f6, 0x17f8, 0x07fb, 0x07f3, 0x07f2,
0x2ff3, 0x2ff2, 0x0ff5, 0x0ff4, 0x0ff3, 0x0ff2, 0x0ff1, 0x0ff0, 0x0fef,
0x0fee, 0x0fed, 0x0fec, 0x0feb, 0x0fea, 0x0fe9, 0x0fe8, 0x0fe3, 0x0fe2,
0x0fe1, 0x0fe0
};
//
// Table G65
//
static const uint8_t G65_len[] = {
4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 6, 6,
6, 6, 6, 6, 6, 6, 7, 7, 7,
7, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 9,
9, 9, 9, 9, 10, 10, 10, 10, 10,
10, 10, 10, 11, 11, 11, 11, 11, 11,
11, 11
};
static const uint16_t G65_code[] = {
0x000e, 0x000b, 0x000a, 0x0008, 0x0006, 0x0004, 0x0003, 0x0000, 0x001f,
0x001a, 0x0019, 0x0012, 0x000f, 0x000a, 0x0005, 0x0002, 0x003d, 0x0036,
0x0031, 0x0026, 0x001d, 0x0016, 0x0009, 0x0006, 0x0079, 0x006e, 0x0061,
0x004e, 0x0039, 0x002e, 0x0011, 0x000e, 0x00f1, 0x00df, 0x00de, 0x009f,
0x009e, 0x005f, 0x005e, 0x001f, 0x001e, 0x01e0, 0x0183, 0x0180, 0x00e3,
0x00e1, 0x00e0, 0x0041, 0x0040, 0x03c2, 0x0305, 0x0303, 0x0302, 0x01c4,
0x0087, 0x0085, 0x0084, 0x0787, 0x0786, 0x0609, 0x0608, 0x038b, 0x038a,
0x010d, 0x010c
};
//
// Table SA129
//
static const uint8_t SA129_len[] = {
2, 3, 3, 3, 4, 4, 4, 5, 5,
5, 6, 6, 6, 7, 7, 8, 8, 8,
8, 9, 9, 10, 10, 11, 11, 11, 11,
12, 12, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14
};
static const uint16_t SA129_code[] = {
0x0001, 0x0006, 0x0005, 0x0000, 0x000f, 0x0008, 0x0003, 0x001c, 0x0013,
0x0004, 0x003b, 0x0024, 0x000b, 0x004b, 0x004a, 0x00e9, 0x00e8, 0x0029,
0x0028, 0x0057, 0x0056, 0x03a9, 0x03a8, 0x0755, 0x0754, 0x0155, 0x0154,
0x02ae, 0x02ad, 0x055f, 0x055e, 0x0559, 0x0558, 0x054f, 0x054e, 0x054d,
0x054c, 0x054b, 0x054a, 0x0549, 0x0548, 0x0547, 0x0546, 0x0545, 0x0544,
0x0543, 0x0542, 0x0541, 0x0540, 0x3aff, 0x3afe, 0x3afd, 0x3afc, 0x3afb,
0x3afa, 0x3af9, 0x3af8, 0x3af7, 0x3af6, 0x3af5, 0x3af4, 0x3af3, 0x3af2,
0x3af1, 0x3af0, 0x3aef, 0x3aee, 0x3aed, 0x3aec, 0x3aeb, 0x3aea, 0x3ae9,
0x3ae8, 0x3ae7, 0x3ae6, 0x3ae5, 0x3ae4, 0x3ae3, 0x3ae2, 0x3ae1, 0x3ae0,
0x3adf, 0x3ade, 0x3add, 0x3adc, 0x3adb, 0x3ada, 0x3ad9, 0x3ad8, 0x3ad7,
0x3ad6, 0x3ad5, 0x3ad4, 0x3ad3, 0x3ad2, 0x3ad1, 0x3ad0, 0x3acf, 0x3ace,
0x3acd, 0x3acc, 0x3acb, 0x3aca, 0x3ac9, 0x3ac8, 0x3ac7, 0x3ac6, 0x3ac5,
0x3ac4, 0x3ac3, 0x3ac2, 0x3ac1, 0x3ac0, 0x3abf, 0x3abe, 0x3abd, 0x3abc,
0x3abb, 0x3aba, 0x3ab9, 0x3ab8, 0x3ab7, 0x3ab6, 0x3ab5, 0x3ab4, 0x3ab3,
0x3ab2, 0x3ab1, 0x3ab0
};
//
// Table SB129
//
static const uint8_t SB129_len[] = {
3, 3, 3, 4, 4, 4, 4, 4, 4,
4, 5, 5, 5, 6, 6, 6, 6, 7,
7, 8, 8, 9, 10, 11, 11, 12, 12,
13, 13, 14, 14, 14, 14, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15
};
static const uint16_t SB129_code[] = {
0x0003, 0x0002, 0x0001, 0x000f, 0x000e, 0x000c, 0x000b, 0x000a, 0x0009,
0x0000, 0x001b, 0x0011, 0x0010, 0x0035, 0x0034, 0x0005, 0x0004, 0x000d,
0x000c, 0x001d, 0x001c, 0x003c, 0x007f, 0x00fd, 0x00fc, 0x01eb, 0x01ea,
0x03d3, 0x03d2, 0x07a3, 0x07a2, 0x07a1, 0x07a0, 0x0fbf, 0x0fbe, 0x0fbd,
0x0fbc, 0x0fbb, 0x0fba, 0x0fb9, 0x0fb8, 0x0fb7, 0x0fb6, 0x0fb5, 0x0fb4,
0x0fb3, 0x0fb2, 0x0fb1, 0x0fb0, 0x0faf, 0x0fae, 0x0fad, 0x0fac, 0x0fab,
0x0faa, 0x0fa9, 0x0fa8, 0x0fa7, 0x0fa6, 0x0fa5, 0x0fa4, 0x0fa3, 0x0fa2,
0x0fa1, 0x0fa0, 0x0f9f, 0x0f9e, 0x0f9d, 0x0f9c, 0x0f9b, 0x0f9a, 0x0f99,
0x0f98, 0x0f97, 0x0f96, 0x0f95, 0x0f94, 0x0f93, 0x0f92, 0x0f91, 0x0f90,
0x0f8f, 0x0f8e, 0x0f8d, 0x0f8c, 0x0f8b, 0x0f8a, 0x0f89, 0x0f88, 0x0f87,
0x0f86, 0x0f85, 0x0f84, 0x0f83, 0x0f82, 0x0f81, 0x0f80, 0x0f7f, 0x0f7e,
0x0f7d, 0x0f7c, 0x0f7b, 0x0f7a, 0x0f79, 0x0f78, 0x0f77, 0x0f76, 0x0f75,
0x0f74, 0x0f73, 0x0f72, 0x0f71, 0x0f70, 0x0f6f, 0x0f6e, 0x0f6d, 0x0f6c,
0x0f6b, 0x0f6a, 0x0f69, 0x0f68, 0x0f67, 0x0f66, 0x0f65, 0x0f64, 0x0f63,
0x0f62, 0x0f61, 0x0f60
};
//
// Table SC129
//
static const uint8_t SC129_len[] = {
3, 3, 3, 4, 4, 4, 4, 5, 5,
5, 5, 5, 5, 6, 6, 6, 6, 6,
6, 7, 7, 7, 7, 7, 7, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9,
9, 10, 10, 10, 10, 10, 11, 11, 11,
11, 11, 12, 12, 12, 12, 12, 12, 13,
13, 13, 13, 13, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15
};
static const uint16_t SC129_code[] = {
0x0004, 0x0001, 0x0000, 0x000d, 0x000c, 0x0007, 0x0006, 0x001f, 0x001e,
0x0017, 0x0016, 0x000b, 0x000a, 0x003b, 0x003a, 0x002b, 0x002a, 0x0013,
0x0012, 0x0073, 0x0072, 0x0053, 0x0052, 0x0023, 0x0022, 0x00e3, 0x00e2,
0x00a2, 0x00a1, 0x0042, 0x0041, 0x01c2, 0x01c1, 0x0141, 0x0140, 0x0081,
0x0080, 0x0381, 0x0380, 0x028c, 0x010f, 0x010c, 0x070f, 0x051c, 0x051b,
0x021c, 0x021b, 0x0e1c, 0x0e1b, 0x0a35, 0x0a34, 0x0435, 0x0434, 0x1c3a,
0x1c35, 0x0877, 0x0876, 0x0874, 0x3877, 0x3869, 0x3868, 0x10eb, 0x10ea,
0x70ed, 0x70ec, 0x70cf, 0x70ce, 0x70cd, 0x70cc, 0x70cb, 0x70ca, 0x70c9,
0x70c8, 0x70c7, 0x70c6, 0x70c5, 0x70c4, 0x70c3, 0x70c2, 0x70c1, 0x70c0,
0x51ff, 0x51fe, 0x51fd, 0x51fc, 0x51fb, 0x51fa, 0x51f9, 0x51f8, 0x51f7,
0x51f6, 0x51f5, 0x51f4, 0x51f3, 0x51f2, 0x51f1, 0x51f0, 0x51ef, 0x51ee,
0x51ed, 0x51ec, 0x51eb, 0x51ea, 0x51e9, 0x51e8, 0x51e7, 0x51e6, 0x51e5,
0x51e4, 0x51e3, 0x51e2, 0x51e1, 0x51e0, 0x51df, 0x51de, 0x51dd, 0x51dc,
0x51db, 0x51da, 0x51d9, 0x51d8, 0x51d7, 0x51d6, 0x51d5, 0x51d4, 0x51d3,
0x51d2, 0x51d1, 0x51d0
};
//
// Table SD129
//
static const uint8_t SD129_len[] = {
2, 3, 3, 4, 4, 4, 4, 5, 5,
5, 5, 6, 6, 6, 6, 7, 7, 7,
7, 8, 8, 8, 8, 9, 9, 9, 10,
10, 10, 10, 11, 11, 11, 12, 12, 12,
12, 12, 13, 13, 13, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15
};
static const uint16_t SD129_code[] = {
0x0000, 0x0005, 0x0004, 0x000f, 0x000e, 0x0007, 0x0006, 0x001a, 0x0019,
0x000a, 0x0009, 0x0036, 0x0031, 0x0016, 0x0011, 0x006e, 0x0061, 0x002e,
0x0021, 0x00c1, 0x00c0, 0x0041, 0x0040, 0x01bc, 0x00bf, 0x00bc, 0x037f,
0x037a, 0x017d, 0x017a, 0x06fd, 0x02f9, 0x02f8, 0x0df9, 0x0df8, 0x05ef,
0x05ee, 0x05ec, 0x1bef, 0x1bd8, 0x0bdb, 0x37dd, 0x37dc, 0x17b5, 0x17b4,
0x6fb7, 0x6fb6, 0x6fb5, 0x6fb4, 0x6fb3, 0x6fb2, 0x6fb1, 0x6fb0, 0x6faf,
0x6fae, 0x6fad, 0x6fac, 0x6fab, 0x6faa, 0x6fa9, 0x6fa8, 0x6fa7, 0x6fa6,
0x6fa5, 0x6fa4, 0x6fa3, 0x6fa2, 0x6fa1, 0x6fa0, 0x6f9f, 0x6f9e, 0x6f9d,
0x6f9c, 0x6f9b, 0x6f9a, 0x6f99, 0x6f98, 0x6f97, 0x6f96, 0x6f95, 0x6f94,
0x6f93, 0x6f92, 0x6f91, 0x6f90, 0x6f8f, 0x6f8e, 0x6f8d, 0x6f8c, 0x6f8b,
0x6f8a, 0x6f89, 0x6f88, 0x6f87, 0x6f86, 0x6f85, 0x6f84, 0x6f83, 0x6f82,
0x6f81, 0x6f80, 0x6f7f, 0x6f7e, 0x6f7d, 0x6f7c, 0x6f7b, 0x6f7a, 0x6f79,
0x6f78, 0x6f77, 0x6f76, 0x6f75, 0x6f74, 0x6f73, 0x6f72, 0x6f71, 0x6f70,
0x6f6f, 0x6f6e, 0x6f6d, 0x6f6c, 0x6f6b, 0x6f6a, 0x6f69, 0x6f68, 0x6f67,
0x6f66, 0x6f65, 0x6f64
};
//
// Table SE129
//
static const uint8_t SE129_len[] = {
4, 4, 4, 4, 4, 4, 4, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 6,
6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 8, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 9,
9, 9, 9, 9, 10, 10, 10, 10, 10,
10, 10, 10, 11, 11, 11, 11, 11, 11,
11, 12, 12, 12, 12, 12, 12, 12, 12,
12, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 15,
15, 15, 15, 15, 15, 15, 15, 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
};
static const uint16_t SE129_code[] = {
0x000e, 0x000b, 0x000a, 0x0007, 0x0006, 0x0003, 0x0002, 0x001f, 0x001e,
0x0019, 0x0018, 0x0011, 0x0010, 0x0009, 0x0008, 0x0001, 0x0000, 0x0035,
0x0034, 0x0025, 0x0024, 0x0015, 0x0014, 0x0005, 0x0004, 0x006d, 0x006c,
0x004d, 0x004c, 0x002d, 0x002c, 0x000d, 0x000c, 0x00dd, 0x00dc, 0x009d,
0x009c, 0x005d, 0x005c, 0x001d, 0x001c, 0x01bd, 0x01bc, 0x013d, 0x013c,
0x00bd, 0x00bc, 0x003d, 0x003c, 0x037c, 0x027f, 0x027d, 0x027c, 0x017d,
0x017c, 0x007d, 0x007c, 0x06fc, 0x06fb, 0x04fc, 0x02ff, 0x02fc, 0x00ff,
0x00fc, 0x0dff, 0x0dfb, 0x0dfa, 0x09fb, 0x09fa, 0x05fb, 0x05fa, 0x01fb,
0x01fa, 0x1bf8, 0x1beb, 0x1be8, 0x0bfb, 0x0bf9, 0x0bf8, 0x03f9, 0x03f8,
0x37fa, 0x37f9, 0x37d3, 0x37d2, 0x17f4, 0x07f7, 0x07f6, 0x07f5, 0x6ff7,
0x6ff6, 0x6fa9, 0x6fa8, 0x2feb, 0x2fea, 0x0fe9, 0x0fe8, 0xdfe3, 0xdfe2,
0xdfe1, 0xdfe0, 0xdfdf, 0xdfde, 0xdfdd, 0xdfdc, 0xdfdb, 0xdfda, 0xdfd9,
0xdfd8, 0xdfd7, 0xdfd6, 0xdfd5, 0xdfd4, 0xdfd3, 0xdfd2, 0xdfd1, 0xdfd0,
0xdfcf, 0xdfce, 0xdfcd, 0xdfcc, 0xdfcb, 0xdfca, 0xdfc9, 0xdfc8, 0xdf57,
0xdf56, 0xdf55, 0xdf54
};
//
// Table A129
//
static const uint8_t A129_len[] = {
4, 4, 4, 4, 5, 5, 5, 5, 5,
5, 5, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11
};
static const uint16_t A129_code[] = {
0x0008, 0x000a, 0x0009, 0x0000, 0x001f, 0x0018, 0x0017, 0x000c, 0x000b,
0x0005, 0x0004, 0x003c, 0x003a, 0x0036, 0x0035, 0x002d, 0x002c, 0x001c,
0x001b, 0x0013, 0x0012, 0x000e, 0x000d, 0x0006, 0x0005, 0x007a, 0x0077,
0x0071, 0x0070, 0x0068, 0x0067, 0x0064, 0x003f, 0x003c, 0x003b, 0x0034,
0x002b, 0x0028, 0x0023, 0x0020, 0x001f, 0x000f, 0x000e, 0x00f7, 0x00f6,
0x00e7, 0x00e6, 0x00df, 0x00de, 0x00d3, 0x00d2, 0x00cb, 0x00ca, 0x007b,
0x007a, 0x0074, 0x006b, 0x0054, 0x0053, 0x0044,
gitextract_4euf4kon/
├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── COPYING.LGPLv2.1
├── Makefile
├── README.md
├── dcacut.c
├── dcadec.c
├── dcadec.pc.in
├── getopt.c
├── getopt.h
├── libdcadec/
│ ├── bitstream.c
│ ├── bitstream.h
│ ├── common.h
│ ├── compiler.h
│ ├── core_decoder.c
│ ├── core_decoder.h
│ ├── core_huffman.h
│ ├── core_tables.h
│ ├── core_vectors.h
│ ├── dca_context.c
│ ├── dca_context.h
│ ├── dca_frame.c
│ ├── dca_frame.h
│ ├── dca_stream.c
│ ├── dca_stream.h
│ ├── dca_waveout.c
│ ├── dca_waveout.h
│ ├── dmix_tables.c
│ ├── dmix_tables.h
│ ├── exss_parser.c
│ ├── exss_parser.h
│ ├── fir_fixed.h
│ ├── fir_float.h
│ ├── fixed_math.h
│ ├── huffman.h
│ ├── idct.h
│ ├── idct_fixed.c
│ ├── idct_float.c
│ ├── interpolator.c
│ ├── interpolator.h
│ ├── interpolator_fixed.c
│ ├── interpolator_float.c
│ ├── lbr_bitstream.h
│ ├── lbr_decoder.c
│ ├── lbr_decoder.h
│ ├── lbr_huffman.h
│ ├── lbr_tables.h
│ ├── ta.c
│ ├── ta.h
│ ├── xll_decoder.c
│ ├── xll_decoder.h
│ └── xll_tables.h
├── msvc/
│ ├── dcadec/
│ │ ├── dcadec.vcxproj
│ │ └── dcadec.vcxproj.filters
│ ├── dcadec.sln
│ └── libdcadec/
│ ├── libdcadec.vcxproj
│ └── libdcadec.vcxproj.filters
└── test/
├── checksum.txt
├── stddev.c
├── stddev.txt
└── test.sh
SYMBOL INDEX (436 symbols across 36 files)
FILE: dcacut.c
function main (line 29) | int main(int argc, char **argv)
FILE: dcadec.c
function print_help (line 43) | static void print_help(const char *name)
function print_info (line 119) | static void print_info(struct dcadec_context *context, FILE *fp)
function BOOL (line 168) | static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
function signal_handler (line 175) | static void signal_handler(int sig)
function my_log_cb (line 182) | static void my_log_cb(int level, const char *file, int line,
function main (line 204) | int main(int argc, char **argv)
FILE: getopt.c
function getopt (line 32) | int getopt(int argc, char * const argv[], const char *optstring)
FILE: libdcadec/bitstream.c
function bits_peek (line 22) | static inline uint32_t bits_peek(struct bitstream *bits)
function bits_get1 (line 39) | bool bits_get1(struct bitstream *bits)
function bits_get (line 52) | int bits_get(struct bitstream *bits, int n)
function bits_get_signed (line 61) | int bits_get_signed(struct bitstream *bits, int n)
function bits_get_signed_linear (line 70) | int bits_get_signed_linear(struct bitstream *bits, int n)
function bits_get_unsigned_rice (line 79) | static int bits_get_unsigned_rice(struct bitstream *bits, int k)
function bits_get_signed_rice (line 98) | int bits_get_signed_rice(struct bitstream *bits, int k)
function bits_get_unsigned_vlc (line 104) | int bits_get_unsigned_vlc(struct bitstream *bits, const struct huffman *h)
function bits_get_signed_vlc (line 118) | int bits_get_signed_vlc(struct bitstream *bits, const struct huffman *h)
function crc16 (line 124) | static uint16_t crc16(const uint8_t *data, int size)
function bits_check_crc (line 140) | int bits_check_crc(struct bitstream *bits, int p1, int p2)
function bits_get_array (line 149) | void bits_get_array(struct bitstream *bits, int *array, int size, int n)
function bits_get_signed_array (line 155) | void bits_get_signed_array(struct bitstream *bits, int *array, int size,...
function bits_get_signed_linear_array (line 161) | void bits_get_signed_linear_array(struct bitstream *bits, int *array, in...
function bits_get_signed_rice_array (line 169) | void bits_get_signed_rice_array(struct bitstream *bits, int *array, int ...
function bits_get_signed_vlc_array (line 175) | int bits_get_signed_vlc_array(struct bitstream *bits, int *array, int si...
FILE: libdcadec/bitstream.h
type bitstream (line 27) | struct bitstream {
function bits_init (line 33) | static inline void bits_init(struct bitstream *bits, uint8_t *data, int ...
type bitstream (line 42) | struct bitstream
type bitstream (line 43) | struct bitstream
type bitstream (line 44) | struct bitstream
type bitstream (line 45) | struct bitstream
type bitstream (line 46) | struct bitstream
type bitstream (line 47) | struct bitstream
type huffman (line 47) | struct huffman
type bitstream (line 48) | struct bitstream
type huffman (line 48) | struct huffman
function bits_skip (line 50) | static inline void bits_skip(struct bitstream *bits, int n)
function bits_skip1 (line 56) | static inline void bits_skip1(struct bitstream *bits)
function bits_seek (line 61) | static inline int bits_seek(struct bitstream *bits, int n)
function bits_align1 (line 69) | static inline int bits_align1(struct bitstream *bits)
function bits_align4 (line 75) | static inline int bits_align4(struct bitstream *bits)
type bitstream (line 81) | struct bitstream
type bitstream (line 82) | struct bitstream
type bitstream (line 83) | struct bitstream
type bitstream (line 84) | struct bitstream
type bitstream (line 85) | struct bitstream
type bitstream (line 86) | struct bitstream
type huffman (line 86) | struct huffman
FILE: libdcadec/common.h
function dca_clz (line 40) | static inline int dca_clz(uint32_t x)
function dca_popcount (line 58) | static inline int dca_popcount(uint32_t x)
function dca_bswap16 (line 73) | static inline uint16_t dca_bswap16(uint16_t x)
function dca_bswap32 (line 83) | static inline uint32_t dca_bswap32(uint32_t x)
function dca_bswap64 (line 89) | static inline uint64_t dca_bswap64(uint64_t x)
function DCA_MEM32NE (line 165) | static inline uint32_t DCA_MEM32NE(const void *data)
type dcadec_context (line 172) | struct dcadec_context
type WaveTag (line 198) | enum WaveTag {
type WaveSpeaker (line 206) | enum WaveSpeaker {
type SpeakerMask (line 217) | enum SpeakerMask {
type Speaker (line 253) | enum Speaker {
type SyncWord (line 267) | enum SyncWord {
type SpeakerPair (line 286) | enum SpeakerPair {
function count_chs_for_mask (line 307) | static inline int count_chs_for_mask(int mask)
type RepresentationType (line 313) | enum RepresentationType {
type ExtensionMask (line 319) | enum ExtensionMask {
type DownMixType (line 335) | enum DownMixType {
FILE: libdcadec/compiler.h
type __int64 (line 31) | typedef __int64 off_t;
FILE: libdcadec/core_decoder.c
type HeaderType (line 32) | enum HeaderType {
type AudioMode (line 38) | enum AudioMode {
type ExtAudioType (line 53) | enum ExtAudioType {
type LFEFlag (line 59) | enum LFEFlag {
function parse_frame_header (line 93) | static int parse_frame_header(struct core_decoder *core)
function parse_coding_header (line 211) | static int parse_coding_header(struct core_decoder *core, enum HeaderTyp...
function parse_scale (line 403) | static int parse_scale(struct core_decoder *core, int *scale_index, int ...
function parse_joint_scale (line 431) | static int parse_joint_scale(struct core_decoder *core, int sel)
function parse_subframe_header (line 453) | static int parse_subframe_header(struct core_decoder *core, int sf,
function parse_block_codes (line 591) | static int parse_block_codes(struct core_decoder *core, int *audio, int ...
function parse_huffman_codes (line 618) | static int parse_huffman_codes(struct core_decoder *core, int *audio, in...
function extract_audio (line 632) | static inline int extract_audio(struct core_decoder *core, int *audio, i...
function dequantize (line 659) | static inline void dequantize(int *output, const int *input, int step_size,
function parse_subframe_audio (line 683) | static int parse_subframe_audio(struct core_decoder *core, int sf, enum ...
function erase_adpcm_history (line 840) | static void erase_adpcm_history(struct core_decoder *core)
function alloc_sample_buffer (line 849) | static int alloc_sample_buffer(struct core_decoder *core)
function parse_frame_data (line 873) | static int parse_frame_data(struct core_decoder *core, enum HeaderType h...
function map_prm_ch_to_spkr (line 910) | static int map_prm_ch_to_spkr(struct core_decoder *core, int ch)
function core_filter (line 943) | int core_filter(struct core_decoder *core, int flags)
function parse_xch_frame (line 1167) | static int parse_xch_frame(struct core_decoder *core)
function parse_xxch_frame (line 1182) | static int parse_xxch_frame(struct core_decoder *core)
function parse_xbr_subframe (line 1257) | static int parse_xbr_subframe(struct core_decoder *core, int xbr_base_ch...
function parse_xbr_frame (line 1382) | static int parse_xbr_frame(struct core_decoder *core)
function rand_x96 (line 1466) | static int rand_x96(struct core_decoder *core)
function parse_x96_subframe_audio (line 1472) | static int parse_x96_subframe_audio(struct core_decoder *core, int sf, i...
function erase_x96_adpcm_history (line 1604) | static void erase_x96_adpcm_history(struct core_decoder *core)
function alloc_x96_sample_buffer (line 1613) | static int alloc_x96_sample_buffer(struct core_decoder *core)
function parse_x96_subframe_header (line 1635) | static int parse_x96_subframe_header(struct core_decoder *core, int xch_...
function parse_x96_coding_header (line 1738) | static int parse_x96_coding_header(struct core_decoder *core, bool exss,...
function parse_x96_frame_data (line 1821) | static int parse_x96_frame_data(struct core_decoder *core, bool exss, in...
function parse_x96_frame (line 1855) | static int parse_x96_frame(struct core_decoder *core)
function parse_x96_frame_exss (line 1878) | static int parse_x96_frame_exss(struct core_decoder *core)
function parse_aux_data (line 1957) | static int parse_aux_data(struct core_decoder *core)
function parse_optional_info (line 2037) | static int parse_optional_info(struct core_decoder *core, int flags)
function core_parse (line 2142) | int core_parse(struct core_decoder *core, uint8_t *data, int size,
function core_parse_exss (line 2180) | int core_parse_exss(struct core_decoder *core, uint8_t *data,
function core_clear (line 2254) | void core_clear(struct core_decoder *core)
type dcadec_core_info (line 2269) | struct dcadec_core_info
type core_decoder (line 2269) | struct core_decoder
type dcadec_core_info (line 2271) | struct dcadec_core_info
function make_spkr_pair_mask (line 2287) | static int make_spkr_pair_mask(int mask1)
type dcadec_exss_info (line 2313) | struct dcadec_exss_info
type core_decoder (line 2313) | struct core_decoder
type dcadec_exss_info (line 2315) | struct dcadec_exss_info
FILE: libdcadec/core_decoder.h
type exss_asset (line 48) | struct exss_asset
type core_decoder (line 50) | struct core_decoder {
type core_decoder (line 153) | struct core_decoder
type exss_asset (line 154) | struct exss_asset
type core_decoder (line 155) | struct core_decoder
type exss_asset (line 156) | struct exss_asset
type core_decoder (line 157) | struct core_decoder
type core_decoder (line 158) | struct core_decoder
type dcadec_core_info (line 159) | struct dcadec_core_info
type core_decoder (line 159) | struct core_decoder
type dcadec_exss_info (line 160) | struct dcadec_exss_info
type core_decoder (line 160) | struct core_decoder
FILE: libdcadec/core_huffman.h
type huffman (line 1238) | struct huffman
type huffman (line 1245) | struct huffman
type huffman (line 1253) | struct huffman
type huffman (line 1261) | struct huffman
type huffman (line 1265) | struct huffman
type huffman (line 1271) | struct huffman
type huffman (line 1277) | struct huffman
type huffman (line 1283) | struct huffman
type huffman (line 1289) | struct huffman
type huffman (line 1299) | struct huffman
type huffman (line 1309) | struct huffman
type huffman (line 1319) | struct huffman
type huffman (line 1329) | struct huffman
type huffman (line 1339) | struct huffman
FILE: libdcadec/dca_context.c
type dcadec_context (line 39) | struct dcadec_context {
function dca_format_log (line 86) | void dca_format_log(struct dcadec_context *dca, int level,
function reorder_samples (line 109) | static int reorder_samples(struct dcadec_context *dca, int **dca_samples...
function shift_and_clip__ (line 153) | static bool shift_and_clip__(int *samples, int nsamples, int shift, int ...
function shift_and_clip (line 173) | static bool shift_and_clip(struct dcadec_context *dca, int nchannels,
function get_dmix_coeff (line 205) | static int get_dmix_coeff(int nchannels, int spkr, int ch)
function down_mix_prim_chset (line 224) | static int down_mix_prim_chset(struct dcadec_context *dca,
function filter_core_frame (line 305) | static int filter_core_frame(struct dcadec_context *dca)
function map_spkr_to_core_spkr (line 357) | static int map_spkr_to_core_spkr(struct core_decoder *core, int spkr)
function is_hier_dmix_chset (line 368) | static bool is_hier_dmix_chset(struct xll_chset *c)
type xll_chset (line 373) | struct xll_chset
type xll_chset (line 373) | struct xll_chset
type xll_decoder (line 375) | struct xll_decoder
function prescale_down_mix (line 385) | static void prescale_down_mix(struct xll_chset *c, struct xll_chset *o)
type downmix (line 400) | struct downmix {
function undo_down_mix (line 405) | static void undo_down_mix(struct xll_chset *c, struct downmix *dmix, int...
function scale_down_mix (line 444) | static void scale_down_mix(struct xll_chset *c, struct downmix *dmix, in...
function hier_down_mix (line 480) | static int hier_down_mix(struct xll_decoder *xll)
function validate_hd_ma_frame (line 529) | static int validate_hd_ma_frame(struct dcadec_context *dca)
function force_lossy_output (line 630) | static void force_lossy_output(struct core_decoder *core, struct xll_chs...
function filter_residual_core_frame (line 651) | static int filter_residual_core_frame(struct dcadec_context *dca)
function combine_residual_core_frame (line 688) | static int combine_residual_core_frame(struct dcadec_context *dca,
function filter_hd_ma_frame (line 757) | static int filter_hd_ma_frame(struct dcadec_context *dca)
function filter_lbr_frame (line 883) | static int filter_lbr_frame(struct dcadec_context *dca)
function alloc_core_decoder (line 903) | static int alloc_core_decoder(struct dcadec_context *dca)
function alloc_exss_parser (line 914) | static int alloc_exss_parser(struct dcadec_context *dca)
function alloc_xll_decoder (line 924) | static int alloc_xll_decoder(struct dcadec_context *dca)
function alloc_lbr_decoder (line 935) | static int alloc_lbr_decoder(struct dcadec_context *dca)
function DCADEC_API (line 947) | DCADEC_API int dcadec_context_parse(struct dcadec_context *dca, uint8_t ...
function dcadec_core_info (line 1060) | dcadec_core_info *dcadec_context_get_core_info(struct dcadec_context *dca)
function DCADEC_API (line 1067) | DCADEC_API void dcadec_context_free_core_info(struct dcadec_core_info *i...
function dcadec_exss_info (line 1072) | dcadec_exss_info *dcadec_context_get_exss_info(struct dcadec_context *dca)
function DCADEC_API (line 1083) | DCADEC_API void dcadec_context_free_exss_info(struct dcadec_exss_info *i...
function DCADEC_API (line 1088) | DCADEC_API int dcadec_context_filter(struct dcadec_context *dca, int ***...
function DCADEC_API (line 1140) | DCADEC_API void dcadec_context_clear(struct dcadec_context *dca)
function dcadec_context (line 1150) | dcadec_context *dcadec_context_create(int flags)
function DCADEC_API (line 1158) | DCADEC_API void dcadec_context_destroy(struct dcadec_context *dca)
function DCADEC_API (line 1163) | DCADEC_API void dcadec_context_set_log_cb(struct dcadec_context *dca,
function DCADEC_API (line 1174) | DCADEC_API const char *dcadec_strerror(int errnum)
function dcadec_version (line 1218) | DCADEC_API unsigned int dcadec_version(void)
FILE: libdcadec/dca_context.h
type dcadec_context (line 169) | struct dcadec_context
type dcadec_core_info (line 171) | struct dcadec_core_info {
type dcadec_exss_info (line 186) | struct dcadec_exss_info {
type dcadec_context (line 217) | struct dcadec_context
type dcadec_context (line 228) | struct dcadec_context
type dcadec_core_info (line 235) | struct dcadec_core_info
type dcadec_context (line 248) | struct dcadec_context
type dcadec_exss_info (line 255) | struct dcadec_exss_info
type dcadec_context (line 300) | struct dcadec_context
type dcadec_context (line 312) | struct dcadec_context
type dcadec_context (line 328) | struct dcadec_context
type dcadec_context (line 341) | struct dcadec_context
FILE: libdcadec/dca_frame.c
function DCADEC_API (line 42) | DCADEC_API int dcadec_frame_convert_bitstream(uint8_t *dst, size_t *dst_...
function DCADEC_API (line 101) | DCADEC_API int dcadec_frame_parse_header(const uint8_t *data, size_t *size)
function DCADEC_API (line 155) | DCADEC_API size_t dcadec_frame_buffer_size(size_t size)
FILE: libdcadec/dca_stream.c
type dcadec_stream (line 46) | struct dcadec_stream {
function parse_hd_hdr (line 71) | static int parse_hd_hdr(struct dcadec_stream *stream)
function parse_wav_hdr (line 142) | static int parse_wav_hdr(struct dcadec_stream *stream)
function dcadec_stream (line 186) | dcadec_stream *dcadec_stream_open(const char *name, int flags)
function DCADEC_API (line 251) | DCADEC_API void dcadec_stream_close(struct dcadec_stream *stream)
type dcadec_stream (line 259) | struct dcadec_stream
function read_frame (line 277) | static int read_frame(struct dcadec_stream *stream, uint32_t *sync_p)
function DCADEC_API (line 349) | DCADEC_API int dcadec_stream_read(struct dcadec_stream *stream, uint8_t ...
function DCADEC_API (line 391) | DCADEC_API int dcadec_stream_progress(struct dcadec_stream *stream)
function dcadec_stream_info (line 404) | dcadec_stream_info *dcadec_stream_get_info(struct dcadec_stream *stream)
function DCADEC_API (line 422) | DCADEC_API void dcadec_stream_free_info(struct dcadec_stream_info *info)
FILE: libdcadec/dca_stream.h
type dcadec_stream (line 24) | struct dcadec_stream
type dcadec_stream_info (line 26) | struct dcadec_stream_info {
type dcadec_stream (line 52) | struct dcadec_stream
type dcadec_stream (line 70) | struct dcadec_stream
type dcadec_stream (line 79) | struct dcadec_stream
type dcadec_stream (line 91) | struct dcadec_stream
type dcadec_stream_info (line 98) | struct dcadec_stream_info
FILE: libdcadec/dca_waveout.c
type dcadec_waveout (line 30) | struct dcadec_waveout {
type header_buf (line 56) | struct header_buf {
function write_u16 (line 61) | static void write_u16(struct header_buf *buf, int v)
function write_u32 (line 69) | static void write_u32(struct header_buf *buf, int v)
function write_header (line 79) | static int write_header(struct dcadec_waveout *wave, FILE *fp)
function write_data (line 144) | static int write_data(struct dcadec_waveout *wave, FILE *fp,
function DCADEC_API (line 198) | DCADEC_API int dcadec_waveout_write(struct dcadec_waveout *wave, int **s...
function dcadec_waveout (line 278) | dcadec_waveout *dcadec_waveout_open(const char *name, int flags)
function DCADEC_API (line 331) | DCADEC_API void dcadec_waveout_close(struct dcadec_waveout *wave)
FILE: libdcadec/dca_waveout.h
type dcadec_waveout (line 32) | struct dcadec_waveout
type dcadec_waveout (line 61) | struct dcadec_waveout
type dcadec_waveout (line 83) | struct dcadec_waveout
FILE: libdcadec/exss_parser.c
function parse_xll_parameters (line 30) | static void parse_xll_parameters(struct exss_asset *asset)
function parse_lbr_parameters (line 53) | static void parse_lbr_parameters(struct exss_asset *asset)
function parse_descriptor (line 65) | static int parse_descriptor(struct exss_asset *asset)
function set_exss_offsets (line 305) | static int set_exss_offsets(struct exss_asset *asset)
function exss_parse (line 361) | int exss_parse(struct exss_parser *exss, uint8_t *data, int size)
type dcadec_exss_info (line 496) | struct dcadec_exss_info
type exss_parser (line 496) | struct exss_parser
type dcadec_exss_info (line 498) | struct dcadec_exss_info
type exss_asset (line 502) | struct exss_asset
FILE: libdcadec/exss_parser.h
type exss_parser (line 28) | struct exss_parser
type exss_asset (line 30) | struct exss_asset {
type exss_parser (line 74) | struct exss_parser {
type exss_parser (line 95) | struct exss_parser
type dcadec_exss_info (line 96) | struct dcadec_exss_info
type exss_parser (line 96) | struct exss_parser
FILE: libdcadec/fixed_math.h
function round__ (line 22) | static inline int64_t round__(int64_t a, int bits)
function norm__ (line 30) | static inline int32_t norm__(int64_t a, int bits)
function mul__ (line 38) | static inline int32_t mul__(int32_t a, int32_t b, int bits)
function clip__ (line 43) | static inline int32_t clip__(int32_t a, int bits)
function round20 (line 57) | static inline int64_t round20(int64_t a) { return round__(a, 20); }
function round21 (line 58) | static inline int64_t round21(int64_t a) { return round__(a, 21); }
function norm13 (line 60) | static inline int32_t norm13(int64_t a) { return norm__(a, 13); }
function norm16 (line 61) | static inline int32_t norm16(int64_t a) { return norm__(a, 16); }
function norm20 (line 62) | static inline int32_t norm20(int64_t a) { return norm__(a, 20); }
function norm21 (line 63) | static inline int32_t norm21(int64_t a) { return norm__(a, 21); }
function norm23 (line 64) | static inline int32_t norm23(int64_t a) { return norm__(a, 23); }
function mul3 (line 66) | static inline int32_t mul3(int32_t a, int32_t b)
function mul4 (line 71) | static inline int32_t mul4(int32_t a, int32_t b)
function mul15 (line 76) | static inline int32_t mul15(int32_t a, int32_t b) { return mul__(a, b, 1...
function mul16 (line 77) | static inline int32_t mul16(int32_t a, int32_t b) { return mul__(a, b, 1...
function mul17 (line 78) | static inline int32_t mul17(int32_t a, int32_t b) { return mul__(a, b, 1...
function mul22 (line 79) | static inline int32_t mul22(int32_t a, int32_t b) { return mul__(a, b, 2...
function mul23 (line 80) | static inline int32_t mul23(int32_t a, int32_t b) { return mul__(a, b, 2...
function mul31 (line 81) | static inline int32_t mul31(int32_t a, int32_t b) { return mul__(a, b, 3...
function clip23 (line 83) | static inline int32_t clip23(int32_t a) { return clip__(a, 23); }
FILE: libdcadec/huffman.h
type huffman (line 22) | struct huffman {
FILE: libdcadec/idct.h
type idct_context (line 25) | struct idct_context {
type idct_context (line 33) | struct idct_context
type idct_context (line 34) | struct idct_context
type idct_context (line 35) | struct idct_context
FILE: libdcadec/idct_fixed.c
function sum_a (line 23) | static void sum_a(const int * restrict input, int * restrict output, int...
function sum_b (line 29) | static void sum_b(const int * restrict input, int * restrict output, int...
function sum_c (line 36) | static void sum_c(const int * restrict input, int * restrict output, int...
function sum_d (line 42) | static void sum_d(const int * restrict input, int * restrict output, int...
function dct_a (line 49) | static void dct_a(const int * restrict input, int * restrict output)
function dct_b (line 72) | static void dct_b(const int * restrict input, int * restrict output)
function mod_a (line 94) | static void mod_a(const int * restrict input, int * restrict output)
function mod_b (line 112) | static void mod_b(int * restrict input, int * restrict output)
function mod_c (line 131) | static void mod_c(const int * restrict input, int * restrict output)
function clp_v (line 153) | static void clp_v(int *input, int len)
function idct_fixed32 (line 159) | void idct_fixed32(int * restrict input, int * restrict output)
function mod64_a (line 197) | static void mod64_a(const int * restrict input, int * restrict output)
function mod64_b (line 219) | static void mod64_b(int * restrict input, int * restrict output)
function mod64_c (line 240) | static void mod64_c(const int * restrict input, int * restrict output)
function idct_fixed64 (line 270) | void idct_fixed64(int * restrict input, int * restrict output)
FILE: libdcadec/idct_float.c
type idct_context (line 22) | struct idct_context
type idct_context (line 29) | struct idct_context
function proc (line 60) | static void proc(const struct idct_context *s, double *x, int flag)
function idct_fast (line 117) | void idct_fast(const struct idct_context *s, const double *input, double...
function imdct_fast (line 143) | void imdct_fast(const struct idct_context *s, const float *input, float ...
FILE: libdcadec/interpolator.c
type interpolator (line 22) | struct interpolator
type idct_context (line 22) | struct idct_context
type interpolator (line 24) | struct interpolator
function interpolator_clear (line 52) | void interpolator_clear(struct interpolator *dsp)
FILE: libdcadec/interpolator.h
type interpolator (line 24) | struct interpolator
type idct_context (line 25) | struct idct_context
type interpolator (line 30) | struct interpolator
type interpolator (line 35) | struct interpolator {
type interpolator (line 41) | struct interpolator
type idct_context (line 41) | struct idct_context
type interpolator (line 43) | struct interpolator
FILE: libdcadec/interpolator_fixed.c
function INTERPOLATE_LFE (line 25) | INTERPOLATE_LFE(lfe_fixed_fir)
function INTERPOLATE_SUB (line 63) | INTERPOLATE_SUB(sub32_fixed)
function INTERPOLATE_SUB (line 127) | INTERPOLATE_SUB(sub64_fixed)
FILE: libdcadec/interpolator_float.c
function convert (line 34) | static inline int convert(double a)
function interpolate_lfe (line 39) | static void interpolate_lfe(int *pcm_samples, int *lfe_samples, int npcm...
function INTERPOLATE_LFE (line 77) | INTERPOLATE_LFE(lfe_float_fir)
function INTERPOLATE_LFE (line 85) | INTERPOLATE_LFE(lfe_float_fir_2x)
function INTERPOLATE_LFE (line 93) | INTERPOLATE_LFE(lfe_float_iir)
function INTERPOLATE_SUB (line 134) | INTERPOLATE_SUB(sub32_float)
function INTERPOLATE_SUB (line 195) | INTERPOLATE_SUB(sub64_float)
FILE: libdcadec/lbr_bitstream.h
type bytestream (line 19) | struct bytestream {
function bits2_init (line 25) | static void bits2_init(struct bitstream2 *bits, uint8_t *data, size_t size)
function bits2_peek (line 34) | static int bits2_peek(struct bitstream2 *bits, int n)
function bits2_skip (line 46) | static void bits2_skip(struct bitstream2 *bits, int n)
function bits2_get (line 55) | static int bits2_get(struct bitstream2 *bits, int n)
function bits2_getz (line 62) | static int bits2_getz(struct bitstream2 *bits, int n)
function bits2_get1 (line 69) | static bool bits2_get1(struct bitstream2 *bits)
function bits2_skip_long (line 75) | static void bits2_skip_long(struct bitstream2 *bits, int n)
function bits2_get_vlc (line 101) | static int bits2_get_vlc(struct bitstream2 *bits, const uint8_t *table, ...
function bytes_init (line 128) | static void bytes_init(struct bytestream *bytes, uint8_t *data, size_t s...
function bytes_get (line 135) | static int bytes_get(struct bytestream *bytes)
function bytes_get16le (line 146) | static int bytes_get16le(struct bytestream *bytes)
function bytes_get16be (line 157) | static int bytes_get16be(struct bytestream *bytes)
function bytes_get32be (line 168) | static int bytes_get32be(struct bytestream *bytes)
FILE: libdcadec/lbr_decoder.c
type LBRHeader (line 30) | enum LBRHeader {
type LBRFlags (line 35) | enum LBRFlags {
type LBRChunks (line 49) | enum LBRChunks {
type lbr_chunk (line 82) | struct lbr_chunk {
function parse_lfe_24 (line 87) | static int parse_lfe_24(struct lbr_decoder *lbr)
function parse_lfe_16 (line 138) | static int parse_lfe_16(struct lbr_decoder *lbr)
function parse_lfe_chunk (line 185) | static int parse_lfe_chunk(struct lbr_decoder *lbr, struct lbr_chunk *ch...
function parse_ecs_chunk (line 201) | static int parse_ecs_chunk(struct lbr_decoder *lbr, struct lbr_chunk *ch...
function parse_tonal (line 228) | static int parse_tonal(struct lbr_decoder *lbr, int group)
function parse_tonal_chunk (line 310) | static int parse_tonal_chunk(struct lbr_decoder *lbr, struct lbr_chunk *...
function parse_tonal_group (line 335) | static int parse_tonal_group(struct lbr_decoder *lbr, struct lbr_chunk *...
function parse_scale_factors (line 345) | static int parse_scale_factors(struct lbr_decoder *lbr, uint8_t *scf)
function parse_st_code (line 415) | static int parse_st_code(struct bitstream2 *bits, int min_v)
function parse_grid_1_chunk (line 435) | static int parse_grid_1_chunk(struct lbr_decoder *lbr, struct lbr_chunk ...
function parse_grid_1_sec_ch (line 525) | static int parse_grid_1_sec_ch(struct lbr_decoder *lbr, int ch2)
function parse_grid_code (line 559) | static int parse_grid_code(struct bitstream2 *bits, const uint8_t *table...
function parse_grid_3_code (line 566) | static int parse_grid_3_code(struct bitstream2 *bits)
function parse_grid_3 (line 583) | static void parse_grid_3(struct lbr_decoder *lbr, int ch1, int ch2, int ...
function lbr_rand (line 602) | static float lbr_rand(struct lbr_decoder *lbr, int sb)
function parse_ch (line 608) | static void parse_ch(struct lbr_decoder *lbr, int ch, int sb, int quant_...
function parse_ts (line 721) | static int parse_ts(struct lbr_decoder *lbr, int ch1, int ch2,
function convert_lpc (line 783) | static void convert_lpc(float *coeff, const int *codes, const float *table)
function parse_lpc (line 797) | static int parse_lpc(struct lbr_decoder *lbr, int ch1, int ch2, int star...
function parse_high_res_grid (line 820) | static int parse_high_res_grid(struct lbr_decoder *lbr, struct lbr_chunk...
function parse_grid_2_code (line 873) | static int parse_grid_2_code(struct bitstream2 *bits)
function parse_grid_2 (line 890) | static int parse_grid_2(struct lbr_decoder *lbr, int ch1, int ch2,
function parse_ts1_chunk (line 924) | static int parse_ts1_chunk(struct lbr_decoder *lbr, struct lbr_chunk *ch...
function parse_ts2_chunk (line 940) | static int parse_ts2_chunk(struct lbr_decoder *lbr, struct lbr_chunk *ch...
function init_tables (line 960) | static int init_tables(struct lbr_decoder *lbr)
function parse_decoder_init (line 999) | static int parse_decoder_init(struct lbr_decoder *lbr, struct bytestream...
function lbr_parse (line 1124) | int lbr_parse(struct lbr_decoder *lbr, uint8_t *data, size_t size, struc...
function decode_grid (line 1389) | static void decode_grid(struct lbr_decoder *lbr, int ch)
function replace_ts (line 1419) | static void replace_ts(struct lbr_decoder *lbr, int ch1)
function random_ts (line 1434) | static void random_ts(struct lbr_decoder *lbr, int ch)
function predict (line 1465) | static void predict(float *samples, const float *coeff, int nsamples)
function synth_lpc (line 1475) | static void synth_lpc(struct lbr_decoder *lbr, int ch, int sb)
function filter_ts (line 1493) | static void filter_ts(struct lbr_decoder *lbr, int ch1, int ch2)
function decode_part_stereo (line 1578) | static void decode_part_stereo(struct lbr_decoder *lbr, int ch1, int ch2)
function decode_spatial_info (line 1601) | static void decode_spatial_info(struct lbr_decoder *lbr, int ch1, int ch2)
function synth_tones (line 1625) | static void synth_tones(struct lbr_decoder *lbr, int ch, float *values,
function base_func_synth (line 1684) | static void base_func_synth(struct lbr_decoder *lbr, int ch, float *valu...
function transform_channel (line 1708) | static void transform_channel(struct lbr_decoder *lbr, int ch)
function interpolate_lfe (line 1783) | static void interpolate_lfe(struct lbr_decoder *lbr)
function lbr_filter (line 1809) | int lbr_filter(struct lbr_decoder *lbr)
function lbr_clear (line 1875) | void lbr_clear(struct lbr_decoder *lbr)
FILE: libdcadec/lbr_decoder.h
type exss_asset (line 34) | struct exss_asset
type bitstream2 (line 36) | struct bitstream2 {
type lbr_tone (line 44) | struct lbr_tone {
type lbr_decoder (line 53) | struct lbr_decoder {
type lbr_decoder (line 131) | struct lbr_decoder
type exss_asset (line 131) | struct exss_asset
type lbr_decoder (line 132) | struct lbr_decoder
type lbr_decoder (line 133) | struct lbr_decoder
FILE: libdcadec/ta.c
type ta_header (line 26) | struct ta_header {
type ta_header (line 34) | struct ta_header
type ta_header (line 40) | struct ta_header
type ta_ext_header (line 49) | struct ta_ext_header {
type ta_header (line 58) | struct ta_header
type ta_ext_header (line 63) | struct ta_ext_header
type ta_header (line 65) | struct ta_header
type ta_ext_header (line 69) | struct ta_ext_header
type ta_ext_header (line 72) | struct ta_ext_header
function ta_set_parent (line 95) | bool ta_set_parent(void *ptr, void *ta_parent)
type ta_header (line 129) | struct ta_header
type ta_header (line 132) | struct ta_header
type ta_header (line 148) | struct ta_header
type ta_header (line 151) | struct ta_header
type ta_header (line 182) | struct ta_header
type ta_header (line 183) | struct ta_header
function ta_get_size (line 210) | size_t ta_get_size(void *ptr)
function ta_free_children (line 219) | void ta_free_children(void *ptr)
function ta_free (line 231) | void ta_free(void *ptr)
function ta_set_destructor (line 260) | bool ta_set_destructor(void *ptr, void (*destructor)(void *))
type ta_header (line 275) | struct ta_header
type ta_header (line 278) | struct ta_header
FILE: libdcadec/ta.h
function ta_calc_array_size (line 32) | static inline size_t ta_calc_array_size(size_t element_size, size_t count)
function ta_zalloc_fast (line 39) | static inline int ta_zalloc_fast(void *ta_parent, void *ptr,
function ta_alloc_fast (line 56) | static inline int ta_alloc_fast(void *ta_parent, void *ptr,
FILE: libdcadec/xll_decoder.c
function parse_dmix_coeffs (line 30) | static int parse_dmix_coeffs(struct xll_chset *chs)
function chs_parse_header (line 107) | static int chs_parse_header(struct xll_chset *chs, struct exss_asset *as...
function chs_alloc_msb_band_data (line 392) | static int chs_alloc_msb_band_data(struct xll_chset *chs)
function chs_alloc_lsb_band_data (line 413) | static int chs_alloc_lsb_band_data(struct xll_chset *chs)
function chs_parse_band_data (line 447) | static int chs_parse_band_data(struct xll_chset *chs, int band_i, int se...
function chs_clear_band_data (line 607) | static void chs_clear_band_data(struct xll_chset *chs, int band_i, int seg)
function xll_clear_band_data (line 625) | void xll_clear_band_data(struct xll_chset *chs, int band_i)
function xll_filter_band_data (line 644) | void xll_filter_band_data(struct xll_chset *chs, int band_i)
function xll_get_lsb_width (line 710) | int xll_get_lsb_width(struct xll_chset *chs, int band, int ch)
function xll_assemble_msbs_lsbs (line 726) | void xll_assemble_msbs_lsbs(struct xll_chset *chs, int band_i)
function filter0 (line 749) | static void filter0(int *dst, const int *src, int nsamples)
function filter1 (line 755) | static void filter1(int *dst, const int *src, int nsamples, int32_t coeff)
function filter2 (line 761) | static void filter2(int *dst, const int *src, int nsamples, int32_t coeff)
function chs_assemble_freq_bands (line 767) | static int chs_assemble_freq_bands(struct xll_chset *chs)
function xll_assemble_freq_bands (line 815) | int xll_assemble_freq_bands(struct xll_decoder *xll)
function xll_map_ch_to_spkr (line 826) | int xll_map_ch_to_spkr(struct xll_chset *chs, int ch)
function parse_common_header (line 849) | static int parse_common_header(struct xll_decoder *xll)
function parse_sub_headers (line 955) | static int parse_sub_headers(struct xll_decoder *xll, struct exss_asset ...
function parse_navi_table (line 989) | static int parse_navi_table(struct xll_decoder *xll)
function parse_band_data (line 1036) | static int parse_band_data(struct xll_decoder *xll)
function parse_frame (line 1079) | static int parse_frame(struct xll_decoder *xll, uint8_t *data, int size,...
function clear_pbr (line 1097) | static void clear_pbr(struct xll_decoder *xll)
function copy_to_pbr (line 1103) | static int copy_to_pbr(struct xll_decoder *xll, uint8_t *data, int size,...
function parse_frame_no_pbr (line 1117) | static int parse_frame_no_pbr(struct xll_decoder *xll, uint8_t *data, in...
function parse_frame_pbr (line 1175) | static int parse_frame_pbr(struct xll_decoder *xll, uint8_t *data, int s...
function clear_chs (line 1219) | static void clear_chs(struct xll_decoder *xll)
function xll_parse (line 1229) | int xll_parse(struct xll_decoder *xll, uint8_t *data, struct exss_asset ...
function xll_clear (line 1249) | void xll_clear(struct xll_decoder *xll)
FILE: libdcadec/xll_decoder.h
type xll_decoder (line 44) | struct xll_decoder
type exss_asset (line 45) | struct exss_asset
type xll_band (line 47) | struct xll_band {
type xll_chset (line 67) | struct xll_chset {
type xll_decoder (line 121) | struct xll_decoder {
type xll_chset (line 157) | struct xll_chset
type xll_chset (line 158) | struct xll_chset
type xll_chset (line 159) | struct xll_chset
type xll_chset (line 160) | struct xll_chset
type xll_decoder (line 161) | struct xll_decoder
type xll_chset (line 162) | struct xll_chset
type xll_decoder (line 163) | struct xll_decoder
type exss_asset (line 163) | struct exss_asset
type xll_decoder (line 164) | struct xll_decoder
FILE: test/stddev.c
function main (line 28) | int main(int argc, char **argv)
Condensed preview — 62 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,113K chars).
[
{
"path": ".gitignore",
"chars": 78,
"preview": "*.d\n*.o\n*.dll\n*.so\n*.a\n/dcadec\n/dcacut\n*.exe\n*.pc\n/test/decoded/\n/test/stddev\n"
},
{
"path": ".gitmodules",
"chars": 99,
"preview": "[submodule \"test/samples\"]\n\tpath = test/samples\n\turl = https://github.com/foo86/dcadec-samples.git\n"
},
{
"path": "CHANGELOG.md",
"chars": 718,
"preview": "v0.2.0 - Jan 04, 2016\n=====================\n- Fixed installation of shared library symlink.\n- Switched LFE channel inter"
},
{
"path": "COPYING.LGPLv2.1",
"chars": 26530,
"preview": " GNU LESSER GENERAL PUBLIC LICENSE\n Version 2.1, February 1999\n\n Copyright (C) 19"
},
{
"path": "Makefile",
"chars": 4744,
"preview": "VERSION = 0.2.0\n\nAPI_MAJOR = 0\nAPI_MINOR = 1\nAPI_PATCH = 0\n\nCFLAGS := -std=gnu99 -D_FILE_OFFSET_BITS=64 -Wall -Wextra -O"
},
{
"path": "README.md",
"chars": 3065,
"preview": "dcadec\n======\n\ndcadec is a free DTS Coherent Acoustics decoder with support for HD extensions.\n\nSupported features:\n\n* D"
},
{
"path": "dcacut.c",
"chars": 2731,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "dcadec.c",
"chars": 13836,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "dcadec.pc.in",
"chars": 222,
"preview": "prefix=%PREFIX%\nlibdir=%LIBDIR%\nincludedir=%INCLUDEDIR%\n\nName: dcadec\nDescription: a free DTS Coherent Acoustics decoder"
},
{
"path": "getopt.c",
"chars": 2685,
"preview": "/*\n * Copyright © 2005-2014 Rich Felker, et al.\n *\n * Permission is hereby granted, free of charge, to any person obtain"
},
{
"path": "getopt.h",
"chars": 1294,
"preview": "/*\n * Copyright © 2005-2014 Rich Felker, et al.\n *\n * Permission is hereby granted, free of charge, to any person obtain"
},
{
"path": "libdcadec/bitstream.c",
"chars": 4684,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/bitstream.h",
"chars": 2786,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/common.h",
"chars": 10572,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/compiler.h",
"chars": 1648,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/core_decoder.c",
"chars": 82955,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/core_decoder.h",
"chars": 8415,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/core_huffman.h",
"chars": 45017,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/core_tables.h",
"chars": 6588,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/core_vectors.h",
"chars": 373624,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_context.c",
"chars": 39925,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_context.h",
"chars": 14203,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_frame.c",
"chars": 5357,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_frame.h",
"chars": 4395,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_stream.c",
"chars": 12393,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_stream.h",
"chars": 3524,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_waveout.c",
"chars": 10277,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dca_waveout.h",
"chars": 3202,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dmix_tables.c",
"chars": 4674,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/dmix_tables.h",
"chars": 961,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/exss_parser.c",
"chars": 18180,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/exss_parser.h",
"chars": 4351,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/fir_fixed.h",
"chars": 26291,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/fir_float.h",
"chars": 74132,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/fixed_math.h",
"chars": 2792,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/huffman.h",
"chars": 913,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/idct.h",
"chars": 1437,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/idct_fixed.c",
"chars": 11839,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/idct_float.c",
"chars": 4416,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/interpolator.c",
"chars": 1855,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/interpolator.h",
"chars": 2278,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/interpolator_fixed.c",
"chars": 6119,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/interpolator_float.c",
"chars": 8028,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/lbr_bitstream.h",
"chars": 3851,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/lbr_decoder.c",
"chars": 59272,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/lbr_decoder.h",
"chars": 3736,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/lbr_huffman.h",
"chars": 8944,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/lbr_tables.h",
"chars": 24840,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/ta.c",
"chars": 9087,
"preview": "/* Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby gra"
},
{
"path": "libdcadec/ta.h",
"chars": 3165,
"preview": "/* Permission to use, copy, modify, and/or distribute this software for any\n * purpose with or without fee is hereby gra"
},
{
"path": "libdcadec/xll_decoder.c",
"chars": 43663,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/xll_decoder.h",
"chars": 8372,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "libdcadec/xll_tables.h",
"chars": 2300,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "msvc/dcadec/dcadec.vcxproj",
"chars": 14461,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microso"
},
{
"path": "msvc/dcadec/dcadec.vcxproj.filters",
"chars": 1155,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
},
{
"path": "msvc/dcadec.sln",
"chars": 3683,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2013\nVisualStudioVersion = 12.0.31101.0\nMin"
},
{
"path": "msvc/libdcadec/libdcadec.vcxproj",
"chars": 16088,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microso"
},
{
"path": "msvc/libdcadec/libdcadec.vcxproj.filters",
"chars": 4872,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
},
{
"path": "test/checksum.txt",
"chars": 9547,
"preview": "9415e0d4c7cd58ee793d7b2bfae34e4de411181c *decoded/dmix_0/core_51_24_48_768_0.wav\nde10f73b35c2db915f69c46ddc95468c25510bd"
},
{
"path": "test/stddev.c",
"chars": 2932,
"preview": "/*\n * This file is part of libdcadec.\n *\n * This library is free software; you can redistribute it and/or modify it\n * u"
},
{
"path": "test/stddev.txt",
"chars": 3465,
"preview": "decoded/mono/core_51_24_48_768_0_C.wav: 2.282641\ndecoded/mono/core_51_24_48_768_0_L.wav: 1.783442\ndecoded/mono/core_51_2"
},
{
"path": "test/test.sh",
"chars": 1423,
"preview": "#!/bin/sh\n\nset -e\n\nif [ ! -f samples/README ] ; then\n echo \"ERROR: Run 'git submodule update --init test/samples' fir"
}
]
About this extraction
This page contains the full source code of the foo86/dcadec GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 62 files (1.0 MB), approximately 471.5k tokens, and a symbol index with 436 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.