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. Copyright (C) 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. , 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] [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 #include #include #include #include #include #include #include "libdcadec/dca_stream.h" int main(int argc, char **argv) { if (argc < 3) { fprintf(stderr, "Usage: %s [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 #include #include #include #include #include #ifdef _MSC_VER #include "getopt.h" #else #include #endif #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #else #include #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] [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 #include #include #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 #include #include #include #include #include #include #include #include #include #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, 0x0043, 0x003c, 0x0033, 0x0031, 0x0030, 0x0011, 0x0010, 0x01da, 0x01d9, 0x01ca, 0x01c9, 0x01ba, 0x01b9, 0x019b, 0x019a, 0x00fb, 0x00fa, 0x00f8, 0x00eb, 0x00d5, 0x00d4, 0x00aa, 0x00a5, 0x008b, 0x008a, 0x0084, 0x007b, 0x0065, 0x0064, 0x0025, 0x0024, 0x03b6, 0x03b1, 0x0397, 0x0396, 0x0390, 0x0377, 0x0371, 0x0370, 0x0332, 0x0331, 0x01f3, 0x01f2, 0x01d5, 0x01d4, 0x0157, 0x0156, 0x0149, 0x0148, 0x010b, 0x010a, 0x00f5, 0x00f4, 0x004f, 0x004e, 0x004d, 0x004c, 0x076f, 0x076e, 0x0761, 0x0760, 0x0723, 0x0722, 0x06ed, 0x06ec, 0x0667, 0x0666, 0x0661, 0x0660 }; // // Table B129 // static const uint8_t B129_len[] = { 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 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, 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, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 14, 14 }; static const uint16_t B129_code[] = { 0x000a, 0x0007, 0x0006, 0x0004, 0x0003, 0x0000, 0x003f, 0x003c, 0x003b, 0x0039, 0x0038, 0x0035, 0x0034, 0x0032, 0x0031, 0x002e, 0x002d, 0x002b, 0x002a, 0x0027, 0x0026, 0x0023, 0x0022, 0x0020, 0x001f, 0x001c, 0x001b, 0x0019, 0x0018, 0x0016, 0x0013, 0x0010, 0x000b, 0x0005, 0x0004, 0x007d, 0x007c, 0x007a, 0x0075, 0x006e, 0x006d, 0x0067, 0x0066, 0x0060, 0x005f, 0x0059, 0x0058, 0x0051, 0x0050, 0x004a, 0x0049, 0x0042, 0x003d, 0x003b, 0x003a, 0x0034, 0x002f, 0x0025, 0x0024, 0x0015, 0x0014, 0x0006, 0x0005, 0x00f7, 0x00f6, 0x00df, 0x00de, 0x00d9, 0x00d8, 0x00bd, 0x00bc, 0x00a6, 0x00a5, 0x0097, 0x0096, 0x0090, 0x0087, 0x0079, 0x0078, 0x006a, 0x005d, 0x0047, 0x0046, 0x0044, 0x000f, 0x0009, 0x0008, 0x01d2, 0x01d1, 0x0187, 0x0186, 0x0184, 0x014f, 0x0149, 0x0148, 0x010d, 0x010c, 0x00d7, 0x00d6, 0x00b8, 0x008b, 0x001d, 0x001c, 0x03a6, 0x03a1, 0x030b, 0x030a, 0x029c, 0x0247, 0x0246, 0x0245, 0x0173, 0x0172, 0x0114, 0x074f, 0x0741, 0x0740, 0x053a, 0x0489, 0x0488, 0x022b, 0x0e9d, 0x0e9c, 0x0a76, 0x0455, 0x0454, 0x14ef, 0x29dd, 0x29dc }; // // Table C129 // static const uint8_t C129_len[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 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, 7, 7, 7, 7, 7, 7, 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, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 13, 13 }; static const uint16_t C129_code[] = { 0x003a, 0x0037, 0x0036, 0x0034, 0x0033, 0x0031, 0x0030, 0x002e, 0x002d, 0x002b, 0x002a, 0x0028, 0x0027, 0x0025, 0x0024, 0x0022, 0x0021, 0x001e, 0x001d, 0x001b, 0x001a, 0x0018, 0x0017, 0x0015, 0x0014, 0x0012, 0x0011, 0x000e, 0x000d, 0x000c, 0x000b, 0x0008, 0x0007, 0x0006, 0x0005, 0x0003, 0x0002, 0x007f, 0x007e, 0x007c, 0x007b, 0x0079, 0x0078, 0x0076, 0x0073, 0x0071, 0x0070, 0x006a, 0x0065, 0x005f, 0x005e, 0x0058, 0x0053, 0x004d, 0x004c, 0x0046, 0x0041, 0x0040, 0x003f, 0x0038, 0x0033, 0x002d, 0x002c, 0x0027, 0x0026, 0x001f, 0x001e, 0x0014, 0x0013, 0x0012, 0x0009, 0x0003, 0x0002, 0x0000, 0x00fb, 0x00f5, 0x00f4, 0x00ee, 0x00e5, 0x00d7, 0x00d6, 0x00c8, 0x00b3, 0x00a5, 0x00a4, 0x008f, 0x008e, 0x007c, 0x0073, 0x0065, 0x0064, 0x0042, 0x0041, 0x002b, 0x002a, 0x0011, 0x0010, 0x0002, 0x01f5, 0x01df, 0x01de, 0x01c8, 0x0193, 0x0165, 0x0164, 0x00fb, 0x00fa, 0x00e4, 0x0087, 0x0081, 0x0080, 0x0006, 0x03e9, 0x03e8, 0x0393, 0x0325, 0x0324, 0x01ca, 0x010d, 0x010c, 0x000f, 0x0725, 0x0724, 0x0396, 0x001d, 0x001c, 0x072f, 0x0e5d, 0x0e5c }; // // Table D129 // static const uint8_t D129_len[] = { 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 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, 14, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; static const uint16_t D129_code[] = { 0x0009, 0x0006, 0x0005, 0x0002, 0x0001, 0x001e, 0x001d, 0x001a, 0x0019, 0x0016, 0x0015, 0x0010, 0x000f, 0x0008, 0x0007, 0x0000, 0x003f, 0x0038, 0x0037, 0x0030, 0x002f, 0x0028, 0x0023, 0x001c, 0x0013, 0x000c, 0x0003, 0x007c, 0x0073, 0x006c, 0x0063, 0x005c, 0x0053, 0x0044, 0x003b, 0x0024, 0x001b, 0x0004, 0x00fb, 0x00e4, 0x00db, 0x00c4, 0x00bb, 0x00a4, 0x008b, 0x0074, 0x004b, 0x0034, 0x000b, 0x01f5, 0x01f4, 0x01b5, 0x01b4, 0x0175, 0x0174, 0x0115, 0x0114, 0x0095, 0x0094, 0x0015, 0x0014, 0x0395, 0x0394, 0x0315, 0x0314, 0x0295, 0x0294, 0x01d5, 0x01d4, 0x00d6, 0x00d5, 0x072e, 0x072d, 0x062e, 0x062d, 0x052e, 0x052d, 0x03ae, 0x03ad, 0x01af, 0x01ae, 0x0e5f, 0x0e5e, 0x0c5f, 0x0c5e, 0x0c58, 0x0a5f, 0x0a58, 0x075f, 0x0758, 0x0353, 0x0351, 0x0350, 0x1cb2, 0x1cb1, 0x18b2, 0x14bd, 0x0ebd, 0x0ebc, 0x0eb2, 0x06a5, 0x3967, 0x3966, 0x3960, 0x3167, 0x2979, 0x2978, 0x2964, 0x1d67, 0x0d49, 0x0d48, 0x72c2, 0x62cd, 0x52cb, 0x52ca, 0x3acd, 0x3acc, 0xe587, 0xe586, 0xc599, 0xc598, 0xa59f, 0xa59e, 0xa59d, 0xa59c, 0xa59b, 0xa59a, 0xa599, 0xa598 }; // // Table E129 // static const uint8_t E129_len[] = { 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, 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, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; static const uint16_t E129_code[] = { 0x000c, 0x000b, 0x000a, 0x0009, 0x0008, 0x0007, 0x0006, 0x0004, 0x0003, 0x0002, 0x0001, 0x0000, 0x003f, 0x003d, 0x003c, 0x003b, 0x003a, 0x0038, 0x0037, 0x0035, 0x0034, 0x0033, 0x0032, 0x002f, 0x002e, 0x002d, 0x002c, 0x002a, 0x0029, 0x0026, 0x0025, 0x0024, 0x0023, 0x0020, 0x001f, 0x001d, 0x001c, 0x001a, 0x000b, 0x007d, 0x007c, 0x006d, 0x006c, 0x0062, 0x0061, 0x0057, 0x0056, 0x004f, 0x004e, 0x0044, 0x0043, 0x003c, 0x0037, 0x0015, 0x0014, 0x00e6, 0x00e5, 0x00c6, 0x00c1, 0x00a3, 0x00a2, 0x008b, 0x008a, 0x007b, 0x007a, 0x006c, 0x01cf, 0x01c9, 0x01c8, 0x0181, 0x0180, 0x0141, 0x0140, 0x010a, 0x0109, 0x00da, 0x039d, 0x031e, 0x031d, 0x0286, 0x0285, 0x0217, 0x0216, 0x0210, 0x01b7, 0x0738, 0x063f, 0x0638, 0x050f, 0x0508, 0x0423, 0x036d, 0x036c, 0x0c7d, 0x0c7c, 0x0a1d, 0x0a1c, 0x0845, 0x0844, 0x1ce6, 0x1ce5, 0x18e6, 0x18e5, 0x1426, 0x1425, 0x39cf, 0x39ce, 0x31cf, 0x31ce, 0x284e, 0x2849, 0x7393, 0x7392, 0x7390, 0x6393, 0x5091, 0x5090, 0xe723, 0xe722, 0xc724, 0xa13d, 0xc725, 0xa13e, 0xc722, 0xa13f, 0xc723, 0xc720, 0xc721, 0xa13c }; // // Table F129 // static const uint8_t F129_len[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 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, 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, 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, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 14, 15, 15 }; static const uint16_t F129_code[] = { 0x0038, 0x0037, 0x0036, 0x0034, 0x0033, 0x0032, 0x0031, 0x0030, 0x002f, 0x002e, 0x002d, 0x002c, 0x002b, 0x0029, 0x0028, 0x0027, 0x0026, 0x0024, 0x0023, 0x0022, 0x0021, 0x001f, 0x001e, 0x001d, 0x001c, 0x001a, 0x0019, 0x0017, 0x0016, 0x0015, 0x0014, 0x0012, 0x0011, 0x000f, 0x000e, 0x000c, 0x000b, 0x0009, 0x0008, 0x0007, 0x0006, 0x0003, 0x0002, 0x0001, 0x0000, 0x007d, 0x007c, 0x007b, 0x007a, 0x0078, 0x0077, 0x0074, 0x0073, 0x0072, 0x006b, 0x0054, 0x004b, 0x0041, 0x0040, 0x0036, 0x0031, 0x0027, 0x0026, 0x001b, 0x001a, 0x0014, 0x000b, 0x000a, 0x0009, 0x00fe, 0x00fd, 0x00f3, 0x00f2, 0x00eb, 0x00ea, 0x00d5, 0x00d4, 0x0095, 0x0094, 0x006e, 0x0061, 0x0042, 0x0041, 0x002b, 0x002a, 0x0010, 0x01ff, 0x01f9, 0x01f8, 0x01da, 0x01d9, 0x0157, 0x0156, 0x0154, 0x00df, 0x00c0, 0x0087, 0x0081, 0x0080, 0x0022, 0x03fd, 0x03b7, 0x03b6, 0x03b0, 0x02ab, 0x01bd, 0x01bc, 0x010d, 0x010c, 0x0047, 0x0046, 0x07f8, 0x0763, 0x0554, 0x0307, 0x0306, 0x0305, 0x0ff3, 0x0ff2, 0x0ec4, 0x0aab, 0x0609, 0x0608, 0x1d8a, 0x1555, 0x1554, 0x3b17, 0x762d, 0x762c }; // // Table G129 // static const uint8_t G129_len[] = { 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, 6, 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, 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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13 }; static const uint16_t G129_code[] = { 0x0000, 0x001d, 0x001c, 0x0019, 0x0018, 0x0015, 0x0014, 0x0011, 0x0010, 0x000d, 0x000c, 0x0009, 0x0008, 0x0005, 0x0004, 0x003f, 0x003e, 0x0037, 0x0036, 0x002f, 0x002e, 0x0027, 0x0026, 0x001f, 0x001e, 0x0017, 0x0016, 0x000f, 0x000e, 0x0007, 0x0006, 0x007b, 0x007a, 0x006b, 0x006a, 0x005b, 0x005a, 0x004b, 0x004a, 0x003b, 0x003a, 0x002b, 0x002a, 0x001b, 0x001a, 0x000b, 0x000a, 0x0008, 0x00f3, 0x00f0, 0x00d3, 0x00d0, 0x00b3, 0x00b0, 0x0093, 0x0090, 0x0073, 0x0070, 0x0053, 0x0050, 0x0033, 0x0030, 0x0013, 0x01e4, 0x01e3, 0x01a5, 0x01a4, 0x0165, 0x0164, 0x0125, 0x0124, 0x00e5, 0x00e4, 0x00e2, 0x00a5, 0x00a2, 0x0065, 0x0062, 0x0025, 0x03ca, 0x03c5, 0x0347, 0x0346, 0x02c7, 0x02c6, 0x02c4, 0x0247, 0x0244, 0x01c7, 0x0149, 0x0148, 0x00c9, 0x00c8, 0x00c6, 0x0049, 0x0796, 0x0789, 0x068b, 0x068a, 0x0688, 0x058b, 0x048d, 0x048c, 0x048a, 0x038d, 0x028f, 0x028e, 0x028c, 0x018f, 0x0091, 0x0090, 0x0f2e, 0x0f11, 0x0d13, 0x0d12, 0x0b15, 0x0b14, 0x0917, 0x0916, 0x0719, 0x0718, 0x051b, 0x051a, 0x031d, 0x031c, 0x1e5f, 0x1e5e, 0x1e21, 0x1e20 }; // // Code books // static const struct huffman transition_mode_huff[] = { { A4_len, A4_code, 4 }, { B4_len, B4_code, 4 }, { C4_len, C4_code, 4 }, { D4_len, D4_code, 4 } }; static const struct huffman scale_factor_huff[] = { { SA129_len, SA129_code, 129 }, { SB129_len, SB129_code, 129 }, { SC129_len, SC129_code, 129 }, { SD129_len, SD129_code, 129 }, { SE129_len, SE129_code, 129 } }; static const struct huffman bit_allocation_huff[] = { { A12_len, A12_code, 12 }, { B12_len, B12_code, 12 }, { C12_len, C12_code, 12 }, { D12_len, D12_code, 12 }, { E12_len, E12_code, 12 } }; static const struct huffman quant_index_huff_0[] = { { A3_len, A3_code, 3 } }; static const struct huffman quant_index_huff_1[] = { { A5_len, A5_code, 5 }, { B5_len, B5_code, 5 }, { C5_len, C5_code, 5 } }; static const struct huffman quant_index_huff_2[] = { { A7_len, A7_code, 7 }, { B7_len, B7_code, 7 }, { C7_len, C7_code, 7 } }; static const struct huffman quant_index_huff_3[] = { { A9_len, A9_code, 9 }, { B9_len, B9_code, 9 }, { C9_len, C9_code, 9 } }; static const struct huffman quant_index_huff_4[] = { { A13_len, A13_code, 13 }, { B13_len, B13_code, 13 }, { C13_len, C13_code, 13 } }; static const struct huffman quant_index_huff_5[] = { { A17_len, A17_code, 17 }, { B17_len, B17_code, 17 }, { C17_len, C17_code, 17 }, { D17_len, D17_code, 17 }, { E17_len, E17_code, 17 }, { F17_len, F17_code, 17 }, { G17_len, G17_code, 17 } }; static const struct huffman quant_index_huff_6[] = { { A25_len, A25_code, 25 }, { B25_len, B25_code, 25 }, { C25_len, C25_code, 25 }, { D25_len, D25_code, 25 }, { E25_len, E25_code, 25 }, { F25_len, F25_code, 25 }, { G25_len, G25_code, 25 } }; static const struct huffman quant_index_huff_7[] = { { A33_len, A33_code, 33 }, { B33_len, B33_code, 33 }, { C33_len, C33_code, 33 }, { D33_len, D33_code, 33 }, { E33_len, E33_code, 33 }, { F33_len, F33_code, 33 }, { G33_len, G33_code, 33 } }; static const struct huffman quant_index_huff_8[] = { { A65_len, A65_code, 65 }, { B65_len, B65_code, 65 }, { C65_len, C65_code, 65 }, { D65_len, D65_code, 65 }, { E65_len, E65_code, 65 }, { F65_len, F65_code, 65 }, { G65_len, G65_code, 65 } }; static const struct huffman quant_index_huff_9[] = { { A129_len, A129_code, 129 }, { B129_len, B129_code, 129 }, { C129_len, C129_code, 129 }, { D129_len, D129_code, 129 }, { E129_len, E129_code, 129 }, { F129_len, F129_code, 129 }, { G129_len, G129_code, 129 } }; static const struct huffman * const quant_index_group_huff[] = { quant_index_huff_0, quant_index_huff_1, quant_index_huff_2, quant_index_huff_3, quant_index_huff_4, quant_index_huff_5, quant_index_huff_6, quant_index_huff_7, quant_index_huff_8, quant_index_huff_9 }; static const uint8_t quant_index_group_size[] = { 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; ================================================ FILE: libdcadec/core_tables.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 5-4: Audio channel arrangement static const uint8_t audio_mode_nch[16] = { 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8 }; // Table 5-5: Core audio sampling frequencies static const int32_t sample_rates[16] = { 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 0, 0 }; // Table 5-7: Rate parameter versus targeted bit-rate static const int32_t bit_rates[32] = { 32000, 56000, 64000, 96000, 112000, 128000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000, 768000, 960000, 1024000,1152000,1280000,1344000,1408000,1411200,1472000, 1536000, -1, -1, -1, -1, 0, -1, -2 }; // Table 5-17: Quantization resolution of source PCM samples static const uint8_t sample_res[8] = { 16, 16, 20, 20, 0, 24, 24, 0 }; // Table 5-26: Selection of quantization levels and codebooks static const int32_t quant_levels[32] = { 0, 3, 5, 7, 9, 13, 17, 25, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, -1, -1, -1, -1, -1 }; // Table 5-26: Selection of quantization levels and codebooks static const uint8_t quant_index_sel_nbits[10] = { 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; // Table 5-27: Scale factor adjustment index static const int32_t scale_factor_adj[4] = { 4194304, 4718592, 5242880, 6029312 }; // Annex D.1.1 - 6 bit quantization (nominal 2,2 dB step) static const int32_t scale_factors_6bit[64] = { 1, 2, 2, 3, 3, 4, 6, 7, 10, 12, 16, 20, 26, 34, 44, 56, 72, 93, 120, 155, 200, 257, 331, 427, 550, 708, 912, 1175, 1514, 1950, 2512, 3236, 4169, 5370, 6918, 8913, 11482, 14791, 19055, 24547, 31623, 40738, 52481, 67608, 87096, 112202, 144544, 186209, 239883, 309030, 398107, 512861, 660693, 851138, 1096478, 1412538, 1819701, 2344229, 3019952, 3890451, 5011872, 6456542, 8317638, 0 }; // Annex D.1.2 - 7 bit quantization (nominal 1,1 dB step) static const int32_t scale_factors_7bit[128] = { 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 7, 8, 10, 11, 12, 14, 16, 18, 20, 23, 26, 30, 34, 38, 44, 50, 56, 64, 72, 82, 93, 106, 120, 136, 155, 176, 200, 226, 257, 292, 331, 376, 427, 484, 550, 624, 708, 804, 912, 1035, 1175, 1334, 1514, 1718, 1950, 2213, 2512, 2851, 3236, 3673, 4169, 4732, 5370, 6095, 6918, 7852, 8913, 10116, 11482, 13032, 14791, 16788, 19055, 21627, 24547, 27861, 31623, 35892, 40738, 46238, 52481, 59566, 67608, 76736, 87096, 98855, 112202, 127350, 144544, 164059, 186209, 211349, 239883, 272270, 309030, 350752, 398107, 451856, 512861, 582103, 660693, 749894, 851138, 966051, 1096478, 1244515, 1412538, 1603245, 1819701, 2065380, 2344229, 2660725, 3019952, 3427678, 3890451, 4415704, 5011872, 5688529, 6456542, 7328245, 8317638, 0, 0, 0 }; // Annex D.2.1 - Lossy quantization static const int32_t step_size_lossy[32] = { 0, 6710886, 4194304, 3355443, 2474639, 2097152, 1761608, 1426063, 796918, 461373, 251658, 146801, 79692, 46137, 27263, 16777, 10486, 5872, 3355, 1887, 1258, 713, 336, 168, 84, 42, 21, -1, -1, -1, -1, -1 }; // Annex D.2.2 - Lossless quantization static const int32_t step_size_lossless[32] = { 0, 4194304, 2097152, 1384120, 1048576, 696254, 524288, 348127, 262144, 131072, 65431, 33026, 16450, 8208, 4100, 2049, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, -1, -1, -1, -1, -1 }; // Annex D.3 - Scale factor for joint intensity coding static const int32_t joint_scale_factors[129] = { 3288, 3490, 3691, 3909, 4144, 4387, 4647, 4924, 5218, 5528, 5855, 6199, 6568, 6963, 7374, 7810, 8271, 8758, 9278, 9831, 10410, 11031, 11685, 12373, 13103, 13883, 14705, 15578, 16500, 17482, 18514, 19613, 20770, 22003, 23312, 24688, 26156, 27699, 29343, 31080, 32925, 34871, 36943, 39133, 41448, 43906, 46506, 49258, 52177, 55273, 58544, 62017, 65691, 69584, 73711, 78073, 82703, 87602, 92795, 98289, 104111, 110285, 116820, 123740, 131072, 138840, 147069, 155776, 165012, 174785, 185145, 196117, 207735, 220042, 233086, 246894, 261523, 277017, 293434, 310823, 329236, 348748, 369409, 391303, 414490, 439043, 465064, 492621, 521805, 552725, 585475, 620170, 656920, 695843, 737073, 780745, 827008, 876014, 927923, 982902, 1041144, 1102834, 1168181, 1237404, 1310720, 1388382, 1470649, 1557790, 1650098, 1747876, 1851441, 1961147, 2077355, 2200441, 2330825, 2468935, 2615232, 2770195, 2934335, 3108206, 3292378, 3487463, 3694108, 3913000, 4144862, 4390455, 4650611, 4926176, 5218066 }; // Annex D.6 - Block code books static const uint8_t block_code_nbits[8] = { 0, 7, 10, 12, 13, 15, 17, 19 }; ================================================ FILE: libdcadec/core_vectors.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 */ static const int16_t adpcm_coeffs[4096][4] = { { 9928, -2618, -1093, -1263 }, { 11077, -2876, -1747, -308 }, { 10503, -1082, -1426, -1167 }, { 9337, -2403, -1495, 274 }, { 10698, -2529, -532, -1122 }, { 10368, -3974, -1264, -750 }, { 10070, -3667, 346, 863 }, { 10278, -3093, 311, -576 }, { 9894, -1330, -1428, -860 }, { 10544, -1923, -1058, -971 }, { 10996, -1632, -841, -1404 }, { 11832, -3465, 1658, -1990 }, { 10852, -688, -2658, -499 }, { 10546, -1749, -147, -1733 }, { 10801, -1004, -708, -1453 }, { 10588, -441, -2113, -952 }, { 10141, -3331, -582, -1432 }, { 9608, -2590, 383, 258 }, { 11422, -3265, 229, -1544 }, { 10460, -1338, -713, -1568 }, { 10306, -1721, -1660, -603 }, { 9580, -1812, -1235, -1061 }, { 11471, -2285, -1617, -607 }, { 10081, -2225, -1408, -868 }, { 10715, -2624, -1367, -704 }, { 10616, -1871, -2770, -35 }, { 9352, -2340, -1024, -1566 }, { 11065, -1458, -1926, -735 }, { 11334, -2056, -1041, -1144 }, { 9825, -2048, -794, -1536 }, { 11850, -2695, -1123, -867 }, { 10654, -2226, -1891, -373 }, { 10024, -1557, -808, -1069 }, { 11142, -1266, -3238, 128 }, { 11729, -3282, -514, -1011 }, { 11402, -2094, -2335, -189 }, { 10195, -3658, 181, -1875 }, { 11431, -2626, -404, -1377 }, { 11001, -3868, -619, -1077 }, { 10894, -2559, 274, -1758 }, { 9633, -1482, -2253, -773 }, { 11245, -3321, 830, -1972 }, { 9768, -2701, -199, -1859 }, { 10500, -2042, 525, -2043 }, { 11669, -4069, 293, -1468 }, { 9192, -1991, -583, -61 }, { 10057, -3220, -2015, -473 }, { 9497, -2315, -2490, -467 }, { 10455, -3069, -1194, -1007 }, { 9994, -1936, -60, -1225 }, { 9295, -2156, -1761, -1134 }, { 10085, -3748, -1026, 197 }, { 9334, -2360, 804, -351 }, { 11561, -2553, 1352, -2313 }, { 12837, -3998, 1195, -1958 }, { 10114, -1100, -2414, -394 }, { 9341, -2530, 315, 755 }, { 10131, -3164, 1411, -674 }, { 9535, -905, -1551, 579 }, { 11717, -1519, -3051, 91 }, { 9824, -2911, -2775, 192 }, { 9662, -2934, -561, 1450 }, { 11085, -3392, -1298, -659 }, { 8955, -2102, -1899, 703 }, { 8607, -1742, -4348, 814 }, { 7640, -2063, -3617, 52 }, { 7074, -826, -4325, 4375 }, { 7714, 584, -4238, 1927 }, { 6355, -952, -4912, 3127 }, { 7069, -660, -6413, 4087 }, { 8313, -132, -2964, -876 }, { 6952, -1422, -3962, -24 }, { 9299, -734, -3088, -263 }, { 9484, -574, -4513, 466 }, { 7246, -91, -3735, -704 }, { 8325, -1417, -3090, -530 }, { 6469, -1226, -4757, 829 }, { 6652, -368, -5682, 1393 }, { 7971, -1278, -2284, 1205 }, { 7229, -699, -3556, 1840 }, { 7994, 1284, -2729, 732 }, { 9005, -698, -4522, 2189 }, { 6963, 197, -2727, 380 }, { 8527, 135, -3991, -213 }, { 8840, 934, -3014, -567 }, { 10125, 418, -3284, -371 }, { 6367, 361, -2318, 2554 }, { 7892, 172, -5247, 4673 }, { 6674, 387, -5424, 4398 }, { 6240, 684, -4047, 1219 }, { 11170, -794, -5081, 1195 }, { 11765, -648, -6265, 2052 }, { 10845, -775, -3837, 366 }, { 12496, -689, -8260, 3562 }, { 7893, -1166, -4972, 988 }, { 8592, 1052, -5986, 3087 }, { 7277, 1874, -5685, 3579 }, { 6900, 2016, -4809, 3491 }, { 8530, -2405, -3250, 1986 }, { 9426, 494, -7067, 5038 }, { 10285, 564, -8210, 5370 }, { 8749, -2207, -3980, 2852 }, { 9653, -2686, -4300, 1400 }, { 9770, -2286, -5663, 4233 }, { 8490, -4, -7048, 4496 }, { 7697, -1209, -5328, 3183 }, { 6451, 801, -4324, -554 }, { 7387, 1806, -5265, 545 }, { 7450, -2302, -4445, 1418 }, { 8817, -1370, -5827, 2168 }, { 10324, -2406, -5629, 2579 }, { 8863, -2578, -3537, 467 }, { 6901, -1624, -3169, 3392 }, { 7846, 156, -6948, 3381 }, { 7928, -1115, -5972, 4816 }, { 6089, -599, -4368, -320 }, { 7833, 1246, -3960, -621 }, { 8931, 2521, -6768, 2052 }, { 8900, 1944, -4126, 40 }, { 7661, -34, -2855, 2480 }, { 5873, 474, -3262, 3712 }, { 7535, -234, -4699, 216 }, { 5856, 143, -5142, 73 }, { 8944, -106, -5874, 3663 }, { 7134, 426, -5879, 2895 }, { 10199, 1011, -4762, 369 }, { 8454, 264, -5971, 1291 }, { 7822, -2449, -4333, 4540 }, { 6200, -2758, -2632, 1497 }, { 6070, -4315, -2699, 414 }, { 7047, -3739, -3210, 1060 }, { 5675, -3801, -2717, -407 }, { 4789, -4063, -2628, -744 }, { 4023, -3366, -3133, -726 }, { 4296, -2407, -3381, -513 }, { 4388, -2931, -2820, 1512 }, { 4559, -4233, -1941, 1976 }, { 6702, -3208, -1755, 1680 }, { 4416, -3521, -1052, 2984 }, { 7154, -4266, -1203, 3732 }, { 3625, -4242, -3244, 1395 }, { 6518, -2856, -1304, 2887 }, { 6170, -1949, -3014, 3973 }, { 5189, -2451, -4020, 3477 }, { 6218, -2988, -1921, 3844 }, { 4827, -3688, -1928, 3343 }, { 6668, -3991, -2805, 3095 }, { 5297, -3115, -3684, 2390 }, { 5354, -4614, -2662, 1504 }, { 4196, -3091, -4147, 1135 }, { 3540, -2893, -4007, 100 }, { 5569, -1602, -4007, 1909 }, { 4341, -2091, -4272, 252 }, { 5559, -2878, -3832, 498 }, { 4548, -4479, -2898, -27 }, { 5176, -2494, -4635, 1476 }, { 3294, -3485, -3738, 716 }, { 4920, -1229, -4195, -365 }, { 3257, -3518, -3349, 2862 }, { 5286, -1948, -3485, -778 }, { 6502, -3051, -152, 2854 }, { 5864, -4192, -1076, 3451 }, { 4656, -3122, -3448, 179 }, { 5907, -754, -1596, 3116 }, { 7229, -3680, -1590, 2892 }, { 5107, -3888, -3364, 806 }, { 6764, -2635, -3450, 134 }, { 5258, -2827, -2844, -1052 }, { 5798, -1725, -4305, 205 }, { 5404, -1213, -3362, 449 }, { 6224, -2738, -3046, -581 }, { 4223, -2438, -2725, 3745 }, { 4751, -3411, -2123, 116 }, { 3868, -3000, -3954, 2297 }, { 6819, -2899, -4277, 2825 }, { 4207, -4754, -2808, 865 }, { 4804, -1494, -1997, 4688 }, { 5282, -2213, -548, 3559 }, { 5580, -1912, -566, 4370 }, { 6168, -2857, -672, 4053 }, { 6583, -4515, -2850, 1670 }, { 6511, -3093, -3988, 1421 }, { 4646, -1790, -1443, 3650 }, { 5915, -924, -2020, 896 }, { 7814, -4181, -3152, 2007 }, { 6190, -2238, -4817, 2279 }, { 4737, -4034, -3288, 1835 }, { 8161, -3633, -3423, 3137 }, { 7415, -2351, -2088, 4290 }, { 4106, -2517, -62, 2905 }, { 4909, -3145, -614, 4112 }, { 4938, -3281, -397, 1100 }, { -173, 919, 1589, -5363 }, { -13, 796, -295, -6655 }, { -1860, -829, 1141, -4555 }, { 2298, -838, -664, -5005 }, { -884, -1097, 2074, -4613 }, { -101, 281, 2846, -4535 }, { 1166, 453, 2429, -5910 }, { 879, -664, 2370, -5452 }, { 1415, -370, -1699, -4727 }, { -1413, 1277, -669, -6649 }, { 2133, 304, -968, -4624 }, { 380, 586, -2087, -4892 }, { 1336, 275, -82, -5789 }, { -2459, 1057, -34, -5416 }, { 2278, -1758, 866, -5653 }, { 1945, -2295, -149, -5302 }, { 1287, -3525, 996, -5255 }, { 2297, 803, 1177, -6067 }, { 187, -180, -619, -6202 }, { -793, -2537, 1554, -5057 }, { -2703, -204, -629, -5853 }, { -1007, -146, 313, -5582 }, { 830, 357, 869, -6363 }, { -228, -575, -3177, -4433 }, { -1001, -1553, -142, -5708 }, { -1644, 1683, 1721, -4533 }, { 893, 1924, -15, -5791 }, { 2195, 2061, -262, -5471 }, { 3031, 270, 311, -5096 }, { 1912, 1638, -1523, -4677 }, { -3142, -55, 253, -4914 }, { 356, -1680, 343, -6123 }, { -2241, -1734, -976, -5939 }, { -2196, -2893, 547, -4938 }, { -1245, 126, -1916, -5419 }, { -249, -3755, -1422, -5594 }, { 575, -2683, -1926, -4566 }, { -762, 1885, 192, -5880 }, { -811, -2562, -1068, -6013 }, { -2264, -3086, -976, -4775 }, { 70, -1215, 2880, -4410 }, { 714, -3760, 2916, -4691 }, { -244, -3404, 1740, -4493 }, { 684, -5137, -328, -5608 }, { -529, -3825, -1786, -4535 }, { -713, -4743, -1118, -5546 }, { 2718, -3788, 1798, -5708 }, { -1639, -3679, -1564, -6095 }, { 1693, -2642, -1389, -4539 }, { 505, -1573, -1651, -4878 }, { -835, -2256, -1941, -5352 }, { 1464, -411, 1993, -6441 }, { 493, -3184, -145, -6148 }, { -1413, 499, -1617, -6479 }, { -294, 1722, -1419, -5725 }, { -2937, -1528, -175, -4624 }, { -594, -5911, -56, -6146 }, { -300, -4275, 1156, -5947 }, { 552, -2643, 2669, -3959 }, { 905, -4158, 1789, -5809 }, { 1336, -2009, 2108, -5903 }, { 1555, -3600, 1110, -6759 }, { -1294, -3464, 77, -6084 }, { -1139, -4006, -1270, -4181 }, { -5094, -3296, 1092, -2847 }, { -5503, -2883, 1984, -2067 }, { -4671, -4218, -1417, -4132 }, { -3763, -3818, 1262, -3082 }, { -5132, -3430, 2928, -728 }, { -5957, -2877, 1251, -2446 }, { -4425, -2319, -212, -4276 }, { -6201, -1993, 1774, -2182 }, { -5500, -3836, 2201, -1396 }, { -6934, -2334, 2366, -1293 }, { -6124, -4140, 1337, -1977 }, { -6553, -4186, 1756, -1325 }, { -5126, -1258, 744, -3656 }, { -5167, -1390, 1581, -2895 }, { -4525, -3398, 2429, -1865 }, { -4076, -3183, 2027, -2510 }, { -6191, -3274, 1838, -1814 }, { -4454, -2753, 2723, -1185 }, { -6655, -4797, 251, -2595 }, { -6332, -2232, 1832, 217 }, { -5869, -1698, 134, 340 }, { -6614, -1045, 2126, -1932 }, { -4859, -2107, 2010, -2435 }, { -6274, -1622, 2808, -1374 }, { -3119, -3209, 521, -3988 }, { -5676, -2082, -420, -2711 }, { -7073, -3623, 696, -2343 }, { -5986, -4224, 572, -2454 }, { -4340, -4521, 882, -2771 }, { -6178, -1933, 535, -1444 }, { -4923, -4163, 1744, -2066 }, { -6410, -1519, 1058, -2683 }, { -5077, -1185, 856, -2216 }, { -7091, -2444, 687, -2597 }, { -5284, -2165, 3239, -993 }, { -4763, -1497, 197, -3179 }, { -4128, -4958, -396, -3578 }, { -5054, -3878, -647, -2672 }, { -7005, -3348, 1679, -1579 }, { -5767, -1017, 2582, -1915 }, { -7069, -2787, 1331, -2070 }, { -5532, -2296, 706, -2950 }, { -5059, -3543, -821, -3637 }, { -6639, -1835, 1016, -696 }, { -5611, -5220, -694, -3371 }, { -5994, -2803, 2933, -729 }, { -5948, -619, 1596, -2676 }, { -5486, -4419, 153, -3265 }, { -4329, -3440, 1646, -1439 }, { -4083, -3978, 177, -3569 }, { -4289, -2599, 1224, -3075 }, { -5707, -3253, 1912, -759 }, { -6606, -3437, 2562, -571 }, { -5254, -2444, 769, -352 }, { -6545, -3154, 582, -1103 }, { -5328, -2241, 2566, -1775 }, { -7216, -1936, 1538, -1983 }, { -3730, -2451, 426, -3869 }, { -5110, -1385, 2031, -1169 }, { -6470, -2715, 269, -3123 }, { -5806, -2480, -97, -3832 }, { -3683, -4916, -490, -4330 }, { -6341, -2083, -669, -115 }, { -4913, -4079, -837, -4673 }, { -3274, -2497, 2334, -2652 }, { -1286, -1731, 2550, -3756 }, { -3375, -877, 926, -3977 }, { -2525, -2079, 2879, -2625 }, { -5308, -504, 3111, -1607 }, { -4904, 460, 4093, -1232 }, { -1993, 1616, 4656, -1913 }, { -3481, -1176, 3119, -2236 }, { -4132, -1502, 2339, -2545 }, { -2542, 1151, 3569, -2550 }, { -4381, 430, 3147, -2082 }, { -3888, 867, 3899, -1657 }, { -2861, 1290, 4202, -1979 }, { -3893, -253, 2363, -2764 }, { -1705, 688, 3827, -2923 }, { -2223, 2312, 3700, -3148 }, { -1986, -720, 5021, -795 }, { -3177, 242, 1952, -3352 }, { -1854, 1509, 2528, -3815 }, { -3173, 97, 5019, -706 }, { -2689, -145, 1375, -3915 }, { -4838, -385, 2488, -2427 }, { -4557, -355, 1603, -3060 }, { -3522, 1832, 3292, -2674 }, { -3769, 780, 2378, -2704 }, { -4323, -1932, 3414, -1169 }, { -2740, 1158, 2729, -3273 }, { -3647, 210, 1464, -2892 }, { -2342, -2097, 1513, -3727 }, { -4422, -1242, 3130, -1833 }, { -1308, -1039, 4290, -1875 }, { -1754, -2535, 3298, -2314 }, { -4102, -186, 4037, -1094 }, { -1008, 1570, 3290, 171 }, { -3322, -2621, 2791, -1536 }, { -2539, -2597, 3442, -1672 }, { -3411, -2015, 3670, -1174 }, { -2097, 730, 5581, -1399 }, { -1510, -74, 4820, -2004 }, { -4086, -868, 4425, -771 }, { -956, -986, 3640, -2925 }, { -2087, -1250, 3464, -2458 }, { -3308, -2411, 1334, -3667 }, { -2264, -389, 4004, -1854 }, { -680, 239, 4058, -3388 }, { -1357, 30, 2993, -3658 }, { -3601, -552, 1177, -1136 }, { -2641, 442, 4374, -1625 }, { -2525, 770, 1640, -3895 }, { -3172, -891, 3893, -1608 }, { -2996, 13, 3277, -2414 }, { -899, 1055, 4470, -2501 }, { -422, -584, 3475, -3787 }, { -1978, -593, 2566, -3415 }, { -3150, -1280, 2362, -3047 }, { -3592, 224, 1026, -3932 }, { -4840, -1189, 3633, -879 }, { -3952, -2255, 2916, -1826 }, { -1695, 28, 1810, -349 }, { -745, -2484, 3308, -3293 }, { -1016, 1563, 5365, -1823 }, { -2172, -1787, 4266, -1287 }, { -1241, -1951, 3982, -2413 }, { -2009, -2639, 2330, -3480 }, { 5105, -1618, -2588, -2015 }, { 6497, -1523, -3218, -910 }, { 6526, -2305, -2029, -1790 }, { 5289, -99, -3436, -400 }, { 5781, -1623, -1577, -2617 }, { 5259, -670, -3125, -1700 }, { 6343, -1256, -331, -3222 }, { 7967, -678, -2195, -1462 }, { 6119, -695, -2988, -1538 }, { 6108, 494, -3359, -1548 }, { 5067, 969, -2328, -2707 }, { 7595, -435, -1497, -2056 }, { 6929, -719, -2420, -1665 }, { 5190, 584, -2982, -2103 }, { 6106, -444, -1411, -2739 }, { 5584, 289, -1804, -2803 }, { 5276, 227, -1180, -3361 }, { 7544, -1525, -1834, -1725 }, { 5986, -1470, -2606, -1701 }, { 5096, -765, -1712, -3006 }, { 5423, -149, -3933, -1157 }, { 7651, 26, -2445, -1507 }, { 4745, -464, -1735, -2362 }, { 5352, -1011, -1094, -1999 }, { 6300, -672, -542, -1950 }, { 6675, -1020, -1318, -1059 }, { 7218, -2036, -603, -2462 }, { 7755, -1514, -2430, -1229 }, { 5041, 449, -1056, -2405 }, { 6710, -2277, -1344, -2284 }, { 6824, -1347, -2254, 251 }, { 6068, -1857, -983, -1316 }, { 5603, -2177, -2730, -1477 }, { 5838, -1059, -3604, -970 }, { 5076, -789, -335, -2413 }, { 6191, -1634, -2000, -2129 }, { 5092, -1292, -2543, -1034 }, { 5305, 435, -1710, -1850 }, { 6140, 561, -2176, -2380 }, { 6752, 348, -2496, -1890 }, { 6405, 273, -1098, -2778 }, { 6942, -1340, -496, -1381 }, { 5238, -687, -2454, -2349 }, { 6959, -882, -1833, -2061 }, { 6292, -253, -2125, -2199 }, { 5838, -574, -759, -3215 }, { 6954, -1484, -640, -2771 }, { 7498, -1706, -1210, -2154 }, { 6772, -1003, -1235, -2532 }, { 6014, 228, -2154, -1108 }, { 6943, -2178, -2644, -1122 }, { 7262, -763, -3056, -1090 }, { 6273, -1478, -1072, 177 }, { 4734, 425, -2912, 357 }, { 7129, 168, -1537, -2327 }, { 7204, -434, -746, -2660 }, { 6879, 57, -3087, -1310 }, { 4623, -610, -718, -3459 }, { 6565, -543, -1998, -339 }, { 4752, -277, -2066, -1405 }, { 7435, -1416, -1904, -505 }, { 4076, 150, -1222, -3556 }, { 7082, -28, -1456, -1174 }, { 5941, -446, -1326, -1158 }, { 3870, -1648, -2474, -2589 }, { 858, 37, -3387, -3721 }, { 3557, -1503, -1664, -3383 }, { 3336, -1972, -3079, -2216 }, { 3186, 60, -4185, -863 }, { 3456, -773, -3066, -2457 }, { 4131, -913, -2060, -2601 }, { 4431, -691, -4114, -972 }, { 3461, -334, -3680, -1751 }, { 2006, -459, -2214, -3827 }, { 1322, 32, -2816, -3203 }, { 4425, -1897, -2791, -1946 }, { 4504, 23, -3421, -1909 }, { 3090, -885, -2366, -3264 }, { 3209, -2363, -3730, -834 }, { 3312, -1471, -3641, -1579 }, { 4184, -1669, -3323, -1248 }, { 2190, -931, -3302, -2944 }, { 2947, -229, -4791, -1195 }, { 2020, -1626, -2700, -3125 }, { 2214, -326, -4352, -1683 }, { 3286, -2619, -2412, -2458 }, { 1000, -2571, -4129, -2158 }, { 2496, -2627, -3611, -1433 }, { 2043, -2191, -2167, -3827 }, { 2571, -2544, -1915, -3222 }, { 2022, -1501, -3856, -2165 }, { 2685, -1180, -1461, -4038 }, { 1610, -2313, -4391, -1173 }, { 2340, -2490, -4215, -516 }, { 1742, -2615, -3632, -2146 }, { 523, -1293, -4246, -2442 }, { 3725, -2723, -3014, -1576 }, { 3554, -1381, -4200, -824 }, { 1291, -1594, -4777, -1430 }, { 1452, 515, -2960, -3830 }, { 4264, -894, -3305, -1826 }, { 2606, -1452, -4522, -966 }, { 1196, -830, -4807, -1816 }, { 1054, -775, -2616, -4071 }, { 4206, 415, -4344, -1132 }, { 3044, 491, -4126, -1934 }, { 988, -901, -3353, -3443 }, { 1729, -3063, -2267, -3370 }, { 3915, 912, -2989, -2387 }, { 3781, 300, -2457, -3050 }, { 2712, 924, -1350, -1206 }, { 4230, 405, -2343, 665 }, { 1878, -873, -225, -29 }, { 3510, 56, -1334, -3420 }, { 2850, 1447, -2651, -3150 }, { 1510, -706, -4125, -2483 }, { 3115, 793, -1692, -3894 }, { 2667, 213, -2973, -2786 }, { 1184, -2384, -3051, -3173 }, { 2139, 796, -2079, -3697 }, { 1464, -1483, -3726, -2754 }, { 2407, -1148, -3915, -1569 }, { 2612, -1779, -3217, -2271 }, { 2406, -2870, -2937, -2496 }, { 2140, 126, -3646, -2758 }, { 2952, -1036, 268, -1423 }, { 93, -1931, -3841, -3535 }, { 389, -2953, -3383, -3343 }, { 8652, -5511, -1662, 565 }, { 7427, -2791, -2535, -842 }, { 8541, -4253, -1407, -988 }, { 8018, -3203, -2998, 105 }, { 7231, -3926, -958, 1308 }, { 7331, -3690, -363, 2586 }, { 6803, -3646, -2226, -903 }, { 8163, -2811, -477, -2235 }, { 9356, -3818, -1685, -684 }, { 8466, -2854, -302, -698 }, { 8458, -3224, 517, 279 }, { 8074, -2619, -1326, 2596 }, { 8779, -2761, -2527, -441 }, { 6533, -2887, -899, -696 }, { 7394, -2305, -1642, -120 }, { 8281, -3780, -22, 1305 }, { 9158, -4413, -779, 901 }, { 9031, -5240, -1109, 1678 }, { 8717, -3650, 410, -1075 }, { 7317, -3197, -818, -2264 }, { 7934, -2385, -1214, -1886 }, { 8256, -4441, -291, -587 }, { 7358, -3395, 1090, -270 }, { 9446, -4910, -1343, -473 }, { 8187, -4726, -808, 1166 }, { 7504, -3845, -47, 267 }, { 8029, -2146, -1283, -383 }, { 7461, -2705, -853, 783 }, { 9367, -3636, -645, -354 }, { 8955, -3473, -308, -1947 }, { 8676, -2683, -2099, 1485 }, { 7481, -3003, -871, -444 }, { 8015, -2839, -1673, 1175 }, { 6947, -4643, -1527, -1047 }, { 7622, -2575, -137, -960 }, { 9388, -4279, -707, -1322 }, { 8382, -5259, -1283, -565 }, { 6856, -4138, -1030, 630 }, { 8659, -2571, -1124, -1666 }, { 8763, -3807, -537, 2543 }, { 8049, -3578, -2186, -604 }, { 8272, -2351, -1985, -1214 }, { 6855, -3796, -1527, -1631 }, { 7178, -2896, -1600, -1756 }, { 7040, -2888, -89, -1586 }, { 6261, -3403, -264, 998 }, { 7756, -4699, -1543, -834 }, { 7682, -4622, -758, -1721 }, { 8839, -4232, -2932, 1959 }, { 9363, -4679, -1956, 39 }, { 7883, -3616, -1414, -1432 }, { 8828, -3188, -1356, -1312 }, { 7746, -3987, -121, -2424 }, { 9262, -3256, -693, 818 }, { 7670, -3420, -148, 3504 }, { 7344, -3183, 608, 1595 }, { 8976, -4139, -1848, 1304 }, { 6708, -4131, 33, -852 }, { 7840, -4429, -2275, 79 }, { 8980, -3858, -2838, 453 }, { 7815, -4604, -2563, 944 }, { 8372, -4422, -1783, 3071 }, { 8623, -5128, -1754, 2888 }, { 7462, -3281, 889, 920 }, { 8416, -59, -1320, -1825 }, { 7928, -1488, -414, -2499 }, { 8110, -977, -1047, -2042 }, { 8278, -687, -1597, -1550 }, { 7988, -174, -977, -2106 }, { 8609, -1547, -1628, -1527 }, { 9000, -1798, -946, -1761 }, { 8954, -872, -1404, -1594 }, { 8939, 466, -748, -1212 }, { 9549, -329, -177, -1360 }, { 9411, -18, -1126, -1568 }, { 8859, -782, -488, -1338 }, { 8955, -218, -43, -1209 }, { 9131, -69, -453, -1001 }, { 9069, -1519, -1091, -1199 }, { 9247, -1309, -566, -1146 }, { 8528, -1617, -287, -1313 }, { 7763, -745, -149, -2040 }, { 8294, -343, 257, -2633 }, { 10149, -893, -552, -1649 }, { 9398, -915, 218, -2042 }, { 9703, -1194, -675, -1592 }, { 9586, -700, -427, -1710 }, { 8930, 497, -1445, -1218 }, { 9285, -1323, -163, -1552 }, { 8431, -1289, -985, -1404 }, { 8965, -655, 653, -1483 }, { 9542, -1001, -951, -1128 }, { 9205, -647, -37, -882 }, { 8603, -56, 514, -1793 }, { 9300, -12, -1324, -567 }, { 8773, 238, -184, -1456 }, { 9941, -1306, -69, -1792 }, { 9360, 279, -376, -1919 }, { 9180, -285, 95, -2170 }, { 9922, -501, -970, -1570 }, { 8341, -1493, -856, -2092 }, { 8780, -981, -850, -1014 }, { 9721, -548, -1504, -1094 }, { 9973, -1493, 482, -2105 }, { 8707, -333, -1027, -1087 }, { 9098, -469, -315, -1723 }, { 8879, -1050, -661, -2020 }, { 8857, 602, -866, -1918 }, { 8945, -1025, -2154, -1071 }, { 8484, -1930, -468, -2179 }, { 9177, -1903, -224, -2112 }, { 8652, -137, -2097, -1214 }, { 9063, -973, -1405, -772 }, { 9328, -456, 662, -2469 }, { 10101, -697, 127, -2113 }, { 9685, 811, -2359, -1024 }, { 8586, -94, -460, -1982 }, { 7924, -141, -509, -2513 }, { 7773, -669, -107, -2835 }, { 8636, -1064, -46, -2409 }, { 9748, 596, -1815, -1349 }, { 8924, 304, 547, -2614 }, { 9442, 746, -1153, -1679 }, { 9454, -278, -529, -1976 }, { 8488, 561, -32, -2160 }, { 10083, -63, -1544, -1364 }, { 9390, -1278, 568, -1131 }, { 9740, -49, -2253, -910 }, { 3636, -2391, -1115, -3614 }, { 6014, -3204, -1902, -1808 }, { 5787, -3497, -1116, -2590 }, { 4365, -3046, -1632, -2668 }, { 4733, -2192, -2029, -2468 }, { 5412, -2753, -1633, -2464 }, { 4455, -3375, -767, -3399 }, { 4456, -1644, -983, -2841 }, { 4039, -2523, 38, -3967 }, { 3406, -2662, 72, -4757 }, { 4279, -2005, 1055, -4399 }, { 4321, -1377, -860, -3786 }, { 3743, -5739, -651, -3047 }, { 3528, -5510, 361, -4060 }, { 6496, -4886, -136, -2689 }, { 4513, -5254, 551, -4010 }, { 6557, -3413, -92, -3063 }, { 4186, -2059, 187, 47 }, { 6210, -4117, -1256, -1985 }, { 6038, -4343, 351, -2124 }, { 4305, -4780, -2077, -1897 }, { 4480, -3815, -2228, -1533 }, { 5582, -3689, 1221, -3429 }, { 5532, -4874, 1195, -2765 }, { 6518, -2853, -905, -2568 }, { 5467, -2192, 470, -4115 }, { 4139, -1577, 240, -3493 }, { 5281, -1926, -729, -3340 }, { 5214, -2870, 1359, -4289 }, { 3046, -3510, -1536, -3214 }, { 5433, -2881, -1230, -1184 }, { 4861, -3932, -1071, -2791 }, { 5693, -4234, -1906, -1502 }, { 4004, -3935, -1804, -2383 }, { 3728, -3792, 681, -4773 }, { 3621, -3030, -1951, -2598 }, { 5133, -3903, 44, -3700 }, { 3561, -3451, 1183, -5301 }, { 5026, -2762, -2341, -1780 }, { 5841, -2492, -467, -3210 }, { 5591, -1791, 497, -2472 }, { 5054, -3898, -1822, -2097 }, { 5813, -2792, 83, -1469 }, { 4432, -4497, 1670, -5193 }, { 5338, -4653, -1109, -2200 }, { 3239, -4401, -648, -3655 }, { 2147, -3598, -1200, -4242 }, { 4417, -2271, -1552, -3210 }, { 6494, -4360, 852, -3565 }, { 2393, -6358, -856, -4524 }, { 4959, -4196, -847, -1403 }, { 4924, -5438, -226, -3026 }, { 4254, -5303, -1306, -2424 }, { 4121, -3126, -2334, -1981 }, { 3437, -4443, -1464, -2953 }, { 3203, -3459, -529, -4339 }, { 5896, -5945, 543, -3246 }, { 1987, -4733, -220, -4863 }, { 4358, -4431, -514, -3081 }, { 4583, -2416, -492, -2287 }, { 2943, -5035, 419, -4927 }, { 5358, -5129, 987, -4309 }, { 4460, -3392, 1752, -5634 }, { 3415, -4633, 1507, -5945 }, { 811, -4692, -445, 2333 }, { 1009, -5613, -1857, 1360 }, { 1338, -2712, -2720, 3036 }, { 1002, -3754, -2582, 2344 }, { 750, -4608, -2334, 714 }, { 2043, -3207, -2822, 2173 }, { -140, -4654, -2953, 357 }, { -54, -4026, -2376, 2695 }, { 1858, -5022, -717, 2287 }, { 2064, -3894, -722, 3255 }, { 2727, -4558, -332, 2603 }, { 1810, -5378, 283, 1826 }, { 3935, -4326, 762, 3383 }, { -767, -4697, -2510, 1922 }, { 2146, -4312, -3090, 1641 }, { 54, -5881, -2114, 921 }, { 1992, -5766, -640, 1574 }, { 1200, -5371, -1114, 1828 }, { 2973, -5337, 34, 2266 }, { 1531, -5018, -2817, 1192 }, { 3078, -4570, 117, 1990 }, { 924, -4286, -1388, 2713 }, { 142, -5058, -2848, 1487 }, { -106, -6180, -881, 842 }, { 673, -5433, -229, 1596 }, { 783, -5710, -2784, 562 }, { 1935, -5729, -2009, 856 }, { -410, -3375, -3326, 2734 }, { 234, -3000, -2628, 3260 }, { 733, -3405, -3806, 1589 }, { 771, -4285, -3544, 1314 }, { 1192, -3563, -3960, 2178 }, { 206, -5555, -1250, 1546 }, { -130, -3815, -1210, 3041 }, { 646, -3940, -393, 2992 }, { -184, -4931, -1767, 1925 }, { 2746, -5120, -2275, 1464 }, { 2440, -3731, -3352, 2729 }, { -490, -4942, -3779, 997 }, { 68, -2636, -4167, 3778 }, { 48, -3986, -4118, 2106 }, { -978, -5486, -1336, 1390 }, { 1126, -5297, -855, 640 }, { -472, -3975, -3622, 1557 }, { 2456, -5344, -1523, 1648 }, { -774, -5652, -2417, 1147 }, { 995, -6122, -812, 1132 }, { 3282, -4571, -1763, 2175 }, { 3655, -3862, -676, 3568 }, { 3038, -3647, -1672, 3381 }, { 2595, -2964, -2772, 3263 }, { 4176, -3353, -1148, 4354 }, { 1603, -3442, -1500, 3444 }, { 828, -6226, -1783, 678 }, { 1421, -3333, -3080, 3403 }, { 1121, -4727, -1924, 1984 }, { -186, -5083, -682, 1796 }, { 819, -2778, -3488, 530 }, { 421, -2873, -3832, 2596 }, { 2164, -4263, -1605, 2282 }, { 585, -4437, -682, -491 }, { -644, -4452, -1157, 2325 }, { 1991, -4299, 210, 2834 }, { 2135, -3632, -2113, 665 }, { -7482, -2724, -2662, -1380 }, { -6983, -2166, -3756, -3509 }, { -7085, -1439, -2397, -3112 }, { -7760, -3049, -3319, -2822 }, { -8413, -2760, -4406, -3298 }, { -5995, -3943, -1260, -3750 }, { -7879, -1554, -3464, -2606 }, { -6314, -2034, -3878, -1681 }, { -8849, -2084, -1399, -1231 }, { -7153, -2602, -1384, -817 }, { -8041, -2571, -407, -2785 }, { -7246, -2233, -1578, 260 }, { -7336, -3883, -4061, -1342 }, { -7619, -3908, -2342, 382 }, { -8684, -3724, -1662, -727 }, { -7850, -2922, -1770, -3449 }, { -6766, -2034, -1293, -1988 }, { -6895, -2116, -968, -3744 }, { -7136, -5147, -2618, -2809 }, { -8224, -3724, -2519, -1589 }, { -6711, -2750, -3021, -219 }, { -8059, -1638, -1102, -3175 }, { -8710, -4839, -3963, -3143 }, { -9363, -4965, -3257, -1002 }, { -6099, -1751, -3157, -395 }, { -6453, -3216, -4597, -483 }, { -7879, -5477, -839, -2638 }, { -7202, -4038, -526, -2856 }, { -8022, -1228, -1910, -1646 }, { -9117, -1393, -1582, -2535 }, { -9095, -2693, -636, -2605 }, { -9076, -2580, -3481, -2519 }, { -8327, -4859, -2422, 83 }, { -8368, -2129, -2324, -2173 }, { -8554, -4563, -3842, -2007 }, { -10462, -4261, -1934, -2084 }, { -9717, -3187, -2294, -1896 }, { -9625, -3889, -3020, -3224 }, { -9857, -4955, -4239, -2184 }, { -9752, -2351, -2277, -3129 }, { -7219, -1302, -2639, -1603 }, { -7477, -4360, -3718, -559 }, { -5680, -2033, -2326, -3078 }, { -10190, -5548, -4643, -3601 }, { -9431, -4121, -879, -2479 }, { -8365, -5450, -2020, -1439 }, { -6289, -5178, -1605, -3845 }, { -8319, -3866, -687, -2792 }, { -8131, -1031, -3608, -3947 }, { -10510, -2560, -1199, -2082 }, { -11015, -3640, -2748, -3041 }, { -8762, -5022, -5231, -1162 }, { -10153, -2715, -4648, -4859 }, { -7930, -5205, -1900, -3600 }, { -9561, -3548, -4812, -3722 }, { -7663, -4709, -1180, -1475 }, { -9073, -5707, -1815, -2980 }, { -8602, -2363, -2675, -3770 }, { -9967, -5614, -3575, -3838 }, { -8324, -1005, -2131, -3254 }, { -10331, -5737, -2550, -2940 }, { -8234, -3354, -3361, -4479 }, { -8140, -1951, -4526, -4545 }, { -6679, -2662, -2284, -4182 }, { -1122, -1514, -6427, -212 }, { 54, -1660, -5424, -1404 }, { 254, -2778, -5222, 846 }, { -267, -1661, -6577, 814 }, { -305, -2021, -5759, 1484 }, { -1791, -2446, -6867, -86 }, { -2929, -3158, -6603, -1799 }, { -1391, -3189, -5557, -1053 }, { -1602, -884, -6767, -1213 }, { -361, -318, -6219, -44 }, { -4078, -2635, -5523, -433 }, { -956, 478, -4382, 1470 }, { -3300, -2462, -6021, -2721 }, { 708, -2434, -5085, -540 }, { -2435, -3607, -5647, -2110 }, { -491, -1134, -4681, -2886 }, { 87, -3435, -4641, -1194 }, { -586, -2927, -4784, 366 }, { -1394, -2326, -6021, 350 }, { 97, -2519, -4678, -2120 }, { -1547, -1907, -5069, -2993 }, { 268, -3724, -4719, 127 }, { -827, -1190, -5912, 1144 }, { -3959, -2322, -6898, -1974 }, { -2728, -2228, -6426, -562 }, { -456, -666, -5785, -1609 }, { 531, -1096, -5731, -656 }, { -3569, -688, -3915, 110 }, { -4752, -1725, -4393, -377 }, { -3210, -3315, -6960, -840 }, { -688, -3416, -4971, 1221 }, { -1833, 77, -6491, -2434 }, { -239, -255, -6850, -886 }, { -2112, -1490, -6291, -2689 }, { -1544, -4579, -5198, -1261 }, { -2771, -4014, -5520, 683 }, { -1635, -2829, -5512, 1214 }, { -958, -2582, -4823, 2360 }, { -2077, -4566, -4642, 365 }, { -3112, -4214, -5960, -823 }, { -2467, -2510, -4858, 1467 }, { -1561, -3399, -5822, 211 }, { -775, -1081, -4424, 2636 }, { -1263, 25, -6378, -1392 }, { -3476, -366, -5417, -1393 }, { -3176, -1476, -4149, 1466 }, { -2479, 518, -4448, -257 }, { -2992, 158, -4660, -1279 }, { -1320, -3872, -4479, 1147 }, { -1475, -312, -5318, 539 }, { -3527, -1679, -5860, -1681 }, { -3397, -3438, -5593, 1866 }, { -4089, -2439, -4763, 1275 }, { -748, -4513, -4687, -48 }, { -2166, -4531, -4691, -2856 }, { -2385, -853, -6035, -627 }, { -1194, -4091, -4472, -1963 }, { -682, -3234, -4084, -3033 }, { -3255, -5015, -5328, -12 }, { -2313, -3436, -4601, -155 }, { -2792, -1038, -6947, -2019 }, { -1244, -1526, -5771, -1882 }, { -4679, -3731, -5506, 283 }, { -3062, -66, -3558, -758 }, { -4895, -1187, 4751, 3728 }, { -7600, -2752, 3320, 4613 }, { -5703, -2975, 3944, 2659 }, { -4972, -1257, -246, 2952 }, { -4221, -2487, 1702, 4295 }, { -2900, -1529, 2458, 4935 }, { -5061, 407, 2416, 4050 }, { -6931, -3478, 2761, 2213 }, { -6037, -3921, 3192, 1866 }, { -6113, -811, 2407, 3782 }, { -5878, -1716, 1207, 3478 }, { -5953, -2853, 2207, 2712 }, { -6807, -3223, 2749, 3595 }, { -3272, -3157, 1389, 3788 }, { -5368, -1904, 1980, 5077 }, { -7235, -1398, 3075, 4548 }, { -4765, -3487, 2755, 2796 }, { -7658, -4435, 2694, 2582 }, { -6997, -4282, 456, 3832 }, { -5563, -3115, -63, 3713 }, { -4244, -4220, 1450, 2767 }, { -3801, -2194, 190, 4303 }, { -5458, -4119, 1958, 2274 }, { -7300, -3469, 3514, 3193 }, { -4594, -2067, 775, 4752 }, { -3389, -1654, 1464, 5412 }, { -4845, -3483, 964, 3437 }, { -6007, -2818, 1666, 4659 }, { -8709, -5007, 1757, 3287 }, { -5833, -4389, 1025, 3171 }, { -5788, -1780, 3944, 3661 }, { -4430, -920, 1938, 4753 }, { -7066, -1857, 4591, 4538 }, { -3549, -513, 1427, 5317 }, { -7517, -1220, 2883, 3049 }, { -7605, -2687, 1874, 2735 }, { -8718, -4035, 2676, 3730 }, { -7990, -3907, 1185, 2607 }, { -6058, -1744, 3349, 5157 }, { -5954, 565, 3161, 3250 }, { -6478, -612, 1930, 2271 }, { -6535, -1445, -2, 1618 }, { -8963, -4151, 1192, 4044 }, { -7227, -3570, 1600, 4234 }, { -4674, 79, 595, 3015 }, { -3974, 430, 2727, 5137 }, { -5299, 9, 3714, 4779 }, { -6779, -2699, -8, 2436 }, { -7016, -1145, 1293, 2310 }, { -6955, -3312, 1534, 1801 }, { -4025, 740, 1850, 4054 }, { -9589, -3460, 4154, 5270 }, { -4404, -1181, 4298, 5173 }, { -7356, -4583, -18, 2644 }, { -6516, -1235, 4439, 6234 }, { -3453, -301, 4344, 4464 }, { -4643, 1530, 3315, 4340 }, { -4575, -2557, 3754, 3682 }, { -3643, -3501, 2051, 2997 }, { -5412, -2475, 2301, 1579 }, { -5846, 259, 1360, 2348 }, { -5258, -1358, 1050, 838 }, { -5542, -219, 6377, 5750 }, { -5713, -2952, 922, 899 }, { -2049, -1135, 5206, 1033 }, { -1693, -1886, 4835, -106 }, { -2344, -3504, 4232, -13 }, { -2475, -2334, 5043, 1126 }, { -787, -2549, 3880, 2138 }, { -3159, -2341, 4830, 2887 }, { -1780, -1009, 6240, 2061 }, { -4327, -3363, 2818, 886 }, { -3376, -2743, 4104, 207 }, { -3250, -4640, 2718, 1498 }, { -382, -1075, 4382, 3460 }, { -2416, -4168, 3530, 816 }, { -1756, -2708, 4861, 622 }, { -1879, -2097, 5156, 2889 }, { -2496, -2418, 3722, 2671 }, { -2717, -3252, 3341, 1944 }, { -4063, -4091, 3306, 267 }, { -3549, -3808, 3747, 842 }, { -2635, 546, 5794, 1894 }, { -1857, -1121, 4383, 3964 }, { -2226, -2166, 3489, 3678 }, { -3492, -660, 5323, 1063 }, { -3033, -3130, 4382, 1828 }, { -2703, -625, 6369, 2851 }, { -1656, -2842, 4584, -528 }, { -4781, -2622, 4390, 2097 }, { -413, -2045, 5081, 3035 }, { -3810, -2662, 4532, 1095 }, { -3144, -1858, 5215, 1880 }, { -3562, -1795, 4928, 670 }, { -4800, -1509, 5189, 1859 }, { -1085, -3832, 4169, 900 }, { -1969, -3270, 2857, 2878 }, { -4267, -4140, 3176, 1805 }, { -5145, -3727, 3524, 1168 }, { -1346, -1876, 5501, 1748 }, { -4998, -2945, 3699, 338 }, { -3458, -3096, 3406, -635 }, { -1751, -3209, 3508, 395 }, { -2507, 170, 5987, 705 }, { -3756, -1072, 5647, 3536 }, { -2870, -1439, 5026, 3212 }, { -3913, -3225, 3669, 2144 }, { -3739, 226, 5747, 764 }, { -2052, -820, 5266, 3093 }, { -3214, -3820, 2409, 2391 }, { -4398, -2588, 3501, -218 }, { -4484, -1763, 4180, -198 }, { -3368, -1525, 4362, -134 }, { -2407, 224, 4905, 3533 }, { -1369, -2937, 4728, 1788 }, { -4848, -1707, 4159, 851 }, { -3454, -1749, 4281, 3230 }, { -1990, -3853, 3487, 1735 }, { -3117, 92, 6155, 4075 }, { -2676, -2472, 4078, -589 }, { -1547, -2012, 2626, 1835 }, { -4275, -588, 4824, 725 }, { -601, -2249, 3736, 3548 }, { -4060, -61, 5333, 3097 }, { -4303, 7, 6551, 3054 }, { -5003, -1029, 5786, 3319 }, { -2810, -728, 5392, 199 }, { -1232, -200, 5228, 3121 }, { 2621, 165, -6255, 298 }, { 3669, 537, -6844, 1564 }, { 1598, -1190, -6235, 2523 }, { 2164, -32, -6894, 1383 }, { 853, -1597, -6069, 1449 }, { 1377, -1661, -5266, 108 }, { 2660, 48, -5172, -517 }, { 1903, -391, -5677, 1010 }, { 3792, 206, -5274, -11 }, { 1239, 2776, -2929, 2721 }, { 4071, 149, -7259, 3125 }, { 1436, -480, -6156, -196 }, { 1373, -1960, -5005, 3122 }, { 3413, -1271, -5176, 3283 }, { 3060, -68, -6495, 2238 }, { 2700, -2075, -4681, 91 }, { 2928, -1728, -5168, 1858 }, { 4424, 828, -4471, 88 }, { 2672, -2604, -4038, 2753 }, { 5223, -123, -6749, 2295 }, { 4237, -420, -5538, 1353 }, { 4744, -1281, -4097, 4708 }, { 1103, -2764, -4751, 2024 }, { 3747, -1913, -3911, 3960 }, { 2470, -1416, -5542, 615 }, { 4847, -1354, -5334, 1733 }, { 5336, 88, -7593, 4007 }, { 2388, -2880, -4807, 1037 }, { 4495, 1391, -5685, -139 }, { 5253, 1637, -6450, 1533 }, { 1199, 795, -5515, 1261 }, { 1397, -1259, -4252, 3838 }, { 746, 70, -6640, 604 }, { 1584, 166, -4972, 3072 }, { 380, -999, -5397, 2267 }, { 2974, 1707, -3242, 5360 }, { 5202, -403, -5453, 2832 }, { 3718, -1731, -4760, 714 }, { 4150, -975, -4792, 61 }, { 2925, -818, -4841, 15 }, { 5301, 577, -4006, 3259 }, { 5265, 1986, -5679, 3028 }, { 3752, 1928, -4509, 3729 }, { 3278, 1925, -6370, 1247 }, { 5107, 1721, -4853, 3127 }, { 3279, 2982, -2515, 4005 }, { 4622, 668, -6204, 759 }, { 6034, 317, -5763, 4818 }, { -558, 57, -3785, 2817 }, { 4476, 1616, -3965, 4536 }, { 5953, 2056, -8215, 2715 }, { 4387, 2613, -7463, 868 }, { 5834, 1088, -4736, 4924 }, { 6473, -856, -6991, 4172 }, { 4959, -293, -5162, 76 }, { 2731, -843, -6119, 3847 }, { 3245, 1202, -6833, 616 }, { 2553, 1383, -3829, 3859 }, { 4332, 2099, -3480, 3622 }, { 2110, 2683, -2728, 3990 }, { 876, 1167, -3290, 3466 }, { 3991, 1709, -2410, 4077 }, { 5105, 939, -2584, 3256 }, { 4719, 688, -1566, 3040 }, { -3632, 4335, 1266, -3303 }, { -4956, 3207, 1312, -2806 }, { -4669, 2627, 2663, -2435 }, { -4282, 3708, 2303, -3038 }, { -4536, 2297, -175, -3350 }, { -5234, 2503, -139, -880 }, { -3978, 1512, 1092, -3619 }, { -4519, 4649, 1363, -2455 }, { -5118, 3132, 1961, -1577 }, { -5196, 3379, -182, -1378 }, { -6420, 4486, 2397, -1993 }, { -5030, 5046, 1292, -1118 }, { -4559, 2573, -927, -1406 }, { -3501, 3730, 691, -4930 }, { -4364, 2758, 1007, -3909 }, { -4026, 2839, -1559, -2340 }, { -5037, 4053, 836, -1571 }, { -4727, 5136, 1110, -3588 }, { -5245, 2799, -999, -2164 }, { -4954, 1501, 422, -3963 }, { -5994, 2726, 1462, -2833 }, { -5621, 5159, 2038, -2512 }, { -4991, 2291, 1917, -3151 }, { -5469, 4382, -148, -2978 }, { -5858, 1983, 807, -2720 }, { -4709, 3556, 952, -467 }, { -2489, 2362, 1714, -4230 }, { -4717, 5004, -1180, -3672 }, { -5914, 3653, 1359, -1317 }, { -5506, 2995, 780, -1059 }, { -5287, 3945, 2480, -2293 }, { -3849, 4358, 322, -1770 }, { -3911, 3570, 252, -3185 }, { -3660, 5128, 158, -3719 }, { -4599, 3277, -503, -2727 }, { -3673, 3760, -1252, -3339 }, { -5161, 2337, 388, -1943 }, { -3529, 2216, 2156, -3080 }, { -4309, 4331, 1808, -1460 }, { -4782, 3820, 480, -2504 }, { -4166, 3544, -378, -1567 }, { -5572, 2466, -418, -2909 }, { -6096, 2930, 119, -1878 }, { -5963, 3554, 1011, -2233 }, { -6433, 4335, 935, -2930 }, { -5004, 3314, -1352, -3430 }, { -6042, 3463, -1008, -3940 }, { -4671, 2214, -640, -5040 }, { -2795, 3759, 1412, -3803 }, { -3647, 4436, 729, -515 }, { -3594, 1033, 56, -4148 }, { -2908, 3027, 2889, -3485 }, { -3338, 2234, 313, -4285 }, { -3825, 4497, -561, -2634 }, { -6167, 3012, -48, -3149 }, { -4828, 3515, -969, -4475 }, { -5789, 2757, -539, -4173 }, { -2452, 3067, 564, -4249 }, { -4921, 1358, 1331, -2889 }, { -3127, 4239, -1045, -1523 }, { -4780, 2326, -1118, -3446 }, { -3908, 5546, 152, -2622 }, { -6972, 2976, 337, -2809 }, { -4839, 4613, -35, -4077 }, { -1408, 4822, -1149, -4997 }, { -981, 4979, -912, -6304 }, { -2098, 5689, -888, -2878 }, { -3343, 4814, -657, -4434 }, { -2461, 3601, -967, -4869 }, { -2652, 3944, 87, -5520 }, { -1104, 6076, 174, -6407 }, { 355, 5370, -1721, -5869 }, { 1242, 4497, -1107, -5091 }, { -89, 4002, -1491, -5182 }, { 1059, 5693, -1591, -4905 }, { 1323, 4682, -2078, -4768 }, { 818, 3996, -549, -5468 }, { -287, 4529, 929, -5543 }, { -919, 5519, -2791, -2844 }, { -1407, 5679, -3289, -3974 }, { -189, 6530, -3547, -4002 }, { -900, 7039, -3371, -4855 }, { -2983, 7211, -363, -4835 }, { -814, 6503, -104, -5106 }, { -2386, 6896, 809, -4919 }, { 845, 4492, 352, -6621 }, { -1998, 7237, -1646, -4231 }, { -3380, 6251, 471, -4577 }, { -1908, 7059, 84, -5726 }, { -340, 6346, -803, -6265 }, { -2279, 5834, -47, -4633 }, { -1532, 5286, -1748, -1901 }, { -2757, 6188, -453, -3415 }, { -1255, 6405, -2043, -6357 }, { 918, 5581, -121, -5667 }, { 1840, 5336, -821, -5034 }, { -2475, 4992, -1825, -3104 }, { -2413, 5606, -1789, -4298 }, { 132, 5128, -2389, -4442 }, { 223, 6400, -2653, -4742 }, { -673, 5012, 680, -4582 }, { -1657, 6624, -349, -3596 }, { -755, 6289, -1860, -3978 }, { -572, 6894, -1946, -5207 }, { -1141, 4756, -2665, -5586 }, { -1073, 4269, -431, -4030 }, { 186, 5761, 916, -5868 }, { -1907, 4836, 1017, -5106 }, { -963, 3363, -1248, -6348 }, { -3262, 4774, -1818, -5858 }, { 847, 3812, -2538, -4302 }, { -1223, 5903, 1360, -5479 }, { -1094, 6923, -1244, -2381 }, { 267, 6276, -709, -2846 }, { -157, 5840, 1124, -4266 }, { 889, 3206, -910, -5305 }, { -1736, 3344, 582, -4838 }, { -2357, 5676, -2695, -6277 }, { -1916, 6901, -986, -5397 }, { -3062, 6028, -695, -5687 }, { 1836, 3566, -1357, -5226 }, { -2176, 4938, 646, -3872 }, { -2199, 3055, -208, -6124 }, { -236, 3032, -821, -5325 }, { -3989, 7277, -565, -3899 }, { -595, 4362, 74, -5975 }, { 684, 5874, -841, -4424 }, { -2731, 6305, -2389, -5465 }, { -5775, 1325, -56, -2528 }, { -7029, -534, -1890, -3278 }, { -5798, -15, -2734, -2210 }, { -5504, -1198, -353, -3659 }, { -5079, 960, -894, -4336 }, { -6073, -36, -133, -3014 }, { -5782, -259, -1025, -3986 }, { -6843, 1262, -807, -1639 }, { -5263, -918, -3290, -579 }, { -4840, 461, -2158, -533 }, { -6014, -50, -620, 504 }, { -5843, 241, -1359, -282 }, { -5898, 577, 769, -3271 }, { -6833, -946, -466, -3347 }, { -6026, 1459, -512, -729 }, { -7361, 747, -388, -1110 }, { -6391, 2142, -1160, -2513 }, { -6995, 304, 498, -2673 }, { -6757, 679, -386, -433 }, { -5222, 1688, -1093, -1032 }, { -5019, 575, 184, -3627 }, { -4237, 628, -3507, -1243 }, { -7479, -456, -1722, -1486 }, { -6464, 713, -1273, -1153 }, { -6255, 1682, -606, -3607 }, { -7033, 1497, -71, -1955 }, { -6694, 1556, -1721, -3214 }, { -6114, -356, 813, -2575 }, { -5308, 632, -1851, -1636 }, { -5742, -911, -1733, 383 }, { -6083, -387, -2313, -879 }, { -6535, -530, -1505, -2083 }, { -4896, 1223, -2750, -1816 }, { -6392, -463, -3247, -2093 }, { -5373, 1264, -2706, -3042 }, { -3894, -1390, -1020, -891 }, { -6179, 1168, -1966, -1922 }, { -5162, 1668, -1617, -1916 }, { -6453, 920, -1169, -2432 }, { -6130, 2005, -536, -1519 }, { -6552, -98, -518, -1938 }, { -7528, 355, -1101, -1772 }, { -5745, 610, -247, -1360 }, { -7003, 177, -2064, -1958 }, { -6956, -570, -2220, -4225 }, { -7830, 791, -1394, -2774 }, { -7634, 480, -3171, -4224 }, { -7913, 1154, -350, -2381 }, { -5063, 1704, -1804, -2977 }, { -4887, -524, -2703, 188 }, { -5551, 406, -1620, -3063 }, { -7109, 1342, 381, -3021 }, { -6846, 631, -458, -3398 }, { -4606, -605, 11, -3930 }, { -8134, -225, -1738, -2648 }, { -7043, 402, -2734, -3059 }, { -7417, 1825, -2545, -4389 }, { -6971, -236, -1031, -665 }, { -5752, 2111, -1632, -3808 }, { -7660, -78, -624, -3135 }, { -6358, 619, -1951, -3911 }, { -8134, 408, -1935, -3695 }, { -6335, 1911, -2368, -4505 }, { -7116, 2163, -344, -2753 }, { 2357, 4488, 2220, -5682 }, { 1385, 3206, 2300, -5305 }, { 1419, 2557, 5203, -3516 }, { 262, 4315, 3920, -1847 }, { 3316, 3187, 1612, -5609 }, { 1729, 2350, 1673, -6068 }, { 1603, 6126, 1467, -2839 }, { -1339, 3316, 3691, -3530 }, { -563, 4618, 3180, -4548 }, { 463, 4624, 3111, -5614 }, { 1246, 5455, 3356, -5720 }, { 480, 2149, 5422, -2893 }, { 1768, 4827, 913, -5579 }, { -149, 5381, 4366, -3297 }, { 985, 3672, 2644, -92 }, { -258, 2911, 5817, -2213 }, { 3428, 3289, 3351, -3541 }, { -666, 3295, 4727, -2869 }, { 35, 6641, 4160, -4052 }, { 623, 6787, 3156, -4560 }, { 2654, 4360, 4676, -4632 }, { 1386, 5246, 4834, -4497 }, { 3488, 4574, 3856, -5946 }, { 383, 4481, 4168, -4110 }, { 1753, 3652, 4288, -3326 }, { 1344, 4905, 2508, -4660 }, { 1580, 4106, 3104, -2224 }, { 2027, 5038, 1683, -1554 }, { 446, 3699, 5872, -3013 }, { 4637, 4087, 3578, -5018 }, { 2629, 3560, 5331, -4900 }, { 1527, 6674, 2523, -4131 }, { -1437, 2804, 2528, -4464 }, { -229, 3355, 2016, -5537 }, { 3666, 3418, 4374, -4581 }, { 1192, 3799, 923, -6596 }, { 2040, 2956, 448, -5322 }, { 2468, 5768, 4029, -5869 }, { 3438, 6516, 3529, -6667 }, { 2737, 5495, 680, -5535 }, { 3896, 5727, 1801, -4958 }, { 4988, 4957, 3592, -6518 }, { -542, 4416, 5794, -2787 }, { 4136, 4354, 2064, -4696 }, { 3067, 5936, 1207, -3396 }, { 2789, 4966, 2405, -3854 }, { 1731, 3270, 3251, -1063 }, { 1767, 5537, 2084, -2349 }, { 465, 3116, 4532, -837 }, { 1499, 2627, 4610, -2212 }, { 122, 3095, 3642, -3552 }, { 2542, 2866, 2705, -6402 }, { 3134, 4323, 698, -4785 }, { 731, 1859, 3112, -5242 }, { 2553, 2980, 3241, -4846 }, { 1329, 5310, 1607, -6624 }, { 2468, 1858, 3476, -1034 }, { -172, 4996, 2000, -5562 }, { 2621, 4220, 1574, -3386 }, { -333, 1832, 3362, -4117 }, { 2169, 6762, 3065, -6225 }, { 2844, 5528, 3223, -4765 }, { 526, 5175, 1644, -4267 }, { 2922, 4426, 2414, -2610 }, { 452, 1399, -4516, -2636 }, { 2872, 1720, -4667, -1435 }, { 1279, 702, -5424, -1984 }, { 2187, 870, -5021, -1341 }, { 583, -144, -4628, -2464 }, { 3, 2237, -5284, -2827 }, { -19, 1005, -5460, -1819 }, { 2897, 2084, -5885, -515 }, { -400, 3370, -5527, -2947 }, { 1505, 2593, -5518, -1802 }, { 1341, 4534, -5094, -1899 }, { 3241, 3670, -5493, -1252 }, { -1287, 921, -5994, -1675 }, { 627, 408, -6652, -364 }, { -260, 1127, -4849, -3247 }, { 371, 3400, -5976, -2285 }, { 1533, 1566, -6373, -610 }, { 2462, 4274, -6184, -1254 }, { 1782, 3363, -6222, -1381 }, { 572, 4650, -5673, -2754 }, { 2674, 3414, -4460, -2154 }, { 3614, 3820, -6883, -398 }, { 1136, -1, -5511, -1112 }, { -1773, 1137, -5647, -2377 }, { -753, 2104, -6085, -2565 }, { -204, 3025, -4731, -1418 }, { -1486, 1438, -4380, -216 }, { 302, 858, -5786, -264 }, { 3486, 1495, -5234, -783 }, { 888, 2327, -3423, -3720 }, { -259, 772, -6596, -1311 }, { -1197, 2073, -5174, -1826 }, { 1500, 3470, -4462, -2645 }, { 3072, 1960, -3277, -2264 }, { 1841, 952, -4324, -2340 }, { 1994, 2200, -3940, -2923 }, { -1782, 1699, -4667, -1075 }, { -1464, 2906, -3468, -375 }, { 366, 2380, -3747, 1467 }, { -545, 1645, -4619, 376 }, { 1724, 2350, -2374, -3512 }, { 3184, 2628, -2996, -3275 }, { 734, 2010, -6239, -1479 }, { 524, 3756, -4496, -3263 }, { 1492, 3570, -3494, -3600 }, { -932, 618, -5389, -2894 }, { -133, 2161, -4083, -3267 }, { 786, 774, -3279, -3731 }, { 1078, 803, -3843, -3007 }, { -332, 3405, -3347, 40 }, { -17, 6, -4005, -3690 }, { -189, 4372, -4488, -2561 }, { -450, 3846, -3790, -1370 }, { 362, 2212, -5272, -15 }, { -1529, 791, -6802, -2296 }, { 2145, 4241, -4474, 376 }, { 1813, 2426, -2932, -2726 }, { -542, 4557, -3140, -1080 }, { 1192, 3784, -4371, -20 }, { 2784, 5188, -6399, -1394 }, { 431, 4561, -3673, -1398 }, { 1382, 3096, -4083, 1253 }, { 1209, 4224, -2930, 1500 }, { 2798, 2684, -6676, -606 }, { -2396, 1510, -5381, -2713 }, { -2625, 2542, -4032, -2880 }, { -1231, 3967, -4098, -2886 }, { -1393, 2374, -3862, -4525 }, { -2495, 1665, -1637, -5445 }, { -3854, 1759, -1750, -4944 }, { -2373, 1668, -2856, -6251 }, { -2668, 1981, -886, -4557 }, { -2927, 4427, -3451, -6172 }, { -1925, 2596, -4696, -2527 }, { -3202, 2847, -3928, -5896 }, { -3332, 1665, -5025, -3412 }, { -3212, 3115, -4155, -4062 }, { -1013, 3205, -5133, -3751 }, { -2022, 4595, -3947, -5611 }, { -3556, 1755, -3715, -2300 }, { -1784, 4114, -2723, -1773 }, { -3586, 4081, -2733, -4942 }, { -1608, 3685, -4154, -4573 }, { -3368, 4042, -4452, -6227 }, { -1407, 3881, -5729, -3719 }, { -2751, 3281, -5077, -4999 }, { -3791, 2410, -4906, -5288 }, { -730, 2303, -4217, -3755 }, { -1812, 2311, -5492, -3709 }, { -610, 4336, -3915, -3783 }, { -2841, 4337, -4278, -4430 }, { -1662, 4666, -4661, -3964 }, { -589, 5209, -4923, -3682 }, { -4155, 2234, -4076, -4218 }, { -3951, 2770, -2665, -2805 }, { -2302, 3228, -3717, -1908 }, { -3129, 4373, -2264, -2851 }, { -447, 1363, -3578, -4323 }, { -2648, 4237, -3159, -3071 }, { -4072, 3241, -3541, -4605 }, { -4507, 3458, -2339, -3838 }, { -1646, 997, -4926, -3970 }, { -3025, 1614, -3940, -1242 }, { -1337, 1756, -3163, -5529 }, { -3203, 1865, -3282, -4354 }, { -1646, 2118, -2203, -6018 }, { 174, 1871, -2707, -4639 }, { -2607, 1485, -4778, -4750 }, { -2199, 3991, -3134, -4879 }, { -2962, 3323, -2816, -2419 }, { -5286, 2495, -4548, -5395 }, { -2810, 3710, -2274, -4211 }, { -330, 3006, -2993, -4678 }, { -1187, 2411, -2743, -5196 }, { -664, 4033, -3101, -5641 }, { -1458, 3602, -2816, -5371 }, { -4116, 4923, -3321, -5630 }, { -4165, 2528, -2592, -4798 }, { -2759, 3080, -2333, -5719 }, { -5157, 3011, -5526, -6348 }, { -3095, 2126, -5881, -4234 }, { -4377, 3849, -3600, -6099 }, { -1994, 4947, -5235, -4753 }, { -1067, 600, -3258, -5133 }, { -4992, 3302, -2208, -5051 }, { -3377, 2981, -1655, -4815 }, { -3325, 2446, -1787, -6116 }, { -2341, 2737, -3240, -6347 }, { -2258, -3732, 3710, -1235 }, { -1558, -3849, 2694, -3012 }, { -599, -4837, 3050, -2951 }, { -2246, -5433, 2798, -1910 }, { -2255, -4989, 3260, 270 }, { -3026, -5353, 2693, -1036 }, { -1151, -6097, 1097, -3782 }, { -3391, -6012, 2130, -1303 }, { -2850, -4422, 3375, -480 }, { -1138, -3779, 1491, -4162 }, { -551, -3892, 3787, -2082 }, { -3221, -3676, 3144, -1202 }, { -3023, -5196, 2650, 605 }, { -1756, -5729, 2646, 321 }, { -2693, -4409, 494, -4797 }, { -1913, -4573, 3372, -1730 }, { -1277, -3604, 4061, -993 }, { -420, -4993, 1351, -4796 }, { -3052, -5333, 1435, -1242 }, { -602, -5034, 3869, -1141 }, { -2436, -4680, 1665, -3019 }, { -2657, -3658, 1459, -3391 }, { -1220, -6246, 2749, -525 }, { -3838, -4844, 2265, -1735 }, { -1247, -5679, 3356, -1417 }, { -917, -5448, 3342, 105 }, { -1756, -6839, 2276, -2350 }, { -412, -5206, 1764, -3539 }, { -1439, -6915, 1442, -3750 }, { -1381, -4439, 3863, -282 }, { -3482, -4953, 2726, -336 }, { -1376, -5931, 1714, -1987 }, { -1716, -4405, 2608, 105 }, { -1590, -5191, 2652, -2704 }, { -2149, -6442, 2453, -1263 }, { -3426, -3832, 2334, -1829 }, { -2747, -5948, 2362, -173 }, { -2435, -3267, 2966, -1710 }, { -3979, -4282, 2705, -775 }, { -356, -4238, 2544, -4343 }, { -1363, -6471, 2817, -1836 }, { -2878, -5117, 218, -3149 }, { -3539, -5196, 1710, -2356 }, { -2888, -4537, 2746, -1701 }, { -1870, -4439, 1496, -4121 }, { -1486, -3388, 3349, -2145 }, { -3333, -4138, 1467, -2876 }, { -345, -5340, 1012, -1190 }, { -1672, -4992, 2289, -1029 }, { -2146, -5528, 3038, -635 }, { -316, -3656, 3426, -3152 }, { -2695, -5812, 2336, -2050 }, { -2067, -6052, 737, -3258 }, { -2664, -4205, -350, -1266 }, { -617, -5406, 80, -4853 }, { -2418, -3825, 1853, -1326 }, { -1961, -4339, 583, -4315 }, { -1495, -5141, -133, -5205 }, { -3208, -6440, 1691, -2069 }, { -2632, -3633, 2325, -2761 }, { -2624, -5670, 1252, -3676 }, { -3687, -5608, 687, -2833 }, { -3320, -5707, 16, -3877 }, { -2738, -6112, 84, -5135 }, { 2277, -5661, 3076, 843 }, { 1555, -5769, 2821, -5236 }, { 536, -6381, 603, -4910 }, { 734, -4609, 3314, -4092 }, { 1836, -4547, 3267, -4322 }, { -13, -5976, 3752, -1607 }, { 1423, -6318, 2336, 398 }, { 365, -7779, 1498, -534 }, { 2104, -8366, 2946, -1345 }, { 143, -5545, 1898, -3756 }, { 655, -6852, 1430, 148 }, { 4, -6653, 2397, -59 }, { 2346, -5996, 4562, -934 }, { 1229, -7104, 2963, -598 }, { -528, -7048, 2887, -1790 }, { 1451, -6857, 3900, -1637 }, { 554, -6018, 3336, 9 }, { 3278, -5758, 4034, 129 }, { 3541, -7145, 4905, -1575 }, { 2339, -6907, 3464, -301 }, { 2775, -7301, 1667, -3894 }, { 539, -7887, 991, -4156 }, { 2115, -7421, 3131, -3075 }, { 2803, -8546, 2564, -5836 }, { 2869, -5833, 1620, -4561 }, { 2591, -7281, 3215, -4719 }, { -1228, -8477, 706, -4782 }, { 1967, -5243, 4813, -1940 }, { 701, -7010, 2273, -3893 }, { 915, -8470, 1918, -5620 }, { -94, -6715, 156, -3873 }, { 1074, -5607, 4389, -1017 }, { 2739, -6551, 1227, -3521 }, { 725, -7835, 2701, -1291 }, { -493, -7475, 2263, -1075 }, { -412, -6508, 2984, -744 }, { 665, -5451, 3725, -2692 }, { 1499, -8129, 3564, -2072 }, { 2870, -6333, 4487, -2108 }, { 706, -5007, 3911, -152 }, { -482, -8660, 1483, -2900 }, { 2481, -6596, 2518, -1715 }, { 1403, -6414, 1398, -5387 }, { 652, -6267, 583, -5942 }, { 694, -7540, 646, -6272 }, { 2275, -7614, 256, -5015 }, { 1416, -9727, 1900, -3153 }, { 2760, -6433, 3875, -3771 }, { 2325, -11196, 2182, -5155 }, { 1223, -11061, 1377, -5097 }, { 108, -10603, 307, -4952 }, { -118, -8268, 1650, -1572 }, { 1839, -7943, 1755, -612 }, { 2501, -9056, 981, -2969 }, { 2902, -8476, 1491, -5780 }, { 1995, -11175, 1585, -3643 }, { 696, -8212, 828, -2474 }, { 1526, -8649, 1380, -1210 }, { 461, -7253, 3222, -2229 }, { 2966, -8641, 4121, -3271 }, { 833, -6039, 2361, -1086 }, { 3565, -7312, 1980, -5427 }, { 2850, -8671, 3760, -1846 }, { 2643, -7281, 2163, -173 }, { 3463, -3706, -3132, -923 }, { 1315, -3825, -3443, 2 }, { 2594, -4083, -3815, 670 }, { 1826, -4291, -2741, -155 }, { 868, -3749, -4175, -298 }, { 2008, -4237, -3897, -517 }, { 1242, -3493, -4335, -1335 }, { -88, -4142, -3390, -1529 }, { 2176, -3488, -3822, -975 }, { 1706, -5188, -3415, -637 }, { 2717, -6159, -2333, -882 }, { 1276, -3978, -4361, 537 }, { 2471, -5556, -2866, -208 }, { 799, -4673, -4086, 56 }, { 1901, -4786, -3533, 270 }, { 3036, -3902, -3606, -333 }, { 2249, -3317, -4319, -144 }, { 2594, -4207, -2105, -2930 }, { 4008, -4774, -2626, -902 }, { 1038, -3659, -3496, -2454 }, { 2725, -3597, -3298, -1535 }, { 1662, -5803, -2813, 175 }, { 705, -3757, -3441, -1484 }, { 1860, -5987, -2821, -886 }, { 3786, -4918, -2199, -1929 }, { 3683, -4235, -2547, -1287 }, { 2531, -4896, -2956, -1593 }, { 1005, -5585, -3324, -180 }, { 1625, -5229, -1756, -3642 }, { 1494, -5041, -2989, -2685 }, { 2718, -4655, -3224, -867 }, { 2374, -6640, -1745, -2975 }, { 2133, -6436, -2477, -1499 }, { 1833, -4418, -3523, -1512 }, { 1128, -4910, -2658, -1106 }, { 689, -4777, -2831, -2085 }, { 3593, -5280, -2627, -315 }, { 3264, -3771, -2673, -1861 }, { 3202, -5602, -2409, 402 }, { 552, -4618, -2221, -3002 }, { 3095, -5356, -2666, -1083 }, { 3401, -4609, -3146, 45 }, { 3051, -4662, -2192, -2232 }, { 2798, -5552, -2462, -1941 }, { 2354, -5815, -2223, -2619 }, { 192, -3708, -2807, -2658 }, { 1886, -4226, -1862, -3529 }, { 2526, -3976, -2819, -2332 }, { 1577, -3870, -2711, -2806 }, { 1288, -5588, -3382, -1403 }, { 2711, -5399, -1564, -3253 }, { 1459, -5492, -2222, -322 }, { 2823, -5091, -2886, 776 }, { 3559, -5821, -2109, -1360 }, { 1587, -6331, -2760, -1909 }, { 2139, -5213, -2874, -2120 }, { 1318, -4337, -3695, -2098 }, { 821, -4471, -1849, -565 }, { 3329, -4782, -1725, -89 }, { 582, -4914, -4105, -1119 }, { 417, -4144, -4072, -2529 }, { -199, -3803, -2765, -4042 }, { 2731, -4283, -2143, 1 }, { 2911, -6187, -1951, -2116 }, { 1573, -6094, -493, -2838 }, { 2081, -6927, -864, -3211 }, { 1058, -7826, 79, -364 }, { 3147, -5570, -684, -978 }, { 3572, -5856, 1060, 1824 }, { 1143, -6702, -1478, 338 }, { 2341, -7220, -88, 260 }, { 3639, -6861, 668, 815 }, { 2227, -6268, -1706, 446 }, { 3390, -6082, -353, 1302 }, { 1123, -7556, -1237, -430 }, { 1729, -7742, 729, -218 }, { 1457, -6774, 587, 579 }, { 505, -6919, -569, 371 }, { 1106, -7245, 78, 158 }, { 2755, -6745, -1122, 338 }, { 3069, -6040, -1415, 986 }, { 2174, -7064, -1430, -283 }, { 1390, -8626, -446, -3031 }, { 3534, -6890, -431, 547 }, { 2267, -9618, 475, -2994 }, { 3672, -7673, 75, -115 }, { 2131, -7560, -1206, -750 }, { 2972, -7477, -685, -262 }, { 1604, -6637, -672, 699 }, { 1666, -7577, -577, -240 }, { 1591, -6554, -2158, -94 }, { 2348, -6286, -353, 1123 }, { 2017, -8810, -412, -1805 }, { 2892, -6713, -1765, -554 }, { 2500, -6828, -1995, -1197 }, { 3877, -6639, -224, -1655 }, { 2392, -7872, -91, -333 }, { 3562, -7370, -532, -2836 }, { 2552, -7614, 164, -1805 }, { 990, -6104, 218, 438 }, { 910, -7861, 312, -1195 }, { 1472, -6327, 372, -640 }, { 1576, -7143, -1983, -843 }, { 422, -7625, -457, -278 }, { 1797, -8532, 405, -1011 }, { 1088, -7396, -238, -2277 }, { 3209, -6753, -1431, -2072 }, { 2617, -6839, 100, -2573 }, { 2575, -8573, -387, -3188 }, { 3618, -6971, -1190, -321 }, { 2205, -7361, -1695, -2008 }, { 2985, -6297, 1464, 1179 }, { 2804, -7310, 1053, 338 }, { 1362, -6074, -1163, -840 }, { 3336, -6325, -1794, 21 }, { 2836, -8109, 818, -329 }, { 2791, -5879, 560, 1546 }, { 2392, -6064, 135, 100 }, { 1838, -6194, 596, 1085 }, { 1926, -7515, -414, -4901 }, { 3225, -7298, -1202, -1189 }, { 3960, -7558, -659, -719 }, { 3442, -6647, -1692, -1095 }, { 3381, -6441, 262, -886 }, { 1431, -8150, -1186, -1406 }, { 340, -8498, -150, -899 }, { 3004, -8149, -260, -953 }, { 2749, -6611, 563, 873 }, { -6647, -1325, -4517, -4691 }, { -6005, -1657, -4089, -3797 }, { -3157, 588, -5213, -3068 }, { -3311, -1425, -6329, -3726 }, { -5866, -819, -3857, -2744 }, { -5001, -1799, -1075, -4621 }, { -5330, -2650, -2672, -4664 }, { -4930, -539, -2363, -4010 }, { -2984, 10, -3863, -5749 }, { -1055, -2106, -3713, -4267 }, { -5476, -502, -4279, -6504 }, { -5231, -1543, -5018, -6425 }, { -5134, -363, -3165, -5109 }, { -3953, -771, -4107, -6393 }, { -2159, -563, -3652, -5342 }, { -3888, -2321, -919, -5057 }, { -1236, -597, -4235, -4193 }, { -4053, 675, -3083, -6174 }, { -2793, -1089, -5396, -3460 }, { -3000, -44, -2209, -6575 }, { -3336, -1531, -4313, -5160 }, { -2127, 128, -4851, -3692 }, { -3321, 136, -2067, -5660 }, { -5215, 1404, -4374, -4356 }, { -2747, 400, -6340, -3691 }, { -3926, -599, -5361, -5006 }, { -2875, -2592, -5143, -4092 }, { -4991, -1958, -5322, -4891 }, { -4965, -1318, -6652, -5333 }, { -4920, -1691, -3388, -5561 }, { -3644, -3354, -2688, -5982 }, { -5076, -919, -4563, -2984 }, { -6114, 250, -3884, -3915 }, { -4014, 744, -3973, -1924 }, { -5543, -1041, -5557, -3847 }, { -4711, -1352, -5649, -2603 }, { -3362, 775, -5305, -4879 }, { -5001, 107, -3554, -2888 }, { -6258, -1651, -6356, -6566 }, { -4529, 407, -5003, -3865 }, { -5154, 550, -5278, -5465 }, { -4195, -467, -1894, -3129 }, { -5022, 1127, -3349, -3314 }, { -6075, 1250, -4313, -5641 }, { -2677, -2283, -2312, -5903 }, { -4113, 193, -1195, -4833 }, { -3940, -1048, -1389, -5079 }, { -3703, 917, -4043, -4451 }, { -3366, -4231, -1534, -5488 }, { -3326, -3583, -2091, -4903 }, { -5144, 1254, -2532, -4949 }, { -5982, -870, -2545, -4555 }, { -3925, -157, -5367, -2281 }, { -6419, -746, -5668, -4371 }, { -5787, 518, -7096, -5805 }, { -4258, 954, -6453, -4321 }, { -4771, -695, -4158, -1639 }, { -7078, -760, -5195, -5877 }, { -7348, 83, -4101, -4586 }, { -2430, 184, -2874, -1679 }, { -2284, -3943, -2924, -5034 }, { -1804, -1785, -3002, -4710 }, { -4399, -2772, -1815, -4637 }, { -6340, -2626, -2824, -5191 }, { -4998, -5168, -3480, 1905 }, { -3958, -5492, -1599, 1579 }, { -2471, -3755, -276, 3182 }, { -3033, -5779, -1063, 1554 }, { -2936, -4829, -1290, 2386 }, { -1835, -5073, -3051, 1299 }, { -1724, -3771, -3935, 2324 }, { -5070, -2550, -3692, 768 }, { -4326, -5333, -297, 1878 }, { -3472, -5619, -3094, 992 }, { -3027, -4384, -3038, 2265 }, { -3201, -5332, 67, 2200 }, { -1681, -4373, -1947, 2461 }, { -3221, -3329, -4238, 2564 }, { -1262, -2968, -2915, 3227 }, { -3419, -1878, -3373, 2110 }, { -2244, -5583, -2012, 1288 }, { -1971, -5266, -990, 1812 }, { -2975, -2778, -452, 4063 }, { -2198, -1165, -3298, 2965 }, { -4782, -4894, -4767, 664 }, { -6002, -3950, -2806, 2025 }, { -3142, -3162, -2859, 3295 }, { -3262, -3340, -4123, 1596 }, { -4014, -3918, -1955, 3361 }, { -1700, -3463, -1346, 3449 }, { -4245, -4445, -4743, 1644 }, { -4180, -3969, -401, 3281 }, { -2782, -5240, -4117, 1156 }, { -5744, -4040, -1439, 3470 }, { -5063, -4663, -323, 3172 }, { -4531, -3319, -844, 3988 }, { -6226, -5125, -2064, 2976 }, { -3115, -3267, -1531, 3898 }, { -4628, -4421, -2864, 2808 }, { -4559, -2989, -3442, 2024 }, { -1775, -4487, -656, 2477 }, { -2664, -1865, -1884, 4081 }, { -1828, -2575, -3894, 3378 }, { -6441, -3677, -2025, 1677 }, { -4141, -2156, -1191, 3474 }, { -4802, -1623, -1727, 2160 }, { -5474, -2745, -1475, 2498 }, { -3664, -1056, -1975, 2491 }, { -4672, -3062, -2235, 2933 }, { -4205, -5960, -2849, 1517 }, { -4995, -5708, -1739, 1805 }, { -4892, -6080, -4793, 872 }, { -4270, -4172, -4263, 2185 }, { -4687, -1470, -2905, 1023 }, { -6446, -5017, -3919, 1000 }, { -6046, -5538, -3943, 2006 }, { -6028, -3750, -3953, 771 }, { -5959, -4582, -5024, 824 }, { -5818, -2576, -2249, 1326 }, { -5659, -5345, -1119, 2500 }, { -3346, -4155, 606, 2749 }, { -5680, -4827, -2501, 1838 }, { -6193, -2543, -1295, 840 }, { -6871, -4925, -3512, 1801 }, { -5605, -1788, -1895, 779 }, { -3922, -5712, -4644, 510 }, { -4745, -3869, -4533, 99 }, { -2984, -4907, -399, 1497 }, { 1847, -478, 3061, -5812 }, { 4450, -1116, 3609, -6570 }, { 3139, 99, 3007, -5532 }, { 2590, -3782, 3138, -4770 }, { 1881, 1204, 5778, -3404 }, { 3631, 2060, 5566, -5038 }, { 3461, 1961, 5167, -3800 }, { 2947, 273, 4536, -4389 }, { 4453, -1730, 5788, -4370 }, { 4032, 1805, 2666, -4534 }, { 3487, -944, 2313, -6028 }, { 1313, 34, 4210, -4067 }, { 5632, -1502, 5825, -5855 }, { 7736, -547, 4879, -5476 }, { 4906, -1512, 4760, -5760 }, { 3843, 447, 1091, -4958 }, { 2982, -1135, 5442, -4386 }, { 3579, 271, 3031, -6770 }, { 3932, -211, 4688, -5507 }, { 4411, 1720, 2387, -5584 }, { 5379, -479, 4575, -6280 }, { 3613, -362, 2012, -4885 }, { 3744, -2013, 4493, -5073 }, { 5693, 109, 4379, -3362 }, { 5475, -621, 5317, -3985 }, { 6411, -673, 5708, -4752 }, { 4933, -796, 7262, -4290 }, { 2804, 444, 6276, -3655 }, { 4120, -517, 6078, -4531 }, { 5119, 841, 3486, -3910 }, { 4738, 1539, 3525, -2970 }, { 5086, 370, 5895, -5640 }, { 4235, 2716, 4589, -5044 }, { 3691, 682, 6199, -4700 }, { 6111, -570, 6271, -6528 }, { 2611, 1277, 3756, -4802 }, { 4395, 970, 3807, -5879 }, { 5225, 2299, 3242, -4333 }, { 5144, 1778, 4946, -5545 }, { 2989, -3016, 3247, -5495 }, { 2983, 920, 2071, -6059 }, { 5270, -903, 4434, -2350 }, { 6415, -585, 3970, -3554 }, { 3866, -197, 5216, -2884 }, { 3767, -1298, 6702, -3315 }, { 6299, 2620, 5284, -6824 }, { 6654, 646, 3653, -4927 }, { 4770, 3047, 5160, -6287 }, { 5364, 434, 2919, -5207 }, { 2998, 1344, 4801, -2456 }, { 3896, 1013, 3773, -1864 }, { 2115, 655, 2999, -6344 }, { 5170, -981, 2849, -4464 }, { 2735, -2159, 2717, -5776 }, { 2430, -1952, 4392, -4559 }, { 6143, -1180, 3659, -4746 }, { 4978, -1483, 1726, -4875 }, { 3486, -2383, 3306, -4301 }, { 1434, -1372, 4171, -4770 }, { 3354, -2627, 1525, -5093 }, { 6790, 2386, 3995, -5909 }, { 1475, -2674, 3451, -4204 }, { 1999, -3494, 3693, -5556 }, { 4764, -2848, 2856, -5589 }, { -3677, 5131, 2827, -2934 }, { -2844, 7078, 2852, -3580 }, { -3902, 6434, 4118, -1911 }, { -1769, 7530, 3492, -3541 }, { -1937, 5679, -447, -1127 }, { -2456, 4680, 4196, -2407 }, { -2778, 8241, 1698, -4288 }, { -2876, 6104, 5182, -2387 }, { -2802, 7341, 4463, -2938 }, { -1025, 6267, 4752, -3201 }, { -2349, 5413, 2041, -3794 }, { -2252, 8225, 2856, -4269 }, { -1465, 4967, 4976, -2500 }, { -636, 7565, 3517, -4233 }, { -1905, 5618, 3904, -2942 }, { -302, 6816, 3343, -3316 }, { -2210, 4156, 2817, -3511 }, { -717, 6568, 1863, -2951 }, { -3873, 5682, 2164, -575 }, { -2878, 5835, 440, -2597 }, { -3228, 7701, 2610, -2514 }, { -3608, 8888, 3377, -2468 }, { -2582, 9717, 2519, -3126 }, { -5238, 6202, 2866, -2831 }, { -3428, 7370, 3056, -335 }, { -1681, 8836, 1210, -2010 }, { -3276, 6724, 1156, -3930 }, { -894, 8149, 827, -1258 }, { -2965, 8631, 2549, -1320 }, { -3961, 6902, 3581, 55 }, { -1894, 7745, 1750, -841 }, { -821, 6844, 850, -676 }, { -608, 6948, -4, -1376 }, { 615, 6524, 1089, -1147 }, { -2972, 5668, 1091, -489 }, { -157, 4649, 2904, -413 }, { 673, 5121, 1498, -66 }, { -390, 5902, 1611, -245 }, { -2349, 5478, 4772, -1320 }, { 88, 6798, 1972, -1859 }, { -1213, 5120, 2991, 200 }, { -2347, 6040, 2839, 376 }, { -578, 5976, 3364, -1796 }, { -1391, 5872, 3002, -965 }, { -564, 4496, 3946, -1186 }, { -2299, 6386, 3135, -2176 }, { -2131, 5641, 2011, 1223 }, { -772, 5807, 1124, 895 }, { -2837, 6758, 2297, -740 }, { -3091, 6298, 1415, -2126 }, { -4197, 6036, 1843, -3022 }, { -41, 6459, 92, 344 }, { -2241, 6860, 2095, -4396 }, { -1931, 7088, 2117, -2135 }, { -2375, 4422, 1688, -3169 }, { -1742, 6674, 1538, -119 }, { -4818, 7749, 4192, -1577 }, { -2004, 5672, 193, -430 }, { -3825, 6042, 2128, -1898 }, { -1108, 8033, 2119, -3013 }, { -2370, 5453, 1721, 266 }, { -1570, 7134, 614, -2638 }, { -1519, 8752, 3503, -4330 }, { -2050, 3845, 2907, -1126 }, { 5085, 4412, -335, -1923 }, { 3618, 1423, -613, -4012 }, { 4481, 3729, 589, -4631 }, { 4270, 3216, -1763, -3168 }, { 4241, 1796, -1701, -2796 }, { 4787, 2338, -487, -3639 }, { 2915, 3429, -621, -4753 }, { 5175, 1660, -1265, -3223 }, { 4280, 4057, -684, -4079 }, { 4980, 4419, -1455, -2719 }, { 5436, 2464, 387, -4197 }, { 4507, 4018, 1121, -3314 }, { 6020, 2401, -413, -3201 }, { 4200, 3789, -333, -2813 }, { 5229, 2493, -1194, -1878 }, { 5851, 2695, -492, -2292 }, { 5743, 3288, -697, -1221 }, { 5692, 2612, 979, -2227 }, { 5085, 2067, 1046, -1214 }, { 3163, 2240, -2098, -3435 }, { 5228, 1898, 145, -2397 }, { 5860, 3976, -418, -2872 }, { 6008, 3399, 1027, -3506 }, { 4126, 2035, 1865, -893 }, { 5375, 3596, 511, -2362 }, { 1937, 1493, -852, -122 }, { 3473, 4849, 547, -2603 }, { 4631, 2977, 1141, -1768 }, { 6149, 3050, -71, -1886 }, { 4069, 4353, -289, -1429 }, { 2884, 1225, -1388, 365 }, { 5485, 2518, -235, -571 }, { 1216, 4375, 1443, 398 }, { 4988, 3106, 107, -1435 }, { 4511, 2801, 307, -444 }, { 3235, 4386, 327, -676 }, { 2055, 3708, 1657, -305 }, { 5839, 2374, 290, -1385 }, { 5110, 3305, 1936, -4206 }, { 6416, 2920, 338, -2736 }, { 3350, 2824, -1269, -3881 }, { 4840, 1815, 464, 186 }, { 2399, 3332, 238, 1238 }, { 3516, 1363, 1582, 688 }, { 3582, 1874, 154, -4770 }, { 3261, 2878, 886, 283 }, { 3877, 2658, -327, 884 }, { 4151, 3436, 2173, -2923 }, { 3592, 3674, 1281, -1295 }, { 4561, 3730, -1114, -1747 }, { 4595, 3625, -558, -575 }, { 2577, 2348, 2267, 120 }, { 5242, 3299, 32, -3412 }, { 4264, 3637, 709, -2320 }, { 6556, 3570, -838, -2472 }, { 5745, 4014, -940, -1973 }, { 5629, 4475, 477, -3328 }, { 5269, 3199, 1682, -3085 }, { 4432, 2416, 1145, -3299 }, { 4465, 2505, 2162, -2186 }, { 4643, 4941, -88, -2885 }, { 4568, 5231, 552, -3915 }, { 5667, 3075, -1406, -2963 }, { 5418, 5259, -771, -2818 }, { -256, -7875, 511, -471 }, { -1813, -7971, -424, -396 }, { -306, -7006, 862, 282 }, { -2306, -6422, -1440, 508 }, { -245, -6787, 375, -100 }, { -1309, -6065, -20, 779 }, { -1656, -6047, -641, 1307 }, { -1496, -6522, 964, 726 }, { -2291, -6588, -202, 795 }, { -762, -7522, 1454, -558 }, { -2270, -7004, -834, -580 }, { -1139, -7078, 259, 362 }, { -2535, -7568, -1040, 49 }, { -3786, -7280, 934, -476 }, { -3336, -6368, 606, 1056 }, { -3602, -6924, 52, 714 }, { -2278, -6550, 1674, 204 }, { -2855, -5765, 930, 1530 }, { -2889, -7325, -215, 305 }, { -2749, -6080, -237, 1452 }, { -985, -6667, 1577, 400 }, { -2036, -6083, 380, 1267 }, { -2077, -7460, 380, -30 }, { -1775, -7175, 1540, -386 }, { -3065, -6927, 989, 168 }, { -2836, -7602, 117, -3392 }, { -1058, -6396, 593, -3078 }, { -844, -6062, 999, -236 }, { -3261, -6951, 1491, -720 }, { -2186, -8484, 75, -1287 }, { -2882, -7756, 456, -510 }, { -1800, -6879, 960, -1183 }, { -2554, -7241, 1614, -1474 }, { -2608, -5305, 392, 851 }, { -2973, -6562, -859, 858 }, { -2640, -5989, 1031, -416 }, { -977, -8366, 705, -1434 }, { -1213, -7409, -77, -1390 }, { -1335, -6657, 2125, -123 }, { -2544, -6862, 1852, -737 }, { -3235, -6422, 1752, -103 }, { -1300, -7557, 939, -348 }, { -3476, -7579, 202, -109 }, { -2482, -6572, 753, 619 }, { -2554, -8136, -648, -429 }, { -1012, -7870, -3, -421 }, { -3604, -6247, 32, -3102 }, { -1486, -7271, 2013, -1021 }, { -578, -6799, -523, 405 }, { -2841, -5948, 1644, 911 }, { -2411, -7473, 1084, -484 }, { -2238, -6033, 294, -1059 }, { -3459, -6470, -201, -790 }, { -2027, -6009, 1833, 805 }, { -1433, -8047, 1531, -1754 }, { -3258, -7884, 763, -1422 }, { -1544, -6928, -729, 478 }, { -2314, -8415, 74, -3757 }, { -3201, -5684, 95, -2214 }, { -2423, -8694, 725, -3631 }, { -3545, -7071, 1162, -1798 }, { -294, -9662, 403, -2274 }, { -2290, -5460, 1196, 402 }, { -1603, -6713, 903, -2363 }, { 4121, 2491, -3142, -2482 }, { 4500, 3305, -3671, -1567 }, { 5973, 3172, -1348, -534 }, { 4830, 3379, -1549, 643 }, { 5214, 3938, -2641, -2302 }, { 4639, 4826, -5532, -847 }, { 5639, 2731, -2170, -963 }, { 6084, 3487, -3525, -1346 }, { 5971, 3154, -2190, -2316 }, { 5618, 4865, -6927, 116 }, { 5345, 3568, -7391, 709 }, { 5429, 5078, -3811, -1524 }, { 6960, 2037, -3515, -1096 }, { 7092, 2531, -4557, -588 }, { 6061, 4247, -5651, -478 }, { 4595, 3684, -4907, -827 }, { 7497, 3213, -3048, -424 }, { 5996, 2137, -3098, -1745 }, { 6198, 5199, -2223, -2274 }, { 6888, 2851, -2768, -1675 }, { 6114, 4210, -2316, -954 }, { 7127, 4242, -3041, -1408 }, { 6126, 3668, -1517, -1427 }, { 6245, 6129, -4225, -1186 }, { 6816, 3213, -2101, -964 }, { 5345, 5276, -2643, -847 }, { 6592, 4665, -4338, 484 }, { 6746, 3751, -3443, 124 }, { 5453, 1980, -2738, 2606 }, { 4662, 2179, -4226, -1059 }, { 5571, 3208, -3554, 174 }, { 5256, 4447, -1815, -1481 }, { 5400, 2570, -1210, 235 }, { 7056, 2549, -2674, 318 }, { 4574, 4340, -2892, -130 }, { 6203, 4587, -3273, -305 }, { 5103, 1925, -2715, -2137 }, { 3905, 4296, -1700, 247 }, { 4421, 4605, -3299, 811 }, { 5671, 1273, -3870, -924 }, { 5486, 1805, -4901, 133 }, { 6437, 2578, -1828, -106 }, { 5530, 5253, -5058, 1223 }, { 4816, 2025, -1215, 1443 }, { 3457, 3525, -2456, 3217 }, { 3316, 2595, -1108, 2459 }, { 3068, 3810, -2207, 1926 }, { 6351, 5436, -6470, 600 }, { 6324, 4240, -5365, 2416 }, { 4851, 4774, -4075, 1878 }, { 4900, 3679, -5198, 1078 }, { 8347, 3633, -4565, -171 }, { 5244, 5718, -3853, 173 }, { 3960, 3492, -2939, 2105 }, { 6070, 3473, -2351, 161 }, { 8228, 3034, -3360, -901 }, { 7006, 3985, -1940, -1926 }, { 7123, 4681, -4301, -878 }, { 5122, 4097, -1851, -449 }, { 6200, 2060, -2251, 1049 }, { 7106, 3844, -7209, 2625 }, { 7108, 3370, -6734, 533 }, { 6859, 2849, -3992, 1360 }, { 5458, 2278, -3253, 1131 }, { -1072, -2109, 4783, -1073 }, { -319, -2604, 4257, -2418 }, { 2466, 1300, 3476, -314 }, { 2847, -1502, 5296, -141 }, { 1667, -1273, 5559, -2725 }, { 2877, -3402, 6434, 204 }, { 53, -2637, 5275, -1181 }, { 1091, -2215, 5803, -1549 }, { 2397, -922, 4327, 1182 }, { 219, -3747, 4647, -1564 }, { -29, -2705, 4812, 1277 }, { 1499, -2608, 5648, 1407 }, { 2139, -2399, 4202, 2791 }, { -426, -2064, 5528, 151 }, { 2560, -2803, 6179, -2806 }, { 4537, -2479, 3797, 1095 }, { 888, -3357, 5341, -415 }, { 4460, -1814, 5388, -1227 }, { 3920, -3268, 6364, -703 }, { 3343, -4698, 4410, 784 }, { 309, -1897, 6306, 1223 }, { 958, -3318, 4254, -3167 }, { -99, 1596, 6018, -1983 }, { -429, -853, 6407, 878 }, { 1170, -1322, 6290, -417 }, { 2288, -505, 6303, -1999 }, { 3312, -1674, 6749, -2494 }, { -415, -3401, 4721, -371 }, { -189, -1210, 4844, -2002 }, { 888, -4142, 4377, 130 }, { 2469, -4381, 5398, -2492 }, { 2879, -2912, 5094, -2598 }, { -717, -617, 5650, -685 }, { 1470, -3863, 5352, -1684 }, { 3935, -96, 3823, -730 }, { 3769, -430, 3168, 694 }, { 2556, 385, 3539, 512 }, { 77, -1415, 5111, 2655 }, { 2724, -2158, 6715, -822 }, { 1832, 1001, 5385, -1900 }, { 900, 2198, 4464, -559 }, { 441, 69, 5921, -1743 }, { -1161, 738, 6732, -308 }, { 257, 2035, 4091, 736 }, { 1607, 1288, 4355, -23 }, { -13, 1316, 4180, 1672 }, { 1511, 1336, 3057, 1435 }, { 2189, -3813, 4530, 939 }, { 3632, -706, 2646, 1375 }, { 4266, -3761, 4241, 1077 }, { 3101, -427, 5273, -1202 }, { 2293, 276, 4810, -313 }, { 3430, -1851, 3101, 2045 }, { 3453, -2979, 5142, 942 }, { 1683, -3281, 4802, 2002 }, { 3954, -4715, 5611, 578 }, { 1272, -155, 5085, 454 }, { 128, -194, 5095, 1409 }, { 820, 880, 5797, -2658 }, { -1095, 656, 5774, 1095 }, { 813, -1669, 4320, -3251 }, { -119, 518, 6372, -651 }, { 2922, -4299, 6115, -877 }, { 4205, -4273, 4004, 2642 }, { -1211, -3892, 224, 3127 }, { -34, -4371, 1321, 2318 }, { 77, -6326, 1201, 828 }, { 3995, -3775, 1958, 3233 }, { 178, -3301, 1985, 3318 }, { 2330, -3801, 1033, 3195 }, { 1413, -5536, 826, 1709 }, { 2468, -3499, 3653, 3631 }, { 741, -4617, 1723, 2008 }, { 1246, -3043, 2978, 3949 }, { -343, -4308, 2258, 2189 }, { -682, -4640, 454, 2272 }, { 1236, -4829, 2491, 1642 }, { -512, -3766, 1182, 3052 }, { 119, -3939, 3712, 971 }, { -1145, -4624, 1360, 2281 }, { 101, -4746, 2866, 1255 }, { -1500, -5455, 539, 1637 }, { -969, -5909, 1414, 1128 }, { -1261, -4939, -231, 2022 }, { -226, -5345, 1207, 705 }, { 2712, -5109, 3205, 1866 }, { -476, -5913, 273, 1208 }, { -2039, -4464, 624, 2545 }, { -2351, -3930, 2019, 2673 }, { -2675, -4849, 1522, 1990 }, { -1524, -3461, 1446, 3204 }, { 477, -5314, 1710, 1577 }, { 656, -3729, 2346, 2511 }, { 550, -5917, 1975, 1040 }, { 1728, -4704, 3067, 1058 }, { -9, -5247, 506, 1760 }, { -574, -5135, 1675, 1672 }, { 2129, -3781, 3444, 2313 }, { 1144, -4439, 2214, 2529 }, { 1292, -4160, 3185, 1833 }, { 2445, -3262, 2534, 3227 }, { 2266, -4401, 2023, 2400 }, { -587, -3602, 3408, 2067 }, { -885, -4951, 3228, 1174 }, { -728, -2711, 2807, 3552 }, { 1019, -3043, 3195, 2954 }, { 1888, -4615, 1140, 2454 }, { 660, -5616, 754, 800 }, { -1975, -5371, 1649, 1585 }, { -1544, -5436, 2422, 1081 }, { -422, -5882, 2390, 750 }, { 1336, -5557, 2441, 1230 }, { 136, -4001, 267, 2854 }, { -522, -3289, 2226, 2728 }, { -971, -4580, 2471, 708 }, { 704, -5306, 3300, 1001 }, { 325, -3464, 3555, 2398 }, { 794, -3686, 848, 3169 }, { 660, -3017, 4584, 3242 }, { -1486, -3978, 2170, 1644 }, { -1615, -4650, 2688, 1844 }, { 750, -4578, 538, 2239 }, { 1668, -5849, 1455, 1031 }, { 3486, -4681, 2030, 2183 }, { 2642, -5429, 1696, 1761 }, { 4491, -4502, 3538, 2767 }, { 3545, -4528, 3514, 2982 }, { 3269, -3676, 2758, 3966 }, { 5572, 1146, 209, -3379 }, { 7459, 1053, 593, -1896 }, { 4480, 200, -310, -4259 }, { 5577, -939, 242, -3992 }, { 8142, 442, 1257, -3083 }, { 5442, 1261, 1424, -3236 }, { 6260, -183, 3125, -2532 }, { 7179, 889, 1618, -2548 }, { 6416, 932, 2379, -2487 }, { 7094, 2560, 961, -3392 }, { 7322, 463, 2732, -3735 }, { 6632, 1577, 1912, -3272 }, { 6312, 1349, 3028, -3460 }, { 6105, 386, 1213, -977 }, { 5478, 1158, 1114, -486 }, { 6493, 410, 1686, -2180 }, { 6378, 1881, 1333, -2240 }, { 5711, 812, 1958, -1300 }, { 6844, 877, 730, -1189 }, { 6824, -245, 2249, -2000 }, { 7515, 1521, 1251, -3058 }, { 6697, 1051, 1300, -1749 }, { 6476, 1425, 811, -2773 }, { 7350, 465, -76, -2849 }, { 6975, 2095, 567, -2492 }, { 4691, 1736, 2660, -2289 }, { 7837, 1456, 340, -2767 }, { 7930, 507, 838, -2074 }, { 6106, 1502, 766, -1110 }, { 4891, -659, 835, -3954 }, { 7250, 141, 1369, -1523 }, { 7651, 67, 1651, -2298 }, { 7364, -305, 601, -3132 }, { 7179, 193, 2491, -2871 }, { 6504, -272, 2167, -1322 }, { 4456, 983, 2300, -421 }, { 4817, 457, 1695, 371 }, { 6914, 555, 850, -3159 }, { 5904, 1030, 202, -1959 }, { 6258, 880, 2233, -4503 }, { 6029, 10, 2130, -3600 }, { 6449, 985, 1129, -3963 }, { 6616, -18, -111, -3285 }, { 4496, 775, 817, -4276 }, { 6134, 2338, 1470, -2973 }, { 6911, 152, 430, -1946 }, { 4053, 991, 3218, -1193 }, { 5435, 1285, 3124, -2412 }, { 5507, 1836, 1935, -1988 }, { 5240, 689, 2189, -2670 }, { 6638, 1719, 606, -1799 }, { 5556, -180, 129, -2595 }, { 5644, 1918, 1281, -4316 }, { 6410, 1088, -282, -3117 }, { 6503, 1841, 312, -3514 }, { 6947, 20, 1358, -3886 }, { 5464, 2109, 2398, -3194 }, { 5616, -407, 2140, -498 }, { 6121, 2707, 2379, -4096 }, { 7303, 1846, 2266, -4095 }, { 5444, 470, 2718, -1553 }, { 5817, -645, 3285, -1349 }, { 5625, 1427, 1103, -1991 }, { 6041, -806, 1196, -2943 }, { 3050, -5722, 4070, -5460 }, { 3420, -4386, 4078, -5155 }, { 6020, -3982, 7268, -2689 }, { 7502, -4317, 7894, -3973 }, { 4156, -3558, 5247, -4316 }, { 4725, -4401, 7290, -1540 }, { 6688, -5122, 8216, -3210 }, { 9176, -6576, 9276, -4963 }, { 8706, -5708, 7987, -4621 }, { 7060, -3535, 6532, -3308 }, { 5600, -2719, 5363, -1568 }, { 4661, -2803, 6263, -4716 }, { 3673, -3636, 6147, -3433 }, { 5305, -2585, 6073, -2638 }, { 7614, -1962, 6079, -5266 }, { 6760, -3366, 7382, -4322 }, { 6385, -3883, 4797, -1353 }, { 8182, -5120, 4298, -4641 }, { 9130, -6198, 4975, -3063 }, { 7421, -5436, 5576, -3713 }, { 3483, -4898, 5443, -2745 }, { 4907, -5643, 6390, -4105 }, { 8119, -7008, 7992, -6764 }, { 6528, -6122, 6967, -5590 }, { 5890, -4190, 6624, -5688 }, { 6815, -7934, 7275, -5456 }, { 5434, -4306, 5169, -5378 }, { 4364, -6436, 5376, -2604 }, { 8152, -3404, 5913, -5048 }, { 7983, -4863, 4262, -2461 }, { 8023, -6188, 6238, -5062 }, { 6753, -3692, 3935, -3723 }, { 6826, -4760, 3284, -4051 }, { 7224, -7423, 4492, -3875 }, { 6904, -2590, 6587, -6248 }, { 6106, -1944, 7345, -5506 }, { 4956, -2990, 7808, -3146 }, { 6908, -6885, 5949, -1288 }, { 7162, -6058, 3419, -3401 }, { 7015, -7080, 6907, -3018 }, { 6971, -6832, 5646, -3273 }, { 8014, -5546, 5471, -1544 }, { 6792, -2220, 5105, -2879 }, { 8494, -3974, 4408, -3999 }, { 9591, -4866, 6027, -4558 }, { 5264, -5161, 6101, -738 }, { 5803, -6141, 5197, -5231 }, { 4657, -6822, 3232, -5189 }, { 4791, -5135, 3809, -4665 }, { 6108, -5103, 2379, -3873 }, { 4680, -3909, 3234, -5093 }, { 5802, -3853, 3795, -4984 }, { 4360, -7483, 4802, -3877 }, { 5429, -7517, 5911, -3717 }, { 6866, -2280, 4880, -4634 }, { 10131, -4628, 4414, -4092 }, { 10811, -5189, 7746, -5337 }, { 5663, -8941, 5287, -5680 }, { 8023, -5991, 7403, -2796 }, { 9669, -6919, 6525, -4932 }, { 7275, -3796, 4962, -2547 }, { 8848, -4806, 5677, -3080 }, { 8128, -4308, 7749, -6569 }, { 4032, -5196, 2282, -6239 }, { 6593, 700, -229, 304 }, { 8260, 539, -66, -1259 }, { 6605, 176, -814, -109 }, { 8057, 0, -1, -136 }, { 7382, -38, -484, -1129 }, { 8373, -929, 682, -454 }, { 7674, 690, -1278, 546 }, { 7326, -517, 406, -1283 }, { 7612, -1715, -1167, 1175 }, { 8590, 441, -782, -710 }, { 8572, -1202, -291, 260 }, { 7308, -147, -1785, 414 }, { 6787, -353, -672, 934 }, { 5177, -133, 179, 82 }, { 4161, -34, 447, 1497 }, { 5997, -902, 1533, -121 }, { 5727, -871, -1370, 945 }, { 8386, -252, 293, -823 }, { 6573, -1354, 682, 616 }, { 7650, -2096, 725, 457 }, { 8122, 78, 636, -1400 }, { 8421, 428, -1620, 131 }, { 7341, -1292, -717, 186 }, { 7998, -49, -720, 266 }, { 5987, -351, 669, 844 }, { 7314, -1620, 250, -603 }, { 7219, -1562, -572, 1994 }, { 8682, -358, -290, -388 }, { 5810, 155, -178, 1199 }, { 7246, -12, 1042, -786 }, { 7357, -923, 1468, -475 }, { 7801, 621, -212, -724 }, { 5346, -514, 1210, 1356 }, { 8459, 36, -127, -779 }, { 6878, -2429, 854, 1750 }, { 7280, -1401, -1353, 2845 }, { 7579, -2148, -1463, 2087 }, { 6637, 946, -872, 750 }, { 4807, -1100, 1289, 2602 }, { 4495, 219, 1551, 1128 }, { 7639, 506, 446, -1107 }, { 6359, 188, 1009, -115 }, { 6641, -1820, 1655, 723 }, { 5394, -2382, 1604, 2542 }, { 6021, -2644, 2396, 1407 }, { 4698, 882, 245, 1525 }, { 8103, 573, -798, -349 }, { 8045, -519, 997, -1092 }, { 7571, -122, 227, -338 }, { 5347, -1200, 630, 1718 }, { 7070, 790, 218, -544 }, { 7440, 728, -527, -20 }, { 6402, -355, 197, -736 }, { 4031, 771, 866, 1895 }, { 6009, 896, 445, -31 }, { 5160, 1098, -856, 1784 }, { 7980, -886, -1293, 1396 }, { 6318, -1361, 2423, 252 }, { 7547, -699, 133, 506 }, { 8562, -2344, 940, 264 }, { 5890, 1187, -1425, 2194 }, { 6558, -645, -1311, 2621 }, { 4634, -1671, 2075, 1623 }, { 5614, 105, -816, 2376 }, { 6646, 1558, -1365, 630 }, { 6998, 1150, -2117, -990 }, { 6555, 2311, -1093, -1783 }, { 6682, 1430, -2391, -1940 }, { 7861, 1555, -2977, -1188 }, { 6745, 1723, -459, -2085 }, { 7504, 1229, -1666, -2060 }, { 7937, 671, -2128, -1529 }, { 7139, 991, -735, -2632 }, { 6867, 1592, -1303, -2324 }, { 6401, 2230, -1732, -2508 }, { 7201, 2184, -2169, -1988 }, { 6636, 2190, -995, -2840 }, { 7620, 2306, -2089, -651 }, { 7584, 1875, -1438, -631 }, { 9214, 1561, -2464, -1139 }, { 6154, 1318, -1237, -2917 }, { 7917, 2847, -1797, -1599 }, { 8309, 2029, -2555, -465 }, { 8204, 1282, -584, -2405 }, { 8440, 1035, -1147, -1137 }, { 7107, 1858, -60, -1568 }, { 6781, 2912, -873, -1463 }, { 7603, 1316, -319, -1249 }, { 7833, 1335, -78, -1849 }, { 7930, 1141, -1016, -695 }, { 7883, 1610, -1017, -1314 }, { 8069, 1409, -1811, -196 }, { 8319, 1031, -582, -1590 }, { 5948, 1537, -2153, -2373 }, { 8684, 1171, -1871, -850 }, { 8357, 2484, -2411, -1292 }, { 6516, 2092, -193, -1167 }, { 6112, 1697, 22, -525 }, { 7161, 703, -602, -1879 }, { 6047, 2351, -807, -219 }, { 8072, 1854, -1817, -1553 }, { 6956, 1304, 76, -1011 }, { 6607, 1481, -544, -162 }, { 6958, 2541, -265, -1938 }, { 6416, 2514, -777, -850 }, { 7272, 2110, -899, -1171 }, { 7741, 2153, -283, -2614 }, { 6482, 2041, -1758, -1221 }, { 6762, 940, -1862, -2281 }, { 5610, 1194, -1691, -1561 }, { 7833, 2164, -823, -1952 }, { 5460, 1438, -848, 1189 }, { 6011, 1377, -771, -1557 }, { 7679, 544, -1134, -2214 }, { 7209, 1292, -2714, -1564 }, { 5567, 1200, -404, -169 }, { 5853, 1461, -1465, -518 }, { 6782, 689, -844, -860 }, { 7330, 1337, -1152, -71 }, { 7189, 1506, -653, -685 }, { 6860, 2116, -1403, -240 }, { 8804, 1516, -1391, -1760 }, { 7210, 2689, -1498, -989 }, { 7030, 3022, -1441, -2083 }, { 5649, 1836, -407, 525 }, { 7451, 3099, -717, -2464 }, { 7384, 1656, -2007, 398 }, { 6504, 707, -1919, -134 }, { -1851, 3639, -2279, -695 }, { -4037, 1644, -77, 1329 }, { -4025, 1960, -1565, -567 }, { -3430, 2495, -795, 368 }, { -4771, 2480, 993, 756 }, { -3431, 2058, -2539, -971 }, { -3802, 3418, 380, 217 }, { -3074, 3350, -1652, -1056 }, { -3705, 326, -1650, 1535 }, { -3122, 1281, -1192, 1607 }, { -4601, 1367, -968, 53 }, { -3808, 958, 44, 2560 }, { -2079, 2530, -1485, 1166 }, { -3707, 343, -2889, 180 }, { -5249, 1431, -31, 688 }, { -4990, 125, -704, 1270 }, { -2771, 1334, -2446, 746 }, { -2292, 994, -1527, 2630 }, { -1261, 3070, -2519, 268 }, { -2544, 3890, -1057, -552 }, { -4421, 255, -1980, 530 }, { -2951, 454, -13, 3643 }, { -2262, 1815, -370, 2880 }, { -2383, 3657, -649, 576 }, { -3541, -161, -1389, 2550 }, { -4241, 1575, 1325, 2561 }, { -2767, 4037, 1221, 1578 }, { -3748, 2697, 1148, 1801 }, { -4686, 2385, -220, 0 }, { -1531, 1645, -2751, 1327 }, { -45, 4032, -799, 2298 }, { -2915, 2280, 709, 2495 }, { -1199, 3278, -406, 2346 }, { -2471, 116, -2706, 2060 }, { -2440, 2173, -2894, -344 }, { -3375, 2287, 1781, 3226 }, { -2153, 3568, 1827, 2918 }, { -862, 2267, -1626, 2527 }, { -2698, 1135, 301, 4239 }, { -2364, 2123, 1010, 3710 }, { -2447, 3281, -81, 1408 }, { -2660, 4735, 472, 258 }, { -1053, 3097, 2682, 2398 }, { -3366, -1037, -1152, -868 }, { -643, 4242, 2212, 1259 }, { 971, 3991, 934, 643 }, { -1617, 2002, 2139, 2195 }, { -4897, 972, 784, 1719 }, { -1275, 2992, 1039, 3821 }, { -392, 4973, -209, 1821 }, { -1028, 4718, -1479, -137 }, { 50, 3914, 553, 2210 }, { 678, 4364, 359, 1303 }, { -582, 4911, 514, 1671 }, { 1276, 3914, -1252, 2934 }, { -1496, 3984, 857, 2330 }, { 772, 4744, -655, 2332 }, { -799, 5283, -439, 624 }, { 1341, 2937, 650, 2027 }, { -1739, 4892, 1275, 1702 }, { -892, 2596, -151, 3951 }, { -3532, 1090, 1292, 32 }, { 321, 3146, 2647, 1475 }, { 264, 4199, -1591, 1317 }, { -452, -2357, 2266, 4192 }, { 3022, -1033, -2389, 5678 }, { -1162, -1342, 3543, 4990 }, { -474, -1477, -1223, 5016 }, { -699, -2857, 900, 3835 }, { -461, -2255, -117, 4626 }, { 1204, -2062, -1211, 4403 }, { 2192, -3035, -337, 3966 }, { 108, -831, 279, 5643 }, { 1457, -620, -2908, 5276 }, { -2527, -78, 1085, 5460 }, { -1978, -1918, -949, 4733 }, { 32, 367, -1904, 5166 }, { 1890, -1665, 440, 4752 }, { -518, -348, 2816, 4891 }, { 3695, -2490, -1374, 4603 }, { 246, -1965, 3549, 3969 }, { 1100, -3111, 656, 3737 }, { -1379, 870, -414, 4575 }, { 628, -357, -1227, 6179 }, { -1129, -1318, -2457, 4576 }, { -425, -98, -73, 6336 }, { 367, -887, 2990, 4207 }, { 2091, -1251, 2444, 3557 }, { -1759, -1610, 2046, 5273 }, { 3210, 1414, -20, 2616 }, { 3303, -2636, 1005, 4237 }, { -327, -3107, -640, 3687 }, { -197, 764, 572, 5486 }, { 646, -767, 1388, 5464 }, { 104, 2742, -228, 3907 }, { -236, 1829, -579, 4585 }, { -2150, -474, -1525, 4006 }, { -23, -2632, -2400, 3892 }, { -12, -1739, -2910, 4867 }, { -2310, -368, -102, 4583 }, { -1991, -2061, 533, 4531 }, { 3884, -1446, -153, 4393 }, { 1568, 14, -289, 5268 }, { -1376, -253, -2797, 3417 }, { 3193, -2577, 2475, 3566 }, { 3418, 617, 1350, 1857 }, { 3792, -24, -272, 3370 }, { 153, 1159, 2906, 2877 }, { 511, 2162, 1548, 2741 }, { 262, 819, -2791, 3734 }, { 4232, -2015, 1486, 3477 }, { 2943, -1110, -1014, 5480 }, { 2842, 369, 703, 3476 }, { 3011, 1634, -933, 3553 }, { 4412, -1548, -942, 5021 }, { -1405, 593, 2372, 5267 }, { 2093, 2129, 896, 2365 }, { 4845, -1980, 0, 3823 }, { -2140, 81, 3278, 5637 }, { 1484, 2665, -324, 3653 }, { 10, 192, 1620, 5291 }, { 2152, 738, -2269, 5000 }, { 2102, 2748, -1652, 4707 }, { 2855, -2131, -387, 5188 }, { 1173, 676, 1338, 3277 }, { 2340, -2329, -2064, 4095 }, { 861, -2024, 1296, 5055 }, { 2189, 3225, -695, 2626 }, { 6196, -7079, 1943, -822 }, { 4547, -4813, 3261, 1856 }, { 4243, -6904, 3443, 448 }, { 4581, -7503, 946, 506 }, { 6626, -7754, 3427, 470 }, { 3407, -9088, 3269, -1496 }, { 4079, -6464, 2304, 777 }, { 5621, -9336, 2684, -768 }, { 5351, -6464, 5238, -214 }, { 5961, -8007, 1724, -3091 }, { 4213, -8067, 603, -246 }, { 7208, -7403, 3168, -1738 }, { 6098, -7700, 329, -1379 }, { 6525, -6735, 4248, -1072 }, { 6073, -6241, 2167, -2378 }, { 4609, -9218, 3051, -1033 }, { 6813, -7283, 1581, -1897 }, { 6126, -6275, 2789, 681 }, { 4423, -6538, 1621, -1692 }, { 6272, -8298, 3167, -1855 }, { 6172, -8558, 4498, -1169 }, { 4844, -8588, 1647, -366 }, { 6209, -8807, 1581, -369 }, { 5389, -8059, 550, -192 }, { 6654, -9775, 2504, -1063 }, { 7103, -7998, 806, 530 }, { 5662, -6736, 1565, -3620 }, { 4165, -9564, 4191, -2131 }, { 4526, -7181, 576, -2875 }, { 4633, -8623, 2807, -4742 }, { 3709, -7794, 1815, 34 }, { 3634, -8622, 2313, -826 }, { 6991, -8447, 2063, -3198 }, { 7757, -9486, 2255, -558 }, { 4149, -7778, 4728, -1696 }, { 5767, -7427, 1113, 707 }, { 4592, -6261, 2329, 1864 }, { 3159, -10498, 1677, -4273 }, { 3534, -9010, 2437, -3565 }, { 4479, -10821, 2715, -4942 }, { 3207, -9805, 3054, -3886 }, { 4627, -8189, 3018, -2354 }, { 5527, -10566, 3244, -2749 }, { 4346, -10127, 3335, -3084 }, { 6132, -10085, 3316, -1308 }, { 5629, -9704, 2178, -3058 }, { 3603, -8538, 1246, -624 }, { 3737, -8488, 395, -3167 }, { 5465, -11414, 2810, -4640 }, { 5306, -7745, 2721, -3988 }, { 7000, -9111, 1695, -1409 }, { 6663, -7741, 2466, -4079 }, { 4083, -7175, 1836, -4831 }, { 3613, -9926, 1342, -3455 }, { 6588, -8033, 457, -258 }, { 4720, -8102, 17, -1209 }, { 7414, -8709, 1294, -344 }, { 5437, -10030, 4043, -1704 }, { 4862, -9281, 1558, -1431 }, { 6800, -6403, 5113, 862 }, { 4623, -8242, 2667, -228 }, { 5919, -5083, 3348, 2135 }, { 5985, -8889, 2733, -5105 }, { 5029, -5767, 4407, 719 }, { 354, -6158, -838, -3001 }, { 351, -5943, -2104, -1534 }, { -633, -7190, -25, -4798 }, { -1595, -7235, -3812, -1400 }, { 103, -6197, -2933, -78 }, { -1722, -5020, -3441, -4333 }, { -1963, -5644, -4365, -270 }, { -846, -5743, -3477, 196 }, { -191, -5348, -4054, -469 }, { -2515, -7754, -3495, -818 }, { -2090, -6710, -2701, 117 }, { -546, -7036, -1398, 163 }, { -278, -7091, -2662, -536 }, { -622, -7962, -2731, -1464 }, { -1555, -8118, -3612, -2057 }, { -1094, -6280, -2314, 505 }, { -2556, -8538, -4024, -2247 }, { 109, -7134, -3107, -1823 }, { -900, -6954, -3340, -717 }, { -605, -7113, -3656, -2154 }, { 837, -6263, -3211, -2177 }, { -417, -5810, -3871, -1469 }, { -1318, -5649, -4207, -3198 }, { 413, -6765, -2082, -33 }, { -3101, -6450, -4362, -766 }, { 755, -6489, -2967, -846 }, { 1117, -7106, -2452, -1352 }, { -1202, -8387, -3072, -2897 }, { -365, -4894, -3561, -2937 }, { -2372, -8776, -265, -4441 }, { -1224, -8678, -896, -5074 }, { -755, -10096, -600, -6623 }, { 300, -8206, -225, -4568 }, { -1176, -6824, -2633, -3527 }, { -2006, -5443, -1526, -5849 }, { -1115, -5540, -2363, -4785 }, { 1059, -6812, -2543, -2654 }, { -1976, -6861, -3062, -5508 }, { -379, -5328, -2321, -3624 }, { -2108, -5860, -4518, -1915 }, { -379, -7885, -1329, -594 }, { 774, -5389, -581, -5213 }, { -2601, -5083, -1849, -4921 }, { -176, -5580, 74, -5075 }, { -204, -6780, -190, -6232 }, { 418, -7594, -1987, -820 }, { -1873, -8529, -2926, -1609 }, { 1340, -6362, -919, -4975 }, { 577, -7990, -2044, -1873 }, { -2572, -7413, -1745, -2224 }, { -2037, -7030, -1461, -7138 }, { -2559, -8756, -2039, -5836 }, { -2079, -6764, -1209, -5669 }, { -1613, -7801, -2006, -685 }, { -1865, -6583, -722, -3529 }, { -589, -6358, -1377, -1003 }, { -540, -7514, -1331, -3542 }, { 419, -6192, -1677, -4927 }, { -2786, -8763, -2966, -5065 }, { -2172, -8411, -1726, -4675 }, { -3382, -9833, -3497, -5722 }, { -2433, -10169, -2077, -5775 }, { -424, -9451, -1096, -3658 }, { -537, -8522, -910, -1897 }, { -5550, 2807, 1683, -693 }, { -6395, 635, 3573, -1246 }, { -7544, 2280, 2140, 44 }, { -8751, 1136, 2951, -794 }, { -5605, 2709, 2052, 916 }, { -7650, 654, 869, 135 }, { -6939, 967, 1409, 870 }, { -7834, 2123, 3310, 974 }, { -6935, 2818, 1274, -1678 }, { -5605, 2233, 1013, 471 }, { -7095, 1849, 1648, 198 }, { -6636, 1634, 712, -37 }, { -7279, 978, 296, -315 }, { -7664, 3504, 3292, -216 }, { -7836, 1209, 1221, -257 }, { -7913, 2201, 1765, -1529 }, { -7077, 3783, 2632, -1407 }, { -5565, 1645, 1410, -622 }, { -6494, 2879, 1181, -759 }, { -7073, 3137, 3010, 550 }, { -7249, 1839, 847, -805 }, { -6630, 2197, 282, -1096 }, { -8836, 1573, 1988, -1090 }, { -7809, 1274, 836, -1198 }, { -7895, 2970, 3511, -1097 }, { -6960, 1664, 1356, -2442 }, { -6582, 2866, 2273, 307 }, { -7221, 821, 2851, -1435 }, { -6015, 1703, 2001, -2367 }, { -8082, 1034, 2103, 239 }, { -5952, 1912, 301, -465 }, { -6099, 841, 379, 567 }, { -6343, 50, 494, 658 }, { -6586, 983, 591, -893 }, { -5500, 869, 2187, -2479 }, { -6482, 60, 1545, -979 }, { -6705, 515, 1974, -53 }, { -6460, 1755, 1325, -1275 }, { -6093, 2617, 2465, -623 }, { -7330, 2161, 594, -2115 }, { -7324, 762, 1593, -2004 }, { -6385, 679, 1510, -2514 }, { -6159, 241, 2976, -1631 }, { -8583, 3030, 4045, -162 }, { -6299, 66, 2209, -2103 }, { -5428, 1279, 3267, -1846 }, { -6438, 1335, 2728, -1631 }, { -8012, 1070, 2428, -1151 }, { -6201, 2781, 2349, -1918 }, { -5918, 1139, 3121, -148 }, { -6314, 2481, 3137, -1808 }, { -7180, 1722, 2435, -1602 }, { -6750, 1829, 3763, -1145 }, { -6713, 1777, 2221, 1212 }, { -7479, 1835, 3627, -479 }, { -7299, 10, 2406, -1593 }, { -8249, 3129, 996, -2870 }, { -8374, 1534, 1333, -1882 }, { -7507, 3353, 1598, -2299 }, { -7379, 2701, 2326, -1167 }, { -8440, 2276, 2796, -542 }, { -10348, 1527, 2649, -1165 }, { -8184, 3614, 2574, -1738 }, { -5539, 1574, 1733, 1138 }, { 9404, -7652, 67, 79 }, { 8654, -3972, 1358, -60 }, { 8617, -4794, 117, 2318 }, { 7886, -4505, 1784, 1200 }, { 8636, -6125, 3879, -1003 }, { 9654, -6836, 1816, 205 }, { 9374, -6553, 913, 1875 }, { 8020, -6150, 1134, 2390 }, { 7786, -4970, 2078, -1857 }, { 8691, -6119, 711, 708 }, { 9039, -5568, 2944, -1902 }, { 9955, -5048, 1433, -601 }, { 8089, -6927, 3093, -2846 }, { 8487, -7024, 2415, 19 }, { 9388, -5287, 3577, -2655 }, { 8591, -7371, 2300, -996 }, { 9104, -4763, 1453, -2558 }, { 7615, -5457, 596, 164 }, { 9860, -7047, 3433, -614 }, { 8756, -4404, 2235, -964 }, { 9462, -4660, 299, -1822 }, { 10119, -5550, 2689, -1273 }, { 10915, -7471, 2705, -1007 }, { 11433, -7090, 1410, -1198 }, { 9882, -7431, 2965, -1895 }, { 7628, -5219, 769, -2661 }, { 8169, -5318, 2262, 70 }, { 8846, -6320, 1939, -754 }, { 7147, -5593, 1248, -971 }, { 10652, -5485, 935, 137 }, { 7778, -6533, 2564, -1932 }, { 8878, -5173, 1214, -361 }, { 9828, -4943, 282, 510 }, { 10042, -6134, 3895, -1914 }, { 7965, -6630, 3566, -433 }, { 8573, -4502, 3574, -1209 }, { 8398, -4801, 1031, -1347 }, { 10136, -7772, 2612, 1547 }, { 9890, -7280, 1768, -1083 }, { 8407, -6585, -706, -58 }, { 7976, -7582, 229, -131 }, { 10481, -8866, 1166, -147 }, { 10914, -4342, 3189, -2412 }, { 10440, -5198, -104, -1109 }, { 11227, -6530, 2381, -2449 }, { 8487, -8064, 1086, 230 }, { 9975, -6123, -857, -134 }, { 8339, -6498, 1232, -2337 }, { 11042, -4506, 1119, -2098 }, { 12563, -5592, 1837, -2062 }, { 11801, -5590, 632, -1296 }, { 10152, -5617, 1511, -1917 }, { 7800, -6473, 51, -1337 }, { 7941, -5560, 2438, -3270 }, { 6554, -3834, 2100, 1476 }, { 9065, -5520, -226, -1120 }, { 10794, -7120, -243, 122 }, { 10429, -6968, 272, -806 }, { 8942, -8914, 1442, -392 }, { 9969, -5051, 2033, -2953 }, { 7275, -4152, 3058, -64 }, { 11127, -5488, 4589, -3227 }, { 9626, -6666, 2739, -2958 }, { 6943, -5362, 4470, 1008 }, { -7456, -967, 2936, -1002 }, { -8622, -333, 6962, 2606 }, { -7486, -3392, 3668, 1287 }, { -8053, -827, 5148, 1097 }, { -6610, 454, 4952, 96 }, { -7701, -1982, 3161, -468 }, { -7307, -1132, 4071, -36 }, { -8125, -271, 5199, 3862 }, { -9182, -1950, 2813, 1878 }, { -9855, -952, 4794, 3010 }, { -7241, 1431, 4202, 2468 }, { -9646, 157, 4766, 1046 }, { -9371, 1230, 6009, 2958 }, { -11514, -64, 8630, 5248 }, { -6766, 565, 2766, 2140 }, { -8426, -9, 2852, 1271 }, { -11291, -1113, 5087, 2937 }, { -8297, 2092, 4495, 1264 }, { -9983, 735, 3809, -51 }, { -9048, -1000, 3191, -308 }, { -7331, -1987, 2655, 1391 }, { -7144, -21, 4333, 2161 }, { -6032, -1540, 3543, 896 }, { -7987, -1036, 1985, 1529 }, { -9264, 2004, 5194, 290 }, { -11308, -840, 5754, 1654 }, { -9130, -2398, 4292, 2973 }, { -6248, 838, 3563, 1223 }, { -6819, -2760, 3511, 119 }, { -7213, -2006, 4364, 762 }, { -5431, -1047, 4533, 166 }, { -7098, -641, 2021, 639 }, { -8628, -2249, 3588, 399 }, { -6352, -1498, 3560, -648 }, { -7033, -2190, 4870, 2562 }, { -7405, -46, 3772, -581 }, { -6104, 796, 5143, 1965 }, { -5787, 943, 5784, 3030 }, { -8367, 1465, 7192, 4097 }, { -8259, 789, 5694, 1963 }, { -10614, -1899, 5748, 2645 }, { -8258, -805, 3698, 2275 }, { -6877, -972, 6431, 3160 }, { -6483, 363, 7018, 3129 }, { -6283, -1358, 5191, 1524 }, { -8853, -3157, 4119, 1741 }, { -6086, -267, 3883, -835 }, { -7254, 1032, 6613, 4017 }, { -11470, -3350, 4649, 3426 }, { -6743, 481, 6148, 1239 }, { -5394, -166, 5309, 3165 }, { -7958, 1068, 4268, -240 }, { -10520, 2256, 7916, 2828 }, { -5132, -4, 5739, 1176 }, { -8643, 120, 3255, -629 }, { -9631, 1974, 8870, 4362 }, { -10663, -1221, 3733, 589 }, { -8224, -1843, 5806, 2655 }, { -8282, 1255, 8647, 3478 }, { -12311, -1505, 9043, 6256 }, { -11312, -856, 7136, 4681 }, { -11944, -722, 7941, 3309 }, { -7868, -463, 6846, 4196 }, { -8679, -241, 7410, 5347 }, { 6759, -4680, -508, 1220 }, { 5176, -6111, 944, 121 }, { 6843, -5667, -1368, -533 }, { 5616, -5884, -1471, -695 }, { 6030, -5089, -1808, -940 }, { 7444, -5463, -52, 1881 }, { 4207, -6079, -506, 1571 }, { 6785, -4410, -649, 3084 }, { 4838, -5214, 2026, 2998 }, { 4201, -5790, 645, 1811 }, { 6930, -5129, -1940, 1698 }, { 6332, -4627, 692, 3027 }, { 6285, -4314, -106, 3644 }, { 6255, -5450, -1975, 742 }, { 4199, -4676, -459, 1796 }, { 5592, -5500, 1345, 1300 }, { 4358, -5556, -2236, 114 }, { 4620, -5875, -1563, 888 }, { 4892, -7550, -327, -419 }, { 4734, -7085, 7, 613 }, { 3883, -5562, -1969, 1080 }, { 5610, -4990, -204, 834 }, { 4117, -6482, -1271, 341 }, { 6585, -5107, 892, 1169 }, { 6632, -3683, 302, 3002 }, { 6326, -5351, -983, -1250 }, { 4382, -7192, -730, -158 }, { 5227, -6540, -451, 1123 }, { 5468, -6472, -870, -1471 }, { 5191, -6402, -1365, -127 }, { 7407, -6317, -973, -336 }, { 4611, -6530, -820, -1980 }, { 4963, -5159, -2050, -966 }, { 4414, -5691, -211, -998 }, { 5954, -5873, 750, -1749 }, { 4394, -4796, -1268, 254 }, { 7161, -6214, -1010, 689 }, { 4965, -3598, 2372, 1711 }, { 6248, -6180, 981, 864 }, { 6473, -5336, 525, -600 }, { 4591, -6864, -1131, -900 }, { 6314, -6440, -1021, -375 }, { 5838, -6209, -1199, 944 }, { 5308, -5283, -2100, 1267 }, { 4342, -5860, -1637, -1356 }, { 5680, -4388, -1227, -104 }, { 4900, -4098, 1449, 4046 }, { 4677, -4284, -106, 3190 }, { 7574, -6173, -848, 1859 }, { 6493, -7207, -131, 726 }, { 5513, -5261, -2117, 4 }, { 6191, -7352, -193, -505 }, { 5885, -4333, 324, -134 }, { 6162, -6081, -312, -2044 }, { 4216, -6200, -1810, -572 }, { 5652, -7035, -696, -197 }, { 7131, -7189, -366, -60 }, { 5032, -4803, -1514, 2832 }, { 7386, -4610, -606, 3489 }, { 4211, -5031, 1221, 3047 }, { 4050, -4653, 1584, 1469 }, { 6852, -5302, -1861, 206 }, { 7736, -4816, -1794, 3359 }, { 6290, -3439, 1522, 2454 }, { 1768, 5990, -5560, -2594 }, { 3903, 5326, -1530, -1501 }, { 2472, 3738, -2117, -4240 }, { 3260, 5448, -904, -4733 }, { 1435, 7297, -3676, -4102 }, { 4096, 5951, -656, -3312 }, { 2178, 6009, -3146, -3724 }, { 3787, 5493, -5473, -1633 }, { 2998, 7286, -3334, -3571 }, { 2894, 6576, -4708, -2804 }, { 830, 6163, -4286, -3348 }, { 4755, 5569, -1730, -2739 }, { 4604, 6065, -3562, -2605 }, { 2749, 5141, -3986, -2775 }, { 3942, 4875, -2143, -3340 }, { 2819, 8517, -2004, -2724 }, { 2146, 6298, -689, -3093 }, { 5196, 6504, -3393, -1475 }, { 1851, 8386, -1748, -1420 }, { 3474, 8572, -3534, -2688 }, { 4503, 7560, -3561, -2245 }, { 4433, 6219, -2393, -1575 }, { 3506, 7248, -2275, -1977 }, { 3490, 7409, -3147, -604 }, { 4214, 6447, -3520, 516 }, { 619, 7034, -829, -1705 }, { 1732, 7395, -356, -2208 }, { 1226, 5204, -3294, -3732 }, { 2027, 5619, -1813, -4146 }, { 3078, 5877, 47, -2651 }, { 1654, 5458, 424, -682 }, { 3163, 5464, -2026, -270 }, { 2884, 5375, -685, -530 }, { 2950, 7286, -35, -2967 }, { 1986, 5066, -597, 482 }, { 3459, 4308, -3845, -2333 }, { 3155, 7037, -1346, -4345 }, { 2193, 6696, -717, -1319 }, { 3677, 5089, -3892, -487 }, { 2186, 5136, -4186, -1492 }, { 773, 5796, -917, 817 }, { 2489, 6546, -3570, -2117 }, { 1223, 6469, -1362, -33 }, { 271, 6061, -1466, -1725 }, { 2540, 5171, -1847, 1032 }, { 2548, 5251, -2697, 1677 }, { 771, 7600, -768, -632 }, { 4710, 6647, -4736, -1275 }, { 1369, 5917, -2971, -1056 }, { 163, 5239, -3499, -2275 }, { 2104, 4285, -3211, -3286 }, { 1107, 7411, -1972, -1671 }, { 2196, 7262, -2310, -1926 }, { -244, 6439, -1745, -839 }, { 3293, 3832, -2890, -3000 }, { 419, 6443, -379, -407 }, { 3077, 4930, -1156, -2869 }, { 2131, 5874, -2330, 224 }, { 690, 6538, -2212, -2841 }, { 1602, 4421, -2515, 1542 }, { 3318, 9373, -3032, -3477 }, { 5646, 7462, -5153, -1463 }, { 4139, 7137, -1539, -3321 }, { 3481, 9077, -1645, -3653 }, { -7747, 375, -106, -543 }, { -8587, -1379, -586, -461 }, { -10146, -892, 2094, 694 }, { -8103, 382, 504, -325 }, { -8548, -92, 94, -656 }, { -7460, 38, 152, 388 }, { -8266, -271, -459, -883 }, { -7935, -664, -1026, -802 }, { -8341, -109, 853, 161 }, { -8802, -1355, 1099, 630 }, { -8957, -6, 1108, -669 }, { -7260, -1520, -43, -407 }, { -7555, -174, 668, -2562 }, { -9014, -126, 227, -1191 }, { -8184, 769, 290, -1375 }, { -9476, 55, 962, -1528 }, { -8679, 541, 755, -1030 }, { -9842, -1626, 838, -1588 }, { -8513, -702, 788, -1998 }, { -10101, -1558, -366, -1841 }, { -8135, 78, 1479, -1813 }, { -9128, -454, 313, -1786 }, { -7554, -1084, 831, -2442 }, { -7576, -701, 2068, -1665 }, { -7791, -1481, 1587, -1808 }, { -6701, -596, -97, 802 }, { -7418, -15, 684, -963 }, { -7127, -477, -139, -426 }, { -8097, -110, -36, -264 }, { -7620, -1922, -590, -101 }, { -7647, -1201, 279, 660 }, { -7856, -1974, 758, -2271 }, { -8496, -167, 2232, -1143 }, { -8506, -1359, 624, -740 }, { -7274, -1052, 1062, -139 }, { -7800, -217, 91, -1794 }, { -7030, -1694, -955, 615 }, { -9020, -1864, 101, -2182 }, { -9400, -740, 598, -667 }, { -8448, -1184, 2024, -1272 }, { -8812, -570, -897, -2384 }, { -10559, -1286, 538, -1536 }, { -8728, -888, -1089, -1397 }, { -7080, -1185, 636, -1252 }, { -9880, 233, 2344, -782 }, { -7952, -1326, -378, -1947 }, { -7207, -378, 1408, -2237 }, { -8467, -1545, 902, -1987 }, { -9163, -1474, 924, -1739 }, { -8159, -992, -77, -2744 }, { -8343, 148, -423, -1573 }, { -9105, -649, -254, -1214 }, { -8939, 456, 281, -1905 }, { -8837, 179, -394, -2634 }, { -9145, 757, 1547, -1319 }, { -9775, -723, 441, -1680 }, { -8910, -686, 1529, -1525 }, { -9492, -1134, 2064, -938 }, { -6111, -943, 677, -31 }, { -7411, -613, -814, 46 }, { -9479, -922, -430, -2061 }, { -11298, -1268, 1318, -1117 }, { -8190, 832, 671, -2214 }, { -10453, -550, 1672, -886 }, { 1044, 9353, -1651, -5423 }, { 1034, 8149, -455, -6166 }, { 761, 8293, -3214, -4838 }, { 938, 8077, 164, -5130 }, { 1295, 8673, 2582, -5490 }, { -314, 7973, -2395, -5231 }, { -507, 9012, -2497, -5775 }, { 2396, 8314, -1022, -4673 }, { -1516, 8501, 1950, -4969 }, { -308, 7401, 1549, -4866 }, { -112, 8340, 3003, -4920 }, { -50, 9315, 1371, -5666 }, { -659, 9449, 2496, -5547 }, { 2573, 9148, -2270, -4783 }, { 830, 7104, -438, -3907 }, { 522, 10672, -677, -6483 }, { -1190, 10108, -510, -6518 }, { -427, 8271, -579, -6315 }, { 1602, 8113, -1927, -4418 }, { -2266, 8180, 448, -5190 }, { -1633, 8816, -226, -5771 }, { 759, 9481, -105, -5813 }, { 2254, 6679, -466, -5662 }, { -88, 6946, 895, -5958 }, { -1705, 10009, 1394, -5574 }, { 748, 7943, 540, -6692 }, { 1411, 7009, 232, -6145 }, { 697, 7290, -1221, -5342 }, { -1764, 10580, 1944, -3981 }, { -1334, 9124, 1195, -3903 }, { -905, 10067, 635, -5039 }, { 664, 10680, 49, -4625 }, { 1374, 9536, -777, -3591 }, { 252, 9698, -597, -2931 }, { 824, 9164, -1014, -2144 }, { 2438, 10569, -2289, -4424 }, { 2101, 7102, 507, -3614 }, { 294, 8051, -432, -1518 }, { -665, 10337, 547, -2852 }, { 1168, 11989, -492, -5427 }, { 1344, 6416, 302, -5061 }, { -1727, 12264, 1507, -4543 }, { 674, 10889, -902, -3605 }, { -582, 9504, 300, -3618 }, { 641, 7654, 689, -2109 }, { 2065, 9243, 508, -4367 }, { 1055, 8373, 688, -3144 }, { -641, 8185, 986, -3307 }, { 1120, 7426, 1785, -3757 }, { 1660, 8070, -593, -3104 }, { 2002, 9467, -1722, -3475 }, { 2361, 8368, 100, -3709 }, { -772, 7845, -613, -4988 }, { 1485, 7430, 1896, -6127 }, { -432, 7823, -947, -2882 }, { 313, 11122, -760, -4871 }, { 412, 8412, -283, -4231 }, { 1585, 10402, -1884, -3267 }, { 321, 6952, 773, -3016 }, { -105, 9014, 121, -2249 }, { 1585, 10313, -977, -4812 }, { 1619, 11869, 1306, -6876 }, { -1168, 8886, -81, -2500 }, { -395, 10886, 733, -6490 }, { -4949, 4274, 3992, -1054 }, { -4241, 5299, 4262, -1584 }, { -2710, 3862, 4552, -1673 }, { -4608, 2472, 3672, -1715 }, { -2843, 2816, 4003, -2326 }, { -5229, 2964, 5636, 90 }, { -4924, 3442, 5015, -1096 }, { -1281, 3313, 5537, -2066 }, { -3808, 1939, 4351, -919 }, { -1915, 2585, 4939, -1614 }, { -3470, 1843, 5562, -682 }, { -3800, 870, 5827, 144 }, { -4985, 1452, 4728, -709 }, { -3745, 2750, 7220, 259 }, { -1875, 1900, 6514, -826 }, { -4329, 1574, 7192, 1304 }, { -5408, 1444, 6208, 631 }, { -3327, 5312, 5707, -1541 }, { -6966, 3334, 4034, 1028 }, { -7484, 4245, 4218, -212 }, { -6567, 5839, 4539, -512 }, { -5715, 5935, 3747, -1186 }, { -6410, 4881, 3356, -1610 }, { -5146, 2590, 2850, 2172 }, { -5196, 4095, 2569, -373 }, { -5043, 6025, 4318, 692 }, { -5525, 4884, 3513, 370 }, { -6804, 7533, 5812, -488 }, { -5657, 2480, 4061, 1234 }, { -3155, 1472, 6071, 1188 }, { -3427, 5217, 3442, 858 }, { -4698, 3013, 5517, 2586 }, { -4449, 2226, 5418, 3580 }, { -6395, 3547, 5487, 2028 }, { -3500, 5019, 4787, 1 }, { -4038, 2578, 3073, 3151 }, { -2750, 1955, 4469, 3856 }, { -5696, 1659, 6118, 2469 }, { -4350, 1241, 6840, 3126 }, { -5565, 5058, 5196, 1314 }, { -1642, 4190, 3948, 607 }, { -1233, 4108, 4850, -640 }, { -997, 3428, 3239, 1378 }, { -6488, 2741, 6926, 2792 }, { -4188, 3763, 4235, 2018 }, { -3210, 3224, 5646, 1427 }, { -5526, 6909, 5070, -627 }, { -2815, 3994, 3425, 1903 }, { -2163, 2734, 5423, 145 }, { -4149, 4247, 2355, 734 }, { -410, 2521, 4138, -16 }, { -2411, 2385, 4927, 2105 }, { -6077, 3591, 3114, 594 }, { -4186, 4834, 5926, -1004 }, { -7315, 3369, 5966, 448 }, { -7042, 5721, 5771, 238 }, { -4466, 3907, 3535, -1751 }, { -2116, 3970, 6163, -1392 }, { -7239, 2143, 8407, 3630 }, { -5431, 4486, 6486, -42 }, { -1874, 1617, 6333, 519 }, { -6478, 2629, 4634, -505 }, { -7784, 2342, 7216, 1365 }, { -1154, 1432, 4831, 1544 }, { -4964, -5801, 1797, 506 }, { -4436, -6905, 1059, -1237 }, { -5400, -6886, 884, -290 }, { -6259, -7103, 523, -227 }, { -4819, -6450, 1412, -450 }, { -4056, -6213, 1725, -943 }, { -5642, -6091, 1357, 605 }, { -4196, -5678, 2187, -173 }, { -4726, -5126, 2470, 321 }, { -6642, -5091, 1507, -1005 }, { -5304, -5250, 1944, 1579 }, { -7179, -5520, 1468, -425 }, { -6033, -4895, 1876, -955 }, { -6595, -5143, 2207, 1291 }, { -4224, -4943, 1846, 1792 }, { -7128, -6950, 539, 724 }, { -4369, -4901, 2590, 1103 }, { -7413, -5696, 1712, 1440 }, { -5885, -6821, 418, 871 }, { -6828, -5599, 710, -1563 }, { -6123, -5817, 1358, 1631 }, { -5291, -5622, 578, 2138 }, { -7171, -6004, 347, 2208 }, { -6083, -5251, 2132, 425 }, { -4329, -5721, 407, -2993 }, { -5326, -5056, 1119, -1837 }, { -5485, -5856, 185, -2389 }, { -6529, -5178, 403, -697 }, { -6719, -4412, 2726, 871 }, { -5126, -5629, 1835, -771 }, { -5622, -4361, 2973, 858 }, { -5282, -5895, 45, -335 }, { -4357, -5656, 1696, -1558 }, { -7139, -6659, 627, -409 }, { -4415, -6328, 35, 1306 }, { -7639, -6110, 1134, 197 }, { -3626, -5592, 2019, 901 }, { -3547, -5064, 1176, 1738 }, { -5075, -3899, 2087, 266 }, { -4086, -6311, 1479, 360 }, { -6210, -5220, -199, -1477 }, { -3910, -5063, 1356, -15 }, { -7616, -4977, 461, 2401 }, { -6118, -6131, 1258, -563 }, { -6127, -4968, 1286, -27 }, { -4121, -5852, 1113, 1476 }, { -5157, -4881, 1162, -662 }, { -4637, -5031, 1179, 709 }, { -5509, -5452, -397, 1224 }, { -4597, -6861, 646, 467 }, { -6247, -4043, 468, 278 }, { -5336, -6465, 874, -1472 }, { -6998, -6346, 78, -1798 }, { -4915, -4530, 2756, -203 }, { -6048, -4373, 1468, 1052 }, { -4273, -7100, 942, -323 }, { -6552, -4287, 2351, 69 }, { -6954, -4613, 722, 1521 }, { -4201, -5361, 763, -1562 }, { -6881, -5596, -748, 669 }, { -6695, -3547, -34, 1299 }, { -3981, -5728, 84, 111 }, { -4663, -4809, 2173, -1031 }, { -6599, -6077, 1303, 256 }, { -7596, -4265, -5791, -4140 }, { -6610, -2758, -5288, -3936 }, { -5880, -3865, -6563, -3088 }, { -7228, -5510, -7677, -3912 }, { -8854, -6553, -8318, -5361 }, { -9362, -5249, -6413, -4319 }, { -4418, -3110, -6368, -4358 }, { -5544, -4203, -6863, -5013 }, { -3056, -4316, -5567, -3181 }, { -3078, -5999, -5051, -2657 }, { -5884, -6292, -5756, -4013 }, { -4825, -4549, -5535, -4053 }, { -4443, -6126, -5316, -1368 }, { -3972, -6341, -6098, -2686 }, { -5751, -2781, -5398, -6230 }, { -4466, -6135, -5570, -3679 }, { -4291, -5992, -3564, -5189 }, { -7189, -4429, -7279, -6082 }, { -5076, -4433, -2748, -5366 }, { -6225, -2825, -6833, -5663 }, { -2989, -4792, -3960, -4492 }, { -7836, -7773, -7722, -5741 }, { -6559, -5703, -5844, -5589 }, { -7612, -5438, -4136, -3774 }, { -4218, -4176, -6591, -2333 }, { -4837, -5063, -6581, 322 }, { -6590, -5990, -2980, -3847 }, { -5558, -2971, -5489, -1932 }, { -7001, -5323, -4975, -1697 }, { -4694, -2688, -6904, -3044 }, { -8511, -5379, -5767, -2549 }, { -7548, -5412, -6522, -2572 }, { -6597, -4973, -6423, -1274 }, { -6415, -4022, -5168, -1072 }, { -5528, -5530, -7218, -2345 }, { -4845, -4805, -5943, -1227 }, { -6049, -7150, -6744, -2161 }, { -9061, -7299, -8542, -4375 }, { -5010, -5546, -5416, -82 }, { -4135, -4205, -5109, -3373 }, { -3311, -5869, -4007, -5061 }, { -5993, -6472, -3962, -4718 }, { -2966, -5832, -2821, -6305 }, { -4851, -5152, -2067, -3930 }, { -3620, -4441, -3362, -5836 }, { -4469, -5221, -4534, -5592 }, { -4022, -6335, -4321, -6107 }, { -4899, -4503, -3084, -3725 }, { -4490, -8276, -4620, -6236 }, { -6591, -4342, -7365, -4063 }, { -6498, -5057, -5553, 485 }, { -6060, -2714, -7093, -4144 }, { -6199, -7774, -7094, -4057 }, { -7536, -6424, -6415, -4265 }, { -7439, -2454, -6348, -4827 }, { -5333, -7565, -4417, -4639 }, { -4353, -7103, -4197, -2689 }, { -5229, -6549, -5129, -6804 }, { -6129, -7701, -5236, -4836 }, { -6797, -3983, -3884, -4406 }, { -6624, -4467, -4745, -5052 }, { -3324, -7596, -2720, -6553 }, { -5473, -6284, -1704, -4511 }, { -4131, -7263, -3180, -5196 }, { -7116, -5565, -3469, 685 }, { -6002, -6021, -3858, 576 }, { -3144, -8203, -1291, -434 }, { -6096, -7027, -4004, 1353 }, { -3943, -7709, -2344, -36 }, { -4510, -6767, -2642, 631 }, { -3657, -11541, -2570, -3984 }, { -5959, -8854, -1333, -867 }, { -6699, -8866, -1606, -344 }, { -3836, -7961, -2334, -2028 }, { -3430, -8045, -3037, -672 }, { -3868, -9184, -3635, -1819 }, { -4258, -9060, -2621, -1008 }, { -3595, -8693, -2022, -752 }, { -4573, -8048, -3166, -2622 }, { -4852, -7903, -1405, 256 }, { -4591, -7057, -1560, 965 }, { -6963, -7655, -980, 808 }, { -5179, -6641, -3356, 1196 }, { -7102, -6941, -2798, 2123 }, { -6867, -5834, -3320, -770 }, { -5977, -7369, -2500, -778 }, { -6160, -6400, -934, -2543 }, { -6741, -7608, -355, -1289 }, { -6856, -6466, -1433, -1643 }, { -4786, -6292, -4970, 376 }, { -5407, -8866, -2255, -400 }, { -3814, -6506, -1387, -3620 }, { -4998, -6137, -1200, -4092 }, { -5123, -9557, -2849, -1306 }, { -4259, -6444, -4395, -338 }, { -5221, -6810, -883, 1225 }, { -6137, -6215, -2165, 554 }, { -3895, -6557, -3176, -1829 }, { -3886, -8188, -87, -954 }, { -7243, -6707, -2216, -316 }, { -5592, -7606, 85, -432 }, { -3957, -7945, -504, -144 }, { -4617, -7624, 218, -312 }, { -4797, -8737, -844, -1051 }, { -4478, -8516, -1401, -454 }, { -4557, -7058, -302, -2332 }, { -6623, -7736, -271, -50 }, { -3157, -7532, -1111, -2207 }, { -3590, -7300, -1271, 517 }, { -4442, -7306, -507, 590 }, { -6458, -7524, -2807, 666 }, { -4991, -8466, -3363, -785 }, { -7474, -7541, -1056, -1839 }, { -7501, -8316, -938, -180 }, { -5329, -7739, -579, -2341 }, { -4549, -7063, -176, -3539 }, { -5191, -8612, -1504, -4250 }, { -3083, -7058, -2251, 32 }, { -4003, -7043, -1093, -791 }, { -5523, -8093, -678, -114 }, { -3022, -10265, -2070, -3109 }, { -3905, -6274, -182, -3652 }, { -3269, -9217, -551, -2650 }, { -3138, -9314, -1726, -1704 }, { -4420, -10339, -1744, -3459 }, { -4163, -8609, -2298, -4113 }, { -5566, -6505, -1241, -463 }, { -3130, -9746, -2352, -4884 }, { -7825, -3439, 1451, -1468 }, { -8451, -3318, 2360, -435 }, { -8462, -4130, 1438, -1024 }, { -9425, -4564, 1328, -689 }, { -11014, -3202, 2278, 2080 }, { -8269, -2761, -146, -440 }, { -7497, -2618, -166, 413 }, { -8250, -3060, 522, -2133 }, { -8365, -5366, 1347, -451 }, { -8589, -3979, 2943, 714 }, { -8111, -2572, 1272, -1748 }, { -7830, -5193, 605, -1484 }, { -8119, -4736, 2141, 256 }, { -7724, -4769, 1463, -812 }, { -7363, -3911, 2540, 4 }, { -7974, -3397, 2363, 1366 }, { -7359, -4204, 1752, -958 }, { -7622, -3505, 660, 916 }, { -9934, -3665, 3165, 828 }, { -8721, -4162, 62, 1718 }, { -9433, -4768, 2722, 1234 }, { -7960, -4496, 138, 1528 }, { -8198, -3454, -443, 631 }, { -7756, -2246, 655, 1137 }, { -8841, -3145, 1113, 829 }, { -7817, -3298, 1251, 230 }, { -9413, -2733, 323, -1862 }, { -9408, -4168, 1270, 1549 }, { -9037, -3892, -942, 283 }, { -8255, -3849, 1301, 1762 }, { -9057, -3987, -41, -682 }, { -9441, -4187, 2019, -111 }, { -9740, -3178, 1602, -871 }, { -8344, -2474, 1461, 1506 }, { -9752, -2925, 1996, 1243 }, { -9199, -3796, 180, 537 }, { -9060, -2405, 1140, -1562 }, { -9348, -2376, 309, -162 }, { -10786, -3182, -5, -1500 }, { -8142, -4540, -434, -826 }, { -7528, -2341, 1104, -73 }, { -9360, -2658, 3062, 56 }, { -8267, -2335, 2000, -1193 }, { -12169, -3154, 1287, -640 }, { -11398, -2120, 946, -1163 }, { -8940, -4559, 328, -1696 }, { -11025, -4213, 2813, 840 }, { -9224, -3581, 2224, 2039 }, { -8943, -3337, 1248, -1298 }, { -7900, -4042, 485, -2080 }, { -9221, -1947, 2191, -880 }, { -10762, -1800, 2516, -324 }, { -10095, -2238, 981, -1335 }, { -11908, -2808, 3255, 645 }, { -10640, -4105, 1283, -595 }, { -7663, -2863, 2467, -797 }, { -10712, -3854, 3710, 1538 }, { -10823, -2893, 1408, -801 }, { -9874, -3832, 256, -1638 }, { -10394, -3391, 2315, -94 }, { -11525, -4079, 4153, 2122 }, { -9546, -2088, 1541, 481 }, { -8731, -2433, 1042, 2160 }, { -7852, -3977, -1370, 1677 }, { 7072, -3420, 1398, -1741 }, { 6180, -1976, 1280, -3557 }, { 7692, -1793, 2844, -1700 }, { 8363, -1773, 3104, -2679 }, { 9213, -3266, 3756, -3542 }, { 9650, -2644, 1426, -1318 }, { 7712, -2796, 3686, -1975 }, { 7316, -3517, 2821, -622 }, { 7434, -2594, 2305, -2264 }, { 7237, -1797, 255, -3114 }, { 8663, -1983, 1338, -3056 }, { 6616, -952, 4059, -2652 }, { 8823, -1327, 1362, -1356 }, { 9938, -1722, 1287, -2362 }, { 7207, -1057, 1913, -1315 }, { 7508, -1585, 870, -1982 }, { 8217, -3680, 1417, -3170 }, { 8329, -2541, 1684, -585 }, { 8062, -2335, 252, -2800 }, { 8204, -4108, 3097, -2569 }, { 7701, -3367, 576, -3008 }, { 7350, -786, 2414, -2129 }, { 6948, -2568, 1607, -225 }, { 7684, -2387, 1308, -3449 }, { 8306, -3458, 2394, -1454 }, { 8438, -2781, 1043, -1362 }, { 9175, -2076, 2144, -1987 }, { 8347, -2709, 3489, -4301 }, { 5696, -2377, 2870, 851 }, { 8825, -1243, 2219, -2603 }, { 8801, -1614, 584, -2513 }, { 8413, -384, 1421, -2244 }, { 9228, -3050, 3279, -2164 }, { 6342, -2698, 3547, -107 }, { 10053, -2476, 2837, -3168 }, { 7439, -604, 3177, -3991 }, { 7749, -1064, 4329, -4855 }, { 8655, -2177, 2252, -3519 }, { 8490, -228, 1958, -3233 }, { 10513, -2968, 1911, -2340 }, { 8146, -862, 1884, -1723 }, { 7788, -666, 3004, -2891 }, { 7785, -1620, 4133, -3417 }, { 10262, -3731, 3455, -2971 }, { 8570, -905, 4519, -4649 }, { 9129, -2562, 463, -2465 }, { 9451, -3587, 1904, -3056 }, { 6549, -2236, 3010, -4523 }, { 7175, -2684, 2967, -3458 }, { 9872, -3278, 1054, -2472 }, { 9153, -931, 1217, -2565 }, { 8789, -3469, 753, -2568 }, { 6683, -3791, 1797, -3968 }, { 6801, -1977, 2311, -452 }, { 6336, -1572, 2612, -3264 }, { 7996, -1008, 730, -2964 }, { 7521, -1059, 1573, -3694 }, { 8148, -3973, 2600, -3572 }, { 7765, -1532, 2528, -3856 }, { 7404, -3918, 4472, -143 }, { 8894, -1398, 3299, -3685 }, { 5768, -2041, 1487, -637 }, { 5131, -2865, 2463, -811 }, { 6439, -1568, 3500, -1550 }, { -8878, -6798, -5319, -1452 }, { -6332, -9713, -3112, -990 }, { -8444, -6316, -3694, -687 }, { -6123, -10840, -3637, -4358 }, { -4784, -9580, -4577, -2581 }, { -6108, -10515, -4859, -2524 }, { -7605, -7518, -2327, -2797 }, { -9662, -8775, -2467, -2010 }, { -6494, -7523, -4715, -118 }, { -8290, -8982, -1672, -317 }, { -8798, -11051, -3888, -1426 }, { -6273, -6623, -6791, -142 }, { -8313, -7668, -2141, -1275 }, { -6453, -8412, -3589, -4102 }, { -6747, -7750, -5690, -2498 }, { -7814, -6693, -3174, -2446 }, { -10383, -10130, -3931, -2364 }, { -10606, -8467, -5539, -2772 }, { -9475, -6671, -3305, -2271 }, { -8982, -9457, -5635, -4005 }, { -10111, -7965, -6515, -4180 }, { -7301, -6479, -5364, 720 }, { -9543, -8999, -7921, -912 }, { -9534, -8562, -3469, -384 }, { -7601, -10344, -3205, -1127 }, { -8088, -8620, -4954, -2888 }, { -8202, -8406, -7038, -3775 }, { -7312, -8324, -3334, -1775 }, { -8566, -9262, -8071, -4174 }, { -7068, -11300, -5573, -2907 }, { -8295, -8952, -4366, -1544 }, { -11104, -10210, -2285, -384 }, { -5213, -7520, -5008, -1339 }, { -5889, -7940, -5987, -1385 }, { -10816, -8201, -4153, -1485 }, { -10277, -8919, -6315, -1652 }, { -5888, -10320, -3821, -1733 }, { -10497, -7181, -6083, -3032 }, { -7721, -9724, -6591, -5336 }, { -5688, -7894, -3486, -2552 }, { -10014, -10500, -3247, -820 }, { -6301, -8765, -4506, -2923 }, { -8261, -7847, -6213, -1552 }, { -10212, -7481, -8113, -3954 }, { -6938, -10874, -6074, -4703 }, { -7183, -10968, -4446, -1773 }, { -7120, -9193, -1966, -2509 }, { -6234, -9263, -2313, -4284 }, { -8503, -9857, -2429, -608 }, { -9372, -7844, -8391, -2120 }, { -7951, -7157, -6535, -11 }, { -7256, -9473, -2172, -660 }, { -10063, -9612, -2515, -15 }, { -6684, -9134, -6109, -4206 }, { -8204, -11932, -5220, -2306 }, { -9710, -6706, -4115, -3275 }, { -6855, -7078, -2409, -4447 }, { -7344, -7673, -4479, -4116 }, { -8851, -6842, -4927, -2948 }, { -8927, -10452, -5633, -2194 }, { -8627, -9002, -7176, -1575 }, { -8209, -9722, -7021, -3324 }, { -3770, -10249, -3623, -4816 }, { -8183, -7465, -4090, 646 }, { -8163, -7149, 200, 498 }, { -8289, -6266, 686, -206 }, { -10030, -6241, -1032, -1864 }, { -8793, -8327, -773, -169 }, { -9149, -6215, 969, -15 }, { -8303, -5859, -7, 2006 }, { -9682, -7283, 255, 1322 }, { -9293, -7227, 71, -231 }, { -8525, -6215, 287, -837 }, { -10477, -5379, 1159, 1449 }, { -10726, -7856, -130, 102 }, { -8694, -7461, -1210, 690 }, { -9367, -5324, 1103, 3170 }, { -10686, -8055, -831, 1633 }, { -9201, -6873, -2704, 2258 }, { -8421, -5358, -1405, 226 }, { -9066, -5830, -307, -1571 }, { -11150, -7381, -2746, -900 }, { -9978, -5925, -2006, -437 }, { -9464, -4741, -273, 1061 }, { -10543, -6684, -1113, 1660 }, { -10073, -5576, 1083, -269 }, { -8826, -5763, 1600, 1486 }, { -10445, -9071, -1253, -64 }, { -12085, -5799, 2, 769 }, { -12939, -6663, 1650, 1437 }, { -10932, -6434, -1252, -649 }, { -11650, -7826, -2053, 710 }, { -12122, -6733, -1889, -731 }, { -9093, -6095, -2463, -842 }, { -10977, -4364, 469, 420 }, { -11488, -6908, -521, 893 }, { -9669, -5478, -842, 337 }, { -10606, -5203, -632, -1361 }, { -10198, -6284, 1662, 1277 }, { -10135, -5292, 2435, 3493 }, { -11027, -6561, 655, 56 }, { -10977, -5030, 1127, -358 }, { -12766, -3986, 1348, -335 }, { -14244, -7731, 264, 317 }, { -15124, -10309, -508, 1447 }, { -12821, -8638, -608, 137 }, { -13076, -8693, -2852, -431 }, { -11156, -5546, -2252, -1600 }, { -8692, -7366, -819, -1223 }, { -12507, -9816, -1714, -121 }, { -10712, -6666, 544, 3349 }, { -12462, -5890, -2491, -2318 }, { -12468, -7226, 437, 232 }, { -11300, -5226, 2068, 687 }, { -11994, -8320, -626, 2728 }, { -12222, -5476, 1142, 18 }, { -10277, -8122, -2418, 2003 }, { -13418, -6115, -3563, -2802 }, { -14759, -9834, -1243, 21 }, { -13699, -5665, 1525, 507 }, { -16269, -9476, -701, 163 }, { -12677, -5437, -247, -1019 }, { -11827, -4295, -181, -1243 }, { -12847, -4496, 2984, 1123 }, { -13860, -7915, -1166, -547 }, { -12276, -8145, -2290, -1527 }, { -11417, -4830, 2983, 1854 }, { -11793, -6002, 1163, 1940 }, { 11443, -4920, -3235, 3151 }, { 11300, -6616, -1506, 1175 }, { 9198, -4628, -2060, 2390 }, { 10532, -4027, -643, 912 }, { 9902, -3573, -1606, 1327 }, { 9653, -3536, -2240, 1869 }, { 9948, -5171, -423, 2662 }, { 12316, -4004, -1989, 281 }, { 12125, -4800, -1265, -163 }, { 10650, -2617, -2337, 1462 }, { 9909, -4968, -2376, 916 }, { 12944, -4647, -1958, 460 }, { 12988, -5283, -1141, 41 }, { 12321, -2915, -3621, 1025 }, { 11449, -2894, -2728, 351 }, { 12087, -3041, -2002, -32 }, { 11558, -4031, -1343, -399 }, { 12983, -3740, -3516, 1245 }, { 12099, -2515, -2752, 225 }, { 12515, -3465, -2701, 550 }, { 14683, -5022, -5272, 2996 }, { 12260, -3383, -1215, -528 }, { 13810, -5422, -2443, 1166 }, { 13421, -5378, -1886, 721 }, { 12961, -4259, -2594, 796 }, { 12266, -2104, -4768, 1591 }, { 13523, -4710, -3045, 1342 }, { 12437, -2099, -5610, 2117 }, { 11850, -2183, -3497, 661 }, { 12275, -3936, -597, -697 }, { 12459, -5253, -517, -544 }, { 12835, -4094, -1322, -168 }, { 14360, -5677, -3305, 1859 }, { 13905, -4552, -4309, 2117 }, { 11559, -3412, -1847, -81 }, { 13379, -3167, -5764, 2746 }, { 11910, -1634, -4342, 1052 }, { 12662, -4742, 71, -974 }, { 13057, -3254, -4424, 1705 }, { 15046, -5706, -4851, 3019 }, { 14162, -4142, -5514, 2843 }, { 12764, -1845, -6684, 2888 }, { 13714, -2374, -7838, 3857 }, { 13295, -1663, -8293, 4073 }, { 10032, -4152, -3403, 1421 }, { 10942, -5386, -2222, 950 }, { 10532, -6385, -1750, 1925 }, { 10273, -5972, -1534, 643 }, { 10605, -4782, -1695, 27 }, { 10988, -5153, -1123, -341 }, { 11629, -5884, -1060, 48 }, { 10441, -4045, -2431, 311 }, { 10788, -3595, -4171, 1807 }, { 12110, -5686, -2127, 976 }, { 11746, -4773, -2639, 891 }, { 11541, -5299, -3031, 1732 }, { 11416, -2559, -5359, 2198 }, { 11583, -5376, -704, 677 }, { 10416, -3214, -3516, 872 }, { 9651, -5435, -1618, 3255 }, { 9973, -5133, -996, 3923 }, { 11707, -4643, -430, -796 }, { 10994, -2709, -3587, 2302 }, { 10716, -5118, -645, 270 }, { 14100, -10314, 1095, 1531 }, { 12944, -8049, 1105, -741 }, { 13276, -7035, -511, 274 }, { 14008, -7254, -283, 139 }, { 11594, -6536, -91, 1671 }, { 11732, -8645, 746, 15 }, { 14613, -7085, -1578, 1183 }, { 13083, -6224, -750, -4 }, { 13988, -6256, -1592, 820 }, { 14678, -8683, 441, 126 }, { 15571, -8872, -521, 1139 }, { 15642, -9533, 341, 697 }, { 15960, -9586, -168, 1121 }, { 15464, -10239, 1433, -1 }, { 14934, -7887, -1046, 1080 }, { 15252, -7630, -1899, 1628 }, { 15485, -8384, -1234, 1484 }, { 15962, -8638, -1815, 1931 }, { 16501, -10664, 398, 1167 }, { 16146, -10145, 411, 918 }, { 14573, -7475, -697, 601 }, { 14302, -7996, 28, 257 }, { 14769, -6792, -2286, 1574 }, { 14144, -6137, -2169, 1257 }, { 14770, -6271, -3111, 1933 }, { 14110, -8312, 1083, -531 }, { 15235, -6991, -2993, 2174 }, { 13222, -5805, 547, -891 }, { 14796, -8762, 1254, -246 }, { 16040, -9181, -1005, 1551 }, { 16487, -10086, -373, 1420 }, { 15077, -9479, 966, 51 }, { 13026, -6468, 932, -1080 }, { 12703, -6152, -33, -573 }, { 15641, -6810, -4128, 2874 }, { 13282, -7673, 1583, -1283 }, { 12373, -7150, 1512, -917 }, { 12992, -7751, -678, 783 }, { 10907, -6858, -313, 2597 }, { 13026, -8963, 125, 2152 }, { 12770, -9946, 1957, -505 }, { 12482, -6849, -1268, 833 }, { 13790, -6181, -138, -279 }, { 12709, -8382, 2044, 227 }, { 12244, -6630, 203, -457 }, { 14209, -6816, -1032, 632 }, { 15134, -8267, -288, 640 }, { 13619, -6157, -1090, 356 }, { 14044, -7413, 725, -484 }, { 12958, -7753, 2585, -1980 }, { 13188, -8396, 2306, -1558 }, { 14379, -9980, 2132, -688 }, { 14275, -9857, 1162, 179 }, { 13690, -8648, 1621, -889 }, { 11770, -6829, -746, 278 }, { 12732, -8202, 286, 90 }, { 13630, -10146, 1867, -207 }, { 12072, -8740, 1299, -645 }, { 12852, -9492, 1226, 62 }, { 11792, -7382, -54, -116 }, { 13779, -9014, 487, 351 }, { 11951, -7729, 121, 834 }, { 11970, -9781, 2276, -4 }, { 12680, -7984, 2787, -787 }, { 13300, -14488, 6408, -1927 }, { 13635, -15355, 9153, -3073 }, { 12804, -13566, 5517, -1625 }, { 16624, -10854, 1690, 28 }, { 20387, -18532, 6162, -261 }, { 16515, -12642, 3392, -519 }, { 15800, -11095, 2151, -202 }, { 16824, -11790, 1651, 599 }, { 17604, -13213, 2563, 538 }, { 17892, -14177, 3562, 147 }, { 16987, -11399, 869, 1052 }, { 17003, -12456, 2442, 265 }, { 21657, -21806, 9198, -1250 }, { 16825, -13341, 3980, -686 }, { 17525, -12714, 1887, 805 }, { 16419, -11034, 1216, 617 }, { 20931, -19939, 7469, -684 }, { 18452, -15390, 4573, -191 }, { 14778, -10077, 2841, -1209 }, { 17402, -13319, 3042, 160 }, { 19365, -17922, 7087, -1061 }, { 16298, -11941, 2810, -351 }, { 19087, -16176, 4775, -84 }, { 17666, -12289, 938, 1224 }, { 18581, -15894, 5132, -430 }, { 19823, -16717, 4142, 545 }, { 19960, -19423, 8400, -1492 }, { 18973, -16817, 5906, -594 }, { 19079, -15431, 3528, 503 }, { 16667, -12485, 4467, -1302 }, { 19791, -17797, 6196, -529 }, { 20005, -17606, 5354, -20 }, { 20123, -18599, 6886, -728 }, { 19068, -14805, 2394, 1105 }, { 14443, -13723, 5631, -2029 }, { 14730, -14231, 5631, -1450 }, { 16089, -15959, 7271, -2029 }, { 13473, -11200, 3236, -924 }, { 14413, -10902, 2347, -267 }, { 17666, -18662, 11381, -3496 }, { 14749, -11042, 3305, -275 }, { 15304, -10486, 1869, -240 }, { 14809, -12126, 3369, -616 }, { 16896, -16561, 7307, -1845 }, { 15782, -14336, 5380, -1264 }, { 16395, -15520, 6415, -1588 }, { 13681, -11114, 2584, -320 }, { 14244, -12326, 4480, -1632 }, { 15247, -13119, 4265, -898 }, { 13987, -12091, 3469, -597 }, { 13941, -12770, 4240, -839 }, { 13771, -13627, 5252, -1384 }, { 15010, -16074, 7592, -2249 }, { 15852, -17226, 8619, -2655 }, { 18921, -16916, 6875, -1501 }, { 14909, -11678, 2768, -295 }, { 18988, -18353, 8424, -2070 }, { 15457, -15080, 6218, -1513 }, { 14916, -15512, 6949, -1883 }, { 18108, -14702, 4681, -701 }, { 17600, -15733, 5616, -775 }, { 14070, -13683, 6472, -2626 }, { 13832, -11914, 5201, -2232 }, { 18846, -19009, 9192, -1961 }, { -11981, -10994, -6324, -2264 }, { -10976, -9047, -6546, -3828 }, { -11288, -10532, -7014, -4191 }, { -10139, -10189, -7799, -2688 }, { -10555, -9988, -9181, -2040 }, { -11596, -11339, -10022, -2707 }, { -13400, -13395, -11306, -4206 }, { -9774, -12281, -7466, -4133 }, { -10842, -13125, -8777, -4956 }, { -11964, -15082, -9779, -5095 }, { -9382, -10188, -9053, -4927 }, { -11562, -11296, -3651, -985 }, { -9287, -10083, -7918, -4069 }, { -12821, -16556, -11410, -6195 }, { -12628, -8959, -4521, -1113 }, { -13845, -11581, -3649, -681 }, { -12685, -10269, -5483, -1275 }, { -14988, -12874, -5107, -1189 }, { -13761, -11367, -6202, -1804 }, { -13225, -11249, -7820, -3354 }, { -14809, -11992, -3202, -312 }, { -15620, -15519, -10210, -3433 }, { -12954, -10200, -3139, -611 }, { -11536, -9981, -5284, -923 }, { -13034, -12417, -4612, -1098 }, { -16911, -15505, -6123, -1352 }, { -17396, -17685, -8330, -2171 }, { -14120, -10764, -2265, -99 }, { -12598, -7367, -5406, -3530 }, { -14143, -12793, -10909, -5226 }, { -14692, -16871, -11626, -5554 }, { -12581, -11197, -9194, -3837 }, { -16752, -16726, -9746, -2808 }, { -10600, -10358, -6560, -1227 }, { -14573, -13312, -8957, -3393 }, { -10172, -8463, -8579, -3387 }, { -11418, -12421, -5522, -1842 }, { -11855, -14204, -6669, -2625 }, { -13308, -8191, -3941, -2194 }, { -10007, -12266, -5022, -1811 }, { -13532, -15771, -9497, -3175 }, { -11760, -11148, -10339, -5529 }, { -12149, -12763, -11198, -3697 }, { -12029, -12119, -8555, -1792 }, { -16995, -19957, -11447, -3471 }, { -13144, -14504, -9988, -3191 }, { -9938, -11064, -6139, -3162 }, { -8873, -11550, -8294, -6550 }, { -9303, -13010, -6150, -2711 }, { -15463, -10469, -1766, -170 }, { -15985, -11693, -3007, -650 }, { -17142, -10671, -1434, 47 }, { -16063, -13858, -4817, -1058 }, { -19446, -19599, -9594, -2464 }, { -20076, -18744, -8313, -1889 }, { -15047, -16085, -7590, -2250 }, { -13481, -16195, -8552, -2998 }, { -13829, -14869, -6704, -1932 }, { -16357, -18484, -9802, -2959 }, { -10551, -8393, -9303, -5070 }, { -11345, -9156, -5641, -3107 }, { -13217, -13449, -9270, -4541 }, { -11988, -13732, -9995, -6374 }, { -11007, -9519, -5168, -4107 }, { 9930, -7858, 8061, -4375 }, { 8274, -7867, 5992, -2096 }, { 9692, -9675, 7621, -3670 }, { 9589, -8110, 6509, -3010 }, { 12617, -11976, 10122, -5360 }, { 11867, -8895, 7948, -5323 }, { 10388, -10482, 9234, -4324 }, { 8188, -8220, 7810, -2737 }, { 10407, -8787, 4806, -1930 }, { 10348, -8845, 9233, -6614 }, { 9422, -7091, 4820, -2878 }, { 9758, -9796, 5584, -2256 }, { 10188, -7994, 5347, -3343 }, { 11133, -7455, 4015, -2306 }, { 10676, -10744, 6093, -2629 }, { 11522, -12184, 7848, -3375 }, { 8805, -9883, 5317, -3071 }, { 9498, -9654, 6555, -3592 }, { 10488, -8008, 4066, -1252 }, { 11261, -8930, 6068, -2738 }, { 12180, -10397, 5027, -1531 }, { 9138, -8531, 3601, -1959 }, { 8107, -8380, 4970, -2061 }, { 9737, -13248, 6438, -2617 }, { 11178, -10423, 2622, -522 }, { 9572, -12372, 5199, -2019 }, { 12057, -12144, 4147, -1099 }, { 9047, -9925, 2516, -665 }, { 10790, -8030, 5882, -4386 }, { 7199, -8426, 6337, -2841 }, { 7778, -8285, 3529, -3442 }, { 7559, -10569, 3484, -1332 }, { 9404, -8115, 7484, -5541 }, { 7792, -11976, 5546, -2573 }, { 9313, -10264, 7661, -5195 }, { 6701, -10725, 4370, -1784 }, { 4918, -11361, 4507, -4527 }, { 5147, -12305, 3978, -5556 }, { 6525, -9899, 4481, -3129 }, { 7538, -12855, 6060, -4826 }, { 8659, -12111, 7159, -4430 }, { 8440, -11304, 4547, -1747 }, { 9216, -10918, 3507, -1195 }, { 6165, -9254, 4771, -4677 }, { 9163, -11019, 5637, -4935 }, { 13441, -11509, 6676, -2434 }, { 7912, -9398, 6663, -4048 }, { 11723, -13745, 8131, -4148 }, { 6065, -10257, 5005, -6327 }, { 11618, -12417, 5336, -1894 }, { 8891, -13924, 8407, -6131 }, { 9622, -12563, 7908, -5109 }, { 11479, -10315, 8349, -3991 }, { 11676, -14103, 6611, -2330 }, { 11951, -8953, 3829, -1550 }, { 10486, -8044, 10493, -5920 }, { 11801, -10769, 9763, -5305 }, { 6109, -8676, 5827, -1346 }, { 7030, -9611, 5624, -5761 }, { 12808, -12886, 8683, -4148 }, { 13213, -10464, 6381, -3189 }, { 11796, -13681, 10703, -6075 }, { 9639, -7949, 9625, -3944 }, { 8538, -6997, 5309, 453 } }; static const int8_t high_freq_samples[1024][32] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { -4, -2, 2, 1, -16, -10, 1, 3, 1, 0, 6, 1, -3, 7, 1, -22, 2, -4, -3, 11, 14, 6, -1, 1, -13, 29, -28, 10, 10, -8, 0, -9 }, { -8, 8, -7, 10, -3, -12, -5, -8, 1, -2, 9, -2, -5, -18, 1, 9, -8, -8, 3, 41, 7, -9, -9, 22, -42, -29, 14, -18, -14, -32, 1, -15 }, { -16, 8, 15, 16, -16, 5, 2, 7, -6, -16, -7, 1, 1, -3, -2, 0, 8, 20, -26, -11, 2, -17, 0, -3, -34, -37, 10, 44, -2, 22, 2, -4 }, { 7, 14, 5, 6, 15, -1, 3, -3, -9, -23, -5, -14, 8, -1, -14, -6, -5, -8, 54, 31, -6, 18, 2, -19, -2, -11, -30, -6, -19, 2, -2, -14 }, { 1, 2, -2, -1, -3, -3, 1, -5, 1, -3, -4, -8, 5, -4, 0, 1, 3, 7, -5, -4, -3, -12, 3, -2, -3, 12, -53, -51, 6, -1, 6, 8 }, { 0, -1, 5, 1, -6, -8, 7, 5, -18, -4, -1, 1, 0, -3, -3, -14, -1, -6, 0, -14, -1, -1, 5, -3, -11, 1, -20, 10, 2, 19, -2, -2 }, { 2, 4, 3, 0, 5, 0, 3, 1, -2, 0, -6, -3, -4, -5, -3, -3, -7, 0, -34, 4, -43, 17, 0, -53, -13, -7, 24, 14, 5, -18, 9, -20 }, { 1, 0, -3, 2, 3, -5, -2, 7, -21, 5, -25, 23, 11, -28, 2, 1, -11, 9, 13, -6, -12, 5, 7, 2, 4, -11, -6, -1, 8, 0, 1, -2 }, { 2, -4, -6, -4, 0, -5, -29, 13, -6, -22, -3, -43, 12, -41, 5, 24, 18, -9, -36, -6, 4, -7, -4, 13, 4, -15, -1, -5, 1, 2, -5, 4 }, { 0, -1, 13, -6, -5, 1, 0, -3, 1, -5, 19, -22, 31, -27, 4, -15, -6, 15, 9, -13, 1, -9, 10, -17, 4, -1, -1, 4, 2, 0, -3, -5 }, { -7, 3, -8, 13, 19, -12, 8, -19, -3, -2, -24, 31, 14, 0, 7, -13, -18, 0, 3, 6, 13, -2, 1, -12, -21, 9, -2, 30, 21, -14, 2, -14 }, { -3, -7, 8, -1, -2, -9, 6, 1, -7, 7, 13, 3, -1, -10, 30, 4, -10, 12, 5, 6, -13, -7, -4, -2, -2, 7, -3, -6, 3, 4, 1, 2 }, { -8, 9, 2, -3, -5, 2, 0, 9, 3, 7, -4, -16, -13, 3, 23, -27, 18, 46, -38, 6, 4, 43, -1, 0, 8, -7, -4, -1, 11, -7, 6, -3 }, { 1, 1, 18, -8, -6, 0, 3, 4, 22, -3, -4, -2, -4, -11, 40, -7, -3, -13, -14, -7, -10, 14, 7, 5, -14, 11, -5, 7, 21, -2, 9, -3 }, { 0, 0, -2, 4, -2, 0, 2, 0, -1, 2, -1, 0, 0, 2, 2, 2, -1, 1, -3, -1, -15, -2, -63, -27, -21, -47, -14, 1, -14, 10, 0, 2 }, { 1, 0, -4, 0, -3, -9, 4, 2, 6, -6, 0, -5, 11, -7, -15, 6, -7, -6, 3, 7, -15, -5, 23, -13, -6, 12, -8, 9, 2, -3, 3, 4 }, { 6, 0, 3, 0, -2, -4, 2, 1, 1, -1, 1, -2, -1, -4, -22, -15, -46, -66, 10, 20, 2, -17, 12, -6, 1, -2, -2, 0, 1, -5, 1, 2 }, { -1, 0, 0, 1, 0, -4, 0, 1, -10, -3, -8, 5, 7, -11, 2, -11, 29, -25, 11, 10, 0, -1, 5, -7, -2, -5, -2, 4, 4, -3, 5, -2 }, { 1, -1, -1, -3, -2, 1, -8, -3, 2, -2, 4, -5, -1, -7, -2, 1, -14, -7, 3, -30, -15, -14, 3, -4, -1, 3, -13, -1, -3, 1, 2, 3 }, { -1, -2, -3, 2, 2, -3, 3, 1, -3, 2, 0, -4, 6, 5, -5, 10, -57, 3, 22, -50, 1, -2, -5, -6, -1, 5, 1, 2, 2, 1, -2, 2 }, { 2, 0, -1, -7, 2, 1, 3, 2, 0, 4, 3, -2, 3, -3, 4, -4, 24, -35, -3, 38, -6, -5, 15, 20, 3, 16, -7, -5, 0, -4, -5, 0 }, { 0, 1, 0, 0, 0, -1, -1, 1, 1, -1, 1, -2, 0, 0, 0, 0, 0, -1, -2, -1, -5, -2, -43, -3, 46, -52, -10, 7, -8, 11, -2, -1 }, { 0, 0, -1, 0, -1, 2, -41, 33, -44, -48, -15, -26, -9, 6, 3, 3, -3, 2, 2, 2, 2, -1, -1, -2, 1, 3, 0, 0, 5, 2, 3, 1 }, { -4, 1, 6, 1, -6, -1, -2, 1, -14, -4, 0, -5, -2, 2, -2, 0, -6, 1, 0, 8, -21, 32, -3, -36, -6, -2, -1, -7, 3, 0, 1, -6 }, { -3, -2, 3, 0, 2, 2, 8, -4, -4, 6, 2, 1, 3, -6, 4, 3, 13, 0, -12, -1, 25, -20, -2, -23, -15, 7, -3, -11, -3, 6, -1, 0 }, { 0, 0, -3, -1, 0, 0, -2, -1, -2, -2, 1, -1, 0, 0, 10, 3, -2, 3, 3, -7, -6, -5, 0, -4, -60, -16, -6, 38, 5, 6, -5, 0 }, { 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 0, 0, 1, 0, 0, -1, 0, -8, 2, -9, 10, 40, 31, -56, -21, 4, 20, -4, 7 }, { -2, -2, 0, 4, -3, -1, 7, 3, 1, 3, -8, 0, 3, 1, 2, 5, 1, -2, 14, 5, 4, 5, 5, 5, -5, 9, -66, 0, -20, -2, -8, 4 }, { -2, -1, 4, -1, -8, -2, -4, -1, -3, -3, 2, -7, -3, 5, 7, -2, 45, 31, -17, -16, -2, -2, -1, -22, 1, -1, -3, 3, 5, -3, 5, -1 }, { -4, 0, 7, 5, 8, 7, 2, 9, -9, -9, -7, -11, -3, -8, 17, -4, 34, 32, 18, 22, 1, 2, 1, -7, -5, 6, -1, 6, 4, 10, -2, -7 }, { 6, 0, 14, 9, 6, -1, -2, -3, 4, -6, -8, 4, 7, -1, 28, 38, 15, -1, 16, -11, 5, 8, 4, -10, 3, -10, -17, 5, 3, 3, 3, 1 }, { 1, 1, 2, -1, 2, 1, 0, 0, -1, 0, 0, -2, 1, -3, 0, 1, 2, -2, -4, -2, 0, -1, 1, -3, 1, 1, 1, -1, 8, 8, 66, 33 }, { -5, 2, -3, -7, 2, -8, -4, 10, 17, -18, -7, 4, -4, -7, -6, -6, -5, 5, -12, 2, 0, 6, 8, -2, 1, 4, -11, 2, 1, 8, 31, 19 }, { 6, 9, 16, -6, -6, -1, -2, -3, -11, -2, 7, 7, 17, 3, 4, 10, 2, 5, -13, 8, 7, 1, 4, 5, 7, 6, 7, -8, 9, -8, 33, 6 }, { 3, -1, 1, 0, -7, -5, 0, 14, -7, 1, -7, 1, 2, -4, 7, 10, -16, 12, 1, -6, 3, 8, -1, 10, -13, -6, -12, -23, 12, -3, 30, 14 }, { -2, -15, 0, 8, 3, -19, 5, -3, 2, 3, 13, 7, 14, -3, -10, 0, 8, 5, -6, -16, -8, -8, 14, 2, -1, 1, -9, -11, 11, -5, 27, 9 }, { -8, 6, -4, 4, -4, -1, 5, 4, 1, -7, -5, -4, -15, 1, 9, 0, 8, 4, 1, -17, 11, -2, -19, -1, -6, -8, 3, -12, 3, -17, 33, -10 }, { -3, -1, 2, 7, 7, -2, 9, 8, -18, -1, -13, -10, -3, -3, 11, 8, -2, -12, -8, 1, 4, 9, 14, 10, -3, 0, 2, 1, -2, 3, 31, 10 }, { -3, -10, 8, -1, -5, -11, 7, -5, 3, 6, 1, 4, -16, 10, 5, -4, -2, -10, -1, 13, 6, -5, -7, 12, 7, -3, -17, 1, 12, -4, 29, 8 }, { 1, 2, 5, 2, -6, -7, 0, -1, 6, -1, 10, 6, -4, 5, 2, 2, -2, -8, -6, -11, 14, -13, 27, 3, -2, -12, 5, -16, 2, -26, 20, 15 }, { -1, -3, -5, -3, -3, 6, -1, 3, -5, 1, 7, 2, 1, 0, -1, -1, 0, -1, 9, 7, -6, -3, 4, -5, -4, 8, -8, -25, -8, -4, 34, 23 }, { -1, -2, 1, 1, -1, -2, -1, 1, -1, 0, 0, 0, 0, -2, -1, 1, 0, 2, 1, -1, 4, 0, 0, 1, -1, 0, 5, 3, 12, -9, 68, -16 }, { 10, 0, -8, 14, -6, 1, -12, 0, 0, -3, -5, -11, -6, 12, 9, -10, -3, 5, 0, 7, 11, 2, 4, -3, -8, -3, 7, 4, 3, -3, 34, 4 }, { -12, 13, -5, 7, -11, -2, -1, 1, -4, -14, -21, 3, -3, -3, -4, -7, -9, -4, 3, -17, -2, -13, 10, -2, 12, -4, 0, -9, 1, -5, 31, 10 }, { -10, 6, 5, 6, 4, -7, 10, 0, -28, -3, 0, -11, -1, -5, 16, -10, -16, 7, 20, 2, -4, 2, -5, 0, 15, 6, 5, -10, 7, -9, 20, 4 }, { 1, -7, -2, -7, 4, -3, -2, -7, -1, -14, 6, -16, 4, -5, -4, -6, -5, 0, -2, 2, -6, 9, -5, 4, -18, 8, -10, 8, 15, 0, 32, 1 }, { -5, 7, -3, 7, 15, -4, 0, -16, 9, 5, -5, 5, 4, -3, -12, -9, -18, 10, 2, 2, -3, 7, 3, -1, 6, -9, -10, 3, 15, -4, 35, -7 }, { -1, -10, 2, 2, -4, -2, 10, 2, -1, 2, -2, 1, -1, -14, -11, 3, -8, 5, -8, -2, 6, -1, -7, 1, 7, 5, 7, 8, 30, -4, 30, 14 }, { 2, -2, 1, 2, 3, -8, 3, 0, -2, 0, -9, 2, 1, 4, -6, -1, -2, 5, 0, 1, -2, 12, 6, -3, 9, -3, 4, -12, 21, -39, 24, -2 }, { 3, 5, 1, -2, -2, -2, -3, 6, -8, -2, -11, -8, -1, 4, 2, 2, -4, -10, 12, -5, -11, 1, -15, -34, -11, -7, -11, -1, 7, -14, 38, -1 }, { -4, 4, 8, 9, 8, 1, -5, -9, 4, -2, 15, -4, 11, -15, 20, -1, -1, -3, 4, -9, -2, -2, -2, 8, 6, 12, -5, 0, 11, -12, 27, -4 }, { 0, 8, -4, 3, -11, 6, -11, 2, 3, 0, 5, -8, -7, -6, -9, -21, 4, -11, -1, -16, -7, 16, -3, 7, -7, 4, -5, 0, 11, -7, 31, 3 }, { 1, 3, 4, 11, -11, -2, -3, -6, 6, 5, 0, 3, -9, -6, 4, -4, 0, 4, -8, 13, -6, -13, -1, -5, -1, 4, 0, 0, 9, -22, 24, 18 }, { -7, 3, 10, -13, -6, 6, -6, 6, 22, 1, 0, -14, 2, 3, 7, -1, 8, 20, -1, 5, -4, 13, 9, -9, -9, 6, 0, -4, 0, -8, 31, -4 }, { -3, -4, 0, 1, 7, 3, -7, 0, 5, -2, 1, 3, 3, 1, -5, -2, 5, 2, -11, 4, 0, -1, 12, 0, -3, -13, 15, 8, -6, -27, 34, 0 }, { -3, -3, 10, -4, 2, -1, -3, 0, -1, -1, -4, 2, 6, -2, 12, 1, 3, -6, -7, -6, -5, 4, -19, -6, -8, -34, -4, -8, 10, -7, 23, 10 }, { -7, 0, -1, -6, 8, 4, -4, 2, -5, -8, -7, -9, -8, 5, 9, 7, -6, 1, -12, -12, -1, -16, 5, 0, 16, 3, -7, -8, 27, -4, 23, 15 }, { -8, 4, 8, 5, 6, 11, -3, 5, 3, -1, -11, 6, -5, 0, 2, -6, -3, -6, 4, -1, 5, -5, -12, -6, 7, -5, 9, 3, 6, -7, 29, 1 }, { 1, 3, -2, -2, -6, -2, 1, 6, -6, -3, 1, 2, 3, 4, 1, 5, -1, 0, 4, 2, 11, 6, 2, -3, 13, -9, -19, 18, -15, -10, 36, 21 }, { -3, -3, 2, -1, -7, 6, -4, 1, -3, -1, -2, 2, 3, -7, -3, 0, -2, 0, -2, 6, -19, 3, -8, 2, -6, 7, -1, 0, 29, -6, 28, -10 }, { -5, 1, -3, -7, -12, -4, 1, 1, -1, 13, -10, -1, -9, -5, -13, 6, 13, 3, -4, 2, 3, 11, 2, 6, -25, -16, -6, 0, 14, -1, 27, 16 }, { -6, -1, -7, -5, -2, -5, -5, -1, 9, 1, 0, 3, -8, -12, -6, 5, -6, 5, 3, -9, 1, 4, -7, -10, -9, -7, -17, -5, -15, -23, 25, 3 }, { -8, -2, 9, -3, -4, 3, -1, 8, -7, -7, -5, -4, -2, 9, 4, -1, -7, -4, -5, -16, 3, -6, 18, -13, -9, 16, -15, 8, 15, -10, 24, 5 }, { 1, -38, 2, 34, 9, 10, 11, 2, 2, -6, 3, 2, -2, 5, 4, -7, -1, 1, 4, 0, 3, 1, -8, -1, -6, 5, 4, 2, -4, 5, 2, -1 }, { 1, -22, 15, 18, -2, 10, -16, -9, -8, -11, 8, 4, 0, 7, -14, -5, -1, -7, 12, 17, 9, 5, -7, -4, -12, -6, 7, 0, 7, 2, -2, 1 }, { -11, -29, 7, 10, 19, -1, -8, -9, 7, 1, 9, 6, 8, -7, -14, 8, -3, -11, -13, 0, -7, -23, -2, -8, 12, 9, 2, 14, 19, 1, -1, 5 }, { -24, -27, -11, 36, 2, 6, -3, 4, -6, 8, 0, 12, -1, -4, -6, 3, 4, -1, 2, -3, -2, 3, 2, -1, -2, -4, 0, -1, -2, 7, 2, 3 }, { -9, -24, 11, 13, -10, -12, 12, -2, 7, 4, 8, 13, -3, -3, 2, 9, -3, -4, 4, 13, 5, 13, -6, -3, 1, 15, 7, -3, 0, 19, -2, -9 }, { -8, -15, 7, 14, -4, -5, 2, -18, -19, -2, 2, 17, 16, 6, -10, 10, -9, 14, -1, -5, -1, -6, -7, 2, 9, 11, 13, 6, -5, -12, 3, 2 }, { -10, -37, 13, 1, 3, -14, 0, -20, 4, -3, 8, 2, -2, -3, -9, -5, -3, -17, -1, 13, -11, 2, -6, 4, 4, 0, 3, 1, -9, -4, -5, -4 }, { -2, -22, -5, 46, -8, 5, 9, -11, 8, 7, 7, -1, -1, -2, -7, 2, -3, 3, -1, -2, 7, 0, 2, -1, 1, -2, -2, -3, 6, 0, -4, -6 }, { -16, -27, 15, 16, -4, 14, -7, -26, 2, -2, 6, 5, -3, 11, 0, 2, 3, 9, -7, -1, 2, -4, -4, -1, 6, 10, 1, 1, -3, -2, 3, 0 }, { -3, -22, 10, 26, 1, 2, -3, 3, 17, -3, -7, 9, 1, -21, -4, 5, 3, 0, -7, -6, 3, 3, -8, -7, -9, 3, 7, 1, -8, 12, 6, -7 }, { -9, -25, 3, 18, 9, -6, -11, 0, -5, -12, 9, -8, -7, -6, -6, 22, 2, -6, -3, 15, 3, 2, -2, 9, 14, -10, -7, 15, 13, 6, -2, 11 }, { 5, -20, -5, 28, 11, 10, -4, -4, 0, -7, 3, 5, 2, -5, -8, 2, 6, 10, 9, -9, -18, 3, 14, 1, 3, -3, -1, -6, 7, 7, 2, -1 }, { -8, -30, 7, 12, 10, 8, 7, -13, -16, 0, 1, -1, -6, -11, -15, 4, 1, -2, 10, -15, 1, 11, -2, 8, 9, -7, -7, 9, -5, 2, 7, -18 }, { -10, -32, 10, 11, 3, -1, 3, -5, 5, 2, 14, -6, 3, 1, 5, -15, -11, 6, 20, 4, 0, -12, -7, 3, 1, -1, 10, 6, -1, -9, -4, -1 }, { 1, -25, -14, 12, -11, 9, 9, -16, -24, -17, 22, -9, 11, -30, -3, -4, 6, -7, 9, 2, -1, -5, -6, 2, -1, -1, 10, 1, -3, 3, 4, 8 }, { -14, -26, -6, 9, 8, 17, -11, -24, -7, -4, -8, -2, 10, 2, 2, -1, 2, 13, 12, -7, 4, -6, -10, 6, 6, -13, -11, -7, -16, 0, -2, 5 }, { -4, -30, -13, 12, 16, -6, 12, -16, -13, 5, 15, -2, -2, -10, -7, 7, 11, -1, -4, -2, -4, 7, 4, -8, 1, 3, 0, 11, 3, -2, -5, 4 }, { -4, -21, 20, 22, 2, 20, -8, 1, -12, -5, -9, 4, -10, -17, -3, -8, -3, 3, -12, 1, -3, 0, 7, 4, 7, 7, -3, 7, 5, 3, 1, -5 }, { -12, -20, 2, 29, 11, -6, 9, -7, -6, -4, 0, 6, 17, -13, -2, -10, -17, -1, -18, 2, 0, 14, -6, 1, 0, 3, 2, -10, 1, -5, -2, 5 }, { 16, -37, -1, 26, -2, -14, 1, -5, -14, 2, 2, 3, 6, 1, 1, 4, 0, -1, 0, -2, -2, 4, 9, -6, 0, -2, 10, -7, -2, 4, 1, 0 }, { -9, -24, -12, 5, 5, 3, -17, -14, 4, 3, 2, -4, 10, -22, -8, -3, 6, 1, 12, -8, 4, 1, 9, -1, 18, -3, 6, 5, 3, -5, 9, -5 }, { -14, -33, -2, 20, -13, -10, 2, -7, -1, 11, -9, -8, 18, -3, 1, 8, 0, -2, 10, 7, -2, -13, 9, -3, -4, 5, -2, -2, -1, -5, 1, -7 }, { -10, -23, 8, 14, 1, 7, 1, -3, -7, 4, 1, 1, 8, -7, 15, -14, 13, 14, 2, 5, -13, -5, -8, -1, 6, 3, 6, 9, 6, 15, 14, 5 }, { -13, -25, -10, 13, -17, -24, -7, -13, -6, -10, -8, 2, 0, -13, -10, -4, -8, 4, -9, 9, -4, 4, -3, -3, 3, 3, -5, -9, 1, -2, 11, 2 }, { -12, -23, 1, 18, -11, -2, 5, 9, -5, 5, 14, -9, -3, -2, -6, 2, -2, 11, -13, 1, -3, 11, -9, -4, -2, -6, 8, 10, 1, 4, 2, 1 }, { -5, -18, 16, 22, 2, 0, 8, -6, -9, -7, 10, -16, 23, 10, -11, -1, 7, 2, 7, 2, 1, -5, 6, 1, 0, -4, 9, 2, -3, 1, 0, -4 }, { -3, -26, 14, 11, 2, -9, 17, -2, -1, -5, -16, -9, -5, 10, -13, 1, 6, 12, 10, 11, 0, 0, -3, -14, 6, -2, 0, 4, -5, -1, -7, -1 }, { -10, -33, 1, 8, 11, -5, 1, -6, 7, 4, 5, 6, 1, -2, -10, -5, -6, 12, -11, 5, -10, 4, 12, -1, -1, -3, 4, -1, 9, 0, 16, -17 }, { -14, -37, 7, 7, -2, 5, -8, -11, 2, -13, 4, -19, 1, 8, 8, 4, -9, 2, -4, 3, 12, 2, 4, -4, -8, 8, 1, 4, 8, -1, 6, -2 }, { -6, -30, 18, 17, 1, -22, -3, 4, -7, -10, 7, 0, -8, 8, -1, 4, 2, 8, 6, -2, 2, 7, 4, 4, 3, -6, 2, 1, -3, 1, -1, -5 }, { -17, -18, -3, 22, -8, 1, 9, -2, -17, 20, -5, -5, -12, -5, 4, -5, -9, 8, -2, 16, -3, 0, 19, -8, 8, 1, 2, -4, 0, 11, 0, -3 }, { -9, -23, 3, 10, 4, 4, -3, -2, -2, -2, 1, -22, 11, 0, -2, 5, -2, 14, -9, -11, -4, 7, 5, 32, 1, -3, -7, 0, 21, -9, 7, -6 }, { 0, 0, 0, 2, -1, 1, 0, 1, 3, 0, 0, 1, 0, 1, 0, 1, -3, 0, -1, -2, 0, -1, -1, -3, -1, 1, -4, 1, -1, -5, -69, -19 }, { -3, -5, -8, -12, 4, -3, -19, -11, -5, 0, -14, 7, 18, -6, 7, 22, 8, 14, 15, 10, 3, -1, -3, 5, -1, 7, -7, 1, -6, 3, -26, -11 }, { -1, -6, 4, -4, -5, -16, 0, -6, -3, 11, 1, 0, 9, 5, 16, 3, -4, -33, -4, 4, -7, 0, 1, 6, -11, -2, -13, -2, -18, 20, -25, -16 }, { 4, 0, -1, 0, -5, 1, 0, 2, 0, 11, -10, 4, -10, 7, 16, 2, 16, 15, 2, -1, 2, 9, 2, 8, -3, -5, -2, 0, -3, 0, -33, -2 }, { -3, -15, 10, 10, -9, -1, 7, 3, 5, -5, -8, -8, -3, 15, -9, 4, 12, 13, -13, -14, 10, -6, 9, 22, -27, 23, -1, 5, -24, 2, -30, 5 }, { 0, -2, 7, -5, -5, 3, 5, 3, -3, -5, 2, 1, -4, 3, -3, -1, 1, -2, 10, 22, -3, -4, -2, -2, -7, 3, 8, 1, 14, 4, -37, 9 }, { -3, -4, -1, 1, -4, 0, 6, 2, 6, -7, -10, -10, -1, -4, 11, -3, 7, -6, 4, -12, -1, 5, 1, -7, 10, -6, 17, -4, 8, 3, -40, 13 }, { 2, 12, 4, -7, 14, -3, 16, -2, 18, 2, 13, 5, 5, 1, 11, -1, 0, 9, 2, -6, -1, 2, -6, 2, -5, 3, 5, 1, -1, 1, -32, -7 }, { -16, 11, 7, -4, 2, -5, -9, 9, 11, 11, 15, -13, -11, 11, 9, 4, 3, -8, -10, 12, 12, 0, 0, -16, -9, 13, 2, 9, 4, -13, -33, 3 }, { 6, 4, 5, 4, 3, -1, 5, 6, 4, 2, -11, -1, -15, -11, -1, 1, 11, -3, -2, 24, -4, -6, -25, -10, -15, -8, 0, 0, -5, 4, -30, 2 }, { 10, -3, -6, 1, -9, -5, 6, 9, -10, -3, 8, -1, 4, -1, 11, -11, 3, 9, 11, -3, 6, -17, 5, -8, -33, 9, -13, 19, -2, 9, -25, 2 }, { 0, 0, -1, -3, 0, -2, 1, 0, 0, 2, 1, 0, -2, 0, -1, 2, 0, -1, 4, -1, 2, -3, 4, -2, 3, 3, 1, 0, -15, 12, -63, 27 }, { -2, 14, 9, -1, 3, 0, 1, 1, -19, 15, 3, 4, 0, -10, 1, -5, 3, 0, -5, -10, 2, -16, -4, 8, -12, -6, 7, -5, -10, -1, -33, -4 }, { 0, 3, 1, 3, 1, 2, 4, 4, 9, -6, -8, -5, 1, -12, 3, 8, -10, 6, -1, 1, 13, -5, -5, 2, -4, 13, -18, -10, -7, -9, -33, 10 }, { -6, -3, -12, 5, -1, 11, -6, 0, -2, 1, 2, -7, 3, 1, 3, -2, 1, 8, -10, 7, -1, -3, 3, 0, 13, 1, 6, 7, -16, -7, -39, 8 }, { -6, -1, 11, 6, -3, 8, 3, -5, 3, 0, -5, -2, -6, -3, -4, 2, -3, 13, -11, 1, 7, 5, 19, -5, -3, -15, -1, 7, -1, 6, -33, 8 }, { -7, 3, -4, -3, -4, 1, 6, -5, -5, 6, -8, -1, -7, 4, -1, -6, -2, 1, 7, 0, 1, 1, -5, 2, -2, 0, -13, -2, -31, -14, -39, -12 }, { -10, 9, 0, -3, 1, -1, -1, 0, 1, -5, -1, -4, -2, 5, 2, -7, 18, -8, -2, -19, -7, -7, -12, -14, -11, -1, -9, -13, -7, -12, -31, -9 }, { -3, -16, 10, 9, 1, -10, -12, 2, -2, 2, 7, -3, -3, 1, -4, -5, -9, 5, 7, 3, -1, 4, -11, -8, 4, 13, -10, 13, 10, -4, -36, 1 }, { -7, -12, 4, -20, -7, -7, 2, 11, -1, -2, 3, -12, 1, 0, -6, -7, 6, 4, 13, 3, -3, 4, 3, -6, -12, 5, -5, -22, -13, -8, -37, -6 }, { -7, 5, 3, 5, 7, 9, -14, -3, 10, 17, -1, 1, -12, 5, -6, 0, -4, -9, 0, -11, -14, 3, 13, 6, -25, -8, -12, 4, -10, 18, -30, -1 }, { -10, 6, -10, 6, 6, 1, -10, 0, -7, 5, -2, 17, -18, -4, 0, -3, -16, -6, -3, -8, 5, 1, -4, 6, -7, 16, 6, 10, -1, 0, -32, -11 }, { -1, 9, 9, -5, 4, 9, 6, 9, -4, -2, 7, 11, 4, 2, -5, -4, -6, 0, 2, -3, -1, 5, 10, 0, 12, -10, -18, -3, -1, 14, -33, 2 }, { 4, -8, -18, -4, -5, -11, 4, -10, -4, 9, 13, -12, 1, -6, 1, 2, 4, -9, 8, 3, -6, 21, 13, -1, -2, 1, -2, 6, -7, 0, -30, 1 }, { 6, -1, 2, -3, -1, -4, 6, -4, 0, 4, 2, 2, -9, 2, 6, 3, -2, 4, -1, 9, -6, 0, 7, -8, 5, 19, -2, 9, -5, 2, -33, -8 }, { 2, 1, 12, -5, -8, 8, 3, -2, -4, 1, -2, 5, -4, -9, -8, -8, 7, -11, -4, 6, -10, 7, -1, -1, -2, -1, 16, 32, -7, 20, -33, -6 }, { -18, 2, 6, 13, 9, 9, -1, 3, -17, 24, -2, -6, 28, 8, -2, 6, 3, -10, -34, -16, -13, -4, -15, -11, -12, -3, -10, 4, -8, 4, -31, -4 }, { -11, 0, 18, 2, -16, -9, -13, -2, -2, -12, -3, -22, 30, 0, 8, 3, 9, -4, -16, 1, 0, -11, 15, -2, -4, 6, -5, 6, 1, 2, -25, -12 }, { 14, -1, 5, 7, 3, -15, -8, 1, 5, -2, 12, 13, 11, -25, 3, 1, 0, -2, -4, -16, -23, 0, -5, -17, 7, 5, -9, 6, -5, 2, -32, -7 }, { 3, -1, 6, 14, 2, -12, -9, -9, 4, 7, 4, 6, 5, -8, 4, 2, 4, 5, -2, 8, 8, -6, 0, 10, -20, -1, 3, -1, 8, 23, -33, -5 }, { -3, 11, -6, 3, -4, 5, 7, 3, 4, 5, -2, 3, -1, 30, 6, 1, 8, -6, 0, 0, -9, 6, -9, 4, 2, 9, -6, 1, -12, 0, -34, 18 }, { -17, 13, 0, 1, 9, -4, -11, 0, 7, 0, -10, -4, -1, 6, -6, 4, 1, 6, -9, 3, -5, -6, -11, 2, -4, 14, 23, -3, 2, 5, -30, 12 }, { -14, 5, -27, 2, 0, 7, 1, 4, 30, 8, 7, 5, 1, -1, 0, 5, 8, -10, 48, -11, 12, 33, 6, 8, -15, 20, -2, -5, 32, 5, -19, 10 }, { -16, -4, -12, -7, -2, 0, 8, -6, -20, -18, 16, -3, 0, 31, -2, 11, 2, -9, 49, -19, -12, -23, 10, 26, 16, -2, 4, -21, -14, 13, -11, -9 }, { -5, -9, -1, 3, -5, -21, 2, 10, 0, 0, 10, -21, -7, 7, -26, -9, 22, 32, 58, 11, -3, 11, -5, -8, -13, 6, -5, -9, 1, 10, 14, -8 }, { 7, 7, 10, 3, -2, -1, -11, -11, -6, -43, -3, 14, -19, -18, 19, 18, -32, 10, 45, -6, 6, 21, -20, -12, 2, 4, 6, 6, -4, 3, 3, 1 }, { 21, 22, -3, -2, -11, -6, -1, -2, 8, 8, 32, -21, 7, 28, -4, -6, -3, -2, 50, 2, 2, 27, -5, -8, 12, 7, -5, -1, -4, -17, 27, 6 }, { 13, 7, 2, -6, -12, 2, -10, -5, -17, 11, 4, 17, -12, -2, 5, -17, 37, -16, 48, -14, -18, 29, 8, 24, 11, -5, -9, 11, -1, 1, -13, -3 }, { 1, 1, -1, 2, 0, 0, 0, -1, 1, -1, 7, 2, -3, 3, 0, 6, 2, 10, 54, -25, 7, 54, -5, -6, -1, -15, 9, 13, -24, -15, -12, 3 }, { 21, 5, 8, 3, -3, -4, -2, -4, 3, -11, -5, -8, 9, 16, 8, -9, -10, -3, 46, -46, 2, 1, -10, 10, 17, 11, -20, -36, 10, 14, 0, -5 }, { 7, -13, -6, -9, -24, 45, 2, 8, 8, 0, 17, 20, 12, -24, 1, -7, -15, -3, 46, -13, -2, 20, 1, -13, -11, -13, 2, 15, 1, 10, -1, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, -1, -16, -9, 31, -69, -34, 26, 7, 17, -1, -6, -1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, -5, -20, 18, -82, 22, 3, -7, 9, 4, 6, 2, -4, -1, 0, -2, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, -1, 15, -5, 62, -36, 4, 52, -7, 5, 0, 6, 1, 2, 1, 1, -1, 0 }, { 3, -19, 19, -20, 13, -4, -11, 8, 8, -16, 10, 1, -14, 30, 1, -33, 10, -11, 45, -30, 3, -4, -3, -13, 7, 12, 3, -22, 3, -2, -4, -2 }, { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 11, 8, 70, 48, -10, 21, 4, 9, -9, -9, -4, -6, 0, -1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, -1, 80, 2, -15, -36, -10, -5, -2, 8, -2, 2, 0, 0, 0, 0 }, { 10, 8, -8, -8, -24, 12, -1, 0, 20, 9, -1, -2, 2, -2, 12, -10, -2, -13, 35, -43, 44, 15, -10, -25, 4, 10, -3, -5, -5, 7, -1, 3 }, { 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, -1, -18, 9, 49, -72, 7, -8, 7, -5, 2, 3, 2, -2, 1, -2, -3, 1 }, { -1, 4, -3, 10, 19, 4, 3, 20, 6, -24, 6, 9, 8, 15, 18, 18, -36, 19, 57, -11, 4, -3, 8, 7, 2, -3, -2, -9, -15, -2, 12, -4 }, { 20, 3, 11, -9, -4, 22, 42, -25, 1, 5, -10, -19, 0, 9, -16, 5, 2, 10, 44, -29, 17, -3, -9, -2, -1, 8, 14, -7, -1, 16, -5, 1 }, { -7, 16, -11, 12, 6, 33, -15, 14, -23, 2, -26, 8, 2, 10, 0, -5, 8, -8, 38, -38, -4, 5, 5, 5, 1, 22, -15, 7, 6, 0, 4, 28 }, { -1, -12, 2, 10, -2, 0, 7, 17, 12, 22, -4, 10, 25, 29, 5, 18, 4, 1, 27, -39, 31, 17, 2, 2, 22, -23, 13, 16, 1, -7, -4, -5 }, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, 0, -14, 0, -7, -11, 49, -22, -4, 19, 17, -39, 4, -29, 10, 2, 36, -4, 23, -1 }, { -2, -2, -2, -2, 1, 15, -5, -7, -16, -8, -19, 16, -3, -20, 36, -9, -3, 20, 39, -20, 0, 2, 27, -16, 10, 10, -14, -22, -16, -3, 13, -8 }, { 5, -9, 6, -25, 7, 37, 13, -10, -5, 3, -5, 7, 18, -22, -7, 9, -5, -4, 50, -11, -4, -5, -5, 8, -4, -2, -4, -27, 14, 20, 7, -9 }, { 0, -14, -10, -27, -14, -17, -6, 26, 10, 2, 14, -12, -5, 0, 8, 9, 0, -28, 55, -7, -12, -7, 4, -10, 10, 7, -12, 11, 3, 5, 9, -8 }, { 2, 23, 4, -2, -1, -20, -2, 14, 10, -9, -9, -24, 10, 0, 11, -12, 12, 11, 49, -25, -2, 29, 7, -13, 21, -10, 11, -17, 3, 1, -8, 5 }, { 3, 0, -14, -6, 18, -2, 17, -9, -19, 9, -5, 9, 14, 6, 19, -3, 27, 1, 41, -21, 20, -15, 33, 0, 26, 14, 7, 10, 3, 20, -3, -12 }, { -1, 16, 15, -8, 3, -8, -8, 21, -5, -16, -29, 4, 1, -6, -4, -28, 2, 31, 37, -26, -2, 13, 24, 8, -9, -6, -29, 10, 7, 2, 7, 8 }, { -10, -10, 11, 13, -32, 2, 16, 9, 14, 23, -15, -13, 24, 13, 4, -27, 14, 12, 31, -18, 17, 23, -2, -7, -14, 9, -17, -6, -10, 20, 9, 6 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 5, 1, 89, 8, 10, -6, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, 4, -7, 64, -50, 7, 37, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, { -2, 5, 3, -4, -4, -3, 2, -3, 3, -3, 5, 4, 1, -6, -1, 1, 6, -2, 50, -35, -7, 43, 7, -7, -5, -26, 24, 21, 3, -15, 5, 6 }, { -8, 21, -19, 33, -8, 22, -11, 17, 3, 0, 0, -2, 1, -3, 6, -1, 10, -8, 4, -11, -4, -5, 0, 8, -4, 3, 1, -4, 4, 2, 8, 4 }, { -7, 5, -20, 9, -22, 3, -14, 1, 6, 13, 23, -2, -4, -7, 2, 0, 11, 4, 6, 3, -7, -11, -7, 4, 5, 5, -12, 8, 2, 4, 7, -3 }, { -7, 6, -4, 20, -20, 16, -2, 7, 6, 16, 11, 12, -7, -7, 5, 3, -9, -4, 1, 2, 5, 2, 1, -9, -2, -17, -4, 6, -10, 7, -7, -6 }, { -9, 18, -17, 12, -24, 1, -1, 4, 14, 9, 4, 3, 2, 8, -12, -14, 4, -8, -4, 7, 7, 6, -1, 13, -9, -4, -1, 1, 0, -4, 15, 8 }, { -25, 2, -11, 6, -5, 24, -28, -5, 8, 12, -2, 6, 8, -3, 8, -9, -1, -5, -1, -5, 6, -1, -1, -1, -4, 8, -12, -2, -13, 7, 2, 1 }, { -14, 14, -18, 20, -10, 12, -2, 9, 1, 0, 12, -2, 15, -10, 26, -17, 16, -11, 10, -10, 9, -2, 4, -8, 2, -3, 4, 4, 2, -3, -5, 1 }, { -18, 12, -18, 21, -6, 12, -6, 13, -25, 18, 1, 11, -9, -5, 0, 10, -5, 3, -3, 8, -9, 7, 4, 2, -9, 0, 5, 0, 2, -3, 9, -8 }, { -4, 16, 1, 18, -30, 9, 1, 6, -8, 13, 13, -12, -6, -1, 13, 7, 6, 2, -15, -3, 5, 5, 1, -6, 1, -5, 0, 2, -16, 0, 3, -4 }, { -21, 1, -2, 6, -43, 18, -1, 5, -1, 4, 6, -2, -1, -3, -1, -3, 0, 1, 2, -9, 0, -1, 0, -2, 0, -1, -1, -2, 6, 0, 1, -2 }, { -23, 10, 4, 7, -32, -11, -18, 2, -2, -7, -6, -3, -3, -12, 19, 3, -5, -6, 16, -6, 16, 2, 16, 16, 8, -2, 13, 8, -15, -11, 2, 10 }, { -8, 2, -13, 2, -29, 24, -20, 19, 1, 10, -4, 10, 1, 2, -9, 11, -1, -2, 9, -5, 19, -7, 16, -9, -2, -18, 11, 1, 1, 0, 7, -3 }, { -6, 3, 4, 13, -26, 10, -10, 28, -7, 28, 1, 7, 0, -14, 5, 7, 4, -4, 3, -2, 3, 3, -11, 7, 6, 4, 0, -1, 2, -1, -3, 2 }, { -6, 16, -31, 13, -10, 17, -6, 4, -14, 4, 4, -1, -10, 12, -5, 1, -14, 15, 0, -8, 1, -5, 3, 3, 9, -5, 7, -20, 7, 4, 11, -5 }, { -19, 3, -17, 14, -12, 16, -22, 18, 14, 8, -2, 4, 10, 12, -14, 4, -3, 2, 3, 7, -7, 7, -6, 2, -2, -4, -5, 0, -5, -2, 2, 1 }, { -9, -7, -11, 24, -36, -9, -11, 5, 7, -12, -13, 18, -2, 20, 1, -4, -1, -10, 15, -6, 14, 1, 0, 2, 1, 2, -9, -16, -11, 7, 13, 0 }, { -24, 24, -18, 18, -22, 14, -11, 13, -12, 11, -10, 11, -7, 11, -5, -4, -1, 1, 5, 2, 3, -1, 1, -5, 7, -4, 5, -6, 8, -7, 8, -6 }, { -6, 18, -22, 22, 5, 11, -1, 6, 19, 22, 8, 4, -8, 20, -2, 15, -6, -18, 0, -33, -9, -12, -1, 6, 5, 2, 5, 5, -5, -17, -3, -3 }, { 1, 11, -16, 9, -18, 11, -4, 18, 20, 26, -10, 8, 1, -11, 8, -4, 0, 7, 3, 5, 2, 2, 10, -2, -4, 4, -4, -2, 1, -4, -5, -1 }, { -10, 6, -1, 18, -17, 27, -3, 10, -2, 12, -7, -9, 1, 1, -1, 7, -12, -1, -7, -6, -1, 8, 3, -15, 8, 9, 3, -7, 4, -1, 1, -1 }, { -14, 6, -16, 22, 2, 5, 0, 5, -18, 11, 6, -3, 22, -20, -9, -3, 6, -6, -7, -15, 1, 15, -8, 11, 8, -3, -8, 1, -8, 2, 6, -2 }, { -21, 5, -19, 19, -7, 4, -7, 0, -8, 6, 12, 5, -3, -22, -13, -6, -1, -3, -2, -14, 6, -3, 1, -8, -7, -5, -6, 11, -3, -10, -5, 2 }, { -1, 9, -12, 15, -6, 6, -19, 14, -9, 11, 3, 12, -17, -3, 8, -4, -3, -4, 1, -5, 4, 5, -7, -15, -7, 15, -6, -5, 1, -5, -3, 1 }, { -12, 20, -15, 20, -14, 3, -14, 9, -6, 33, -13, 6, -2, 8, -6, 7, -5, -6, -3, -3, 0, 8, -3, -3, 1, -2, 2, 2, 6, -5, -5, -2 }, { -7, 12, -18, 12, -18, 10, -4, 8, 2, 4, 8, 9, 0, 3, -8, 3, 6, -12, -4, 1, 25, -5, -9, 6, -7, 0, -9, -7, 3, -5, -4, -4 }, { -18, 12, -10, 11, -22, 0, -15, 5, -2, 2, -3, 6, -4, -4, -3, -15, -2, -3, 21, 6, -12, -11, 19, 3, 3, -14, 7, 0, -11, -22, -10, 0 }, { -15, 2, -30, 15, -17, 13, -16, 8, -7, 10, -8, 2, 11, 3, 10, -7, 7, -22, 12, -10, 3, -12, 6, -10, 12, -10, 7, -8, 5, 2, 9, 1 }, { -9, 11, -14, 6, -10, 21, 5, 12, -5, 5, 7, 21, 6, 2, -2, -1, -1, 4, 2, -20, -18, -1, -14, 3, -1, 4, -7, 10, 1, 11, 4, -4 }, { -22, 8, -30, 13, -21, -4, 4, -1, 12, 9, -2, -3, 2, -6, 4, -13, -2, 8, 8, 1, -7, 3, -4, -5, -1, -7, -2, 8, 8, 7, 8, 0 }, { -6, -4, -35, 16, -13, 15, -11, 14, -7, 9, -1, 11, 7, 0, 13, 10, -1, 8, 1, 1, -2, 8, -1, 2, 2, 3, -10, -1, 7, -13, -3, -7 }, { -15, 7, -16, 14, -18, 17, -6, 14, 3, 4, 7, -3, 10, -22, 5, -15, 4, -4, -11, 15, -15, 11, -11, 20, 1, 0, 2, 1, 11, -3, 11, -7 }, { -12, 3, 5, 16, -37, -1, 15, 15, -15, 10, 3, -10, 1, 15, 7, -15, -13, 8, 9, -3, 2, 12, -8, 2, -5, 0, -3, 4, 5, -9, -4, 5 }, { -16, 26, -4, 14, -22, 26, 6, -3, -8, 4, 21, 6, 16, -4, -11, 7, -10, 3, 3, 7, -4, 2, -9, 8, -2, 2, 5, -2, -4, -2, 7, -1 }, { -7, -10, 4, 3, 2, -4, -12, -10, -4, -5, 16, 19, -16, 1, 2, -9, -10, 0, 9, 7, -8, 3, 12, 8, -6, -11, -13, -1, -3, -20, 6, -5 }, { -14, -17, 3, -5, 14, -12, -12, 8, -6, -25, 21, 21, 10, -8, -12, 4, 10, -4, 3, -9, 11, 9, 0, 4, 2, -15, 1, -14, 4, 1, 0, -4 }, { -4, -9, -3, -1, 6, 3, -6, 6, -10, -4, 14, 8, 2, -3, -12, -19, 0, 11, -20, 1, 6, -2, -27, -6, 10, -17, -14, -17, -9, 8, -8, 3 }, { -12, -13, 16, -4, -2, 12, -7, -11, 2, -13, 3, 7, -16, -18, -1, -12, -2, 1, -12, -9, -2, -6, 2, 9, -22, -3, -4, -14, -7, 7, -1, 2 }, { -7, -8, -8, 15, 15, 18, 15, 16, -4, -37, 11, 15, -12, -1, -3, 3, 6, 6, 0, -5, -3, -5, 9, 1, 1, -11, -1, -8, -6, 2, 3, 0 }, { -6, 7, -5, -12, 13, 10, -18, -4, -3, -21, 6, 16, -15, -7, -12, -9, 1, -12, -1, 10, -2, -1, -3, 4, -4, 1, -16, -1, 12, -9, 5, 9 }, { -14, -5, 9, 3, 4, 26, -28, 3, -6, -24, 4, 5, 3, 13, 5, -1, 3, -1, 3, 1, 1, -5, 3, 0, -7, -8, -7, -3, 3, -5, 4, 0 }, { -4, 2, -10, -6, 25, 26, -6, 10, -6, -8, 15, 11, -6, -3, 2, -7, 5, 14, 9, -1, 0, -12, 4, -4, -10, 1, -3, 3, -2, -2, -6, -1 }, { -10, 8, -15, -10, 19, 17, -8, 0, -3, -7, 7, 5, -13, -1, 7, -7, 1, 13, -12, -13, 17, -12, 1, 26, -18, -3, -5, -6, 4, 5, 8, 1 }, { 2, -5, 3, 0, 0, 0, 2, -3, -2, -5, 7, 13, -4, 9, 0, -5, 4, -1, -11, -8, -4, 0, -13, 2, -47, -23, -8, -11, -4, 4, -2, -3 }, { -18, -4, 4, 5, -1, 17, -12, -8, 1, -12, 7, 20, -12, 3, -2, -11, 16, 12, -6, 1, -13, -16, -6, -3, -3, -5, 4, -12, -5, -9, 10, 1 }, { -11, 0, 4, 7, 7, 8, 3, -1, 3, -19, 32, 8, -19, -8, 2, 4, -12, 15, -16, 3, 1, 9, -2, 1, -2, 8, 5, 6, -4, -1, 11, -8 }, { 3, -1, 4, -2, 14, 32, -9, -23, -10, -12, 22, 15, -1, -2, 10, 0, 4, 6, -8, 4, -15, -2, -1, -4, 0, -8, 4, 1, -8, 3, 4, 1 }, { -17, -12, 6, -8, 16, 13, -20, -8, -1, -16, 10, 21, -19, 11, -9, -5, 7, 18, -6, 7, -7, -18, 13, 2, -2, 8, -12, -9, 2, 4, -5, 16 }, { 4, 0, 17, -11, 12, 7, -12, 5, -1, -25, 30, -8, -7, -6, -4, -7, 9, 8, 7, 3, 3, -16, 8, 0, -2, -2, -18, -3, -4, -5, 1, 4 }, { -3, -6, 6, -16, 17, 6, -3, 2, -9, -17, 12, 11, 11, 2, -20, 8, 1, 1, 0, 2, -2, -6, -21, -13, -9, -15, -1, -8, -6, -8, 0, -2 }, { -11, -7, 6, -9, 3, 6, 8, 16, 4, -5, 23, 26, -10, -3, 4, 0, 2, 2, -4, 4, -2, -12, 12, 10, -11, 0, -10, -16, 3, 0, 0, -10 }, { -5, -16, 10, -6, 27, 13, -3, 4, -2, -13, 15, 5, 2, 5, 3, -4, 13, 12, -11, -7, 0, 1, 11, 12, 2, 13, -15, -8, 9, -2, 3, 8 }, { -5, -8, 4, 3, 9, 3, -11, 10, 14, -25, 14, 8, -2, 5, -12, -21, 2, 10, -7, 2, -3, 2, 0, 2, -1, -3, -5, -6, -1, -16, 2, 8 }, { -1, 5, 1, -11, 5, 9, -7, 8, -13, -12, 4, 12, -4, 1, -1, -1, 27, 29, 10, 15, 2, -6, -3, 4, -21, 10, -9, -11, -6, -1, -9, -3 }, { -6, -3, -1, -6, 11, -5, 0, -2, -5, -31, 11, 3, -1, 5, -3, 4, 5, 7, -10, 5, -10, -13, 4, 12, -15, -2, 2, -7, 1, -9, -3, -10 }, { -3, -7, 17, -8, -5, 36, 8, -7, -8, -20, 12, 8, 1, -1, 3, 0, 1, 4, -10, 3, 1, 4, -2, -3, -2, -3, -10, 4, -1, -7, 3, 2 }, { -13, -3, -5, 9, 22, 6, -23, 3, -10, -7, 17, 17, 18, -14, -8, -8, 2, 4, -8, 2, -3, -8, 6, 4, -1, 7, 0, 0, -3, 0, -12, -3 }, { -3, -10, -15, -3, 9, 3, -23, -9, -13, -18, 12, 13, -2, 0, 1, 8, -1, 2, -7, -12, -5, 14, 2, 1, -22, 6, -10, -8, -9, 28, -7, -14 }, { -3, 1, 2, -1, 13, 7, -2, -7, 1, -3, 6, 9, -3, -2, 4, -2, 2, 1, -10, -2, -2, -22, -2, -7, -10, -5, -11, -27, -12, -16, 4, -7 }, { 2, -6, -3, 1, 8, 0, -2, 12, -3, -4, 58, 15, -10, -4, -2, 2, -2, 0, -2, -6, 2, 4, -1, 1, -4, 1, -1, -5, -4, -3, 3, 1 }, { 10, -1, 0, 5, 21, 7, -14, 6, -3, -16, 15, 17, -16, 13, 3, -6, -4, 6, -12, -5, 1, -4, -7, -8, 2, 3, -6, 6, -1, -8, 5, 4 }, { -6, -2, -8, -11, 15, 10, 0, 8, -6, -15, 33, 8, -2, 18, -15, -11, 5, -1, 0, 15, -15, -4, -4, -1, 10, 7, -13, 4, -4, 0, 8, 3 }, { -7, -2, 0, -2, 0, -2, -4, -5, -14, -16, 12, 38, 7, 12, 6, -4, 0, -1, 0, 3, -2, -6, 0, 2, -9, 1, 0, -1, 0, -2, 4, 1 }, { -8, -4, 18, 1, 14, 5, -12, -3, 20, -17, 5, 19, -11, -8, 11, -3, 3, 9, -7, -8, 9, -17, 2, 15, -10, -11, 5, -5, 7, 15, -6, -2 }, { -7, 2, 38, 5, 19, 16, -5, 4, -13, -20, 0, 4, -4, 6, 4, 2, -7, 6, -8, -2, -5, -7, 6, 3, -4, -3, -2, -3, 7, -6, -4, 0 }, { -11, -12, 8, -15, -3, 14, -7, -22, -11, 2, 22, 14, -19, 2, -19, -6, 1, 3, -18, 14, 2, -6, -2, -8, -3, -6, 5, -7, -8, -4, 1, 1 }, { 8, 7, 25, -21, 12, -6, -5, -4, -10, 6, 0, 10, 1, -12, 18, -5, -15, 4, 1, 14, -1, 5, 8, -7, 1, -7, -3, 9, 10, 1, -1, 0 }, { 9, 10, 32, -15, 8, 2, 11, -7, -18, -8, 2, -6, -9, -16, -3, 3, -1, 3, 1, -5, 4, -2, 1, -8, 0, -6, -3, -11, 1, 5, 0, 0 }, { 14, 0, 23, -25, 22, 3, 7, 10, 0, -2, 7, 8, 0, 10, 0, 0, 3, 2, 3, -10, 0, 10, 0, -7, 0, 10, -1, -5, -7, 1, -1, 2 }, { 12, 0, 25, -18, -5, -4, 13, -10, 3, -6, 7, 21, 0, -16, 3, -10, -6, 5, -7, -3, 2, 5, 3, -6, 4, 9, -8, 12, -2, 3, 2, 4 }, { 31, 15, 27, -20, 10, -7, 15, -10, 9, -8, 4, -5, 3, -3, 5, 6, 11, -2, -12, -2, 6, -2, 1, 2, -1, -1, 1, 1, 3, 1, 1, 2 }, { 12, -4, 13, -23, 12, -6, 2, 4, -3, 13, 6, -7, 5, -19, -7, 18, 1, -7, 7, 1, 16, -7, 3, 0, 3, 0, -12, 8, -11, 9, 4, 7 }, { 29, 1, 3, -22, -5, 6, 0, 12, -14, 11, 1, 6, -3, 4, 6, -2, 4, -13, 12, 1, 1, 3, -11, 9, -10, -1, -7, 16, -11, -1, 3, 9 }, { 4, 4, 36, -23, -5, -8, -15, 1, -6, 3, 13, -1, -5, -7, 4, 9, 2, -11, -3, 5, 1, 3, -6, -1, -4, -4, -2, 2, 3, -1, -5, -2 }, { 19, 10, 6, -17, 2, -4, -2, -4, -3, 13, 2, 2, -13, -7, -3, -11, 9, -6, 1, -9, -5, 4, -5, -9, -18, -7, -11, 9, 4, -11, 8, 4 }, { 16, -3, 9, -16, 18, -2, -12, -16, -11, 11, -18, 16, -13, 6, 2, 8, 3, 8, -4, -16, 10, -11, -1, -3, -8, 5, -9, -4, 9, -4, 0, -3 }, { 14, 15, 3, -23, -5, 7, -8, -6, 2, 17, 2, 12, -8, -12, 13, -1, -9, 3, 1, 1, 19, 15, 4, -1, 1, 2, -3, 2, -3, 1, 5, 3 }, { 32, 5, -10, -47, -5, -1, 4, 11, -7, 0, 2, -2, 1, -7, 6, -4, 6, 2, -4, -2, 2, -2, 0, -4, 1, -6, -5, 2, -2, -1, -3, -4 }, { 20, 8, 10, -21, -7, -9, -16, 12, 1, 4, 6, -5, 9, -11, -7, 4, -11, 28, -3, 2, 4, -6, 10, -8, -5, -5, -9, 9, -2, -1, 6, -5 }, { 38, 3, 23, -25, -6, -18, 3, -10, -8, 6, -10, 1, -10, 2, 2, 0, -7, 2, -4, 5, -1, 8, -3, 0, 3, 3, -1, 1, 0, -4, -4, 0 }, { 20, 5, 16, -22, 24, -18, 2, -12, -14, -7, -3, 10, 2, 7, -10, 2, -8, 1, 8, -1, 4, 1, 4, -2, 5, -9, -18, -8, -13, 5, -11, 10 }, { 14, 8, -12, -16, 9, -11, -3, -6, -25, -7, 6, 5, -7, -16, 10, 2, -7, -1, -9, -3, 16, 4, 3, 3, -3, -3, -15, 13, -3, 4, 13, -7 }, { 16, -9, 19, -23, 7, -19, -3, -5, -15, 11, -21, 21, -16, 18, -1, 6, 10, -10, 18, -14, 16, -15, 6, -5, -9, 5, -17, 13, -10, 13, 0, 10 }, { 8, -4, 4, -24, 8, -21, -18, 9, -11, 4, -6, 17, 5, -9, -2, -2, 2, 15, -2, -3, -2, 1, 7, -13, 15, -10, -8, -11, 3, 3, -1, -1 }, { 14, 17, 6, -32, 5, -17, -2, 0, 15, -1, -5, 16, 1, -5, -2, 9, -3, 8, 4, -2, -2, -4, -3, 1, 0, 7, -3, 4, -5, 0, -7, 2 }, { 24, 6, 22, -12, 8, 3, -14, 4, -7, 8, 6, 5, 6, 1, 6, -12, 15, 10, 4, 11, 9, 6, -7, -4, 10, -9, 2, -1, -5, 11, 15, 3 }, { 17, 12, 3, -23, 5, -1, -2, 1, -9, -1, -3, 1, 8, 1, -5, 17, 11, 0, -2, -11, 7, 4, 0, -27, -7, 1, 2, -8, 9, 7, 5, 3 }, { 12, 10, 12, -10, -4, 5, -1, 2, -24, 5, -8, 2, 6, -17, 19, 5, 12, -2, 16, -7, -6, -14, 4, 1, -3, 13, -16, 5, -1, 4, 1, 1 }, { 31, 9, 11, -17, 10, -3, -7, 7, 1, 2, 2, 4, -3, -1, 11, 4, -5, -8, 1, 4, 15, -6, -28, 1, 8, 3, -6, 5, 17, -2, 2, -4 }, { 11, 19, 16, -26, 0, -7, -7, 2, -13, -15, -12, 9, -3, 27, 8, 4, -6, 1, 4, -6, 11, -1, -6, -7, -3, 0, -6, 4, -6, -7, -3, -1 }, { 10, 18, 16, -32, 19, -9, -4, -3, -7, 8, 8, -3, -11, -2, -6, -16, 13, 13, -6, -1, 10, -2, -2, -9, 0, -3, 9, 4, 11, -2, -6, 6 }, { 9, 4, 19, -33, 4, 7, -12, 36, -3, -1, 8, -2, 2, -8, -9, -4, -8, 0, 1, -1, 0, -4, -4, 3, 0, 3, 6, 0, -6, 2, 0, -2 }, { 25, 7, 15, -12, 2, -24, -1, 24, -4, 4, 9, 0, -2, -9, 4, 6, 3, 13, -3, 1, 5, -1, -3, -5, -1, 7, -2, 3, 4, 4, 1, 0 }, { 19, 6, 8, -20, 9, -9, 5, -4, -13, 7, 11, -3, 5, -13, -9, 6, -11, -1, 0, 4, 11, 26, 3, 6, -7, 12, 6, -3, 1, -9, 7, 1 }, { 15, 6, 19, -23, -3, -9, 3, 16, -6, -4, 6, -5, -10, 1, 16, -14, 2, 0, 2, -13, -3, 8, -6, 3, 1, 1, 2, -5, 12, -4, -8, -3 }, { 14, 4, 16, -20, 1, 12, 0, 6, -3, 9, 4, 16, 10, -16, 5, 7, 5, -4, -4, -18, -3, -11, -4, 4, -7, 3, 13, 7, 3, 3, 2, -7 }, { 22, 3, -1, -30, 18, -3, -9, 9, -2, 11, -16, -2, -14, 12, 0, 4, -5, 4, -1, 3, -20, 12, 4, -10, -2, -2, -12, -12, 10, 6, 11, -3 }, { 15, 7, 2, -21, 5, 4, 9, -9, -33, 7, 7, 3, -6, -14, -8, 10, 12, 0, 2, -1, 5, 4, -2, 0, -7, 0, 2, 4, 0, 1, -3, 8 }, { -7, 0, 12, 3, 0, -6, 8, -4, 0, 2, 14, -15, 2, -7, -31, -3, 14, 0, 14, -15, -1, -4, -15, 10, 1, -3, 1, 2, 5, 2, -8, 1 }, { -2, 5, 1, 0, -3, 3, 3, -6, -1, 2, -4, 1, -19, 0, -11, 18, 11, 10, 21, 5, 6, 2, 10, 3, -6, 0, -2, 13, 5, -1, -2, 9 }, { -9, 1, -5, 0, 0, -15, 8, 4, 8, 3, 8, 12, -13, -2, -39, -2, 4, -4, 5, -3, -4, 3, -3, 3, 10, 5, 3, 2, -3, 5, -2, 8 }, { -9, 6, 6, -8, 12, -12, 23, -18, 4, -15, -5, 2, -20, 13, -7, 7, 7, -12, 14, -12, 6, 1, 1, -3, -8, 9, 0, 1, -7, 3, 7, -6 }, { -18, 13, 4, 3, -10, -30, -10, -6, -14, 1, -7, -4, -35, 5, -25, 11, 9, 8, 19, -4, -7, -3, -18, -8, 1, 5, 10, -4, -14, -9, 3, -4 }, { -6, -1, 4, -9, -9, 4, 20, 0, 0, 3, 11, 7, -16, -17, -20, 11, -6, -14, 1, 4, 19, 2, -8, 6, -15, 3, 6, -5, -14, 3, 7, 2 }, { 1, 6, -2, -8, -5, -3, 3, -8, 21, 1, 3, 16, -14, -2, -9, -4, 13, -2, 18, 14, 14, 19, -13, 5, -10, 2, -3, 3, 5, 5, 1, -1 }, { -1, -5, -6, -2, -11, -7, 5, -4, 5, -1, 0, 3, -3, 2, -19, 18, 16, 4, 14, -22, -2, -11, -22, 1, -1, 11, 1, 2, 11, -10, 7, -12 }, { 1, 4, 5, -1, -9, -5, 1, 12, 5, 6, 12, 9, -24, 23, 1, 20, 14, -11, 13, 5, -2, -2, 5, 6, 2, 1, -9, 6, 10, 5, -4, 11 }, { -1, -1, 1, 7, -3, -4, 8, -16, 15, -1, -7, 9, -22, -11, -11, 10, 16, 9, -2, 4, 13, 10, 6, 16, 4, 7, 1, -8, -7, -14, -7, 4 }, { 1, 3, -6, 0, 15, -9, -4, 0, 4, 6, 12, 9, -6, -5, -22, 17, 7, -11, 15, -5, 1, 3, -19, 0, -15, -3, 16, 5, 5, -7, -11, 12 }, { -2, -1, 13, 2, 4, -24, 37, -5, -2, -6, 12, 7, -2, -23, -4, 9, 2, -3, 3, 2, 3, 3, -14, 11, 0, -4, -2, -2, 3, 10, -10, 4 }, { 2, 9, 8, -6, -28, 14, 28, -11, 18, -11, 0, 2, -2, 4, -12, 3, 6, 0, 7, -7, -6, 2, 5, -1, -1, -1, 5, 2, 3, 0, -3, 9 }, { -7, 14, 5, -10, -3, 7, 4, -5, 7, -8, -7, 4, -12, 14, -16, 25, 3, 0, 1, -5, 12, -10, 0, -10, 0, 12, 12, 17, 12, 10, -1, 0 }, { -4, -2, 5, -2, -17, -3, 5, -5, 7, -17, 1, 5, -4, 4, -20, 0, 11, -15, 13, -8, 10, 1, 1, 5, -12, 9, -8, 0, 6, -1, -11, 4 }, { -3, 12, 13, -15, -7, -7, 0, 5, 33, 3, 3, -6, -13, -7, -15, 10, 3, 3, 3, -5, 2, 7, -1, 0, -12, 2, 11, -6, -9, 0, 5, 11 }, { -8, 5, 10, -7, -14, -4, 13, 0, 18, -3, -6, 7, 1, -6, 0, 21, 8, -7, 10, -8, -3, 17, -9, 0, -5, 1, 4, 8, -3, 11, -5, 0 }, { -8, 8, -3, -8, 8, -11, 16, -16, 17, 0, 8, 16, -17, 10, -16, 10, -8, 6, 11, 0, 10, 7, 4, 5, 7, -5, -5, -6, -7, -5, -1, 16 }, { -6, 0, 6, 1, -8, -8, 8, -7, -5, -10, -11, 8, -19, 6, -7, 13, 5, -3, 4, -8, 7, -1, -18, 9, 0, -5, 6, 26, 3, 8, 2, 4 }, { -2, -2, 23, -2, -20, 2, 7, -7, -6, -15, 3, 9, -19, -2, -10, 7, -2, 7, 9, 11, 0, 4, -4, 6, 9, -2, 4, -3, 4, 3, 2, 8 }, { -6, 12, 10, -10, -7, 4, 17, 11, -6, 1, 12, 11, -18, 8, -12, 4, 1, 13, 6, -13, 23, 9, -5, 8, -2, -5, 1, 3, 0, -2, -4, 4 }, { 7, 1, 7, -17, -8, 8, -1, -7, 5, -6, 4, -3, -16, 9, -24, 18, -3, 10, 13, -11, -6, -11, -4, 10, 0, 11, 8, 2, 6, -5, -11, 4 }, { -4, 1, -5, -10, 0, -3, 9, -2, 4, -1, 1, 5, -41, -10, -7, 4, -3, 3, 1, 0, -12, 4, -3, 0, 2, -1, -2, -5, 3, 2, -7, 5 }, { -2, 1, 4, 4, -3, -6, 1, 0, 12, -5, 11, 0, -17, -3, -1, 11, 4, 1, 27, -12, 0, -14, 2, -15, -3, -9, 0, -7, -3, 15, -8, 6 }, { -6, 4, 9, 2, 4, 3, 7, -10, 28, 1, -2, 48, 7, 0, -10, 10, 1, -9, 2, -1, 0, 3, -5, 5, -4, -2, 7, 7, 1, 3, 2, 5 }, { -3, 3, -1, 3, -9, 0, -1, 3, 2, -6, 39, -14, -12, 5, -19, 21, 7, -6, 4, -1, -4, 0, -4, 1, 0, -9, 1, 10, 0, -2, 0, 7 }, { 4, 2, -29, 12, 5, -3, 16, -6, 15, -13, -4, -1, -13, 22, -16, 17, 16, 4, 9, -4, 4, -6, -4, 11, -8, 7, 8, 4, 3, -3, -7, -13 }, { 0, 3, 3, -6, -4, 0, 9, 0, 5, 0, 10, 10, 4, -13, -12, 16, 23, -4, -12, -6, -4, 20, 2, 0, -4, 23, 1, 8, 11, -4, -5, 15 }, { -6, 4, -15, -9, -1, -19, 12, -30, -17, -4, 1, -13, -13, 4, -3, 26, 5, -25, 11, -14, -6, -13, 0, -7, 9, 2, 8, -1, -8, 1, -8, 13 }, { 1, 6, 1, -4, -4, 1, 2, 0, -3, 2, 10, 6, -6, -2, -11, 4, 32, 15, 15, -47, -8, 3, -12, 4, -5, 4, -1, 0, -5, 5, 1, -7 }, { 2, -1, 0, 0, -1, -6, 0, -6, 4, -4, 5, 9, -5, 1, -3, 51, 4, -5, 4, -14, -1, -4, -3, 1, -4, -1, 0, 2, -8, 0, 1, 2 }, { 0, 4, -2, -7, -2, -9, 6, -8, 11, -3, -6, 3, -11, -8, -12, 8, 11, 5, 19, 3, -24, 19, -14, 11, -5, -18, -8, -12, -5, -4, -1, 4 }, { 16, 9, 10, 14, -18, -2, -18, -27, 10, -5, 12, 14, 4, 0, -2, -6, -12, -7, -1, 3, 4, 7, 11, 10, 5, -5, -7, -16, -3, -6, 6, 9 }, { 7, 15, -9, 10, -19, 4, -5, -37, -2, -4, 8, 2, 4, -1, 1, 9, -5, -5, -12, 1, -1, -8, 3, -3, 4, 6, 9, 3, 3, -1, 2, 4 }, { 13, 17, 3, 9, -7, -7, -15, -17, -8, -13, -4, -8, 19, 2, 16, 25, 7, 15, 2, 16, -5, -6, -10, -9, -7, -6, -2, -7, 7, 2, 4, 5 }, { 24, 7, 9, 8, -13, -2, 0, -4, 1, -13, 3, 6, 7, 10, -4, 15, 5, 7, -4, 5, -5, 3, 13, -7, 5, 15, -11, -2, 7, 5, 8, 6 }, { 17, 6, -15, 23, -2, -1, -6, -2, 0, -4, 11, -3, 12, 15, 6, -8, -15, 10, -9, 7, -1, -11, 2, -8, -4, 3, 4, -10, 4, 4, 11, 1 }, { 21, 12, -3, 6, -8, 8, -11, -8, -5, -5, 3, 7, -1, -5, 12, 15, -10, -11, 3, 15, 8, 4, 2, -15, 0, 14, 1, -8, -1, 3, 10, -7 }, { 16, 12, 5, 13, -6, 15, -23, 0, -17, -9, 0, 4, -9, 13, 6, 18, 0, 0, -4, -1, 0, 14, 5, -1, 8, -4, -8, -6, 5, -2, -2, 0 }, { 14, 16, -1, 12, -15, -9, -6, -20, 4, 6, 8, 9, 3, 1, -9, -4, -1, -11, 9, 11, -12, 1, -14, -7, 2, -8, 11, 9, -4, 10, 4, -16 }, { 13, 10, 3, 7, 0, -8, -33, -6, 4, -4, 19, -2, 14, 6, 5, 7, 6, -3, -1, -10, -10, -9, 4, -3, 5, 9, 2, 2, 10, 9, -2, -3 }, { 11, 10, 25, 18, -1, -6, -21, -21, -11, -16, 6, 5, 14, 4, 8, 7, 0, -10, -7, -9, -5, -4, 3, -1, 1, 6, -1, 6, -2, 2, -3, -9 }, { 15, 9, 5, 22, -17, 15, -9, 7, 7, -9, 13, 9, 10, -1, 8, -3, -2, 6, 1, 17, 8, -14, 7, -3, 12, 9, 1, 0, 1, -5, 17, -18 }, { 25, 19, -17, 12, -4, -10, 1, -13, -19, -7, -3, 9, 6, -2, 3, 1, 4, -2, -11, -14, -1, -7, -5, -9, 7, -1, -3, 4, -5, 1, 0, -1 }, { 20, 8, -3, -10, -24, 3, -6, -2, 0, -12, 14, 6, 7, 11, 4, 7, -12, -5, -8, -10, 5, -1, -4, 4, 16, 7, -14, 6, -1, -2, -7, -11 }, { 16, 18, 17, 1, -15, -6, -5, -3, -1, -19, 8, -2, 2, 8, 12, -19, -12, 8, 0, -3, -1, -1, 4, -14, 9, -1, -12, -1, -7, 10, -3, 5 }, { 18, 12, -7, 7, 0, -3, -13, 0, -1, -4, 9, -2, 6, -1, 0, 1, 15, -21, 1, -8, 25, -19, 13, -9, 2, 12, 5, -7, -3, -1, -3, 1 }, { 13, 16, -4, 9, -2, 2, -1, -19, -7, -4, 18, -6, 14, 18, -5, 4, -6, -3, -19, -14, -1, -12, 10, 6, 7, 17, -12, -13, -10, -4, 5, 4 }, { 27, 17, 4, 14, -9, -2, -4, -8, 0, -6, 14, -11, -7, 2, -3, -3, -2, -3, -13, 12, 16, 1, -5, -9, -10, -11, -2, 3, -7, 5, 11, -7 }, { 7, 17, -16, -2, -14, -28, -7, -8, 15, -10, 7, 15, 8, 17, 13, -1, 4, -7, -12, -11, 0, 0, 2, 3, -3, 7, -6, 6, 1, -16, 1, -2 }, { 23, 11, -9, 15, -23, -4, -6, -4, 2, -9, -7, 9, -8, 3, -13, -4, 8, 18, -6, -2, 1, -5, 6, -14, -5, -2, -6, -5, -3, -2, 4, -5 }, { 12, 13, 18, 18, -35, 2, 7, -17, 3, -11, 6, 9, -3, -2, 10, -4, 3, 3, -2, -7, 0, 2, -4, 0, -4, 0, -6, 5, 10, 4, -3, -1 }, { 19, 11, 1, 20, -14, 4, -9, -13, -2, 11, 0, 17, -1, -1, -1, -1, -5, -8, 0, 5, -1, -8, 5, -1, 3, 2, -12, 21, -2, -24, 5, 7 }, { 15, 15, -15, 17, -14, -22, 3, -4, -11, -3, -7, 1, 18, 10, 1, 10, -6, -3, 8, 2, -7, 0, -2, 1, 1, 2, -9, -2, 1, 2, -3, 4 }, { 45, 13, 8, 17, -5, 2, -16, 2, 8, -2, 8, -15, 4, 5, -1, 7, -6, -2, -6, 2, -3, 0, 0, -9, -1, 7, 2, 3, -3, -3, -1, 5 }, { 1, 18, -8, 18, -12, -10, 3, 4, -22, -12, 20, 8, -3, 9, 2, 10, -10, -3, 9, 3, 6, -3, 10, -1, -3, 2, -2, 4, 2, 3, -3, -18 }, { 9, 10, -5, 9, -35, -21, -18, -16, -1, -12, -6, -7, -15, -19, 12, 4, 4, 9, -7, 2, 14, 1, 4, 0, -1, 6, -7, 2, 1, 1, -4, 4 }, { 31, 8, -17, 35, -8, 1, -5, -6, -7, -6, 10, -2, -3, 6, 9, 3, -6, -2, 3, 3, 5, -3, 0, 6, 0, 1, -5, -3, -2, -4, -1, 0 }, { 18, 4, -8, 7, -8, -15, -1, -16, 12, 18, 3, 19, 2, 4, 8, 8, 0, -5, -8, -12, 10, -5, 0, 1, 0, 4, -3, 16, 11, 11, -2, -6 }, { 27, 15, -17, -10, -23, -22, -1, -14, -4, -7, 20, -2, -7, 6, 15, -5, 32, 4, 9, -11, -3, -8, 11, -4, -1, -4, -8, -6, -4, -5, -2, -7 }, { 22, 4, -7, 2, -15, -11, -17, -10, 2, 0, 15, 11, 7, 12, -8, 6, -10, -18, -6, -12, 7, 3, 22, 3, -7, 14, -5, -2, -13, -7, -1, -7 }, { 18, 13, 9, 24, -4, -19, -9, -11, 13, 8, 2, 4, -1, 8, 14, 10, -12, 0, 0, 5, 10, 5, 4, -1, 5, 1, -1, 11, 2, -4, 0, -9 }, { 15, 19, -5, 1, -4, -10, -8, -27, 6, 8, 5, 10, 4, 11, 5, -5, -11, 0, -11, -14, -4, -9, -8, -8, 6, -9, 4, -5, -1, 1, 5, -4 }, { 18, 1, -13, 14, -14, 9, -15, -7, 12, 1, 13, -4, -20, 12, 10, 12, -12, 7, 1, -13, 10, -6, 5, -3, 4, 8, 10, -13, -3, -6, 9, -3 }, { 19, -14, 5, -8, -6, 2, -5, 5, -3, -1, -28, 11, 18, -6, -4, -2, 11, 14, -43, -42, 9, 2, 20, -23, 6, 32, 0, 5, 0, 6, 9, 5 }, { 8, 11, -14, -1, 7, 12, -7, 2, -16, 2, 10, -3, -1, -7, -7, -1, 1, -10, -60, -23, -18, 42, -13, 9, 18, -11, 0, 1, 0, 2, -5, 1 }, { -5, -1, 2, 0, 3, -3, 3, -2, -6, 0, -3, -3, 7, 2, 0, -2, -2, 3, -34, -15, 37, 47, 10, 20, 9, 1, 3, -21, -25, -33, -14, 8 }, { 5, 6, 2, -2, -2, -2, 6, 5, -5, 7, -3, 1, -5, -13, 9, 3, -17, -19, -2, -79, -12, -7, -8, -6, -2, -2, -1, -1, -7, -13, 6, -1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 3, 4, -87, 6, -11, 16, -9, -1, 8, 0, 5, 0, 1, 2, 1 }, { -5, 6, 2, -24, 5, -9, -7, 0, 7, 3, -3, 16, -14, -16, 0, 18, 15, -9, -14, -28, -17, 53, 14, -6, -28, -1, -3, -10, -7, -14, 19, -15 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, -13, 0, -53, 3, -22, 63, 19, 16, 1, -11, 0, -3, 0, -3, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -6, -43, -43, -2, 65, -13, -4, 9, 1, 1, 2, 1, 0, 0, 1 }, { 0, 1, 0, 0, -1, 0, 1, 1, 0, 0, 1, 2, -1, -1, -3, -1, -23, 1, -61, -55, 3, -28, -6, -4, -4, 8, 2, 1, 1, -1, 0, 0 }, { 0, 1, -1, 1, -1, 0, -1, 0, 1, -1, 0, 1, -1, 0, -9, -4, -48, -19, -52, -46, 11, -12, 5, -14, 0, -10, 0, 0, -1, -2, -1, 0 }, { 0, -3, -1, -4, 2, -1, -7, 3, 1, 3, -1, 1, -3, 0, -7, 0, 3, -7, -61, -51, -4, -21, -16, -21, -11, 14, -7, 8, 3, -5, 1, 2 }, { 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 9, -3, 56, -11, -6, -67, -1, 13, 0, 7, 1, -9, -1, -1, 0, 0, 1, 0 }, { 14, 9, -2, 14, -10, -10, 9, -5, 1, -8, -23, 30, 8, -7, 23, 8, 2, 10, -1, -27, -17, 57, 22, 4, -5, 2, -12, -6, 2, -7, -4, -9 }, { 1, 5, 12, -2, -2, -3, 2, -3, 6, 0, 4, -2, -8, -6, 0, 16, -15, 29, -55, -29, -24, 29, 3, 10, 6, 13, 10, -5, 21, 11, -14, 5 }, { 4, 2, 26, -6, 10, 11, -23, -10, -27, -20, 3, -24, -11, -10, -13, 25, -10, 5, -9, -36, -7, 43, 3, -13, 6, 13, -2, 0, 1, 3, -3, -4 }, { -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, -1, 0, 0, 0, -1, 1, -12, 12, -26, -64, -15, 29, 37, -7, -3, -12, -5, 14, 8, -8, -10, -2 }, { 19, -4, -11, -16, 8, 14, 5, 19, 3, 22, -11, -21, -1, -6, -11, 11, 10, -24, -23, -40, -8, 20, 17, 5, 13, -6, 3, 14, -20, -8, 3, 28 }, { 2, -12, 10, -14, -18, 26, -22, 4, -2, 5, -21, 8, 3, 1, 19, 0, -12, 24, -14, -40, 15, 29, -15, 6, 15, 1, -19, 2, 4, 7, -12, -3 }, { 0, 17, 13, 7, -5, -11, 2, -19, 3, 38, -21, -3, -6, -4, 7, 1, 1, -5, -40, -10, -2, 35, 8, 8, -10, -8, -9, 33, 4, 4, 0, -2 }, { -2, -12, 7, 29, -24, 2, 16, -1, -7, 16, 10, -2, -2, -2, 13, -2, -37, 15, -22, -40, -11, 33, 10, -1, 8, 10, 6, 8, 9, 0, -12, 2 }, { 15, -8, -9, -2, 7, -17, 7, 19, 14, 4, 12, 27, 11, 10, 4, 11, -15, 14, -13, -48, 5, 18, 0, -9, -36, -11, 2, 4, 5, 5, -15, -12 }, { -12, 0, 3, 4, 7, -5, 5, -14, -24, -18, -6, -15, -8, -20, 1, -7, -33, -28, -40, -38, -18, -10, -5, 17, -12, 4, 3, -5, 5, -13, 4, -7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, { -8, 2, 1, 22, -31, -6, -25, -3, -3, 1, -15, -11, -2, -3, 4, -13, -9, 15, -18, 37, -7, -37, 12, -13, -11, -25, -10, -11, -22, 7, 16, 7 }, { 14, 10, 4, -10, -1, -5, -7, -3, 16, 13, -5, -15, 5, 11, -1, 8, -27, 7, -12, 49, 17, -22, 9, -2, -9, -1, 2, -15, -1, 41, -18, -17 }, { -4, -9, -15, -3, 3, 4, 4, 2, 7, -3, -7, -8, -5, 17, -19, -7, 36, -9, -38, 17, 1, -48, 11, -18, -13, -2, -8, 4, -10, -5, 21, 11 }, { 15, -13, 4, 2, 1, -5, -2, 1, -10, 7, -1, 3, -6, 0, 11, -11, 8, 20, -17, 51, -17, -41, 2, 15, 4, 8, -2, 16, -32, -1, 17, 6 }, { -8, 8, -18, -5, 4, 6, -3, 8, 0, -4, 2, 0, -1, -4, 5, 8, 30, 30, -8, 70, 2, 8, 2, 0, 7, 1, 13, -1, -6, -7, -11, 2 }, { -8, -7, 9, -10, -13, 6, -11, -14, 13, 25, -26, 5, 2, -5, -5, 5, -8, 4, 0, 33, 12, -38, -4, 6, 13, 6, 25, 34, -1, 25, -19, -5 }, { 18, 3, -17, 4, -8, 7, 20, 1, -1, 5, -5, -2, -8, 8, -35, 15, 24, 43, -5, 51, 5, -12, -3, 1, -2, 3, -3, -3, -9, 8, -9, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 10, 24, 76, -2, -22, 11, -1, 4, 33, 4, 1, -1, 1, 2, 0 }, { 0, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 2, 0, 24, 13, 32, 70, 26, 5, -21, -9, -6, -15, 2, -2, 2, 4, 1, 1 }, { 5, -4, -11, 4, -4, 22, 10, -2, 13, -11, -4, -21, -17, 0, -7, 4, 10, -34, 11, 52, 2, -46, -5, 0, 0, -1, 2, 4, -9, 1, 1, -7 }, { 0, 1, 1, 0, -1, 0, 1, 0, 1, 1, 0, 1, 0, 0, -3, 1, -8, 9, -1, 64, -13, -61, -3, 3, -5, 10, 1, 3, -1, -1, -1, -1 }, { 0, 1, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 1, 10, -2, -31, 79, -10, 27, 0, -1, 3, 8, 1, 1, 0, -1, 0, -1 }, { 3, 12, 10, 26, -19, 10, -9, 6, -4, -15, 10, 3, -16, 6, 11, -19, 3, 10, 18, 44, 5, -30, 5, -9, 21, 4, 20, 10, 14, -25, 8, -17 }, { 0, 0, 0, 1, -1, 0, -1, 0, 1, 0, 1, 1, 0, 0, -6, -2, 8, -8, 13, 69, 26, -19, -25, -17, 16, 6, -12, 22, 2, -6, 9, 5 }, { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, { 16, -18, 7, -4, 31, -15, -9, -13, 20, -12, -6, 0, 12, -6, -2, 4, 3, -3, -1, 0, 1, 3, 3, -2, 1, 6, 4, 0, -3, 2, -5, 1 }, { 38, -5, -13, -4, 8, -15, 11, 1, 2, -4, -1, 9, 13, 4, -12, -7, 0, -2, 7, 2, -6, -2, -3, -2, 3, -4, 6, 15, 1, 1, -11, -2 }, { 47, -22, 9, -26, 3, -5, 2, -7, 4, -2, 2, -2, 3, 0, 3, -4, 3, -3, 2, -3, 7, -3, -1, 1, 1, -5, 5, 0, 2, -5, -3, -2 }, { 14, -16, 2, -6, 7, -2, -7, -4, -4, -7, 14, -3, 7, -19, -14, -17, -29, 6, 26, 16, -5, 13, -4, -1, 21, 14, 1, 3, -6, 0, -7, -1 }, { 29, -11, 5, -3, 4, 11, 4, -10, 1, -22, -3, -10, 5, 4, 2, 8, -2, -7, -12, -12, -8, -3, -18, -2, -9, -5, -1, -3, 2, -14, -14, 7 }, { 28, -12, 5, 3, 9, -7, 0, -2, 2, 1, 4, 0, -7, -3, -2, 4, 4, 14, 8, -1, -4, 14, -7, 17, -2, -2, -9, 2, 19, -7, 9, -8 }, { 31, -18, -22, 8, 15, -5, -10, -15, 1, 10, 6, 7, 6, -8, 2, -1, 12, -3, 3, -1, 1, 5, -6, -4, 0, 1, 7, -10, -2, 4, -3, -4 }, { 53, -30, -4, 12, 2, 3, -3, -3, 0, 1, 6, 5, -5, -4, -7, 1, 0, 2, 1, 3, 1, 5, 0, 2, 2, -1, 0, 4, 2, 0, -2, 0 }, { 27, -18, -3, -2, 4, -8, 3, -2, -11, 2, 10, -8, -8, -4, 0, -2, 8, 0, 9, 0, -16, 11, 1, -6, 13, -3, -10, -13, -15, 25, 1, 0 }, { 35, -5, -1, -8, 23, 11, -14, -3, 2, -2, 8, -6, 17, -2, 7, 0, -2, 10, -17, 13, -2, -2, 11, 11, -14, 2, -2, -3, -8, -1, -12, -5 }, { 29, -9, 7, 3, 2, -10, 0, 3, 9, 0, -3, 5, 1, -10, 10, -5, 3, 6, -20, -9, -6, -4, 1, 0, 12, 17, -8, 9, 3, -1, -9, 0 }, { 15, -16, 18, -19, 16, -15, 17, -18, 13, -16, 17, -14, 15, -9, 13, -17, 9, -7, 4, -5, 3, -4, -3, 0, -6, 7, -9, 7, -2, 7, -9, 9 }, { 21, -10, 7, -2, 12, -7, 13, -17, 11, -2, 20, 3, 5, -11, -6, -6, -15, 0, -9, 5, -11, 7, -1, 7, 8, -10, -9, 3, -5, 9, -8, -2 }, { 23, -22, 15, -5, 16, -4, -3, -12, 9, 3, -1, -2, -8, 2, -2, -16, 3, 4, -2, -6, -7, 12, -8, 2, -14, 2, -7, 11, -2, 6, -4, -1 }, { 34, -17, -4, 8, 4, -6, 1, 8, 4, 16, 3, 6, 12, -1, -1, -15, 6, 4, -7, -6, 6, 0, 2, 1, -2, 2, 3, 3, -3, -2, 8, -6 }, { 18, -18, 2, -2, 10, 1, 18, -23, -3, -10, 0, 4, 20, -19, -3, -4, 2, 8, 6, 1, -3, 1, 1, 3, 5, -1, -11, 3, -7, 5, -1, 1 }, { 15, -14, 2, 3, 10, -8, 12, -13, 13, -15, 6, -8, -4, -10, 14, -9, 24, 2, -7, -18, 13, -11, 8, 14, -6, -2, 3, -1, -4, 7, -7, -4 }, { 20, -12, 13, 5, -1, -10, 15, -6, 8, -1, -3, -10, 17, 0, -6, -19, 2, -1, 8, -3, -16, 0, -3, 2, -2, 0, 8, -9, 0, 1, -10, -9 }, { 32, 0, -9, -5, -1, 5, 13, -11, 8, 3, 11, -11, 0, -8, -2, -14, 7, 10, 6, -5, 1, 10, 2, 12, -10, 4, 4, 6, 4, 0, -7, -10 }, { 16, -14, 10, -7, 11, -11, 11, -11, 18, -13, 8, -15, 16, -11, 13, -9, 8, -7, 12, -11, 7, -6, 3, -5, 9, -5, 4, -1, 7, -4, 8, -3 }, { 24, -27, -1, 5, 8, -5, 12, 7, 4, -3, 3, -1, -9, -11, -13, -5, 10, 0, -13, 7, 1, -5, 4, -9, 7, -3, 13, 2, -5, -3, -17, -2 }, { 23, -19, 15, 1, -10, -18, -12, -6, 8, -3, 12, 0, -12, -10, -4, -4, 8, -10, 4, 2, -2, -8, 13, -3, -2, -6, 2, -3, 5, -2, 2, 11 }, { 25, -12, 4, 2, 24, -3, 3, -6, 14, 11, 0, -21, -3, -3, 1, -8, 7, 0, 0, 3, 3, -6, -7, 6, 2, 1, -4, 5, -1, 10, -2, 9 }, { 24, -8, -6, 7, 16, -12, 13, -1, 11, -21, 2, -6, 3, -12, 0, 9, 4, 11, -7, 1, 4, 1, -8, 3, 3, -6, 3, 3, 0, -8, 8, 4 }, { 25, -21, 13, 14, 13, -18, 4, -3, 0, -5, -4, 5, -3, 0, 4, 12, 7, 3, 5, -5, 2, -2, 3, -10, 2, -9, -15, 6, 1, 7, -5, 1 }, { 23, -16, -2, 10, 4, -1, 3, 1, 32, 3, -5, -2, 9, 10, -1, -4, -6, 2, 9, -1, 14, 12, -6, -1, -17, -2, -4, -9, -7, -6, -8, 3 }, { 50, -8, 5, 2, -11, 10, 0, 0, 6, -3, 7, 0, -3, -2, -3, 0, 6, -4, 2, -5, -9, 0, 3, 10, 1, -7, -2, -3, -6, -9, 1, -2 }, { 28, -17, 0, -2, 2, -9, 1, 5, -4, -1, 0, 0, 19, -27, 5, -12, 7, -14, -3, -6, 10, -2, -4, -2, 4, -5, -2, -7, 1, 7, -9, 4 }, { 22, -19, -6, -6, 3, -22, 3, 5, 20, -8, -14, -5, 1, 1, 20, 2, 16, 6, 3, 14, 4, 3, 5, 1, 5, -7, -10, -6, 3, -6, 1, -14 }, { 29, -14, -8, 13, 8, -10, -6, 4, 4, -6, 5, -7, 1, 12, 14, 11, -7, 1, 2, -9, -11, -9, 0, 4, -1, 7, 10, 4, 4, 20, -1, -11 }, { 18, -9, 4, 1, 7, -29, 12, 1, -1, -9, -2, -1, -2, 2, 9, -8, -13, 5, 4, -13, -4, 2, -5, -7, -6, 14, -10, -34, -3, 1, -3, -13 }, { 38, -9, 24, 8, 11, 4, -6, -11, -2, -12, 1, 1, -11, -8, -5, -2, -15, -8, 8, 0, 1, -7, 5, 4, -1, 8, -2, 11, -3, -1, -5, -5 }, { -20, 11, -4, 24, -11, 1, 15, 4, 0, -28, -10, -1, 10, 10, -6, 5, -6, 2, 7, -2, 1, -2, -6, -3, -7, 1, 2, 12, -1, 7, 0, -2 }, { -9, 10, -23, 27, -4, -17, 20, -6, 14, -17, 5, -1, 5, -9, -7, 5, -6, 4, -2, 9, 0, 8, 0, 1, -3, -3, -5, -8, 5, -2, -2, 12 }, { -10, 19, 4, 9, 1, -16, 17, -2, 9, -29, -16, -11, -4, 7, -5, 4, -1, -3, 3, 2, 3, -4, 5, -12, -2, 6, 5, -4, 4, 1, 4, 10 }, { -20, 10, -24, 14, -5, 11, 9, 0, 16, -20, 10, -5, -6, -6, -1, 2, -4, 5, -16, 8, -2, 5, 5, -11, 9, -11, 4, -11, -1, -1, 4, 3 }, { -9, 11, 3, 19, 24, 4, 5, -14, 30, -17, -4, -2, -17, 7, 2, 3, 1, 3, -7, -4, 2, -3, 1, 4, -1, -1, 3, -12, -2, 3, -3, 10 }, { -19, 18, 11, 19, 19, 19, 10, 4, 13, 6, 5, 4, 8, 3, -2, 12, -6, -2, 7, -6, 15, 12, 16, 16, 18, -3, -4, -20, 0, 10, -9, -3 }, { -21, 9, 20, 12, 0, -3, 5, -9, 15, -13, 5, -5, -6, 24, 2, 9, -5, 2, -7, 2, 5, 7, -5, 2, 15, 3, 1, -1, -4, -2, 7, 0 }, { -18, 16, 13, 15, 2, -10, 14, -11, 4, -11, 5, 12, 12, 20, 8, 30, 2, 11, -9, 7, 0, -3, -16, -5, -6, 5, -4, -21, 0, 5, 6, 1 }, { -26, 8, -13, 9, 6, -10, 2, -11, 7, -4, 6, -19, -11, -6, -12, 16, 0, 5, -7, 8, 5, 6, 17, -9, 10, -10, 5, -3, -11, 2, 4, 10 }, { -11, 17, -3, 22, -5, 18, 3, 1, 4, -5, 14, -27, 5, -7, -4, -5, -10, 11, 1, 15, 1, 1, -6, -5, 10, -22, -7, -7, -15, 13, -4, 5 }, { -17, 14, -7, 13, 3, 0, 13, -6, 9, -14, -22, -1, 1, 19, 14, -3, 4, -13, -13, 2, -4, 8, -2, -2, 13, -12, 13, -12, -7, -5, -3, 6 }, { -17, 17, -1, 33, 6, 3, 9, -16, 3, -14, -8, 6, -17, 8, 3, 13, 8, -6, 3, 1, -2, 0, -2, 8, 4, 9, 13, -10, 4, -17, 0, -6 }, { -20, 7, 7, 21, 1, -3, 7, -3, -2, -12, 9, -7, 2, -3, 14, 1, -1, -7, 12, -10, 5, -20, 11, -2, 0, -24, -17, 6, 6, -4, 3, -1 }, { -8, 10, 6, 7, -1, -6, 28, -6, 10, -33, 1, -20, 0, -12, 10, 1, -6, 8, -3, -1, -10, 8, 5, 0, 10, -2, 8, 16, -5, -3, -7, 4 }, { -17, 13, 3, 15, 1, -5, 27, -5, 6, -6, 12, 2, -4, 8, -1, -3, -2, 12, -15, 3, 4, 1, 2, -9, 0, -16, -21, 2, -4, 16, -7, 4 }, { -15, 20, 8, 17, 5, -14, 15, -11, 21, -11, 13, -13, 2, -15, -13, 1, -5, 5, 2, 10, -9, 4, -1, 3, 2, -4, 13, -5, 1, -4, 5, -3 }, { -21, 8, 2, 16, -1, 2, 15, -16, 13, -12, -12, -7, -8, 2, -7, 11, -8, 5, 2, -7, 16, -4, 1, -7, 3, -15, 6, -5, -8, 2, -8, 5 }, { -15, 17, -6, 3, -3, 3, 9, -7, 14, -23, 11, 1, -1, 4, 7, 6, -1, -14, 7, 6, -8, 5, 1, -15, 10, -9, 2, -3, -1, 4, -10, -4 }, { -10, 18, 3, 11, 1, 4, 14, -14, 7, -4, 15, -10, 10, -11, 10, -4, 5, -14, 10, 4, 15, -12, 15, -13, 20, -15, 14, -15, 8, -11, 4, -6 }, { -7, 23, 2, 20, 7, 8, 19, -5, 9, -16, -8, -17, -5, 1, 5, -6, -8, 1, -6, -4, 10, 6, 6, 2, -11, -4, 0, 2, 4, 7, 9, -4 }, { -15, 20, -5, 22, 11, -8, 9, -5, 10, -13, -8, 8, 2, -2, -3, 7, 6, 10, 1, 2, -5, -9, 1, 10, 16, -22, -7, 0, 7, 7, 6, 1 }, { -26, 19, -5, 3, 5, 25, 18, -5, 9, -14, -8, -6, -2, -6, 2, 3, -8, -2, -7, 7, -3, 7, 3, 4, -8, 0, 1, -8, -4, -2, -2, 1 }, { -20, 14, -10, 6, -3, 7, 8, -32, -2, -7, -2, -10, 16, -12, -9, 15, -2, -5, -6, 2, -7, 5, 9, 1, 6, -7, -1, 0, -2, -4, -7, 3 }, { -14, 16, 4, 11, -8, 1, 23, -4, 17, -13, -10, 1, 12, 9, 12, -4, 7, -1, -1, 5, -8, -6, 3, 3, -6, -3, -18, 0, 18, 20, 4, -2 }, { -33, 19, -10, 30, 15, 2, -3, -1, -4, -14, 7, -7, -1, 7, -8, 9, -1, -3, -5, 2, 2, 4, 0, 5, 0, 0, 2, 3, 3, -3, -3, 4 }, { -6, 20, 0, 5, 17, -10, 18, -17, 9, -16, 4, -13, -6, 2, -14, 14, -28, 9, -12, 25, -4, 7, 7, -8, 6, -6, -2, -10, 2, -11, -1, 2 }, { -12, 14, 12, 52, -3, 5, -5, 4, 8, -13, 2, -5, -4, 2, -2, -1, -2, 3, 3, 5, 2, 3, 0, 1, -5, 2, -4, -3, 1, -5, -2, 0 }, { -13, 6, 9, 24, 0, 8, 14, -15, 18, -9, -11, -8, 3, 15, -2, -4, -9, 4, -3, 12, 14, -13, 11, -4, 2, -4, 0, -6, -6, -6, -14, -1 }, { -10, 28, 3, 12, 9, 3, 11, -28, 6, -11, -7, 4, 0, 7, 8, -9, 0, -6, 0, -16, 4, 7, 4, 4, 7, 3, 4, -7, 0, -3, -10, 6 }, { -11, 14, -2, 19, -1, -1, 7, 9, -2, -27, 10, -14, 15, -4, 12, -4, 2, -2, -6, 12, -6, 0, -5, -4, -5, 1, 3, -11, 5, -9, 3, -8 }, { -18, 7, 13, 16, -4, 3, 9, -10, 10, -10, -3, -22, -4, -12, 3, -16, 0, -3, -16, 8, -11, 1, 10, -7, 15, 3, 0, -1, -13, 8, 1, 6 }, { -20, 10, -10, 10, 8, -1, 6, 0, 16, -12, 9, -10, -1, -5, -4, -13, 13, 16, -8, 12, -2, 14, 18, 13, 0, -16, 2, -5, -5, -5, -4, 3 }, { -14, 5, -7, -17, 5, -13, 23, 20, -4, -1, 1, -6, 13, 5, -1, 4, -14, -2, -7, 8, 3, 2, 2, -7, 2, -1, 4, 7, 3, -9, -1, -5 }, { -19, 3, -24, -28, -9, -7, 19, 3, 2, 19, 7, 5, -13, 8, -15, -17, 3, -11, 4, 13, 3, 2, -1, -3, -4, -4, 2, 0, -5, -6, 6, 2 }, { -17, 18, -30, -20, -2, -3, 1, 15, -1, -11, 6, -4, 11, 11, -4, -5, -10, 0, 0, 1, 3, -7, 8, 2, 5, 1, 5, -5, 1, 6, 4, 1 }, { -6, 1, -30, -25, -1, -8, -2, -9, -17, 16, 3, -1, -2, -9, -6, -7, -3, 12, 6, -4, -10, 0, 10, -8, -6, -5, -3, -11, -4, 0, -1, -3 }, { -1, -1, -34, -28, 1, -10, 2, 9, 4, 16, 2, 6, 14, 17, 0, 7, -4, 4, 4, 4, 0, 1, -1, -5, 8, 1, -4, 1, -9, -2, 5, 6 }, { -11, 14, 1, -31, -7, -24, 9, 7, 6, 5, -13, 1, -1, 3, 4, -1, -2, -8, -6, 3, 5, -4, -6, 7, -2, 5, 3, 3, 0, 0, -5, 2 }, { -25, 8, -11, -18, 1, -4, 8, -3, -4, 15, 6, -5, 8, 2, 3, 4, -4, 5, 6, 8, -7, 6, 1, -11, -15, -13, 9, -4, -14, 10, 12, 7 }, { -20, 11, -15, -25, 3, 4, 18, 13, -4, -5, -9, -1, -5, -2, -2, -7, 16, 5, -4, -5, -7, -2, -3, -9, 11, -2, 0, -7, -17, -6, -11, 6 }, { -11, 18, -5, -20, -15, -3, 9, 11, -20, 12, 5, 5, 11, -3, 7, 1, 10, -6, -3, -3, 3, 3, 14, -7, 10, -17, 9, -11, -2, -6, 7, -12 }, { -20, 8, -14, -17, -9, -13, -3, 0, -27, -14, -3, -14, 4, 3, 6, -6, 7, 4, 23, 9, 11, 9, 3, -4, 9, 2, 4, -1, -6, 1, -8, -11 }, { -9, 14, 2, -37, -7, 13, 6, -11, -6, 9, 18, -11, -6, 2, 12, 4, -1, 3, 1, -2, -2, 1, -9, -4, -2, -3, 3, 5, -6, 0, -2, -8 }, { -29, 8, -1, -13, -2, 8, 23, 2, -10, 7, 13, -6, -5, 11, 13, 0, -10, -13, 11, -12, -10, 6, 4, 6, 4, 3, 6, -5, -9, -2, -1, 3 }, { -18, 6, -10, -55, -4, -11, -2, 0, 1, -3, -9, -6, 3, -2, -1, 6, 3, -1, 3, 1, -4, -7, -2, 6, 3, -2, -1, -3, -2, 0, 4, 1 }, { -14, 5, 3, -21, -8, -16, -4, -2, -11, 27, 15, -20, 3, 0, 1, 1, 2, -5, -5, 4, 1, -9, 5, -3, 3, 0, -4, -2, -11, -4, -3, 7 }, { -17, -1, -9, -17, -8, -18, 12, -13, -9, 13, -3, 3, 3, -3, 1, -2, 0, 16, -9, 6, 12, 9, 5, 11, 2, -15, 1, -4, -16, 7, -4, -12 }, { -18, 8, -6, -11, -8, -7, 13, 7, 1, 6, 8, -1, 21, -4, 14, 15, 18, -4, -3, 15, 0, 9, 4, 7, 3, -1, 9, -2, 0, 7, -8, 2 }, { -10, 7, -18, -29, 3, 12, 12, 9, 11, 4, -1, -15, 1, -1, 8, -2, -2, 10, -15, -1, 0, 6, 12, -6, -1, 10, -6, -3, -11, -4, 9, -6 }, { -14, 14, -9, -21, -12, -2, -1, -7, -5, -10, 5, -8, 0, 6, 9, -11, 11, -3, -5, 3, 8, 15, -2, -4, -22, 4, -6, 12, 2, 13, 6, -7 }, { -12, 11, -5, -29, -25, 4, 12, -13, -11, -7, 4, 2, 2, -5, 5, 8, 7, -5, -5, 6, 3, -10, 1, -6, 6, -6, -5, -1, -2, -4, 7, 6 }, { -15, 11, -5, -16, 0, -13, 26, -23, -6, -3, 5, -2, -2, 21, -6, -3, -5, -1, 6, -1, 0, -13, 2, -3, -9, -1, -4, -3, 5, -4, 12, -16 }, { -9, 9, -1, -17, -3, -6, 12, 6, -18, -2, 11, -14, -6, 3, 14, -12, -11, -5, 14, 2, 5, -8, -4, -11, 2, -5, 16, 6, -7, -4, 8, 13 }, { -13, 5, 3, -28, -14, 0, 6, 23, 5, 4, -1, -17, 1, -3, 0, 0, 5, 4, 0, -18, 14, 10, 4, 2, 5, -2, 4, -3, 2, 0, 2, 0 }, { -15, 4, -13, -16, -3, -12, -2, 2, 7, 10, 9, 3, 11, 4, 23, 14, 9, 16, 4, 1, -12, -3, 4, -7, -15, -7, -10, -14, -6, -8, -1, -6 }, { -7, 10, -5, -10, -3, -13, 16, -1, -12, 7, -3, -12, 2, 13, 13, 2, 17, 15, -13, 1, -5, -2, 3, -1, 1, -3, 6, -3, -12, -16, 7, -7 }, { -11, -5, -12, -30, -6, -22, 1, 4, -6, -3, 12, 6, 7, 0, 16, 6, -2, 0, -22, -2, -9, 2, -13, 8, 6, -8, 4, -7, -1, -6, 4, 6 }, { -14, 5, 1, -27, -4, 2, 1, 14, -11, -7, -8, -4, 1, 8, 0, -6, -13, 11, -12, -7, -5, 1, 10, 7, 3, -2, 0, 6, -8, 2, 10, -1 }, { -10, 10, -25, -13, -20, -4, 19, 3, 13, 5, 5, 7, -8, 2, 4, 2, 3, -1, -1, -9, 14, 10, 9, 14, 3, 3, -6, 0, -5, 4, 1, -1 }, { -9, 15, -18, -17, 4, -11, 6, 7, -12, 8, -1, -11, 2, 3, 7, 16, -3, -9, 7, -12, 23, 0, 6, 7, -14, -9, 8, 1, -2, 6, -2, -1 }, { -6, 9, -16, -26, -14, -11, 9, -6, 5, -2, 13, 17, 21, 7, 18, -19, 6, -23, -2, -15, -2, 2, -10, -8, 2, 1, -2, 4, -3, -4, -5, -4 }, { 0, 6, -5, -28, -17, -32, 2, -10, 11, 3, -5, 9, 10, 3, 11, 11, -3, 12, -2, 2, 4, -6, 9, -4, -4, -4, -4, -9, 2, 0, 2, 4 }, { 0, -8, -18, -34, -9, -7, -4, -11, 10, 15, 11, -1, -8, 15, 6, -13, 9, 2, -4, -12, 0, -1, 19, 12, 6, 5, 0, -3, -10, -12, 3, -5 }, { -10, 6, -9, -17, -12, -11, 9, -6, 11, 11, 18, -7, 0, 16, 4, 2, -6, 3, -12, -1, 0, 1, -5, -22, -2, -12, 0, 6, 17, 5, 5, 6 }, { 12, -5, 7, 1, -5, -2, -1, 2, 2, -4, -3, -3, -3, -2, -29, 11, 5, -13, -73, 24, 12, 4, -14, -10, 5, 1, 0, -11, -7, -7, 7, 3 }, { 10, -3, -1, -3, 4, -11, -5, -2, -8, 7, 9, 2, -8, -6, 6, 7, 21, 17, -54, 47, -14, -10, 14, 19, 13, 21, -4, 3, 1, 2, -4, 2 }, { -12, 4, -16, -12, 5, -9, -4, 19, -7, -22, -22, -17, 3, 0, -6, 8, 23, -4, -55, -28, 2, -26, 2, 1, 4, 0, -13, 6, 0, 10, -7, -11 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, 35, -1, -67, -35, -24, -24, -6, 2, 2, -2, 1, 3, 2, 0, -1, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0, 41, -4, -73, -15, 18, 4, 17, 8, -1, -16, -1, -2, 1, 0, 0, 0 }, { -4, -4, 4, 6, -1, 2, -16, -10, -15, -10, 21, -2, -6, -2, 14, -7, 10, -5, -55, 34, -12, 11, -13, -2, 2, 28, -26, 0, 7, 4, 21, -7 }, { 2, 1, 15, -22, 10, -3, 14, -6, -2, 15, -2, -7, 20, 6, -15, -7, 23, 10, -60, 8, -4, 29, -22, 2, -13, 9, -10, 12, -1, -3, 4, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -2, 11, -5, -21, -11, -60, -27, -17, -39, 6, 36, 0, -8, 2, 2, 0, 0, -2, 3 }, { 2, -5, 9, -17, -1, 2, -3, -6, 8, 12, 7, -6, -33, -11, -14, -40, 10, 36, -46, 0, -19, 5, 0, -10, 3, 12, -6, -8, 6, -12, -7, 1 }, { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, -2, 0, 4, -2, -87, -3, -2, 2, -2, 20, 2, 6, -1, 6, 0, 0, 2, -1 }, { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 16, 65, -2, -2, 4, 3, 0, -7, 3, 1, 3, 1, 0, 5, 1, -5, 0, 2, -1, 3, 0, 0, -1, -2, 6, 0, -2, 0, 0, -1, 1, 1 }, { 5, 37, -4, 8, -4, -1, 9, 17, 6, -7, 5, -1, 11, 6, -4, 7, -2, 4, 1, -3, 11, 3, 3, -9, 6, 0, -2, -4, -5, 4, -12, -11 }, { 15, 24, -14, 2, 6, 17, 26, 5, 8, 11, -9, -7, -6, -8, 3, -5, 9, 10, -3, 10, 0, 1, 4, -9, 4, 9, 3, 0, 4, 0, -5, 3 }, { 9, 36, -9, -8, 7, 7, 4, 3, -1, -16, -2, 7, -5, -6, 6, 12, -11, -12, 9, -1, -3, -9, 12, 6, -6, 2, 2, 5, 0, 5, 6, -6 }, { 25, 39, -5, 24, 3, 10, 3, -6, 13, -8, 3, -7, 2, -10, -5, 2, -2, 3, 5, -2, 1, 5, -2, 3, -4, 1, -5, -4, 0, 1, -2, 0 }, { 16, 27, -1, 0, -14, 6, 4, -5, 7, -2, -6, 0, -3, -5, 2, -1, -1, -19, 5, -8, 0, 11, 12, 5, 0, 3, 10, 6, -14, 14, -13, -15 }, { 12, 23, -14, 2, 1, 4, -3, 16, 7, -8, 2, -8, 8, 6, -8, -7, -3, 0, 2, 8, -13, 7, 13, -6, -4, 6, -13, -16, 14, 11, -7, 5 }, { 16, 28, -7, -1, 6, -3, 9, 0, -7, 3, 0, 3, -12, 20, 8, 9, 8, 23, 8, -13, -2, 4, 9, 3, -5, 13, 5, -2, 12, 14, 5, -1 }, { 19, 37, 19, 5, 7, 5, 10, 5, 19, 10, 14, 0, 2, 5, 1, -4, -4, 2, 2, -5, -2, -1, 2, -6, -4, -4, -5, -3, 2, -2, -2, -2 }, { 24, 21, 1, -11, -10, 17, -14, 14, 6, -1, -6, -1, 0, -13, -1, -12, -2, -5, 6, -4, -12, 14, 5, -2, -8, -8, 15, -7, -30, -12, 4, 0 }, { 11, 26, -3, 3, 5, -1, -2, 3, -2, 10, 15, -4, 10, -28, 10, -17, -8, 1, 2, -7, -1, -6, -15, -1, 4, 5, -7, 9, 0, -5, -4, 4 }, { 18, 32, 1, 2, -7, 4, 15, 2, -9, -2, 12, -11, 7, 11, 13, 2, 0, 5, 9, -10, 16, 3, -3, 5, -9, -23, 2, -2, -1, 5, 2, 11 }, { 35, 24, -20, 2, 4, -1, 5, 14, -10, -9, 8, -7, 0, 5, -7, -7, 11, 1, 5, 3, 2, 0, -2, 3, 0, 1, 4, 0, -2, -8, 0, -4 }, { 9, 35, -1, 2, -1, -19, -3, 12, -1, 8, 8, -13, -1, -2, 2, 5, -8, -1, 13, -2, 11, 1, 0, -10, 0, -3, -7, 2, 1, -12, 3, 12 }, { 20, 27, -12, -12, 7, 4, -1, -13, -1, -9, 2, 13, -11, 5, 7, -9, 9, 1, 1, 8, -9, 0, -6, 7, 4, 2, -2, 7, 3, -2, 1, -9 }, { 8, 37, -20, -5, 0, -21, 10, -8, 3, 19, -9, 7, -3, -8, 10, -2, 0, 5, 6, -4, -2, -1, 0, -7, 6, 1, 0, 4, -5, 6, -8, 2 }, { 8, 27, 1, -3, -5, 1, 6, 0, 15, 2, 17, -1, 3, -17, 10, 5, 5, -6, -6, 6, -10, 18, -5, 0, 0, 13, 7, 10, -5, -6, -2, -4 }, { 14, 29, -20, -4, -3, 1, -5, -1, 2, 12, -10, -3, 4, -18, 4, 14, -4, -1, -9, 15, -2, 2, -5, -3, 2, 9, -2, -14, -3, 4, -4, -7 }, { 23, 23, -23, -11, 27, 4, 4, -1, 7, 0, -5, 9, 2, -11, 3, 7, -2, -5, 2, -7, -7, 13, -3, -6, 2, 3, 3, -4, -1, -8, 5, -2 }, { 16, 26, -6, 8, -9, -1, -2, -1, -8, 4, -2, 0, -12, 9, -1, 0, -17, -9, 30, -5, -15, -16, -13, 0, 10, -11, -7, -3, -1, 0, -11, -2 }, { 12, 32, -4, -5, 10, 19, -10, 4, -12, 5, -6, 9, -12, -6, -6, -8, 4, 1, 3, 0, 8, 0, -3, -4, -7, -4, 10, 8, 6, 5, -1, 4 }, { 46, 42, -3, -14, -2, -6, 6, -2, -5, -1, -3, -3, 1, -1, 3, 1, 1, 4, -1, 2, 3, 1, -2, 6, 0, -1, -2, 4, -2, -1, 2, 2 }, { 9, 33, -13, 4, -11, 3, -8, 22, 12, -2, 4, 0, -16, 5, 4, -1, 7, -6, -9, 1, 7, 5, 0, -5, 5, -1, 10, 3, -2, -1, 3, -2 }, { 9, 30, 6, -3, 6, 1, -7, 5, 11, 14, 7, 1, 0, 2, 2, -1, 8, 7, -6, -13, -10, -2, 1, -6, 10, 7, 6, 5, -2, -5, -1, -16 }, { 9, 28, -11, -10, 9, -10, 15, 8, 4, 9, -4, -7, 0, -5, 9, 8, -7, 2, -15, -23, 4, -4, 4, 16, -8, -3, 0, -8, 14, 5, -3, 15 }, { 17, 26, -5, -5, -1, -8, 20, 18, -7, -2, 4, -7, -8, -5, -4, 16, 0, 0, -7, -2, -13, -5, -2, 3, 12, 1, 3, -5, 2, 2, 0, -1 }, { 11, 37, 7, -23, 6, -1, 15, 13, 4, -9, 7, 5, 3, -3, -5, -8, -2, 3, -5, -1, -8, 7, 2, 13, 1, 3, 0, -3, -1, 2, 0, -2 }, { 21, 33, 7, 20, 21, -10, 6, -5, -5, -6, -9, 2, 10, 0, 8, -4, 10, 2, -2, -2, 0, -10, -6, -2, 0, -5, 3, -11, 3, -9, -3, 1 }, { 6, 30, -15, -8, 16, 1, 4, 6, 4, 5, 8, -3, 8, -9, -1, -6, 8, 2, -2, 4, -2, 5, 11, -21, 3, -10, 16, -11, 24, 10, 14, -6 }, { 15, 36, -3, -9, -20, 12, 0, -7, -18, -4, -8, -9, 9, -7, -3, -1, 2, 7, -5, -8, 6, 2, 2, -1, 7, 1, 1, -3, 3, -4, -8, 1 }, { 16, 34, 21, 3, -9, 10, 7, 9, -7, 1, -4, -9, -4, -5, -5, 3, 3, -19, 1, 5, 4, -2, -6, -5, -10, -11, -8, -2, 2, -5, -8, -7 }, { 28, 29, -3, 18, -2, 0, -6, 12, -2, 10, -11, -4, -13, -12, -6, -4, 0, 4, -1, -8, 6, 4, 12, 11, 10, 10, -3, -6, 1, 2, 1, 7 }, { 3, 8, 22, -8, 3, 36, -8, -1, 9, 6, -13, -14, 8, -1, 1, 2, -2, -8, 0, 3, 1, 2, -1, 5, -1, -8, 0, -2, 2, 2, -1, 1 }, { 0, 6, 0, 0, 4, 13, -7, -16, -6, 15, -14, -21, -9, -10, -10, -6, -21, 5, 4, 2, 12, 4, 12, 11, -4, -6, -6, -10, -7, -18, 1, 4 }, { -1, 3, 10, 1, -1, 15, 4, -7, -16, 3, 0, -22, 10, 2, -3, -2, 13, 5, -8, 16, -5, 4, 0, -11, -10, -22, 0, -4, -17, 5, 2, 1 }, { 12, 8, -4, -9, 14, 40, -21, 0, 1, -15, -10, -12, 12, 6, -10, 2, 8, 6, -12, -10, -11, 1, 0, -11, 2, 1, 13, 0, 6, 3, 8, 4 }, { -10, 3, 5, -4, -3, 3, 0, -9, 2, 8, -22, -23, 17, 8, -17, -3, 14, -8, -4, 1, -8, 3, 0, 5, -1, -3, -2, -4, 1, -10, 0, -2 }, { 0, -1, 5, -7, 4, 12, -2, 0, -7, 2, -16, -15, 12, 21, -7, -4, 7, -7, -11, -15, -7, -9, -5, -8, 0, -6, 8, -3, -8, 22, -7, -9 }, { 7, 19, 4, -9, 24, 22, 2, -6, 8, 13, -14, -20, -4, 11, 8, -4, -1, 2, 0, -7, 5, -17, -3, 3, -6, 5, 3, 4, -5, -7, -3, 14 }, { -2, 6, 2, 8, -2, 5, -4, -2, -10, 3, -45, -30, -3, -3, -12, -4, -3, -3, -1, 9, -6, -6, 5, -4, 0, 5, -1, -2, -1, 0, -6, -1 }, { -3, 14, -16, -10, 10, 0, -2, -40, -9, 12, 2, -19, 15, -4, 4, 3, 3, -4, 7, 1, -4, -5, 0, 4, -1, 0, -9, -2, -4, -1, -2, 0 }, { 7, 16, 2, -7, 8, 2, 0, 1, 5, 21, -10, -26, 7, 2, -9, -7, -3, -16, 8, 5, 5, -6, 10, 4, -14, -6, 5, 3, -2, -2, -4, 1 }, { -9, 14, -1, 3, 3, 11, 1, -5, -3, 13, -16, -18, 20, 6, -5, 0, -3, 2, 8, 4, -19, -9, 12, 0, -8, 2, 2, 1, 6, 13, -7, -11 }, { 2, 5, 16, -4, 19, 15, 4, 0, -11, 7, -10, -10, -16, 18, -11, -12, -9, -4, 7, -4, -4, -17, 1, 1, -8, -3, -3, 5, -2, -6, -11, -5 }, { 2, 12, 0, -9, -10, 14, 6, 2, -3, 2, -12, -28, 12, 1, -1, 2, 0, -3, -4, 7, 16, 5, -7, 8, -4, -3, -1, 3, -12, 4, -17, -5 }, { -4, 7, 11, 6, 1, 14, -4, -6, 5, 5, -6, -24, 23, -9, -15, 13, -7, -9, -15, 10, -1, 8, -5, 1, 12, 6, 2, 0, 4, -2, 9, -10 }, { 1, 5, 11, 3, 6, 12, -3, 8, -21, 5, -7, -20, 12, -2, -9, -3, 17, -7, -8, -9, -14, 3, -13, 18, -8, 9, 2, -8, 4, -8, -5, -2 }, { -3, -3, -1, 5, -2, 15, 3, 2, 1, -8, 1, -39, -6, 13, -13, 0, -2, -5, -6, -3, 0, -5, -2, 15, -9, 5, -3, -6, -2, 7, 0, -13 }, { 2, 8, 5, -12, -13, 22, 8, -16, 11, 5, -2, -32, -2, -4, 11, 5, 5, -6, 1, 3, 1, 5, 3, 6, -5, 4, 4, -8, 8, 4, 1, 3 }, { 13, 9, 5, -4, 9, 18, -11, 2, -1, 15, -10, -19, -2, 14, 0, -10, 1, 1, -18, 3, 2, -6, -8, 20, 7, -8, 16, 9, 9, -13, -3, -2 }, { -13, 11, 11, -9, -10, 13, -3, -18, 2, 10, 5, -21, 6, 15, -11, -21, 3, 14, 0, -12, 9, -1, -2, -4, 3, -3, -9, -8, -5, -2, -8, 2 }, { 3, 3, 11, 4, 0, 13, 1, -8, 10, 13, -6, -26, 2, 12, -3, -5, 12, -2, 1, 8, -7, -17, -19, 5, 10, 7, -3, 2, -3, 0, 5, 0 }, { 5, 0, 3, -3, -9, 5, -15, -5, -5, 17, -5, -31, 0, 13, 13, 5, -1, -6, -14, 7, -8, 9, -14, -2, -16, -4, -4, -6, 6, -6, -10, 6 }, { 13, 3, 1, 7, -3, 4, -1, -2, -1, 4, -8, -32, -1, -4, 0, 3, -10, 7, 10, -10, 4, -1, 6, 2, -16, -9, 4, 3, 13, -23, -3, -4 }, { 4, 11, -4, -9, 4, 11, -12, -12, -12, 6, 1, -28, -3, 14, 18, -2, -12, 7, 15, -3, -5, -7, -3, 2, -6, 4, 4, -2, -5, -3, 2, -13 }, { 8, 7, -7, 0, 13, 7, -8, -7, 8, 36, -10, -22, 3, 23, -3, -10, -3, 11, 1, -7, 3, 3, -1, -7, -4, 2, 3, 2, 5, 3, -4, -1 }, { -1, 1, 13, 1, -6, -1, -6, -9, -18, 17, -5, -37, -1, -1, -6, -4, 1, -6, -15, 2, 17, -9, 0, -3, 0, 4, 0, -5, 0, 4, 1, -5 }, { 0, 14, 5, 0, -7, 2, -6, 17, -6, -9, 7, -16, -5, 23, -14, -13, 8, -15, 11, 10, -11, -13, -33, -5, -2, 1, 6, 8, 0, -13, -9, 5 }, { 11, 7, -2, -8, 9, 11, 25, -14, 7, 3, -1, -33, 14, 8, -6, -19, 3, 3, 2, -1, -3, -1, -2, -10, -3, 1, 2, 1, 4, 2, -3, 4 }, { -2, 8, 4, -2, 9, 13, -4, -2, -15, -3, 19, -37, 9, 25, -9, 2, -5, -2, -2, -4, 4, 2, 2, 0, 3, 3, 3, 5, -2, -3, -4, -3 }, { 10, 13, -1, -15, 4, 6, -18, -4, 25, 1, -23, -17, 15, 13, -8, -8, 7, 4, -5, 3, 6, 9, -7, 6, 0, -5, 8, 0, -6, -1, -2, -2 }, { 1, 3, 9, -5, 27, 15, -9, -31, -1, 23, -2, -9, 1, 8, -1, -7, -2, -8, -4, -4, -2, -1, 3, 5, 0, 0, -1, 1, -7, 7, -3, -3 }, { -8, 7, 3, -6, 8, 3, -11, -2, 36, 14, 1, -30, 6, 10, -12, -6, -6, -2, -4, -3, -5, 0, 9, 4, -5, -5, -8, 12, 4, -3, 1, -8 }, { -2, 9, 33, 0, 12, -3, -7, -4, -4, -1, 6, -25, 11, -6, -9, -11, -2, -4, -2, 6, -1, -3, -6, 15, -6, 3, 10, -4, 1, 0, 5, 8 }, { -22, -21, -9, -19, -5, -7, -12, -15, -8, 9, -19, 14, -7, -4, 5, -8, -2, 7, 1, -3, 4, -4, 6, 11, 2, 6, -3, -5, 2, -2, 0, -3 }, { -32, -13, 3, -24, 3, -8, 4, 1, -10, 14, -15, 0, 4, 6, -1, 6, 7, -1, 6, 4, -3, -17, 1, 4, -6, -1, 1, 0, 3, 3, -7, -4 }, { -32, -11, 7, -8, -12, 13, -5, -22, -4, 12, -16, 2, 0, 4, 0, 1, 0, 6, -5, -8, 2, 6, 5, 0, -3, -6, 5, 6, 5, 5, 13, -4 }, { -44, -33, 6, -4, 2, 0, -9, 10, 3, 4, 7, 0, -1, 7, 5, 1, 1, -3, 1, 6, -1, 0, 2, 3, -4, 0, 0, 1, 0, -1, -2, -1 }, { -30, -18, -24, -8, 5, 0, -2, 14, 7, 0, 1, 12, 6, 4, -9, 7, 5, 7, -11, -5, 1, -8, -1, 2, 2, -9, 7, -1, 7, 5, 6, 6 }, { -22, -20, -13, -9, 20, -3, 10, -8, 6, -4, 2, -7, 10, 8, 0, -1, 2, -3, 6, -19, 2, 4, 3, 3, -7, 2, -1, -6, 1, 1, 6, -2 }, { -27, -8, -1, 3, -1, -11, 24, 4, -1, 1, -8, 8, 5, -11, 15, -3, -15, -1, -1, -13, -1, 1, -5, 5, 2, 3, -9, 0, 4, 3, -7, 6 }, { -33, -16, -1, -8, 10, -23, 6, 13, -1, -3, -9, 0, 5, -7, -5, -12, -2, 3, 3, 6, -2, -3, 2, -3, 9, -6, -3, -2, 0, 5, -3, -4 }, { -22, -17, 11, -3, 3, 1, -1, -5, 17, 2, -15, -2, 10, -9, 6, 14, -16, -12, 20, -1, -7, 6, -3, -12, 1, 10, -10, -1, 7, -3, -1, 10 }, { -28, -13, 1, -3, -1, -1, 0, 3, 3, 5, 1, 10, -10, -3, 7, 2, 4, 19, -1, -1, 10, 5, -8, 1, 11, -15, -4, -3, -5, 4, -13, 3 }, { -22, -13, 42, -20, 5, -13, 7, -11, 1, 1, -1, 1, 6, 3, 6, -11, 3, 3, -2, 0, -4, 4, -3, -1, -5, 2, 0, 0, -9, -1, 4, 4 }, { -26, -15, -2, -6, -4, -2, 16, 8, 21, 8, 1, -3, -10, 7, -8, -12, -5, 12, -9, 3, -2, -3, 18, 1, -12, -15, -4, 5, -3, 0, 12, 7 }, { -26, -16, 5, 6, 14, -3, 15, 6, 1, -7, -13, 16, -15, 5, 11, -2, 9, -7, -4, -2, 0, 0, -2, 7, -8, -6, -5, 2, 7, -3, 2, 12 }, { -31, -17, -8, -30, 4, 14, 6, -6, 6, -11, 0, 3, -4, 0, 0, -4, 0, -4, 1, 4, 3, 4, 0, -5, 3, 2, 2, 0, 2, 1, 3, 5 }, { -61, -10, 4, 10, 4, 7, 0, -3, 0, 1, 0, -3, 0, 1, 0, -2, -1, 1, 2, -2, 4, -3, 1, 1, -1, 1, -2, -4, -4, 4, 0, 0 }, { -28, -13, -8, -4, 3, -3, 2, 1, 11, 14, 3, 9, 1, 13, 3, 5, -3, -2, -2, -12, -14, -9, -11, -15, -12, -5, -4, -12, 3, -3, 0, -5 }, { -41, 0, 12, -24, 13, 4, 5, 16, -5, -4, 0, 0, 13, -4, 1, -9, 9, -6, -1, 6, -2, 5, 2, 9, 6, -9, -8, 8, -2, -3, -6, -4 }, { -26, -19, -2, -15, 4, -14, 6, 0, 26, 20, 8, 9, 9, 3, -4, -5, -8, 1, 0, -1, 5, 9, 3, 4, 4, 7, 1, 3, -2, -2, -10, 0 }, { -29, -18, 9, -4, 1, -5, -14, -12, 5, -10, -5, 4, -5, 0, -1, -1, 4, -5, 7, -16, -11, 2, 7, -15, 2, -4, 6, -4, -6, 7, -3, 7 }, { -27, -16, 9, -14, 3, -8, 9, 0, 7, -4, -3, -7, 0, -10, -1, 2, 1, -2, 15, -10, 14, 7, 6, 17, 3, -4, 3, -10, 8, -8, 3, 11 }, { -21, -20, -8, -8, 4, 5, -3, -2, 0, -5, 14, -10, 11, -4, 13, 0, 5, -11, 19, -18, 18, 3, -5, -3, -4, -8, 11, -10, 10, 3, 4, -9 }, { -35, -15, 13, -12, 4, 0, -2, -4, -12, -3, -8, -24, -7, 1, 7, 8, -3, 0, -2, -1, 3, -2, -2, -6, 8, 1, 0, 1, -6, -1, 2, -6 }, { -19, -14, 13, -10, 9, -1, 1, 3, -12, 5, -16, 7, 13, 9, 4, -4, 6, -5, 4, 9, -3, 17, -4, 12, -11, -6, -5, -6, 13, 2, 7, -9 }, { -34, -8, -4, 1, 2, -1, 3, 6, -20, -11, 8, -1, 4, 2, -9, 4, -4, -5, 16, 10, -4, 14, -13, 1, -6, 0, 2, -10, 0, -3, -3, 7 }, { -36, -10, -8, -3, 2, -2, 14, -4, -1, -7, -4, 10, -1, -3, 15, -11, 0, 2, 3, -1, 4, 0, 8, -1, 0, 18, -11, -5, 15, -5, 13, -12 }, { -22, -13, 14, -20, 15, 25, 16, 10, 8, -2, -10, -5, -1, -8, 11, 8, -1, -2, -4, 1, 2, -1, -7, 0, 0, 0, -3, 0, 2, -1, 0, 2 }, { -31, -22, 7, 6, -2, 5, -20, 14, -6, 7, 0, 14, 3, -7, 3, -6, -2, 1, -3, -5, 1, -10, 1, -24, 6, -2, 3, -7, 1, -7, 8, 7 }, { -25, -20, -3, -9, 10, 6, 12, 7, 5, 4, -3, 6, -1, -5, -6, -8, 3, 5, 6, 5, -10, 10, -4, -15, -15, -2, -9, 2, 18, 1, 8, 12 }, { -24, -19, -2, -4, -7, 11, 6, 9, 16, 2, -7, 18, 6, -7, 6, 6, -2, -9, 3, 12, -2, 3, -1, 6, 7, 8, 0, 8, -11, 8, 4, 2 }, { -26, -20, -12, -12, -2, -3, 1, -5, -1, -2, 0, 3, 7, 9, -2, 2, 9, 22, 13, 4, -4, -1, -2, -14, 5, 15, -8, -5, -7, -11, -14, -6 }, { -21, -18, -1, -4, 0, 3, 7, -2, 10, 8, -8, -1, 15, 1, -9, 3, 1, 3, -5, -2, 2, 4, 0, -1, 10, 2, -19, -8, 8, 30, -7, 8 }, { -25, -6, 26, 4, -8, 4, -2, 21, 5, -4, -16, 5, 13, 4, -10, -1, -6, -2, 2, -10, -13, 1, 3, -3, -6, -8, 2, 11, 1, -7, 0, 5 }, { 0, -1, -2, 19, -12, -48, -6, 11, 8, -2, -4, -2, -7, 5, -3, 2, -2, -1, -1, -7, 0, -3, -3, -4, -4, 4, 1, 3, -3, -1, -2, -5 }, { -11, -8, -28, 18, 16, -24, -8, 19, 4, 8, -12, 9, -4, -2, 4, -7, 6, 2, 3, 3, -4, 0, 1, -6, -4, -2, 2, 6, 0, -3, 1, -16 }, { -9, -5, -26, 7, -3, -37, -16, -2, 2, -7, 4, -13, 0, -4, -6, -5, -6, -4, 0, 3, 4, -3, -4, -4, 4, -3, 9, -4, -2, 2, 7, -4 }, { 2, 9, -18, 7, 29, -24, -1, 7, 14, 10, 3, -3, -2, -5, 6, -10, -6, -3, -8, 0, 5, 1, 4, 3, -12, 2, 6, 1, 3, 4, 1, -3 }, { -20, 2, 8, 20, -9, -24, -4, 18, 3, 11, -1, -11, 6, 9, -1, -3, 1, -1, -15, 3, 15, 9, 3, 2, -13, 2, -8, 8, 1, -1, 1, -8 }, { -12, 5, -11, 6, 19, -26, -17, -6, 4, 14, 6, -8, 9, 5, -6, -5, 2, -1, 20, 1, -11, -10, -18, 20, -7, 0, -3, 4, 2, 0, 10, 4 }, { -15, 1, -2, 13, -8, -21, -22, 4, 4, 3, 3, -7, -31, 4, -10, -14, 0, 8, 4, 5, 8, 11, 2, -8, 6, 7, 0, -2, 6, 8, 8, 7 }, { -13, -10, -9, 12, 19, -16, -3, -2, 9, 2, 11, -29, -1, 9, 4, -3, 1, -10, -10, 16, 1, 7, -7, -6, -4, -1, -5, 3, 6, 0, 3, 1 }, { -17, -1, -5, 19, 12, -9, -21, -5, 2, 12, -7, -7, -3, 8, 7, -2, 6, -9, -9, 1, -4, 1, 1, 3, -14, 2, -8, 0, 10, 1, -12, -6 }, { -13, -5, 8, 15, 0, -20, -2, 20, 8, -8, 8, -19, 12, 10, 2, -11, 0, 12, 1, -11, 0, -11, -15, 5, -11, 2, 4, -4, -11, 5, -4, -5 }, { 3, -11, -7, 8, 0, -17, -26, 15, 19, -7, 10, -9, -5, -5, 14, -25, 0, -8, 2, -9, -3, 9, 1, -6, 4, -4, 3, -9, -1, 6, 2, 2 }, { -12, 5, 5, 9, 14, -18, -19, 4, 2, 16, 14, -21, -15, -9, -1, 16, 12, -11, -10, -5, -7, 4, 15, -8, -5, -1, 1, 14, 13, -7, -1, -4 }, { -10, -5, -1, 8, 7, -23, -10, 14, 6, 11, 10, -16, -3, 16, 6, 0, 0, 9, 6, -2, -7, 1, 22, 5, 3, -8, 0, 3, -2, -10, 3, 0 }, { -2, -14, 2, 16, 15, -17, -17, 6, 19, 4, -10, -15, -1, 15, 11, -14, -8, 5, 8, 8, -2, -8, -11, 10, 10, -8, -14, 2, 13, 4, -2, -12 }, { -10, 3, 6, 4, 19, -23, -19, 1, 4, -9, -30, 3, -6, 18, 0, 2, 0, -11, 0, 3, 7, -2, 8, 5, 2, -3, 6, -9, 1, -4, 7, -6 }, { 9, 5, -2, 21, 20, -33, -13, 7, -10, 8, 8, -15, -6, -4, 1, 5, 3, 7, -2, -9, -1, 4, -6, 1, 0, 9, -1, -5, 2, 1, -3, 3 }, { -9, -3, 3, 15, -3, -30, -7, -7, -25, 6, 2, -6, 1, 19, 1, -12, 1, -8, -13, 9, 13, 1, 8, 2, 5, 15, -2, 3, -9, 0, -4, 4 }, { -6, -12, -17, 25, 22, -13, -10, 9, 2, 11, -7, -16, 4, 6, 1, 0, 0, 18, -4, -5, 4, -2, -1, -5, 0, -4, 6, 1, 6, -1, 7, 0 }, { -1, 0, -10, 8, 8, -27, 0, -2, 29, 16, -2, -4, 9, -1, 2, 0, 6, 10, 6, 4, 2, -7, 9, -18, 3, 3, 3, -10, 17, 10, 9, -6 }, { -3, -12, -6, 11, 20, -32, 5, 21, 3, -4, -9, 2, -10, 1, 7, -4, 5, 0, 0, -1, -8, -9, -7, 4, -10, 5, 0, 2, -5, 4, 9, 1 }, { -5, -1, -5, 1, 2, -19, -13, 1, 6, 12, 2, -16, -17, 11, 10, 13, 16, -12, -11, 3, -6, 0, 6, 4, -3, 1, 8, 2, 5, -11, 3, -14 }, { -19, 5, 10, 11, 2, -23, -9, 16, -2, 7, 0, -11, -7, 10, 6, -7, 26, -15, -4, 8, 6, -4, 7, -9, -15, 1, 8, -4, 4, 2, -12, 16 }, { -11, 1, 11, -4, 1, -31, -13, -1, 8, 5, 4, -2, 0, 13, 7, -17, 7, -10, -6, 1, 4, -1, 2, -9, -4, 9, 3, 3, -4, -5, 3, 4 }, { -3, 1, 10, -1, 0, -15, -22, 4, 40, -11, -4, -3, -14, 9, 11, -1, 9, -1, -6, 6, 3, -6, 0, 0, -12, 7, -2, 0, 9, 3, 1, 3 }, { -1, -1, -1, 14, 8, -24, -14, -8, 5, 8, 5, -12, -17, 8, 2, 7, 10, -8, 0, 4, -6, -6, -10, 8, 4, -12, 3, -9, -12, 5, 4, -3 }, { -5, 1, -11, 8, 9, -24, 0, 2, 2, 14, -12, -13, 1, 6, 7, 0, 7, -6, 9, 26, 11, -14, 8, 10, 1, 9, 0, 11, -2, 6, 2, -10 }, { -13, 1, 4, 34, 19, -17, -15, 0, 3, -2, -7, -1, 0, -3, -3, -1, 1, -1, -10, 8, 5, 0, -8, 4, -17, 9, -2, 0, 0, 6, 2, -3 }, { -6, -4, 1, 2, 2, -14, -29, 0, 9, 34, -3, -5, -14, 6, -10, -9, -5, -1, 0, 3, 3, 0, 1, -1, -2, -1, -1, -3, -3, -4, 3, -3 }, { -4, 6, 3, 14, 14, -8, -29, 31, 11, 14, -4, -5, -6, 10, 6, -9, -1, -11, -7, 1, 7, 4, 1, -6, 4, 0, 10, -7, -5, -1, 2, 4 }, { -4, -4, -2, 14, 6, -32, -6, -14, 14, -5, -11, 10, -18, -4, 6, -8, 9, 5, -4, 1, -4, 5, -2, -9, 3, 5, 2, -10, -6, -17, 3, 17 }, { -16, 9, 21, 19, 4, -20, -17, 14, 9, 15, -6, -17, -1, 1, 6, -3, 1, 1, 8, -3, -6, 6, 9, 4, 9, -9, -5, 1, -1, 0, -1, 2 }, { -7, -5, 3, 19, 1, -20, -9, 14, 21, -7, -18, -9, 26, -7, -17, -7, 12, 6, 0, -9, -6, 14, 9, -9, -8, 4, 15, -7, -9, -1, 9, 1 }, { -20, 30, -6, 11, 24, -4, 0, -6, -2, 8, -4, 12, -8, -17, 0, 5, -4, 1, -1, 3, -3, 5, 3, 3, 7, -2, -3, -2, 4, 0, 0, -1 }, { -35, 17, 6, 1, -9, -1, -16, 3, -20, -13, 8, 7, -4, -7, -4, -20, 7, 12, -5, 5, -5, -11, 12, -1, 15, -9, -6, 16, -4, -9, -13, 4 }, { -21, 36, -19, 9, 0, -7, -8, 9, -4, -3, 3, 0, 7, -8, -2, -2, -11, 13, -1, 5, -3, 7, 2, 3, -1, -2, -5, 1, -1, -2, -5, -3 }, { -12, 33, -4, 1, -12, -9, 0, -13, -1, 2, -8, 4, -10, 6, -16, -7, -1, -4, -10, 15, -1, 0, -5, -8, 5, 5, -3, 0, 2, -7, 1, -7 }, { -14, 32, 5, -7, -15, 3, -5, 8, 14, 5, 9, 13, 3, 18, -3, 7, 4, -10, -10, 10, -1, 2, 0, -2, -11, 5, -3, -4, 2, 2, 7, 4 }, { -14, 34, 1, 20, -1, -12, 0, -3, -7, -4, 7, 18, 9, -3, 14, -7, -9, -20, -7, -4, -13, 12, 1, 12, 5, -6, 2, -4, 0, -15, 1, 3 }, { -21, 23, 7, -8, 3, -13, -3, 0, -6, -2, -7, 6, -12, 9, -6, -2, -2, -4, -1, 6, 9, 5, -9, 15, 0, 8, -8, 7, 6, -15, 3, -5 }, { -27, 32, -1, -4, -2, 4, -10, 12, -3, 8, 13, 7, 0, -15, 4, -2, 3, 5, 7, -4, 9, -12, -1, -2, -1, -4, 0, -4, 2, -5, 6, -6 }, { -17, 29, 15, 0, -1, -4, -10, 13, 12, -1, -8, -10, -10, 4, 7, -2, 6, -5, -13, 19, 6, 1, -7, 2, -9, -2, 12, -4, -8, -3, 2, 4 }, { -38, 27, 16, -15, -6, 3, -7, -4, 0, -1, 6, -2, -3, -6, 6, -6, -3, 0, 2, 0, -4, 6, 1, -1, 0, 4, -1, 3, 4, 1, -2, 5 }, { -33, 40, -4, 2, 1, 0, 0, -10, -14, 0, -7, 4, -1, 3, -2, 5, 7, 6, -1, 4, 1, 3, 1, -7, 1, -4, 5, 7, 0, 4, 3, -4 }, { -20, 25, 12, -4, 16, -4, 2, 2, -14, -2, -3, 29, -1, 1, 3, 1, 9, -5, 2, -8, -3, 1, -7, -2, -7, 1, 0, 4, 16, -2, -1, -1 }, { -10, 30, 17, 3, -5, -2, 0, -5, -22, 4, 5, 5, -3, -18, -6, 10, -5, -7, 2, 8, 7, -7, -11, -2, 0, -3, 3, 2, 11, -4, 4, -4 }, { -11, 30, 11, 4, -3, -8, 1, -2, 4, 18, 3, 1, -1, 0, -8, -4, -3, 10, 13, 14, 5, -5, 1, 1, -10, 2, 15, 4, 9, -1, -5, -3 }, { -17, 32, 18, -18, -3, -5, 6, 10, 1, -15, -5, 9, 8, -12, -10, -6, 11, 9, -5, -8, -7, 10, 5, -10, -14, -4, -3, 1, 9, -11, 2, 1 }, { -13, 28, -11, -1, 2, -16, -2, 7, -24, 0, 3, 6, 3, -1, -8, -7, -12, 2, 2, -20, 10, 4, 0, -13, -2, -2, 1, 8, -14, 0, 4, 1 }, { -14, 23, 12, 8, 8, -26, 2, -4, -14, 13, -14, 15, 3, -9, -1, -13, -10, -2, -10, 6, -16, 12, 8, 0, 9, -10, -7, -4, -4, 7, -8, 8 }, { -20, 45, 10, -14, 4, 16, 8, -9, 1, -8, 10, 5, -7, -2, 2, -5, -1, 0, -5, 4, -6, -2, 4, 1, 3, 4, -4, 2, -2, -2, 5, 1 }, { -20, 26, -4, 1, 7, 4, -8, 1, -5, -13, 2, 13, -7, -3, 6, -6, 22, 0, 5, 11, -4, -11, 8, -9, 2, -2, -4, -2, 2, -13, -4, -8 }, { -28, 18, 17, 3, -8, -23, -16, -6, 5, -10, 14, 10, 5, -1, -8, 4, -2, 13, -3, -2, 3, 4, 3, -2, -3, -4, 0, 1, 3, 4, 0, 4 }, { -12, 32, -6, -16, 18, 12, -16, 0, 7, 13, -4, 5, -8, -1, -3, 4, 6, -2, -1, -13, 4, -1, 3, 12, -3, -10, 1, 6, 8, -11, -2, 4 }, { -18, 26, 2, 5, 0, -9, -17, 14, 5, 1, 7, -3, -8, -3, 11, 7, -5, -12, -8, 7, 0, -7, 2, -12, -9, 13, -11, 9, 6, -11, -5, 11 }, { -24, 22, -15, -9, 8, 1, -7, -12, -9, 3, 11, 15, 14, -11, 12, -15, -5, 7, -2, 0, -8, 3, 3, -1, 2, 11, -11, 14, -6, 13, 1, -6 }, { -20, 28, 18, -4, -6, -5, 12, 14, 2, 10, -13, -6, -8, -6, -13, -1, -26, 22, -3, -14, 6, 0, 10, -15, -13, -9, 6, -7, 1, -5, -4, -1 }, { -19, 26, -8, -3, -14, -6, -9, -4, -8, 15, -8, 3, -12, -4, -2, -7, -5, 3, 13, -3, -4, -25, 4, -1, 5, -12, -1, -13, 5, 2, 0, 6 }, { -18, 43, 14, -8, 1, -23, -2, -2, 1, 3, -7, 0, 0, 8, -1, -3, -5, 1, 5, 2, 0, -2, -2, -2, 1, -1, -1, -7, 0, 3, -3, 9 }, { -11, 30, 10, -14, 3, 1, 10, -11, 1, -7, -4, 14, 2, 1, -9, 1, -11, -2, -7, 5, -11, 1, 3, 14, 1, -16, -8, 3, -5, 7, -4, 4 }, { -18, 24, 6, 3, 8, 7, -22, -7, -7, 3, -8, 4, 23, 9, 3, -1, 3, 6, 7, -1, -7, 6, 4, 1, -3, 1, -6, -1, 2, -7, 3, 3 }, { -15, 38, -7, -1, -11, 2, -17, -24, 24, 8, 7, -4, -5, 2, 2, -7, 1, 4, 0, -9, 5, 0, -1, 1, -1, -5, -6, 3, 0, 7, 8, -3 }, { -14, 22, 1, -5, 9, -12, -9, -5, -6, 5, 7, 8, -1, -4, -9, -3, -33, -16, -9, -1, 12, -11, 17, -7, -3, -1, -7, 3, 2, -3, 16, -4 }, { -14, 20, 6, 4, -10, -4, -4, -4, 1, -7, 2, 6, 8, -12, 4, 1, -1, 12, 10, 3, -14, -10, -3, 18, -2, 33, -5, -17, 17, -5, 9, 7 }, { -12, 23, 13, 0, -11, -8, -11, 12, -5, -9, -16, 11, 6, 4, 12, -5, 5, -13, 7, -12, -3, 1, 2, 12, 1, -4, -1, 5, 4, 11, -12, -3 }, { 15, 2, 14, 7, 1, 2, 1, 12, 10, 23, 4, 6, -20, -10, 4, 26, -6, 13, 4, 3, 2, -11, 5, -7, -10, 4, 9, 1, 10, -4, 11, 4 }, { 17, 15, 31, 17, 18, 16, 11, 24, 2, 4, 2, 3, -8, -3, 7, -3, -5, -7, -2, -6, -4, -5, -4, -1, -4, -2, -5, -6, 2, -1, 4, -2 }, { 16, 8, 15, 14, 3, 7, 21, 9, 8, 15, 21, 6, 8, 12, 5, -5, 7, -3, 10, 2, -3, 8, 6, 0, 5, 5, 6, -3, 2, 4, 0, -5 }, { 5, -4, 6, 12, 6, 13, 24, 17, -5, 17, -1, -6, -7, -10, -8, -18, 3, -2, 2, 7, -15, -11, 12, -3, -2, -2, -4, -7, 2, 0, 5, 5 }, { 10, -6, 8, 11, 12, 20, 22, -11, -3, 15, -3, 15, -2, -2, 0, 2, 5, -8, 4, -5, -9, -4, -1, 2, -1, -3, 1, 3, 13, -1, 9, 7 }, { -5, 8, 5, 11, 14, -5, 14, -9, 2, 35, 8, 15, 1, -2, 2, -2, 4, -9, -3, -14, -12, -2, -2, -4, -2, -8, -3, 1, -6, 3, 10, 0 }, { 16, 0, -6, 15, -3, 4, 4, 3, 3, 20, 5, -4, 10, 9, -9, -3, -10, -2, -7, 11, -11, -10, 17, -1, 3, -15, 2, 9, -15, -10, 16, 10 }, { 14, 4, -7, 19, 3, 0, 19, 8, 16, 34, -9, 6, -13, -1, 6, 5, -1, -2, 4, 3, 2, 1, 1, -1, 0, -7, 2, -1, 1, 0, 6, -1 }, { 1, 6, 9, 13, 9, 10, 15, 16, 10, 18, 13, 17, 3, -1, -7, 2, -15, -11, -10, -4, -13, -6, -17, -13, -6, -14, 1, -10, 6, 4, -1, -1 }, { 13, 1, 7, 10, 14, 13, -7, 5, 5, 28, 14, 14, -2, 2, 3, -3, -13, -4, 10, -9, 19, -4, -3, 4, -5, -5, 0, 5, -5, 0, 3, -4 }, { 1, 0, 6, 22, 9, 18, 18, -3, 5, 10, 12, -2, 1, -3, -8, -12, 9, -10, -7, 1, -1, 19, 0, 2, -8, -11, -10, 9, 6, 11, 0, 3 }, { 10, 11, 19, 44, 0, 14, 1, -7, 6, 22, 2, -1, 9, 2, 0, -4, 4, 0, -6, -6, 3, 0, 0, -2, 2, -5, 1, -2, 0, 1, 1, 1 }, { 5, 7, 0, 32, 30, 26, 5, 4, -7, -3, 15, -6, 3, -10, 7, 6, -8, -7, 2, -13, -5, -1, -3, 7, 3, -2, -8, 0, 6, 4, 5, 0 }, { 9, 8, -2, 4, 2, 11, 4, 29, -5, 14, 8, -5, -14, 8, 0, 9, 8, -10, 5, -15, -6, -9, 9, -1, 18, -16, 9, -21, -3, -13, -2, 8 }, { 25, 7, -9, 23, 20, 18, 6, 16, -9, 8, 8, -5, 11, 13, -8, 7, 4, 10, -2, -1, -7, -9, -7, -9, -4, 1, 1, -5, -10, 8, 4, -5 }, { 9, 2, 16, 14, -5, 14, 1, 0, -21, 17, -1, 9, 12, -3, -3, 4, -4, 14, 10, 3, 0, -10, 7, 4, 4, -11, 2, 4, -1, -3, 9, -1 }, { 17, 8, 11, 26, 15, -3, 14, -1, 12, 9, 10, -8, 8, -18, -11, -3, -14, -7, 7, -3, -3, -4, 1, -7, -3, 2, -3, 16, 10, 0, 9, 6 }, { 9, 8, 3, 8, 18, 14, 11, 1, 10, 6, 1, -4, -16, -2, 14, -2, 1, 8, 12, 14, 3, -3, 8, 8, 12, -15, 3, -3, 3, -2, 14, 10 }, { 22, -3, -11, 13, -7, 11, 4, 11, 3, 14, 0, -6, -2, -9, 4, 2, -2, 0, -5, -27, -10, 3, -1, 5, 8, -24, -3, -11, -3, 2, 11, -1 }, { 19, 2, 8, 36, 5, -6, 3, 15, -3, -4, -5, 14, -10, 1, -12, -10, -3, -4, 3, -2, 1, -8, 4, 3, 5, -3, 0, 4, 8, -2, 8, 4 }, { 8, 14, 15, 9, -4, 10, 5, 11, 9, 10, 8, 9, -15, 15, 6, -8, -10, -13, 5, -8, -20, -13, -6, -11, -1, -3, -6, -4, -1, 0, 13, 15 }, { -2, -1, 9, 12, 2, 2, 13, 3, -23, 33, 15, 2, -4, -1, 3, 8, 8, 6, 6, -7, 8, 6, 9, -1, 3, -8, 0, -4, 1, -8, 11, -1 }, { 6, 5, -6, 16, 2, -3, 31, 21, -9, 12, 0, -1, -4, 1, -12, 3, -13, -18, 2, -11, -9, 2, -8, -6, 11, -3, -1, 0, -1, 0, 13, 5 }, { 5, -1, 2, 0, 25, 5, 10, 16, -5, 21, 14, 12, 13, 2, -5, 5, 5, -3, -2, -14, 0, -12, 7, 11, -1, -7, 19, -1, -1, -1, 8, -1 }, { 10, 7, 3, 11, 0, 8, 22, 3, 3, 19, -4, 12, 15, 9, 5, 15, 2, 1, 2, -10, -10, 0, 2, -1, 0, 1, -12, -1, 21, 16, 9, -7 }, { 11, -4, -5, 24, -7, 11, 20, 11, -15, 18, 5, -13, -15, 0, -5, 9, 1, 0, -1, -9, 4, -8, 6, -8, 1, -2, -7, 20, 9, 3, 9, 3 }, { 20, 0, -12, -6, 9, 31, 9, 12, 8, 27, 15, 7, -16, 5, -3, -7, -1, -9, -2, -7, -3, 4, -8, -3, 3, -6, -2, -2, -3, -6, -1, 2 }, { 6, -6, 48, 8, -3, 19, 12, 11, -7, 2, 3, 0, -1, 1, 8, -4, 4, -6, 0, -4, -4, -3, 3, 6, 3, -13, -8, 5, -3, -7, 8, 5 }, { 7, -2, 6, 11, 12, 2, 14, 4, -5, 12, 2, 9, 4, 2, 0, -1, 2, 0, -15, -9, -16, -2, 8, -17, -5, -22, -19, -5, -1, -10, 1, -2 }, { 11, -9, 3, 12, 6, 6, 1, 17, -6, 19, 14, 7, -7, -1, -1, -9, 9, -11, -17, 0, -6, 16, 0, 1, 9, -24, 3, 3, -9, -3, 3, -2 }, { 9, 0, 1, 8, 1, 7, 2, -5, -3, 8, -1, 7, 2, 6, -3, -6, 5, -2, 6, -2, -4, -3, 0, -3, 13, -50, 1, -2, 2, 4, 4, 3 }, { 7, 0, 26, 21, -4, 2, 17, 8, 7, 11, -7, 1, -1, -15, -1, -15, -11, -4, -17, -4, 1, -7, 3, 6, 3, -9, 2, 3, 6, 10, 6, 12 }, { 1, -2, 2, -1, -10, -4, 6, -3, -5, -2, -8, 2, 2, 2, 8, 0, 1, 1, 6, 0, 11, 13, 3, 4, 0, -12, 11, -5, 19, 20, 2, 5 }, { 5, 3, -13, -2, 1, -12, 11, -7, -12, 7, 10, 0, 7, 0, -2, 4, -6, -9, -11, -12, -23, 12, 10, -3, 0, 6, 19, -1, 24, 18, 9, 12 }, { 6, -3, 2, 5, 2, 2, -2, -5, -8, -11, -4, 3, -8, -4, 5, -3, -16, -4, 3, -12, -4, 3, 32, 7, 2, 8, 32, -18, -1, 12, 1, 7 }, { 0, -8, -1, 0, -8, 7, -8, -1, -1, 4, -12, -1, 3, 0, 1, -18, 8, 8, -14, -10, -11, 19, 9, 5, -7, 6, 8, -4, 26, 12, -1, 6 }, { 3, 5, -14, 7, 14, 8, 20, -13, -16, -10, -2, 17, -7, 4, -8, -9, 14, -5, 3, -4, -12, 7, 14, -10, -19, -20, 35, 8, 13, 14, -2, 9 }, { -2, -4, -1, 1, -3, 0, -1, 1, 2, 2, 6, 0, 0, 4, 5, -2, 3, 3, 3, -2, -7, -3, -3, -1, 6, -2, 29, 22, 13, 34, 0, 14 }, { -3, -9, 3, 1, 5, -4, 2, 0, 7, -9, 0, 2, -5, -3, 0, 6, -1, -1, -1, 2, 2, 4, 8, 7, 20, -6, 7, 16, 33, 20, 6, -1 }, { -11, 1, -3, -3, -11, 3, -9, -25, -1, -16, 4, -8, 15, 1, -2, 7, 8, 23, 2, 18, -13, 16, 3, -7, 6, 3, 16, -8, 12, 16, 3, 4 }, { 0, 5, 5, -5, 1, -1, 2, -3, -2, 1, -13, 2, 2, 10, 6, 7, 18, 18, 7, 9, 8, 9, 21, 14, 7, 12, 15, 14, 15, 12, 11, 5 }, { 1, -5, 11, -2, 17, 8, 3, 0, -1, 6, 11, -7, 6, 6, 7, 5, -15, 14, 1, 11, 4, 10, 12, 1, 2, 4, 30, 1, 11, 1, 6, 13 }, { 2, 4, 3, -7, 5, 8, -11, 7, -5, 9, -10, 6, 8, -10, -3, 10, 1, -29, -4, -26, 5, -8, 13, 4, 3, 6, 35, 1, 3, 6, 3, 0 }, { -2, 1, 0, 0, -1, -3, -7, -3, -9, -3, -1, -6, 3, 4, 4, 0, 5, -1, -2, -2, -1, -4, -10, 8, 0, -6, 10, -4, 46, 12, 2, 28 }, { 4, -1, 4, 1, 0, 4, -2, -2, -2, -1, 2, -4, 1, 5, 0, -3, 1, 1, -2, 0, 1, -2, -1, -1, 3, -6, 35, -11, 13, 53, -3, -1 }, { -5, -2, 0, -13, -16, 5, -12, -11, 1, -30, 3, -18, -24, -8, -5, -19, 1, -3, -8, 7, -7, -8, 15, -19, 4, 10, 30, 24, 6, 1, -9, 10 }, { -4, 8, -7, -4, -6, 12, -1, -9, -4, 2, -9, 3, 2, -2, 4, 2, 22, 9, 4, -5, 0, 5, -2, -9, -3, 1, 18, -12, 18, 16, 4, 16 }, { -5, -8, -3, -5, -3, 6, -7, -3, -2, -5, -3, 1, 2, 2, 4, -6, 10, 3, 12, -3, 20, 0, 27, -4, 16, 5, 18, -3, 23, 4, 12, 11 }, { 0, 1, 0, 1, -2, 1, 2, 1, -1, 0, -2, 2, -2, -4, 1, -2, -2, -1, -5, -2, 0, 0, -2, 2, 9, 7, 63, 5, 12, -1, 1, 0 }, { 4, -3, -7, -5, -11, -5, -12, -10, -10, -12, -15, -12, -14, -14, 1, 1, 10, -10, 16, 6, 2, 9, 11, 9, 9, 8, 12, -1, 13, 12, 6, 3 }, { 7, -3, -2, 4, 6, -8, 2, -3, -12, -5, -9, -8, -10, 15, -2, -4, 8, 9, 7, -13, -18, 34, -5, 7, 12, 22, 16, -11, 13, 25, -15, -11 }, { -3, -2, 0, -4, 1, 0, -3, -13, -7, 13, 12, -7, -10, 13, 19, 6, 16, 15, -12, -15, -3, 34, 1, 5, 1, -9, 11, 21, 8, 17, -5, -6 }, { 3, -5, 0, -4, 0, 4, -11, 4, -7, -3, -1, -8, 3, -2, 2, 1, 11, 5, 6, 14, -3, 2, -4, -7, 0, 31, 15, -2, 24, 11, 5, 4 }, { -1, -4, -9, 5, -8, -18, -4, -9, -20, -18, 7, -14, -16, 3, 8, -3, 29, 11, -13, -13, 7, 1, 17, 6, 6, 21, 11, 1, 14, -8, 2, 5 }, { -3, 8, -10, -6, 12, 2, 1, 3, 3, 3, 3, -6, -8, -14, 15, -5, 16, 4, 16, 0, 7, -1, 0, 16, 2, 1, 22, 4, 19, 13, -11, 1 }, { 2, -3, 10, 20, -4, -1, -8, 5, -8, -9, -6, -2, -4, -7, 8, -10, 0, 8, -6, 1, -8, 14, 13, 5, 17, -6, 26, -1, 7, -1, 0, 12 }, { -4, -7, -31, -2, -7, -1, 5, -5, -5, -12, 4, -7, -6, 3, 15, -2, 5, -2, 7, -1, 10, 7, 8, -1, 14, 20, 14, 9, 16, 16, 8, 24 }, { -7, 0, -3, -6, 1, 3, -13, -6, -4, -4, -5, -9, -1, -10, -4, -8, 2, 0, -1, 1, 24, 24, 21, 31, 5, 2, 11, 12, 7, 4, 3, 6 }, { -3, -5, 6, -4, -3, -1, 2, -1, -2, 1, 0, -8, -1, 2, 0, -4, 6, 22, -1, -5, 8, 12, -1, -2, 28, 27, 20, -27, 14, 1, 2, -3 }, { 1, -5, -2, -2, 6, -2, 9, 1, -2, -5, 3, 4, 11, 5, 2, 8, -3, -1, 1, -2, -3, -5, 5, 8, 49, 12, 8, -3, 9, 20, 12, 17 }, { -6, 0, 1, 7, 0, 9, -2, -4, 8, 0, -2, -10, 0, 7, 21, -1, 0, 1, 17, -7, -5, 2, 4, 16, -2, 17, 14, -20, 15, 14, 4, 15 }, { 0, 3, -4, 9, -4, 0, 6, 4, -6, -6, -5, -7, 2, -9, -10, -2, -5, 0, -3, -21, 9, 14, -11, 13, 29, 2, 25, 4, 22, -1, 2, -3 }, { 2, 12, -11, 2, 16, 9, -4, 7, 1, -10, -15, 11, -4, 3, -2, 4, 4, -5, -10, 1, 4, 19, -15, 6, -4, -2, 30, -7, 11, 21, -12, 5 }, { -2, -3, -2, 4, -1, -5, -3, -7, -5, 1, 0, -6, 1, -6, 7, 0, 8, -7, -3, -2, 2, 14, 2, -3, -26, -1, 26, 22, 32, 1, -2, 6 }, { 1, -38, -1, -20, -2, -3, -6, -4, 2, 2, 7, 0, 3, 5, 3, 10, 6, 1, -3, -5, 7, 5, -5, -4, 8, 3, 1, -14, -1, -9, -5, -4 }, { -5, -26, -7, -19, -10, -5, -11, 5, -11, -25, -8, -14, -9, -16, -8, -6, -17, -14, -1, -1, 6, 2, 2, 2, 3, 0, 2, 8, -8, 3, 0, -3 }, { 17, -49, -3, -23, -1, 11, 7, 3, 4, -4, 0, 0, -1, 4, 2, 4, -2, -4, 2, -2, -1, -2, 2, 0, 0, -1, 0, 0, 1, 2, 0, 0 }, { 4, -34, -6, -9, 1, 21, -7, 3, -2, -1, -3, 18, 2, -16, 7, -3, 8, 7, -5, 7, 2, 4, 8, -6, -7, -2, -5, -1, 4, 1, 2, -4 }, { 5, -29, 13, -2, -14, 3, 1, 18, -15, 4, -8, 8, -10, 8, 2, 1, -8, 15, 3, -10, -4, -4, -2, 0, -3, -4, 2, -3, -4, -3, 12, -6 }, { 13, -20, 3, -18, -17, 4, -14, 13, 28, 11, -8, -6, 16, 6, 0, 10, 3, 4, -9, 13, 5, -7, 12, -5, 0, -7, 5, 1, 3, 3, 2, 1 }, { 3, -27, -5, -11, -21, -11, -12, 0, -5, 7, -22, 1, 3, 5, 0, -5, 8, 7, 1, -5, -7, 2, -5, 4, 1, 3, -8, -2, 0, 4, -2, 6 }, { 31, -45, 0, -1, -12, 1, 2, -6, 4, 3, -1, 3, 3, 0, 5, 3, -5, 12, 4, 6, 2, 1, -2, 1, 3, 2, 5, 2, 2, 2, 3, -1 }, { 9, -45, 6, 5, -1, -17, -2, 18, -3, 2, 0, 1, 0, -1, 10, 8, -7, -2, -5, -8, 6, -1, 0, 4, 6, -3, 12, -1, -2, 0, 5, -7 }, { 3, -26, -2, -12, -12, 2, -10, 16, -3, 12, 4, 5, 11, 8, -16, -17, -2, -3, -3, 2, 5, -9, 13, 1, 10, 11, 3, 5, -2, 2, 2, -7 }, { 8, -26, 32, -7, -5, 22, 2, 14, -10, -8, -7, 3, 3, 7, 0, -5, 0, -1, -3, 0, 8, 4, -5, -7, 6, -1, 4, 8, 1, 1, 7, -6 }, { 4, -31, 2, -14, 2, 0, 1, 8, -6, -1, 17, -3, 13, -6, 5, -10, -2, -10, -2, -10, -3, 7, 1, 5, -8, 8, -14, -3, -15, 7, -10, -6 }, { 16, -27, 13, -4, -23, 7, -9, 6, -7, 5, 4, 2, -1, -3, 23, -18, 7, 0, -3, 4, -3, 9, -6, -2, -1, 8, -6, 2, 6, -3, 2, -2 }, { -1, -35, -2, -8, 11, -1, -7, -3, -2, 11, 7, 6, -6, -10, 9, 6, -3, -5, -6, -3, 9, 16, -16, -9, -20, 12, 3, 5, -3, 1, -9, 4 }, { 2, -24, 1, -12, -16, 5, -4, 3, -4, -1, -11, -11, -8, -14, 14, 10, -8, 20, 8, -3, -11, 1, 1, -4, -4, -7, -3, 15, 2, -6, -2, 7 }, { 9, -21, 2, -19, -7, -5, -8, 25, 3, 17, 5, -3, 9, -12, 8, 2, -4, 3, 3, 1, 11, -9, -4, -3, 4, 3, -22, 6, 4, 6, 11, -5 }, { 16, -23, 13, -17, -21, -12, 5, 9, -20, 7, 6, -6, 0, 2, -9, 6, -6, -13, -7, -1, 5, -3, 5, -7, -10, 1, 0, 8, -9, 11, 0, -8 }, { 10, -26, -9, -7, -19, -4, 6, 16, -7, 5, -4, 4, 8, 0, 4, -1, 6, -7, 1, -8, -11, 10, -14, 0, -16, 6, -3, 5, -1, 14, 12, 1 }, { 8, -27, 12, -14, -1, -1, -19, 10, -11, 21, -14, 9, -8, -3, 8, -1, 12, -13, 3, -4, -2, 0, -9, 0, -7, 2, -3, 12, 1, -3, 3, 1 }, { 18, -20, -14, -14, -16, -3, -24, 6, -17, 2, -3, -11, 2, -3, 12, 10, 10, 1, 10, 7, 8, 5, 5, 4, -1, 7, 2, 2, 0, 4, 7, 0 }, { 0, -30, 9, -16, -18, 15, 12, -3, 4, -4, -5, -11, -4, -12, -10, 0, 2, -2, -4, -1, 2, 0, -1, -6, 2, -3, 4, -5, 7, 3, 5, 7 }, { 25, -24, -1, -6, -9, 6, -13, -2, 3, 15, -3, 11, 4, -8, -11, 2, 0, -9, -2, 7, 4, 8, 5, -8, 5, 6, -1, -11, -15, -5, 0, 11 }, { 0, -34, -7, -11, -7, 9, -3, 19, 4, -8, 3, -11, 11, -3, -9, 12, 9, 9, 2, 1, -7, 1, -3, 0, -6, -2, -1, 3, 0, -7, -2, -5 }, { 6, -34, -4, -5, -3, -9, 2, 9, -1, 9, -5, -3, -26, -12, 8, -6, -7, 11, -8, 4, 4, 1, -1, 0, 8, 9, -4, 7, -1, 1, -3, -1 }, { 3, -30, 5, 6, -10, 3, -7, 6, 3, 3, -26, -19, -3, 1, 7, 5, -4, -5, 6, 10, 13, -10, 4, -7, -4, 5, -3, 9, -6, 3, 9, 5 }, { 4, -24, 9, -19, 2, -4, -5, 8, -3, 2, 0, -15, -1, 9, -4, 22, 6, 9, 3, 7, 11, -9, 0, -3, 4, 5, -5, 10, -8, 5, -7, -3 }, { 8, -27, 7, -3, -1, 2, -9, 13, 7, 12, -4, -6, -6, 5, 0, 7, 5, 1, 15, -3, -4, 0, -5, -2, 7, -5, -7, 1, -2, 13, -8, 13 }, { 17, -22, -15, -11, -8, 16, -14, 18, 2, -1, 14, -7, 14, -6, -6, -7, -8, 17, 6, 4, 4, -7, -5, -9, -14, -6, -1, 9, -3, 1, 6, -5 }, { 25, -30, 2, -12, -13, 18, -18, 16, 8, -3, 10, -8, -3, -1, -6, 3, -5, -7, 4, 6, 7, 1, 1, -11, -5, 6, 2, -4, 9, -1, -5, -2 }, { 7, -23, 7, -15, -1, -3, -1, 0, -10, 12, 2, 5, -4, 0, 4, 6, -1, 5, -9, -1, -1, -7, 1, 17, 9, -17, -16, 8, 4, -14, 11, 14 }, { 0, -31, 7, -13, 3, -11, -7, 6, 1, -11, 8, -7, 15, -3, 16, -11, -1, -15, 16, -3, 5, 0, -2, -2, -6, 11, 5, 6, 5, -5, 6, 3 }, { 13, -24, -2, -20, -10, 7, -3, -1, 15, 2, 6, -5, -7, -10, -20, 1, -4, 14, 8, -2, 3, -13, -3, 1, -4, 1, -3, 2, 8, -7, 16, -4 }, { 1, -2, -2, -3, -4, -7, 0, 3, 6, 7, 3, 2, 1, -2, -1, 0, -6, 4, 2, -4, -3, -4, 5, 9, 5, 0, -3, -3, -4, -7, -31, -50 }, { -1, -3, 7, 2, -1, 2, 4, 6, 0, 10, -2, 0, -20, -6, -3, 9, -20, -22, -1, -1, 15, 9, -12, 10, -13, -20, 12, 3, 5, 6, -7, -26 }, { 0, 4, -2, -14, -12, 6, -13, 11, -10, 3, 22, 6, 16, -2, -5, 1, -3, -11, 0, -7, 5, -5, 0, 1, -1, -6, 8, 8, 10, 9, -5, -27 }, { -5, 10, -2, 7, 9, -9, 5, -9, 5, 4, -15, 14, 1, 3, -10, 5, 0, -2, 7, 3, -13, 6, 9, -6, 5, -14, -17, -1, 11, 14, -2, -26 }, { 0, 6, -3, 0, -8, 6, 0, 1, 4, -8, 2, -5, 4, 7, 15, 11, 9, 19, -2, 14, -8, 7, -1, 3, -3, -3, -10, -2, 12, -2, -12, -29 }, { -12, -5, 0, -3, -2, 6, 3, -3, 2, -2, 1, 11, 2, -7, 5, 1, 2, -2, -14, 0, -1, -5, 3, 8, -28, -26, 6, -6, 3, 8, -10, -27 }, { -1, -3, 6, 2, 4, 15, 1, 0, 2, -2, -2, 13, 3, 6, 0, 6, -1, -4, -1, -5, 8, -1, 5, -5, -15, 11, -8, -5, 14, -6, -14, -29 }, { -5, -6, 0, 1, 0, 6, -3, 2, -5, -1, 5, -3, 2, -10, 3, 4, 3, 0, 13, -3, -1, 4, -4, -6, 2, 9, 8, 2, -3, 28, -11, -31 }, { 1, -4, -10, -9, -4, -3, -15, -6, 1, 5, -3, -6, 5, -6, -22, 27, -13, 5, 3, -7, -4, 20, -7, -12, -1, -24, -4, -13, -8, -11, -15, -21 }, { -6, -4, 19, -6, 2, 11, -6, 1, -3, -10, 9, -9, 12, -10, 2, 1, -9, 1, 15, 7, -5, 5, -29, -35, 4, -30, 9, 9, 19, 17, 2, -17 }, { -3, 3, -3, 1, 2, 5, -1, 5, -2, -3, 1, -3, -8, 3, -4, -2, -4, -1, 12, 0, 2, -8, -6, -4, 16, -1, -14, -2, 25, -6, -15, -36 }, { 0, -1, 3, -4, -4, -1, 7, -4, 8, 0, 10, 9, -4, 1, 10, -1, -3, -13, -5, -4, -1, -4, 8, 11, 14, -7, -5, 16, 12, 13, -1, -28 }, { 1, -2, 2, -3, -8, 10, 4, 9, 12, 3, 5, 0, 8, -3, -6, 2, 16, -11, 11, 0, 1, 6, 1, 18, -10, -16, -1, -4, 5, -14, -15, -20 }, { 1, -12, 5, 4, -7, 8, -1, -17, -2, -9, -14, -11, 6, -9, 5, -4, 3, -2, 7, 18, -5, 5, 6, -1, -11, -2, -10, -3, 8, -3, -2, -32 }, { -12, 5, 20, -5, -6, -11, -6, -6, -13, 4, -6, 19, -8, 2, 3, -9, -4, -4, -1, 9, -1, 21, -1, 7, 15, -10, -1, -3, 9, -3, 2, -24 }, { 0, -3, 2, -6, 4, -1, -9, -2, -1, -3, 6, -1, -5, -6, -5, -8, 0, -2, -6, 9, -4, 3, 2, -13, 1, -7, 23, -13, 4, -3, -15, -33 }, { -7, 2, -15, 11, -10, 14, 0, -11, 3, -1, 12, -4, -4, 9, 11, -13, -13, -3, -14, 1, 3, 6, -5, 8, 0, 5, 5, -10, 4, 5, -6, -30 }, { -6, 4, 0, -5, 4, 1, -1, -1, 3, 6, 5, -2, -5, 0, -2, 5, -4, -2, -4, -2, 4, 7, -7, -1, 1, -4, -3, -19, 37, 12, 10, -40 }, { -7, 2, -7, -12, 17, 11, -7, 2, 2, 3, 1, -1, 3, 4, -2, -5, 9, -9, 6, 4, 9, 12, 11, -5, 2, -1, 0, 9, 5, -7, -2, -24 }, { -7, 6, 1, 3, 1, 0, 6, 0, 4, -12, -2, -2, 1, -9, 10, -2, 11, -1, 21, -12, 15, -5, 10, -5, 5, -5, 14, -6, 5, -7, -3, -29 }, { -2, 0, -5, -2, -3, 1, -3, 0, 4, 2, 3, 0, 2, -2, 7, -2, 3, -5, 2, -1, 6, -4, 0, -3, 8, -11, 19, -8, 22, -34, 13, -35 }, { -1, -3, -1, 9, 11, -3, -3, -1, 7, 18, 11, -5, 2, -12, -11, 18, 9, -5, 1, -6, -9, 12, 1, -3, -3, -9, -14, 9, 9, 8, -6, -26 }, { 0, 5, -5, -1, -1, -2, 4, 6, 8, 2, -1, -2, 5, 1, -5, -4, 1, 1, 18, 1, 7, -10, 3, -2, 12, -1, -15, 9, 12, -14, 13, -38 }, { 3, 0, -8, -1, 0, 8, -9, -3, -8, 16, 3, 16, -5, -9, 0, -1, -7, -1, -4, 13, 7, 0, 1, 2, -1, -16, 0, -2, 1, 8, -8, -28 }, { 7, 9, -5, -3, -2, 2, 0, 3, 11, -6, -4, -2, -2, -5, 28, -18, -6, 2, 15, -10, -15, -10, -2, 0, -2, -2, 4, -3, 7, 11, 5, -30 }, { 9, 0, -7, -1, -4, -7, 2, 2, 9, -2, 2, 3, -8, -6, -6, 3, -10, 4, 10, 5, 21, -4, 14, -18, 1, 3, -10, -2, 6, 14, -8, -26 }, { -14, -1, 2, 3, -3, 7, 1, -22, -1, -1, 0, 1, 12, -14, 3, -5, 0, 10, -3, 1, -5, 12, -3, 10, -8, -22, -11, -13, -7, -10, -13, -25 }, { -2, -5, -4, -4, -9, -18, 9, -3, -5, 17, 13, 5, 6, 11, 3, 8, 20, 4, 2, 9, 8, 5, 6, 1, 7, -7, -6, -2, -7, 0, -17, -23 }, { -5, -5, 2, 0, 6, 2, -2, 2, -3, 4, 4, 0, -5, -2, -4, 6, 8, 10, -1, 1, -5, 5, -14, -2, -11, 8, 6, 25, 7, -1, 0, -43 }, { -4, 0, 4, -2, 7, 0, 3, 17, 5, 2, -5, 1, 21, 3, -2, -10, -16, -9, 7, -12, 9, -8, 2, 5, -5, -10, -2, -11, -5, -1, -9, -30 }, { -2, 3, 1, -4, -1, 0, 8, 1, 12, 4, -1, -1, 3, -17, 13, 9, 0, 7, -6, -5, 9, 1, 5, 4, -10, -18, 0, 14, 11, -4, -16, -28 }, { -1, 0, 2, -1, 4, 1, -1, 1, -1, -2, -1, -2, 3, 0, 0, -1, -1, 1, 2, -2, 3, 3, -2, 4, -2, -1, -6, 1, -1, -1, 6, -70 }, { 7, 3, -11, -1, 12, -4, -14, 4, 4, -4, 4, -2, 2, -12, -4, 15, -17, -4, -3, 6, 8, -5, 22, -22, 5, -11, 15, -4, 4, -1, -21, -1 }, { 10, -2, -13, 11, 4, 14, 4, 9, 8, 8, 19, 15, 14, 15, 5, 10, 8, 15, -5, 4, 14, -8, 1, 1, 2, 1, -1, -3, 21, 8, -29, 13 }, { -6, 0, -6, 6, -1, 2, 8, -4, -5, 4, -4, -5, 0, -2, -4, 0, 9, -2, 1, -2, 26, -19, 21, -10, 4, 1, -8, 5, 22, -10, -13, 15 }, { 11, -5, 1, 0, 6, 3, 7, -2, -2, -3, -5, -1, -2, -6, 1, 1, -8, -5, -13, 13, -2, -3, -1, -9, -28, 4, 2, -11, 18, -20, -24, 9 }, { 7, 4, -3, 6, 6, -6, -7, -5, -7, -4, -4, 0, -7, -5, -6, -5, 2, -13, -12, 2, 0, 5, 18, 15, -13, -7, 13, -20, 16, -10, -19, 6 }, { 5, -8, -1, 5, 10, 2, -1, -10, -11, 23, 8, -5, -8, 4, -5, -4, -5, -5, -11, -8, 5, 1, 7, -9, -9, -6, 12, 14, 17, -12, -22, 3 }, { -5, -8, -3, 3, 12, -1, 0, -4, -5, 1, 1, 6, 1, 5, -5, 7, -2, 7, 1, 6, 6, 2, 0, -5, 17, -4, -5, -24, 13, -20, -27, 14 }, { -1, 2, -3, 1, -3, 1, -3, 0, -2, 3, -2, 1, 2, -1, -2, -1, -2, -5, 5, -2, 0, -7, 1, -6, 8, 8, 11, -5, 24, -43, -13, 2 }, { -2, 4, 7, -3, -4, 4, 13, -4, 0, 0, -2, 9, 0, -3, -6, 1, -7, 1, -1, 10, 0, 5, -1, -24, 25, -15, 7, 2, 22, -10, -21, 0 }, { -5, 2, 6, -2, 13, 3, 5, -12, -11, 16, 6, 10, -5, 0, -3, 6, 5, -5, -5, 10, 12, 10, 11, -7, 8, -14, 2, -15, 13, -14, -8, -3 }, { 5, 6, -7, -5, 5, 2, 9, 5, 0, -1, -4, 2, 8, 0, 3, 5, -12, 3, -3, -6, 2, -1, -5, 14, 11, -20, -21, -25, 24, -1, -10, 6 }, { -5, 5, -2, 9, 4, -4, -1, -6, 11, -6, 5, 0, 2, -3, 6, -1, -17, -18, -4, -13, 9, -1, 9, -7, -4, -8, 2, -3, 12, -31, -18, 5 }, { -7, -11, 6, -8, 4, -3, -12, 0, -1, -6, -3, 0, 5, 9, 7, 2, 1, -8, -6, 8, 2, -5, 7, -1, 16, -10, 16, -12, 18, -1, -25, -12 }, { 3, -12, 1, 2, -2, -18, -8, -15, -10, -9, 2, -7, 11, -11, 2, -1, -1, -1, -9, -6, 3, -14, -2, -1, 2, -13, -7, -9, 19, -5, -17, 2 }, { 7, 1, -8, 7, 17, -13, -10, 5, 7, 1, -6, 4, 9, -4, 0, 3, 8, 1, -14, -9, 4, 7, -9, 0, 6, -5, -12, -2, 25, -2, -19, 1 }, { 7, -3, 6, -3, 1, 6, -7, 0, 10, 0, 4, -5, -17, -4, 4, -1, 0, -3, -7, 19, 24, -1, 21, 8, 10, 9, 8, -1, 23, -2, -18, -2 }, { 3, -3, 0, 5, 8, -2, -9, 2, 9, 6, 19, 8, 2, 6, -9, -2, -4, -3, -8, 7, -7, -8, 5, 4, 26, -6, 7, 18, 24, 0, -13, 4 }, { 0, -13, -11, -1, 3, -9, 5, 4, -7, 3, 0, 2, -1, 4, -5, 2, 9, -2, -11, 15, 1, -21, 1, -1, 0, 4, -14, -4, 24, -16, -13, 1 }, { 1, -9, -8, 0, 0, -4, 11, -1, 14, 16, 0, 17, -2, -9, -12, 0, -1, -14, -9, -14, 0, -2, 19, 4, 6, 4, 4, -11, 8, -17, -19, -5 }, { -3, 1, 2, 12, -4, -18, -1, -4, -7, 14, -3, 2, 0, -7, -8, 12, -5, -9, 14, 12, -9, -2, 4, -6, 4, 18, -1, -25, 22, 2, -23, -5 }, { -2, 0, 0, 0, 1, 3, 5, -1, 5, -2, -2, 2, -3, 0, 1, 2, 0, -1, 2, -1, -9, -6, -7, -4, -2, 4, -7, -5, 64, -3, -25, 4 }, { 12, -2, -3, 0, 8, -9, 13, -7, 6, -3, -12, 12, 15, -9, -4, 2, 9, -4, -12, 3, 14, 1, 7, -15, 15, 0, -6, -12, 0, -3, -20, 6 }, { 2, -1, -4, 5, 9, 6, -7, 2, -2, -7, -2, 0, -1, -18, -4, -6, -15, -5, 11, 5, -10, -1, 2, 7, 12, -19, -7, 8, 21, -4, -15, 4 }, { 4, 2, 5, 5, -5, 1, 3, 2, -8, 13, 0, -5, -2, -14, -11, 6, 2, 17, 8, -13, 26, -2, 5, -15, -4, -14, 12, -9, 13, -21, -23, -4 }, { 2, -3, -2, -3, 3, -2, 6, 9, -9, 13, 4, 2, 12, -3, -3, 1, -17, -22, -3, 4, 3, -2, 1, -9, 1, -6, 11, -13, 14, 0, -15, 6 }, { -16, -4, 17, -2, -20, -11, 11, 10, 5, -8, 16, 2, -17, -14, 11, 11, -6, -11, -7, 12, 12, -10, -6, 5, 8, -4, -2, -5, 28, 3, -13, 4 }, { 0, -3, 3, -7, 6, 8, -12, 20, -19, 18, -11, 10, -5, 0, -9, 11, 3, 0, -2, 9, -7, -5, 18, 3, -2, -16, 1, 6, 12, -7, -16, 1 }, { 4, 1, 5, -5, 15, 2, -8, 3, 5, -11, 15, -3, 8, -8, -1, 7, 4, 7, -2, 6, -9, 5, 12, 2, 33, -2, -6, -18, 4, 0, -18, 11 }, { 3, -1, 1, -1, 0, 1, 4, -1, -5, 0, 1, 0, 4, 2, -1, 4, -3, 2, 0, -2, 4, 6, -1, 6, 42, 19, -4, -37, 19, 1, -15, -4 }, { 2, 0, -5, 0, 10, 0, 0, -5, 3, 0, 0, -3, -3, 0, 2, -4, -10, 2, -6, 4, 4, 1, 27, -7, 17, -34, 5, -9, 15, -16, -7, -5 }, { -2, 7, 7, -2, 9, -2, -15, 11, 11, 7, 5, 1, 15, 1, -9, 31, 2, -15, 2, 4, 3, 4, -1, -8, 2, -7, 6, -17, 11, -14, -11, 2 }, { 1, 1, -11, 9, 9, -6, -14, -11, -10, 8, -3, 11, 16, -9, -8, -13, -8, 9, 0, 6, 6, -2, 13, -8, -2, 3, 13, -3, 10, -6, -17, 4 }, { 14, 5, 4, -6, -12, 10, -7, 8, 21, -8, -30, 15, -2, 1, 11, -9, -5, 1, 0, -1, -1, -6, -2, 3, -5, 7, 9, 5, -5, 2, 0, 1 }, { -1, 2, 20, -17, -15, 3, 3, 7, 11, -17, -13, -6, -3, 18, 17, -15, -4, -4, -5, 22, 14, -14, -2, -10, -7, 11, 8, -7, -3, 0, -7, 11 }, { 7, -11, -7, -8, -14, 22, 5, 2, 6, 13, -12, -2, 10, 3, 0, -21, -4, 20, 3, 10, 21, -10, -12, 8, 11, 2, -5, 2, 1, 3, -1, 15 }, { -1, -2, -1, -2, -13, 8, -4, 0, 7, -2, -17, 8, 18, 5, 3, 8, -8, -2, 3, -4, 14, -18, -13, 14, 15, -13, -1, -2, 4, 11, 1, 12 }, { 13, -6, -4, -16, -17, 16, 21, -2, 5, -11, -9, 19, 21, -17, -3, -17, 3, 12, 8, -12, -6, 1, -7, 9, 9, -7, -5, -1, -3, 5, -6, -4 }, { 11, 5, 12, -20, -6, 10, 4, 12, 8, -5, -10, 15, 13, 14, 10, -15, -13, 1, 6, 14, 15, -17, -13, 4, -5, 10, 7, -6, -8, -3, -4, 12 }, { 25, -1, 7, -5, -7, 11, 1, 17, 13, -15, -14, -4, 5, 3, 8, -3, -2, 2, 0, 6, 16, -12, -6, -4, 4, -3, 7, -10, -3, -7, -13, 7 }, { -8, 10, -3, -13, 5, 2, 4, 9, 9, -17, -13, 2, 11, 1, 6, -4, 8, -10, 4, 1, 19, -15, -4, 12, 31, 7, -5, -17, -4, 9, -2, 7 }, { 14, -6, -6, -6, -14, 13, 17, -5, 4, -14, -9, 7, 7, -9, 3, -16, -15, 11, 11, 6, 4, -11, -19, 3, 5, 8, 13, -14, -14, 3, -4, 12 }, { -2, -4, 10, -4, -7, -1, 27, 5, 2, -16, -18, 4, 12, -2, -3, -2, -1, 1, -8, -12, 3, -4, 8, 15, 2, 4, 9, -13, -14, 9, -7, 5 }, { 4, 2, -10, -5, -7, 2, 1, 4, -1, -6, -15, 6, 1, 10, 5, -10, -9, -1, 13, -3, 5, -21, -11, 8, 8, 5, 27, -21, -18, -5, -1, 15 }, { 11, 1, -16, -8, -11, 0, 5, -8, -12, -13, -17, 22, 4, -6, -1, -18, -10, 0, 19, 2, -2, -8, -7, -3, 2, -2, -9, -17, -5, 4, 4, 10 }, { 8, -6, -19, -5, -4, 12, 14, 15, 10, -9, -1, -9, 19, 12, 0, -1, 2, 4, 7, 9, 16, -16, -14, 9, -4, 3, 1, 0, -2, 10, -1, -1 }, { 12, -8, 12, -9, 0, 25, 7, 9, 2, -31, -9, -4, 15, 4, -5, 1, -10, 11, 8, 10, 0, -6, 5, 11, -1, -6, 4, -10, -9, 6, 4, 5 }, { 14, 6, -17, -2, 17, 12, -9, 2, 0, -25, -14, 5, 20, 14, 8, -20, 5, 2, -2, -3, 9, -13, -3, -1, -6, 3, 7, -6, 0, 2, 3, 1 }, { 8, 4, -15, -3, 10, 18, -4, 13, 8, -22, -10, 9, 19, -15, 7, -5, -13, 12, -4, 9, 2, -9, -6, 0, 2, 1, -9, -6, 6, 1, -1, 11 }, { 4, 1, 4, -5, -10, 18, 7, 2, -4, -9, -11, 0, 32, -7, 4, -16, -1, 0, 6, 3, 6, -3, -14, 16, 9, -2, 7, -1, 0, -5, 5, -3 }, { -3, 2, 3, -8, -6, 4, 6, 2, 4, -12, -15, 2, 8, 8, 9, -3, -18, 6, 34, 11, 12, -15, -1, 2, 9, 2, -4, -4, 2, 4, 2, -3 }, { 18, -6, -12, -8, -1, 15, 20, -4, -1, -11, -5, 6, 6, -11, -15, -7, 3, 7, 10, 2, 8, -10, -5, 8, 15, -5, 5, -17, -13, 13, 11, 7 }, { 8, -4, -6, -1, -14, -3, 6, -2, 1, -5, -1, 10, 10, -15, 5, 0, -10, -4, -3, 7, -4, -19, -15, 27, 11, 18, 3, -19, -2, 6, 0, 12 }, { 12, 0, -5, 0, 4, -5, 1, 5, 10, -7, -11, 21, 29, 1, -2, 1, -4, -11, -1, 13, 11, -20, -1, 4, 4, 4, -5, 6, -13, -2, 11, 9 }, { 2, -7, -7, -3, -10, -1, 20, 12, 1, -19, -19, -1, 5, 4, -7, -25, 14, 1, -3, 2, 12, -4, -3, -3, -2, 6, 1, 0, 3, 2, 5, -1 }, { 12, -8, 3, -12, -10, 10, 13, 0, 23, -14, -18, 10, 0, 15, 3, -12, -3, -5, 5, -4, 2, -14, -10, 8, 2, 9, -1, -11, -3, 5, 13, 2 }, { 9, -6, 7, -7, -30, 17, 6, 13, 1, -14, 0, -1, 6, -9, 8, 3, -4, 0, -1, -7, -5, -13, -19, -3, -4, 4, -6, -2, -13, 1, -2, 3 }, { 10, 1, 3, -18, -26, 17, 4, -16, 4, -3, -13, -4, -6, -11, -4, -21, 7, 8, 2, 5, 13, -6, 1, 5, 8, 7, 9, -6, -6, 1, -1, 2 }, { -3, -1, 0, -2, -2, 0, -1, 3, 4, -14, -8, -9, 13, 2, 50, -23, -8, 8, 7, 11, 16, 3, -7, 0, -2, 6, 5, -1, 1, -2, 4, 3 }, { 1, 3, 1, 1, -6, 3, 6, 6, 2, -2, -3, 10, 2, -8, -5, -5, 5, 4, 4, -2, 10, -8, -40, -1, 21, 8, 3, -4, -1, 13, 4, 7 }, { 2, 0, -4, -8, 5, 2, 7, -5, 5, -8, -4, -1, 12, 2, 12, -13, -9, 0, 1, -12, 9, -43, 1, -5, 12, 1, 3, 6, 1, -1, 3, -2 }, { 6, -2, -1, 1, 0, 4, 8, 14, 4, -7, -23, -5, 23, -17, -6, -15, -8, 7, 10, -1, 7, -16, 4, -6, 2, 3, -3, -3, -1, 8, -1, 4 }, { 10, 4, -4, 1, 7, -3, 2, 11, 4, -6, -3, 8, 5, 4, 1, -45, -6, -4, 4, 2, 1, -14, -10, 1, 1, 6, 2, -8, -1, -3, 3, 3 }, { 1, -1, 2, -3, -8, 9, 3, 3, -2, -5, -8, 8, 7, -7, -4, -6, 5, -9, 11, -2, 46, -5, -1, 9, -2, 0, 3, -5, -3, -5, 7, 0 }, { -4, 1, -2, -1, -11, 11, 8, -3, -2, -10, 0, 4, 9, 9, -17, -17, -34, -4, -5, -7, -3, -12, -3, 11, 18, 3, -2, -5, -18, -5, -3, 6 }, { 7, -5, -3, 1, -4, -3, -5, -1, 2, 5, -2, 3, -10, 12, -18, -5, -10, 12, -9, 4, -6, 2, 0, 16, -17, 15, 14, -12, -10, -2, -9, -1 }, { 4, -5, -3, -5, -3, -1, 7, 18, -7, 12, 3, 5, -8, -4, -20, 1, -25, 1, -8, 13, -10, 8, -19, -1, -8, 10, 6, -9, -1, 0, 12, 4 }, { -4, 5, 0, -1, 2, 5, -8, -2, -6, 4, -8, 9, 3, 2, -7, 4, -25, 13, -23, 10, 14, 15, -11, 3, -18, 4, 16, -4, 1, -10, -10, 3 }, { 5, -3, -1, -3, 4, 1, -3, -4, -5, 1, -12, 14, -7, 11, -15, 6, -6, 24, -4, 13, -1, 15, -13, 8, 3, 7, -5, 2, 2, 0, 3, -7 }, { -3, 1, 0, 8, 6, -1, 6, 5, -5, -2, -12, 4, 0, -2, -3, 5, -6, 0, -8, 9, -10, 4, -28, 12, -20, 11, -13, 7, -18, 1, -11, 1 }, { 1, -4, -15, 5, 0, -13, -5, 13, -11, 4, -4, -5, 5, -14, -16, 0, -14, 5, -20, 12, 10, -7, -5, 6, 6, 22, 6, -4, -2, 3, 8, 11 }, { 13, -11, -2, 16, 16, -7, 0, 20, -7, -1, 0, 5, -9, 12, -2, -5, -22, 5, -10, 12, -6, 11, 9, 21, -8, 15, 4, 0, -8, -4, -4, 10 }, { 18, -4, -13, 0, 1, -15, -1, -3, 2, 10, -1, 6, 1, -4, -20, -5, -8, 6, -8, 17, -5, 5, -10, 8, -22, 6, -5, -2, 8, -17, 8, 2 }, { 1, -2, -9, 6, -31, -8, -8, 8, 0, 5, -9, -4, 2, 3, -12, 11, -18, 10, -5, 3, -11, 13, -6, 11, -3, 12, -7, 3, -9, -1, 2, 11 }, { -9, -6, 21, -8, -15, 4, -11, 12, -11, 17, -1, 2, -6, 0, -15, 13, -12, 19, 0, 2, -6, -3, -9, 10, 3, 17, -2, 5, -10, -3, 0, 1 }, { 4, -6, 5, -10, 1, -5, 1, 0, 0, 0, 2, 7, -2, 2, -2, 0, -4, 3, -4, 1, -12, 6, -49, 16, -10, 13, 0, -2, 8, 6, 1, 8 }, { 5, -8, -7, 9, 13, -5, 7, 0, 10, 11, -4, -3, -1, 13, -14, 6, -15, -6, -14, 16, 15, 1, -18, -4, -20, 20, -7, -1, -9, -2, -10, 10 }, { -12, 4, 0, 10, 0, 3, 8, 4, -27, -1, -2, 19, -4, 2, -13, 3, 1, 9, -12, 1, -22, 19, -5, 4, -9, 12, 2, -9, -8, 11, -3, 7 }, { 4, -5, 11, -6, 17, -17, 5, -4, -2, -6, 1, -5, 2, 4, -14, 6, -20, 19, -20, 12, -21, 5, -14, 13, -2, 11, 4, -3, 0, -10, -4, -2 }, { -2, -1, -3, 8, -9, -7, -22, -3, -24, 13, -2, 10, -15, 5, -9, 4, -7, 0, -5, 15, -8, 11, -13, 6, -4, 19, -8, 12, -4, 6, 9, 7 }, { 2, -3, 2, -1, 0, 3, 1, 2, 1, -4, -2, -3, 1, 5, -12, 6, -16, 14, -23, 10, -14, 17, -15, 16, -2, 9, -25, 9, -10, 16, 4, 9 }, { -3, 7, -8, -3, 2, 2, -4, -8, -9, 10, 3, -11, 25, -10, -28, 27, -9, 7, -13, 9, -2, 4, -12, -8, -14, 6, 7, -10, 3, 3, -3, 5 }, { -8, -3, 1, -10, 8, -3, -9, -4, 13, 7, 2, 4, -10, 4, 3, 7, -18, 2, -22, 15, 4, 20, -7, 5, -6, 13, -1, 4, -7, -6, 6, 13 }, { -2, 3, 0, 2, -4, -2, 0, 0, 1, 2, -2, -5, 0, 1, -4, 0, -2, -3, 1, 2, -1, 2, -8, -1, -24, 68, -3, 8, 3, 3, -1, -1 }, { -15, -2, -9, -7, -1, 8, -14, 8, 3, 6, 0, -1, -8, 8, -23, 2, -14, 17, -15, 8, -4, 7, -18, 0, -8, -3, -1, -4, -10, 4, -1, 4 }, { 8, 0, 2, -7, 0, 5, 1, 3, -11, 4, -8, 14, 3, 20, 1, 26, -11, 13, -13, 20, -2, 0, -8, 2, -6, 6, -1, 9, 3, -6, -3, 10 }, { 5, 0, -1, -7, 10, 1, -3, 5, 4, 7, -5, -1, -3, -1, 12, -3, -15, 7, -9, 22, -19, 8, -9, 4, -23, 13, -14, 6, -6, -14, -4, 7 }, { 14, -5, -8, -10, 25, 3, -23, -7, -28, 0, -1, -9, 4, 1, -13, 20, -8, 10, -16, 8, 12, -13, -21, 5, -13, 11, -2, 1, 12, -7, 2, -10 }, { -5, -4, 9, 5, -6, 35, -7, 8, 15, 2, -1, -9, -6, 2, -18, 7, -15, 6, -3, 2, 8, 12, -30, 7, -4, 20, 2, 6, 13, -6, -4, 0 }, { 1, 8, -9, 9, -5, 12, -9, 16, -9, 16, -17, 14, -13, 15, -18, 14, -15, 17, -12, 14, -13, 7, -16, 13, -9, 5, -11, 10, -9, 6, -12, 13 }, { -10, -4, 5, 3, 1, 6, 8, -14, -5, 15, 7, 4, 8, 7, -22, 8, -7, -8, -15, 26, 1, 13, -3, 17, -5, 9, -2, 4, -6, 3, -8, 9 }, { 8, -3, 2, 3, 3, 1, -2, -1, -11, 8, -4, 0, -6, -5, -1, 13, -37, 9, 1, -6, -10, -2, -10, 11, 8, 13, -3, -2, -6, 8, -4, 13 }, { 3, 2, -3, -4, -4, 7, -8, 9, -8, 9, -20, 12, -19, 15, -18, 17, -15, 7, -1, 20, -11, 6, -6, 3, 1, 9, 2, -14, -2, -2, 2, 1 }, { -7, 1, -1, -3, -6, 4, 4, -3, 3, -1, 5, -4, 3, 2, -1, 9, -59, 5, -4, 30, 3, 3, -2, -3, -1, 2, 2, 1, -1, -1, -2, 1 }, { 0, -3, 2, 0, -1, -8, 0, 2, -3, 4, -4, 1, 10, 6, -6, 8, -7, 4, 10, 11, -41, 27, -20, 3, -3, 8, 1, 11, -5, -8, 0, 4 }, { 5, 1, 4, -2, 1, 2, -1, 6, -7, 2, 11, 4, 0, 0, -8, 7, -10, 0, 0, 8, 2, 10, -1, 1, -2, 44, -2, -21, -12, -3, -1, 2 }, { -4, 4, -2, -2, 6, -8, 2, 1, -10, 14, 8, 6, 5, 1, -2, 4, -13, 4, 2, 5, 10, -2, -21, 32, -3, 18, 9, -6, -9, -9, 10, 2 }, { 9, -16, -6, -2, 1, 4, 22, 2, -2, 1, -3, -2, -9, 3, 16, 19, -24, -6, -6, -5, -8, -7, 8, -7, -1, -12, 5, -3, 0, 4, 2, -3 }, { 10, 3, -16, -4, -1, 13, 4, 4, 1, -3, 1, -6, -14, 18, 3, 8, -8, -28, -16, 4, 4, 2, 12, 7, 9, -4, -4, 5, -1, -1, 2, 2 }, { -5, -13, -22, -3, -8, 21, -2, -9, 21, -4, -9, 5, -8, 15, 5, 1, -5, -9, -7, -2, -5, -5, -1, -5, -5, -5, 3, 10, -4, 0, -7, -2 }, { 5, -10, -18, 2, 20, 4, 13, -10, 8, -15, -11, -3, -1, 16, 10, 9, -8, 6, 7, -5, 6, 11, 5, 17, -4, 7, -11, 5, -3, -6, 2, 1 }, { 3, -5, -19, 1, 1, -3, -2, -25, -11, -17, 0, -13, -4, 10, 10, 2, -5, 4, 0, 3, -3, -5, -10, -2, 13, -22, 0, 3, -11, -5, 7, -1 }, { 12, -14, -29, 6, -1, 10, 7, -17, -12, 14, 3, 9, -9, 9, 7, 6, -3, -13, 0, 5, 3, -1, -6, -1, 0, 2, 4, -12, -5, -1, 2, 11 }, { 12, -15, -7, -2, -12, 17, 20, -16, -2, -12, -6, 15, -6, 12, 11, 9, 7, -6, 7, -4, -19, 6, 2, 2, 3, -11, -10, -4, -5, -3, 3, 2 }, { 11, -22, -6, 0, 8, 18, 3, -11, -4, -7, -15, -17, -12, 6, 16, 4, -9, 4, -5, 3, 6, -16, 10, -7, -7, -3, 5, 0, 1, -15, -4, 5 }, { 12, -22, -16, 5, -6, 8, 12, -4, -9, -17, -11, 3, 5, 8, -17, 0, 11, -4, -13, -6, 2, -1, -1, 3, 3, -11, -12, -1, 1, 1, 12, -2 }, { 8, -10, -33, -5, -3, -6, 1, -7, -8, -4, -6, -1, 5, -4, -6, -12, -16, -8, 11, 8, -14, 7, 12, 11, 4, -14, -3, 6, -7, -5, -3, 3 }, { 0, -8, -7, 2, -4, 24, 2, -9, -11, -3, -7, 11, -12, 17, 1, -1, 3, -5, -7, 12, 4, 11, 0, 3, 2, -18, -3, 4, 7, -6, 3, 15 }, { 10, -15, -16, -2, -4, -9, 7, -15, -6, 2, -16, 13, -8, 7, 19, -21, -4, -12, -9, -3, -3, 6, 11, -3, -1, -19, 3, -7, -9, -4, 3, -6 }, { -5, -10, -21, 0, -3, -7, 18, -21, 15, -5, -12, -4, -13, 2, 6, -9, -9, -11, -4, 13, -3, 6, 4, -1, 7, -9, -4, 9, 5, 2, 6, 3 }, { 15, -1, -27, -2, 10, 3, 7, -8, 9, -2, 7, 1, -2, -5, 18, 9, -11, -17, -2, 7, -9, 11, 10, 0, -8, 6, -16, -3, 2, -7, 3, 11 }, { 4, -9, -39, 19, 6, -13, 13, -5, -5, -15, -2, 9, 0, 4, 14, 6, -10, -4, -5, 2, -4, -2, 5, -11, 3, 3, -2, -2, -7, 9, 7, -10 }, { 5, -11, -8, 10, -2, 12, 16, 0, 12, -2, -6, 8, 14, 8, 7, 1, 18, -30, 4, 10, -4, -6, 2, -11, 9, -10, -8, 5, 0, 0, -7, 6 }, { -1, -16, -10, 11, 0, 13, 12, -4, -4, -5, -21, 12, 4, 13, 14, -7, 6, -16, -13, 8, 2, 9, 15, -12, 1, -9, -22, 10, -9, 9, 9, -7 }, { 4, -12, -27, 1, -2, 11, 15, 3, 14, -14, -9, 0, -9, 16, 22, 10, 16, -10, 5, -5, -9, 1, 1, 6, 6, -4, 2, -17, -5, -6, -15, -1 }, { 7, -12, -17, 1, -9, 5, 20, -7, 3, 23, -8, -8, -8, -1, 13, 17, -7, -13, 4, -4, 7, 14, 8, 11, -3, -3, 4, 0, 4, 6, -1, -9 }, { 7, -15, -15, -4, 10, 12, 3, -13, 6, 14, 9, -8, -15, 14, 23, -5, -10, -5, 1, 15, -10, -7, 1, 9, 4, -13, -10, 10, 7, -3, 2, 3 }, { 4, -10, -14, 0, 3, 4, 0, -9, -3, -4, -11, 2, -17, 8, 2, 15, 6, -12, -12, 15, -5, 17, 18, 3, -3, -3, -4, -6, -8, 13, 4, 10 }, { -2, -18, -26, 10, -4, 10, 13, 4, -4, -16, -7, -17, -3, 5, -4, 2, -15, -10, -1, -8, -7, -3, 2, 2, 8, -10, -7, 2, 2, -4, 4, -1 }, { 4, -19, -5, -1, -1, -6, 2, -8, 10, -16, -28, -6, 8, -1, 11, 28, 2, -10, -4, 6, -6, 6, 11, 15, -4, -2, 7, 3, 7, -7, 4, 1 }, { -3, -6, -10, -5, 13, 18, 10, -15, -5, -3, -13, 5, 1, 2, 18, -5, -10, -10, -7, 4, 2, 1, 5, 4, 2, 5, 4, 8, -9, -17, 7, 7 }, { 20, -12, -2, -4, 5, 14, 7, -11, -1, -16, -6, -4, -11, 17, 14, 0, -8, -10, -8, 10, 3, 5, 10, -16, 3, -8, -14, 10, 3, 9, 0, 3 }, { 12, -10, -36, 0, 7, 15, 2, -16, 2, -1, 0, -1, 5, 4, 5, -3, 1, -10, 5, -1, -15, -3, -12, 12, 2, 5, -1, 5, 6, -3, -2, 2 }, { 17, -15, -31, 23, -4, 15, -2, -3, 6, -7, -5, 1, -12, 4, 6, 8, -10, 8, 3, 5, -4, 1, 5, 3, -1, -4, -3, 1, 10, -4, -2, -2 }, { 6, -18, -5, 12, 10, 12, 14, -11, 15, 2, -9, -6, -5, -2, -9, 4, -5, -28, -4, 14, 0, -16, 9, 14, -1, 3, -4, -4, 2, 1, 0, 4 }, { -5, -14, -31, 8, 16, 7, 13, -13, 5, 6, -16, 10, -5, 2, -2, 2, 14, -5, 8, -5, 7, -16, 6, -13, -5, 0, -5, 8, -3, -1, 4, 3 }, { 1, -2, -1, 0, 6, 5, 2, -4, -3, -1, 0, 1, 4, 2, 43, 28, -12, -35, -2, -2, -7, -1, 0, 2, -1, -2, -2, 1, -4, 0, -2, 3 }, { 2, -9, -22, 12, 3, 3, -7, -4, -19, -22, -14, -4, -1, 21, 9, -3, -15, -16, -13, 1, -11, 4, -9, 1, -7, -1, -1, 0, -2, 9, -13, -3 }, { -1, -3, -23, 0, 2, 12, 3, -9, -4, 7, 3, 9, -10, 1, 27, 28, 0, 9, -15, -2, -2, 1, 6, 8, -8, 7, -3, 20, 0, 0, -1, -6 }, { -1, 11, 8, -2, 1, 5, -6, -1, 4, 2, -4, 0, -1, -5, 4, -6, -10, -12, 19, 1, -7, 9, -8, -9, -16, -11, -2, 12, 14, 4, 4, 34 }, { 17, 7, -6, 1, 4, -10, -5, 4, -11, 3, -18, 4, 14, -13, -3, 1, 0, 0, -11, 0, 7, -17, -4, 4, -11, -6, -8, 18, 0, 0, 0, 26 }, { -6, -7, -1, -1, 11, -8, 1, 3, 2, 11, -6, -6, 10, -3, 1, -3, 7, 4, -12, -8, 0, -9, 8, -22, -5, 0, -6, 22, -2, 11, -13, 24 }, { -3, 4, 0, 3, 9, 10, -1, 3, -9, -12, 1, -5, 18, 0, -3, 8, 25, 15, -8, 2, 2, -2, 4, 8, 9, -1, -5, 10, -3, 1, -1, 23 }, { -5, 2, -9, -1, -3, 0, 3, -1, -10, -4, 0, -13, 16, 9, -1, -14, 2, 6, -2, -6, -5, -2, -7, 7, 5, 3, 11, -2, -14, 0, -9, 30 }, { 4, 6, 6, 5, -3, -1, 4, 5, 10, 0, 5, -4, 7, -11, 14, 14, 7, 34, -9, 0, -10, 22, -7, -1, 7, -9, 2, -8, 0, -7, -5, 29 }, { -4, 3, -1, -4, -3, 5, 1, -4, 0, 2, 4, 2, 1, -1, -10, 1, 6, -6, -4, 1, 4, -3, -3, -5, 0, 3, 7, -12, 0, -2, -10, 55 }, { 5, 9, -1, 0, 4, 9, -21, -9, 4, 2, 6, -7, 11, -7, 1, -5, 0, -4, 2, -3, -13, -8, 0, -9, -4, 2, 16, -2, -15, -7, -11, 31 }, { 8, 2, -1, 0, 3, -5, -5, 5, 1, -1, -9, 1, 0, -6, -2, -1, 5, 2, 0, 0, 12, 20, -19, 1, 8, -12, -11, 0, 6, -5, 2, 31 }, { -1, -1, -2, 1, -1, 3, -9, -5, 8, -2, 5, -1, 0, -2, 4, -2, -3, -12, 0, -2, 3, 0, 9, 4, -1, 21, -8, 3, -4, 9, -6, 30 }, { -4, 0, -7, 17, 10, -12, -2, -10, -12, -3, 10, 0, 11, -4, -13, -3, 5, 6, 10, 7, -8, 0, -7, -13, 1, 0, -2, 7, -12, 4, -3, 24 }, { -13, 9, 4, -2, 2, -4, -14, -1, -3, -5, -10, 4, 13, -2, 5, 13, 8, 3, -2, 1, 5, -6, 7, -18, -10, 1, -1, 5, 4, 1, 0, 25 }, { -5, -1, 18, 12, 8, 8, -16, -1, 1, 1, 1, -4, -5, 3, 3, 4, 4, -11, -12, -16, -6, 2, 12, -13, 0, 9, 7, 9, -9, 0, -10, 24 }, { -4, 1, -3, 0, 2, -4, 4, 1, 5, 0, -3, 2, -3, -2, 2, -1, 1, 4, -1, -2, -2, 1, -1, -1, -4, -1, -4, -2, -6, 6, 12, 69 }, { 8, 5, 11, 0, -15, -4, 13, 6, 0, -4, 9, 1, -5, -3, 15, 0, 1, 6, -5, 0, 1, 6, 5, 8, 0, 7, 1, -1, -4, -11, -9, 41 }, { -4, -9, 32, -6, 0, 7, -4, 6, -6, 1, -6, -2, 4, -8, -5, -3, -16, -1, -2, -6, 1, 15, 0, 21, 3, -3, -4, 3, -12, 16, 2, 27 }, { -6, -5, 1, -9, -5, 3, 7, -3, 5, 5, 14, 13, 20, -7, -1, 12, -1, 10, -11, -11, -7, -4, -14, 7, -14, 13, 22, 18, -1, 0, 14, 28 }, { -8, 3, -2, 0, 5, 6, -1, -4, 1, 3, -7, 3, 1, -15, 4, -9, 22, -10, -9, -4, 1, 8, -4, 9, -15, 2, -6, -4, -16, 12, -10, 23 }, { 0, 0, 2, 0, -1, 3, -3, -1, 3, -5, 7, 1, 5, -5, -8, 1, 13, -15, -5, -7, 12, -6, -2, 3, 10, -5, -8, 17, -5, -11, -14, 23 }, { -7, -4, 6, -4, 5, -6, -5, 2, -4, 11, 9, -4, 2, -2, -4, 6, 15, 3, -3, 18, -15, -2, -6, 3, 3, -20, 17, 11, -4, 2, 3, 29 }, { 6, 1, -6, 2, 3, 0, 0, -3, 3, 3, -1, 3, -4, -6, -6, -7, -3, -2, -7, -2, -4, 5, 3, -5, -20, -13, -4, 10, -14, -29, 14, 37 }, { 3, 4, 3, -6, -4, 5, 0, 3, 2, 3, 0, -2, 4, 0, -3, -5, -4, 4, -4, 4, 4, 3, 1, -4, -4, -9, -14, 20, -30, 3, -18, 33 }, { 0, 2, 5, -2, -4, -2, -1, 2, -6, -3, -2, -2, 2, -5, -1, 4, 3, 2, -3, 0, -1, -1, -10, -7, 2, -4, -18, 2, -37, -1, 12, 40 }, { -7, 2, -1, 0, -2, 4, -8, 1, -4, 12, 7, 4, 15, -7, 1, -9, 18, 0, 12, -17, -3, -1, 0, 0, 0, 2, -6, 0, -4, -3, -1, 26 }, { -6, 4, 8, -5, -6, -2, 2, -1, 1, -1, -15, 8, 7, -1, -17, -4, 1, 5, 6, -11, -6, 14, 17, -5, -15, 11, 8, 0, -3, -15, -6, 28 }, { -1, 0, 0, 0, 1, 0, -1, 0, 1, 3, 2, -2, 3, -1, -1, 2, 2, -1, -1, -7, 1, 2, -9, 0, -1, -4, -18, 7, -10, 49, -13, 32 }, { -1, -3, 4, 1, 2, -5, 1, -7, -1, 5, -9, 4, 4, 25, 1, -1, 2, -5, 2, -7, 17, -2, 10, -5, 0, 2, -15, 3, -9, 7, -9, 30 }, { -5, -1, 0, 2, 1, -1, 2, 5, -33, 3, -5, 14, 11, 7, 5, -3, 2, -8, -4, -2, -7, -6, 4, -8, -1, -8, 2, -2, -8, -1, -4, 27 }, { -1, 0, -1, -2, 1, -1, -2, -1, 2, 0, 1, 2, 2, 4, 1, 3, 4, 2, 1, -7, -4, 1, -3, -4, -35, -25, 17, 10, -3, -26, -7, 32 }, { -5, 1, 6, -2, 6, 6, -9, 3, -1, -4, 5, -4, -2, -2, -9, 2, -5, 2, 2, 4, 3, 5, -5, -16, -31, -12, -11, 2, -19, 20, -2, 21 }, { -5, 2, 7, -7, -7, 5, -7, 2, 0, 0, -4, 3, -1, 0, -1, -2, 0, -3, 5, -11, -8, -3, -7, -7, 28, -11, -7, 0, -16, -11, -4, 29 }, { 2, 1, -3, -2, -1, 3, 4, 0, 1, 0, -1, -5, 4, -5, -12, 2, -2, -5, -22, -2, -1, 11, 8, -7, -12, 0, -34, 6, -5, 11, -8, 19 }, { -1, -3, 5, 11, 18, -2, -2, -5, -2, 4, -1, 8, 5, -6, 1, -1, 2, 8, 4, -5, -8, -2, 5, -18, 7, 12, 7, 19, -18, 2, -6, -13 }, { 9, 0, 0, 5, 4, 3, -6, 4, 1, -4, 5, -1, -4, 8, 8, 6, -8, -6, 0, 6, -3, 3, 5, -3, 17, 31, 16, 10, -13, 0, -9, -19 }, { 12, -10, 2, -2, -2, -1, -3, 6, -12, -5, -2, 14, -16, 4, 12, 12, 17, 4, 7, -16, 7, -6, 11, 7, 7, 2, -25, 23, -24, 5, -7, -9 }, { 10, 4, 13, 10, 10, 3, -6, 3, 3, 2, -1, -6, 8, 4, 10, 0, 1, 2, -4, 2, -3, -8, 0, -1, 9, 9, -10, -3, -29, 1, -1, -27 }, { 2, 2, 0, 7, 9, -2, -10, -1, -1, 1, -9, -5, 8, 4, 1, 2, -10, 1, 13, 12, -3, 15, -9, 2, -7, 1, -10, 23, -20, -18, -9, -15 }, { -3, -5, -1, 8, 0, -5, -1, 4, 7, -1, -7, 2, -8, -5, 11, 7, -6, 3, -3, -9, 7, 9, -22, 1, 6, -4, 14, 27, -25, -14, 3, -5 }, { 1, 3, 8, 4, 7, 6, 12, -17, -15, 1, -8, -10, 7, -14, -8, 6, -2, -2, -11, -11, -7, 13, -2, -2, 4, 5, -5, 13, -23, -6, -17, -8 }, { -5, 4, -14, -5, -4, -5, 6, 5, -8, -5, -2, -11, -7, -12, 3, -11, 2, -6, 4, -10, -5, -7, 14, 5, 23, 11, 7, 12, -16, -6, -4, -16 }, { 5, 6, 2, 5, -2, -5, -5, -6, -5, -19, -13, -1, -3, -13, 5, 0, 6, -2, -2, -6, -7, -7, -1, -9, 4, 14, 17, -12, -27, 3, 0, -1 }, { 7, -1, 9, -10, 8, 2, -7, -2, 5, 2, -3, -7, 3, 0, 6, 4, 12, 5, 11, 14, -13, -1, 8, 1, 13, 9, 12, 12, -18, -14, -11, -16 }, { -7, -5, -6, -5, 0, -1, -3, 2, 2, 1, 4, 9, 2, 3, 5, -2, 2, 1, 8, 0, 3, 0, -2, 2, 1, 7, 29, 0, -36, -5, -9, -21 }, { 14, -6, -9, 0, -1, -8, -8, -11, 2, 2, -9, -12, 12, -4, 5, 3, -5, -9, 11, -1, -3, 12, -21, -3, 12, 5, 3, 11, -18, -15, 1, -2 }, { -1, 3, -9, -3, 7, -7, -18, 2, 4, 12, -10, 2, 8, -3, -14, 13, 17, -5, 5, -9, 13, -3, -7, -18, 17, -2, 5, 7, -20, -3, -6, -11 }, { -3, 3, 3, -1, 1, -6, -5, 1, 5, -3, -14, -6, -5, -8, 14, -6, 7, -1, 5, 1, 15, -1, -7, -4, 6, -11, 9, -2, -37, 16, -7, -3 }, { -1, 0, 6, 1, -3, -9, 0, 11, -8, 2, -2, 0, 5, 2, 12, -10, 10, 13, 2, 7, -6, 2, -10, -10, 21, -5, 5, 5, -12, -23, 3, -14 }, { 6, 0, -2, 1, 0, 1, 0, -4, 1, 1, 8, -2, 2, -5, -2, 1, 8, -4, -1, -1, 4, -1, 2, 6, 32, 1, -5, -20, -40, -4, -18, -14 }, { 2, 2, -7, -2, 4, 4, -1, 2, 0, -2, -4, -7, 3, 5, 0, -5, 1, 2, -6, 4, -1, -2, -1, -15, 8, 3, 9, 46, -7, -18, 6, -11 }, { 5, 5, 16, 21, 3, -11, -4, 11, -12, 2, 4, -12, -1, 11, 8, 1, -4, 11, -11, -21, 1, 1, -11, 3, 13, 1, 5, 12, -25, 1, -3, -2 }, { 1, 6, -7, 4, 2, 3, 1, -5, 8, 9, -15, 3, -3, -14, 17, 4, -8, 14, -2, -8, -4, 5, 8, -7, 8, 9, 7, 6, -29, -17, 8, 4 }, { -7, -7, 4, 0, 13, 1, 0, 4, 4, -16, -10, -7, 5, 9, -15, -10, -10, 8, -4, -1, -11, -1, -10, -15, 3, 3, 14, 10, -19, 2, -18, -12 }, { -4, 0, 2, 0, 5, -2, -9, 0, 4, -4, 2, -1, -2, 2, -4, 9, 2, -6, -4, -2, -1, -3, -3, -1, 2, 5, -1, 11, -24, -44, -9, -15 }, { -1, -10, 6, 21, 11, 15, -7, 10, -14, -9, -8, -8, 4, 6, 19, 1, -6, 1, -5, -17, -8, -10, 9, 5, 11, 18, -1, 10, -16, -7, -9, -8 }, { 3, -5, 0, 0, -2, -2, -6, 4, -4, 1, -1, 0, 7, -3, 4, -4, -7, 7, 17, -20, 6, 4, 1, -6, -12, 31, 13, 19, -14, -10, -7, -2 }, { -2, 6, -10, 3, 9, 6, -14, 15, 2, -5, 2, -11, 9, -8, 4, 6, 20, -15, -3, -3, -1, 32, -21, 6, 1, 9, 11, 17, -19, 6, -1, -3 }, { 8, 10, -2, 0, -8, -16, 7, 7, 6, 10, 4, -14, 7, -6, 21, -7, 10, 5, 5, 0, -7, 2, -6, 0, -7, 11, -9, 15, -20, -7, -11, 2 }, { 0, -7, 5, 2, 0, -3, -6, -4, -2, -1, -4, -5, -13, -1, 27, -9, -6, -11, -7, 1, 11, -4, -4, -14, -2, 11, 6, 10, -19, -6, -15, 2 }, { 0, 7, -1, 2, -7, -15, -2, -3, 13, -5, -5, 12, 3, 0, 5, -5, -22, 2, 7, 22, 13, 0, -1, 2, 3, 2, -7, 7, -27, -4, -4, -12 }, { 11, 1, -16, 6, -15, 1, 3, 2, 0, 2, -3, 2, 5, -2, -5, 9, 5, -3, 3, -2, -11, 3, 9, 6, 9, 3, -1, 12, -41, 8, -6, 9 }, { 3, -7, 3, 2, 5, 5, 0, -1, 1, 3, -5, -2, -13, 7, -1, -2, -2, -6, 4, -6, 0, 2, -2, 2, 4, 1, -4, 1, -47, -21, 7, -6 }, { 3, 16, -7, 13, -4, -2, 10, -3, -1, 18, -13, 7, -13, -4, 8, 4, 8, 9, -5, 13, 8, -5, 3, -6, 7, 18, -8, 10, -25, -3, -12, -12 }, { 1, -1, -1, 0, 2, 5, -5, -3, 0, -5, -1, 0, -4, -8, -2, 3, 2, -2, -17, -6, -4, 1, 33, -6, -20, -6, 8, 31, -26, -8, -1, -4 }, { 3, -3, -3, 5, -3, -2, 1, 7, 0, 3, 6, 3, 6, -2, 9, 15, -10, -3, -15, -5, -3, -4, -6, -30, 17, -8, -2, 2, -20, 0, -8, -2 }, { -2, -1, -1, -1, 3, -5, -2, -3, 4, -2, 0, 5, 8, -3, 1, -4, 1, 1, -3, 4, 4, -14, 3, 11, -5, 3, -3, 7, -3, 13, 23, -16 }, { 2, -6, 1, -3, 5, 0, -6, -11, -7, -4, -1, 2, -7, -1, -1, 7, 1, -2, 6, 12, -6, 8, -13, 17, 25, -23, -19, -7, -12, 9, 16, -17 }, { 9, 4, 4, 4, -3, -1, 6, -2, -3, 0, 13, -4, -7, 14, 1, -7, 0, -5, 3, -19, -3, 5, 3, 9, -1, 9, -13, 13, -17, 4, 21, -26 }, { 0, -5, 0, 0, -4, -5, 2, -6, -4, 5, -7, 10, 0, 2, 0, -2, -2, 0, 4, -6, 7, -2, 6, 5, -5, 2, -12, 1, -29, 29, 27, 12 }, { 9, -10, -22, 6, -1, -1, 9, -14, -12, -2, 1, -1, 10, -11, -16, 0, 3, 11, 13, -14, -9, -2, -1, 6, 4, -14, 0, -10, -2, 16, 17, -11 }, { 2, 0, -1, -2, 4, 3, -6, -2, 1, -1, 1, 3, -4, 1, 3, -4, -1, -1, 4, -1, 1, 0, 1, 6, -5, -7, 2, 1, -47, -3, 50, -17 }, { 8, -4, -11, -7, 11, 11, 14, -7, 12, -7, 6, 2, 13, -6, -3, -2, -14, 6, 6, 6, 0, 2, -1, 5, -20, 2, -1, 4, -5, 6, 21, -11 }, { -2, -9, 3, 0, -6, 7, 8, -8, 1, -3, 4, 1, 5, -2, -3, -7, 4, 7, -12, -9, -2, 10, -6, 13, 6, 5, 20, 2, -15, 9, 28, -7 }, { 0, -5, -6, -6, -6, 1, -6, 6, -2, 4, 8, -3, 12, -1, -4, -2, 6, 16, -14, 9, -14, -2, -8, -27, -3, 18, -1, -7, -3, 8, 23, -23 }, { 1, 4, -9, -1, -5, 10, -2, 1, -11, 1, -9, 4, 7, 14, -9, -2, -3, 2, -5, -1, -6, -10, -7, 11, 20, 2, 3, -19, 3, 15, 30, -9 }, { 7, 2, -14, -4, 0, -2, 5, 2, 5, -2, 8, -3, -7, 6, 6, -11, -14, 1, 10, -1, -7, -8, 1, 10, 3, -6, -15, -12, -17, 4, 30, -6 }, { 4, 2, 1, -2, 3, 0, 1, 0, 2, 0, 1, 6, -7, 0, 3, 4, 4, -4, -2, -5, -2, 2, -1, -2, 0, -2, -11, -7, -3, 42, 24, -14 }, { 4, 1, 3, 2, 0, -2, -3, -2, 2, -1, 4, 11, -2, 2, 3, -4, -5, 9, 2, -4, -9, 5, 8, -1, -7, 1, 24, -13, -28, 20, 15, -22 }, { -3, 7, 6, 3, -2, -5, -10, -2, -2, -1, -6, -6, -2, -14, -16, -6, -5, 0, 18, 0, 9, 1, 7, -13, -5, -6, -9, 11, -15, 9, 22, -11 }, { 9, -2, 6, 5, 2, 9, -10, 1, 1, 5, -4, 12, 2, 2, -10, -7, -4, -6, 7, 9, 6, 15, 6, 6, -10, 10, 5, -13, -5, 6, 24, -12 }, { 1, 3, -3, -3, 8, 1, -6, 2, -5, -3, 7, 2, 14, 6, 9, -6, -5, -4, 27, 7, -3, 8, -6, 3, -8, 8, 22, -5, -6, -2, 22, -17 }, { -2, -2, 3, 10, 9, 9, 12, -15, -1, -11, -13, 3, -2, 1, -3, -11, 7, 9, 16, -3, -10, -5, -5, 1, 8, -3, 9, 9, -5, 3, 31, -12 }, { 7, -5, 10, -4, -8, 2, 16, -2, 10, 10, -3, -2, 3, -8, -3, 3, -13, -6, 15, 20, -9, -3, -12, 1, -2, -16, 8, 8, -1, 16, 22, -5 }, { 5, -3, -15, -2, 12, -8, 8, -5, 2, -8, 20, -18, 14, -4, 3, 3, 7, -13, -16, 1, -10, 7, 16, 7, 4, -14, -4, -5, -9, 8, 23, -6 }, { 5, -4, -5, -4, 1, 8, 4, -7, -5, 8, 10, 6, -6, -10, -2, 6, 9, -17, -14, 11, 12, -3, -13, -7, 2, 18, 3, -25, -16, 18, 22, -5 }, { 5, 6, -7, -20, -4, 2, 8, 4, -24, -4, 1, 4, -5, -2, 1, -10, -2, 9, 3, -4, -3, -4, -4, -4, 10, 10, 3, 0, -6, 25, 21, -11 }, { 0, 7, -1, 14, -6, -4, -10, 5, 4, 4, 4, -5, 3, 4, -1, -7, 8, -19, 0, 6, 2, 3, -18, -3, -6, 2, 8, 14, -26, 22, 27, -13 }, { -2, -6, 7, -5, 12, -7, 8, -1, 3, -2, 4, 1, 8, -2, 0, 14, 6, -5, 6, -4, -7, 7, -21, 8, 1, 8, -9, -4, -3, 11, 25, -13 }, { 4, 4, -1, -6, 4, 9, -8, 1, -3, -10, -2, 0, 15, -9, -16, 11, 1, 1, 6, 3, -9, -5, 16, 26, 1, -14, 1, -3, -14, 7, 15, -9 }, { -12, -2, -9, -13, 2, 6, 14, 0, 1, 0, -1, -13, 0, 10, -1, 6, 9, -7, 8, 8, 19, 6, -1, 9, 10, -4, 1, -7, -22, -2, 29, -7 }, { 2, 4, 13, -12, -8, -4, -5, 13, 12, -5, -3, -3, -4, 1, -1, 10, 15, -6, -1, -11, -30, 4, 15, -1, 9, -7, 0, -2, -7, 10, 25, -16 }, { 7, -15, -7, -7, -1, -5, -5, -11, -20, 10, 3, -10, -3, 5, 20, -4, 0, -2, -2, 17, 2, 0, -3, 3, 6, 5, -1, -12, -3, 15, 22, -16 }, { 4, -1, 3, 4, -5, 0, -1, -5, -24, -29, 4, -9, 1, -3, 0, 0, 0, -4, 7, -4, -4, -4, 3, 1, -6, 5, -3, -5, -10, 3, 25, -10 }, { -2, -1, -1, 4, 4, -1, 2, 0, -4, -4, 2, -1, -3, -1, -2, -2, 1, -3, -5, -1, 2, -3, -4, -4, -3, 5, -9, 1, -11, 7, 46, -46 }, { 0, -9, 3, 4, 4, 3, -5, -6, 5, -4, 4, -2, 1, 7, -4, -10, 13, 1, 3, -6, 4, -4, 7, 2, -19, -25, -3, -16, -12, 16, 20, -1 }, { 18, 6, 4, -12, 0, -14, 9, -6, -1, -4, -5, 2, 1, 12, 4, 2, 7, 0, 2, 5, -11, -5, -2, 2, -4, 10, 0, -9, -7, 9, 25, -8 }, { 5, 0, -6, 5, 6, 3, 3, -10, -5, 1, -1, 4, 3, -11, -8, 5, 4, -5, 5, -5, -7, -5, 11, 5, 20, -8, -16, 21, -4, 27, 23, -5 } }; ================================================ FILE: libdcadec/dca_context.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 "core_decoder.h" #include "exss_parser.h" #include "xll_decoder.h" #include "lbr_decoder.h" #include "fixed_math.h" #define MAX_PACKET_SIZE 0x104000 #define PACKET_CORE 0x01 #define PACKET_EXSS 0x02 #define PACKET_XLL 0x04 #define PACKET_LBR 0x08 #define PACKET_FILTERED 0x100 #define PACKET_RECOVERY 0x200 #define dca_warn_once(...) \ dca_format_log(dca, DCADEC_LOG_WARNING | DCADEC_LOG_ONCE, __FILE__, __LINE__, __VA_ARGS__) struct dcadec_context { dcadec_log_cb log_cb; ///< Logging callback function void *log_cbarg; ///< Logging callback argument int log_shown; ///< Bitmask of logging levels shown once int flags; ///< Context flags passed to dcadec_context_create() int packet; ///< Packet flags set by dcadec_context_parse() struct core_decoder *core; ///< Core decoder context struct exss_parser *exss; ///< EXSS parser context struct xll_decoder *xll; ///< XLL decoder context struct lbr_decoder *lbr; ///< LBR decoder context bool has_residual_encoded; ///< XLL residual encoded channels present bool core_residual_valid; ///< Core valid for residual decoding int *dmix_sample_buffer; ///< Primary channel set downmixing buffer int status; ///< Filtering status int nframesamples; ///< Number of PCM samples per channel int sample_rate; ///< Sample rate in Hz int bits_per_sample; ///< PCM resolution in bits int profile; ///< Type of DTS profile decoded int channel_mask; ///< Channel or speaker mask int *samples[SPEAKER_COUNT]; ///< Sample buffer pointers }; static const uint8_t dca2wav_norm[] = { WAVESPKR_FC, WAVESPKR_FL, WAVESPKR_FR, WAVESPKR_SL, WAVESPKR_SR, WAVESPKR_LFE, WAVESPKR_BC, WAVESPKR_BL, WAVESPKR_BR, WAVESPKR_SL, WAVESPKR_SR, WAVESPKR_FLC, WAVESPKR_FRC, WAVESPKR_TFL, WAVESPKR_TFC, WAVESPKR_TFR, WAVESPKR_LFE, WAVESPKR_FLC, WAVESPKR_FRC, WAVESPKR_TC, WAVESPKR_TFL, WAVESPKR_TFR, WAVESPKR_TBC, WAVESPKR_TBL, WAVESPKR_TBR, WAVESPKR_BC, WAVESPKR_BL, WAVESPKR_BR }; static const uint8_t dca2wav_wide[] = { WAVESPKR_FC, WAVESPKR_FL, WAVESPKR_FR, WAVESPKR_BL, WAVESPKR_BR, WAVESPKR_LFE, WAVESPKR_BC, WAVESPKR_BL, WAVESPKR_BR, WAVESPKR_SL, WAVESPKR_SR, WAVESPKR_FLC, WAVESPKR_FRC, WAVESPKR_TFL, WAVESPKR_TFC, WAVESPKR_TFR, WAVESPKR_LFE, WAVESPKR_SL, WAVESPKR_SR , WAVESPKR_TC, WAVESPKR_TFL, WAVESPKR_TFR, WAVESPKR_TBC, WAVESPKR_TBL, WAVESPKR_TBR, WAVESPKR_BC, WAVESPKR_BL, WAVESPKR_BR }; void dca_format_log(struct dcadec_context *dca, int level, const char *file, int line, const char *fmt, ...) { char buffer[1024]; va_list ap; if (!dca || !dca->log_cb) return; if (level & DCADEC_LOG_ONCE) { level &= ~DCADEC_LOG_ONCE; if (dca->log_shown & (1 << level)) return; dca->log_shown |= 1 << level; } va_start(ap, fmt); vsnprintf(buffer, sizeof(buffer), fmt, ap); va_end(ap); dca->log_cb(level, file, line, buffer, dca->log_cbarg); } static int reorder_samples(struct dcadec_context *dca, int **dca_samples, int dca_mask) { int nchannels = 0; if (dca->flags & DCADEC_FLAG_NATIVE_LAYOUT) { for (int dca_ch = 0; dca_ch < SPEAKER_COUNT; dca_ch++) { if (dca_mask & (1U << dca_ch)) { if (!dca_samples[dca_ch]) return -DCADEC_EINVAL; dca->samples[nchannels++] = dca_samples[dca_ch]; } } dca->channel_mask = dca_mask; } else { int wav_mask = 0; int *wav_samples[WAVESPKR_COUNT] = { NULL }; const uint8_t *dca2wav; if (dca_mask == SPEAKER_LAYOUT_7POINT0_WIDE || dca_mask == SPEAKER_LAYOUT_7POINT1_WIDE) dca2wav = dca2wav_wide; else dca2wav = dca2wav_norm; for (size_t dca_ch = 0; dca_ch < sizeof(dca2wav_norm); dca_ch++) { if (dca_mask & (1 << dca_ch)) { if (!dca_samples[dca_ch]) return -DCADEC_EINVAL; int wav_ch = dca2wav[dca_ch]; if (!wav_samples[wav_ch]) { wav_samples[wav_ch] = dca_samples[dca_ch]; wav_mask |= 1 << wav_ch; } } } for (int wav_ch = 0; wav_ch < WAVESPKR_COUNT; wav_ch++) { if (wav_mask & (1 << wav_ch)) { dca->samples[nchannels++] = wav_samples[wav_ch]; } } dca->channel_mask = wav_mask; } return nchannels; } static bool shift_and_clip__(int *samples, int nsamples, int shift, int bits) { bool clipped = false; for (int n = 0; n < nsamples; n++) { int s = samples[n] * (1 << shift); #ifdef __ARM_FEATURE_SAT s = clip__(s, bits); #else if ((s + (1 << bits)) & ~((1 << (bits + 1)) - 1)) { s = (s >> 31) ^ ((1 << bits) - 1); clipped = true; } #endif samples[n] = s; } return clipped; } static bool shift_and_clip(struct dcadec_context *dca, int nchannels, int storage_bit_res, int pcm_bit_res) { int shift = storage_bit_res - pcm_bit_res; int nsamples = dca->nframesamples; if (dca->flags & DCADEC_FLAG_DONT_CLIP) { if (shift) for (int ch = 0; ch < nchannels; ch++) for (int n = 0; n < nsamples; n++) dca->samples[ch][n] *= 1 << shift; return false; } bool clipped = false; switch (storage_bit_res) { case 24: for (int ch = 0; ch < nchannels; ch++) clipped |= shift_and_clip__(dca->samples[ch], nsamples, shift, 23); break; case 16: for (int ch = 0; ch < nchannels; ch++) clipped |= shift_and_clip__(dca->samples[ch], nsamples, shift, 15); break; default: assert(0); break; } return clipped; } static int get_dmix_coeff(int nchannels, int spkr, int ch) { switch (spkr) { case SPEAKER_C: case SPEAKER_Cs: return (nchannels == 1) ? 23170 : 16423; case SPEAKER_L: return (ch == 0) ? 23170 : 0; case SPEAKER_R: return (ch == 1) ? 23170 : 0; case SPEAKER_Ls: return (ch == 0) ? 16423 : 0; case SPEAKER_Rs: return (ch == 1) ? 16423 : 0; default: return 0; } } static int down_mix_prim_chset(struct dcadec_context *dca, bool dmix_embedded, int dmix_type, int *dmix_coeff_cur, int *dmix_coeff_pre, int **samples, int nsamples, int *ch_mask) { // No action if already 2.0 if (*ch_mask == SPEAKER_LAYOUT_STEREO) return 0; if (dmix_embedded && dmix_type != DMIX_TYPE_LoRo) { dca_warn_once("Unsupported primary channel set downmix type (%d)", dmix_type); dmix_embedded = false; } if (!dmix_embedded) { // Remove LFE channel if 2.1 if (*ch_mask == SPEAKER_LAYOUT_2POINT1) { *ch_mask = SPEAKER_LAYOUT_STEREO; return 0; } // Unless both KEEP_DMIX flags are set, perform 2.0 downmix only when // custom matrix is present if (!(dca->flags & DCADEC_FLAG_KEEP_DMIX_6CH)) return 0; } assert(nsamples > 1); // Reallocate downmix sample buffer if (ta_alloc_fast(dca, &dca->dmix_sample_buffer, 2 * nsamples, sizeof(int)) < 0) return -DCADEC_ENOMEM; memset(dca->dmix_sample_buffer, 0, 2 * nsamples * sizeof(int)); int nchannels = dca_popcount(*ch_mask); int nsamples_log2 = 31 - dca_clz(nsamples); // Perform downmix for (int spkr = 0, pos = 0; spkr < SPEAKER_COUNT; spkr++) { if (!(*ch_mask & (1U << spkr))) continue; int *src = samples[spkr]; int *dst = dca->dmix_sample_buffer; for (int ch = 0; ch < 2; ch++) { int coeff_cur, coeff_pre; // Use custom matrix if present. Otherwise use default matrix that // covers all supported core audio channel arrangements. if (dmix_embedded) { coeff_cur = dmix_coeff_cur[ch * nchannels + pos]; coeff_pre = dmix_coeff_pre[ch * nchannels + pos]; } else { coeff_cur = coeff_pre = get_dmix_coeff(nchannels, spkr, ch); } int delta = coeff_cur - coeff_pre; if (delta) { // Downmix coefficient interpolation int ramp = 1 << (nsamples_log2 - 1); for (int n = 0; n < nsamples; n++, ramp += delta) dst[n] += mul15(src[n], coeff_pre + (ramp >> nsamples_log2)); } else if (coeff_cur) { for (int n = 0; n < nsamples; n++) dst[n] += mul15(src[n], coeff_cur); } dst += nsamples; } pos++; } samples[SPEAKER_L] = dca->dmix_sample_buffer; samples[SPEAKER_R] = dca->dmix_sample_buffer + nsamples; *ch_mask = SPEAKER_LAYOUT_STEREO; return 1; } static int filter_core_frame(struct dcadec_context *dca) { struct core_decoder *core = dca->core; // Filter core frame int ret; if ((ret = core_filter(core, dca->flags)) < 0) { dca->core_residual_valid = false; return ret; } dca->core_residual_valid = !!(dca->flags & DCADEC_FLAG_CORE_BIT_EXACT); // Downmix core channels to Lo/Ro if (dca->flags & DCADEC_FLAG_KEEP_DMIX_2CH) { if ((ret = down_mix_prim_chset(dca, core->prim_dmix_embedded, core->prim_dmix_type, core->prim_dmix_coeff, core->prim_dmix_coeff, core->output_samples, core->npcmsamples, &core->ch_mask)) < 0) return ret; } // Reorder sample buffer pointers int nchannels; if ((nchannels = reorder_samples(dca, core->output_samples, core->ch_mask)) <= 0) return -DCADEC_EINVAL; dca->nframesamples = core->npcmsamples; dca->sample_rate = core->output_rate; dca->bits_per_sample = 24; // Set profile if (core->ext_audio_mask & (EXSS_XBR | EXSS_XXCH | EXSS_X96)) dca->profile = DCADEC_PROFILE_HD_HRA; else if (core->ext_audio_mask & (CSS_XXCH | CSS_XCH)) dca->profile = DCADEC_PROFILE_DS_ES; else if (core->ext_audio_mask & CSS_X96) dca->profile = DCADEC_PROFILE_DS_96_24; else dca->profile = DCADEC_PROFILE_DS; // Perform clipping after Lo/Ro downmix if (ret > 0) shift_and_clip(dca, nchannels, 24, 24); return 0; } static int map_spkr_to_core_spkr(struct core_decoder *core, int spkr) { if (core->ch_mask & (1U << spkr)) return spkr; if (spkr == SPEAKER_Lss && (core->ch_mask & SPEAKER_MASK_Ls)) return SPEAKER_Ls; if (spkr == SPEAKER_Rss && (core->ch_mask & SPEAKER_MASK_Rs)) return SPEAKER_Rs; return -1; } static bool is_hier_dmix_chset(struct xll_chset *c) { return !c->primary_chset && c->dmix_embedded && c->hier_chset; } static struct xll_chset *find_next_hier_dmix_chset(struct xll_chset *c) { struct xll_decoder *xll = c->decoder; if (c->hier_chset) while (++c < &xll->chset[xll->nchsets]) if (is_hier_dmix_chset(c)) return c; return NULL; } static void prescale_down_mix(struct xll_chset *c, struct xll_chset *o) { int *coeff_ptr = c->dmix_coeff_cur; for (int i = 0; i < c->hier_m; i++) { int scale = o->dmix_scale_cur[i]; int scale_inv = o->dmix_scale_inv_cur[i]; c->dmix_scale_cur[i] = mul15(c->dmix_scale_cur[i], scale); c->dmix_scale_inv_cur[i] = mul16(c->dmix_scale_inv_cur[i], scale_inv); for (int j = 0; j < c->nchannels; j++) { int coeff = mul16(*coeff_ptr, scale_inv); *coeff_ptr++ = mul15(coeff, o->dmix_scale_cur[c->hier_m + j]); } } } struct downmix { int *samples[XLL_MAX_BANDS][SPEAKER_COUNT]; int *deci_history[SPEAKER_COUNT]; }; static void undo_down_mix(struct xll_chset *c, struct downmix *dmix, int band) { struct xll_decoder *xll = c->decoder; struct xll_band *b = &c->bands[band]; int nsamples = xll->nframesamples; int nsamples_log2 = xll->nframesamples_log2; if (!b->dmix_embedded) return; for (int i = 0; i < c->hier_m; i++) { for (int j = 0; j < c->nchannels; j++) { int coeff_cur = c->dmix_coeff_cur[i * c->nchannels + j]; int coeff_pre = c->dmix_coeff_pre[i * c->nchannels + j]; int delta = coeff_cur - coeff_pre; // Undo downmix of channel samples int *src = b->msb_sample_buffer[j]; int *dst = dmix->samples[band][i]; if (delta) { // Downmix coefficient interpolation int ramp = 1 << (nsamples_log2 - 1); for (int k = 0; k < nsamples; k++, ramp += delta) dst[k] -= mul15(src[k], coeff_pre + (ramp >> nsamples_log2)); } else if (coeff_cur) { for (int k = 0; k < nsamples; k++) dst[k] -= mul15(src[k], coeff_cur); } // Undo downmix of decimator history if (band == XLL_BAND_1 && coeff_pre) for (int k = 1; k < XLL_DECI_HISTORY; k++) dmix->deci_history[i][k] -= mul15(c->deci_history[j][k], coeff_pre); } } } static void scale_down_mix(struct xll_chset *c, struct downmix *dmix, int band) { struct xll_decoder *xll = c->decoder; struct xll_band *b = &c->bands[band]; int nsamples = xll->nframesamples; int nsamples_log2 = xll->nframesamples_log2; if (!b->dmix_embedded) return; for (int i = 0; i < c->hier_m; i++) { int scale_cur = c->dmix_scale_cur[i]; int scale_pre = c->dmix_scale_pre[i]; int delta = scale_cur - scale_pre; // Scale down channel samples int *buf = dmix->samples[band][i]; if (delta) { // Scaling coefficient interpolation int ramp = 1 << (nsamples_log2 - 1); for (int k = 0; k < nsamples; k++, ramp += delta) buf[k] = mul15(buf[k], scale_pre + (ramp >> nsamples_log2)); } else if (scale_cur != (1 << 15)) { for (int k = 0; k < nsamples; k++) buf[k] = mul15(buf[k], scale_cur); } // Scale down decimator history if (band == XLL_BAND_1 && scale_pre != (1 << 15)) for (int k = 1; k < XLL_DECI_HISTORY; k++) dmix->deci_history[i][k] = mul15(dmix->deci_history[i][k], scale_pre); } } static int hier_down_mix(struct xll_decoder *xll) { struct downmix dmix; struct xll_chset *c; int i, nchannels = 0; // Build channel vectors for active channel sets that are part of hierarchy for (i = 0, c = xll->chset; i < xll->nactivechsets; i++, c++) { if (!c->hier_chset) continue; if (nchannels + c->nchannels > SPEAKER_COUNT) return -DCADEC_EINVAL; for (int ch = 0; ch < c->nchannels; ch++) { dmix.samples[XLL_BAND_0][nchannels] = c->bands[XLL_BAND_0].msb_sample_buffer[ch]; dmix.samples[XLL_BAND_1][nchannels] = c->bands[XLL_BAND_1].msb_sample_buffer[ch]; dmix.deci_history[nchannels] = c->deci_history[ch]; nchannels++; } } // Walk through hierarchial downmix embedded channel sets for (i = 0, c = xll->chset; i < xll->nchsets; i++, c++) { if (!is_hier_dmix_chset(c)) continue; // Stop once enough channels are decoded for downmixed output if (c->hier_m > nchannels) c->hier_m = nchannels; if (c->hier_m == nchannels) { // Scale down preceding channels in all frequency bands scale_down_mix(c, &dmix, XLL_BAND_0); if (c->nfreqbands > 1) scale_down_mix(c, &dmix, XLL_BAND_1); break; } // Undo downmix of preceding channels in all frequency bands undo_down_mix(c, &dmix, XLL_BAND_0); if (c->nfreqbands > 1) undo_down_mix(c, &dmix, XLL_BAND_1); } return 0; } static int validate_hd_ma_frame(struct dcadec_context *dca) { struct xll_decoder *xll = dca->xll; struct xll_chset *p = &xll->chset[0], *c; int i; // Validate the first (primary) channel set if (!p->primary_chset) { xll_err_once("The first channel set must be primary"); return -DCADEC_ENOSUP; } if (!p->ch_mask_enabled && p->nchannels != 2) { xll_err_once("Unsupported number of channels with channel mask " "disabled for primary channel set (%d)", p->nchannels); return -DCADEC_ENOSUP; } if (p->storage_bit_res != 16 && p->storage_bit_res != 24) { xll_err_once("Unsupported storage bit resolution for " "primary channel set (%d)", p->storage_bit_res); return -DCADEC_ENOSUP; } if (p->pcm_bit_res > p->storage_bit_res) { xll_err("Invalid PCM bit resolution for primary channel set (%d > %d)", p->pcm_bit_res, p->storage_bit_res); return -DCADEC_EINVAL; } // Validate channel sets dca->has_residual_encoded = false; for (i = 0, c = xll->chset; i < xll->nactivechsets; i++, c++) { if (i > 0) { if (c->primary_chset) { xll_err_once("Multiple primary channel sets are not supported"); return -DCADEC_ENOSUP; } if (!c->ch_mask_enabled) { xll_err_once("Secondary channel sets with channel mask " "disabled are not supported"); return -DCADEC_ENOSUP; } if (c->dmix_embedded && !c->hier_chset) { xll_err_once("Channel sets with embedded parallel downmix " "are not supported"); return -DCADEC_ENOSUP; } if (c->freq != p->freq || c->pcm_bit_res != p->pcm_bit_res || c->storage_bit_res != p->storage_bit_res || c->nfreqbands != p->nfreqbands) { xll_err_once("Channel sets with different audio " "characteristics are not supported"); return -DCADEC_ENOSUP; } } if (c->interpolate) { xll_err_once("Channel sets with sampling frequency modifier " "are not supported"); return -DCADEC_ENOSUP; } dca->has_residual_encoded |= c->residual_encode != (1 << c->nchannels) - 1; } // Verify that core is compatible if there are residual encoded channel sets if (dca->has_residual_encoded) { if (!(dca->packet & PACKET_CORE)) { xll_err("Residual encoded channels are present without core"); return -DCADEC_EINVAL; } int rate = dca->core->sample_rate; int nsamples = dca->core->npcmblocks * NUM_PCMBLOCK_SAMPLES; // Double sampling frequency if needed if (p->freq == 96000 && rate == 48000) { rate *= 2; nsamples *= 2; } if (p->freq != rate) { xll_err_once("Sample rate mismatch between core (%d) and XLL (%d)", rate, p->freq); return -DCADEC_ENOSUP; } if (xll->nframesamples != nsamples) { xll_err("Number of samples per frame mismatch between core (%d) " "and XLL (%d)", nsamples, xll->nframesamples); return -DCADEC_EINVAL; } } return 0; } static void force_lossy_output(struct core_decoder *core, struct xll_chset *c) { // Clear all band data xll_clear_band_data(c, XLL_BAND_0); if (c->nfreqbands > 1) xll_clear_band_data(c, XLL_BAND_1); // Replace non-residual encoded channels with lossy counterparts for (int ch = 0; ch < c->nchannels; ch++) { if (!(c->residual_encode & (1 << ch))) continue; int spkr = xll_map_ch_to_spkr(c, ch); if (spkr < 0) continue; int core_spkr = map_spkr_to_core_spkr(core, spkr); if (core_spkr < 0) continue; c->residual_encode &= ~(1 << ch); } } static int filter_residual_core_frame(struct dcadec_context *dca) { struct core_decoder *core = dca->core; struct xll_decoder *xll = dca->xll; int i, ret, flags = DCADEC_FLAG_CORE_BIT_EXACT | DCADEC_FLAG_KEEP_DMIX_6CH; struct xll_chset *c; // Double sampling frequency if needed if (xll->chset->freq == 96000 && core->sample_rate == 48000) flags |= DCADEC_FLAG_CORE_SYNTH_X96; // Filter core frame if ((ret = core_filter(core, flags)) < 0) { dca->core_residual_valid = false; return ret; } // Force lossy downmixed output if this is the first core frame since // the last time history was cleared, or XLL decoder is recovering from sync loss if ((dca->has_residual_encoded && !dca->core_residual_valid && xll->nchsets > 1) || (dca->packet & PACKET_RECOVERY)) { for (i = 0, c = xll->chset; i < xll->nchsets; i++, c++) { if (i < xll->nactivechsets) force_lossy_output(core, c); if (!c->primary_chset) c->dmix_embedded = false; } xll->scalable_lsbs = false; xll->fixed_lsb_width = 0; } dca->core_residual_valid = true; return 0; } static int combine_residual_core_frame(struct dcadec_context *dca, struct xll_chset *c) { struct core_decoder *core = dca->core; struct xll_decoder *xll = dca->xll; int nsamples = xll->nframesamples; int nsamples_log2 = xll->nframesamples_log2; if (c->freq != core->output_rate) return -DCADEC_EINVAL; if (nsamples != core->npcmsamples) return -DCADEC_EINVAL; // See if this channel set is downmixed and find the next channel set in // hierarchy. If downmixed, undo core pre-scaling before combining with // residual (residual is not scaled). struct xll_chset *o = find_next_hier_dmix_chset(c); // Reduce core bit width and combine with residual for (int ch = 0; ch < c->nchannels; ch++) { if (c->residual_encode & (1 << ch)) continue; int spkr = xll_map_ch_to_spkr(c, ch); if (spkr < 0) return -DCADEC_EINVAL; int core_spkr = map_spkr_to_core_spkr(core, spkr); if (core_spkr < 0) return -DCADEC_EINVAL; int shift = 24 - c->pcm_bit_res; // Account for LSB width if (xll->scalable_lsbs) shift += xll_get_lsb_width(c, XLL_BAND_0, ch); if (shift > 24) return -DCADEC_EINVAL; int round = shift > 0 ? 1 << (shift - 1) : 0; int *dst = c->bands[XLL_BAND_0].msb_sample_buffer[ch]; int *src = core->output_samples[core_spkr]; if (o) { // Undo embedded core downmix pre-scaling int scale_inv_cur = o->dmix_scale_inv_cur[c->hier_m + ch]; int scale_inv_pre = o->dmix_scale_inv_pre[c->hier_m + ch]; int delta = scale_inv_cur - scale_inv_pre; if (delta) { // Scaling coefficient interpolation int ramp = 1 << (nsamples_log2 - 1); for (int n = 0; n < nsamples; n++, ramp += delta) { int scale_inv = scale_inv_pre + (ramp >> nsamples_log2); dst[n] += clip23((mul16(src[n], scale_inv) + round) >> shift); } } else { for (int n = 0; n < nsamples; n++) dst[n] += clip23((mul16(src[n], scale_inv_cur) + round) >> shift); } } else { // No downmix scaling for (int n = 0; n < nsamples; n++) dst[n] += (src[n] + round) >> shift; } } return 0; } static int filter_hd_ma_frame(struct dcadec_context *dca) { struct xll_decoder *xll = dca->xll; struct xll_chset *p = &xll->chset[0], *c; int ret, i; // Filter core frame if present if (dca->packet & PACKET_CORE) if ((ret = filter_residual_core_frame(dca)) < 0) return ret; // Prepare downmixing coefficients for all channel sets for (i = xll->nchsets - 1, c = &xll->chset[i]; i >= 0; i--, c--) { // Pre-scale by next channel set in hierarchy if (is_hier_dmix_chset(c)) { struct xll_chset *o = find_next_hier_dmix_chset(c); if (o) prescale_down_mix(c, o); } // Flip buffers and mark downmix coefficients valid for the next frame c->dmix_coeffs_signature = XLL_DMIX_SIGNATURE(c); c->dmix_coeffs_parity ^= true; } // Process frequency bands for active channel sets for (i = 0, c = xll->chset; i < xll->nactivechsets; i++, c++) { xll_filter_band_data(c, XLL_BAND_0); // Check for residual encoded channel set if (c->residual_encode != (1 << c->nchannels) - 1) if ((ret = combine_residual_core_frame(dca, c)) < 0) return ret; // Assemble MSB and LSB parts after combining with core if (xll->scalable_lsbs) xll_assemble_msbs_lsbs(c, XLL_BAND_0); if (c->nfreqbands > 1) { xll_filter_band_data(c, XLL_BAND_1); xll_assemble_msbs_lsbs(c, XLL_BAND_1); } } // Undo hierarchial downmix and/or apply scaling if (xll->nchsets > 1 && (ret = hier_down_mix(xll)) < 0) return ret; // Assemble frequency bands 0 and 1 for active channel sets if (xll->nfreqbands > 1 && (ret = xll_assemble_freq_bands(xll)) < 0) return ret; // Output speaker map and channel mask int *spkr_map[SPEAKER_COUNT] = { NULL }; int ch_mask = 0; // Fake up channel mask for primary channel set if needed for LtRt decoding if (!p->ch_mask_enabled) { if (p->nchannels == 2) p->ch_mask = SPEAKER_LAYOUT_STEREO; else return -DCADEC_EINVAL; } // Build the output speaker map for (i = 0, c = xll->chset; i < xll->nactivechsets; i++, c++) { for (int ch = 0; ch < c->nchannels; ch++) { int spkr = xll_map_ch_to_spkr(c, ch); if (spkr < 0) return -DCADEC_EINVAL; if (spkr_map[spkr]) return -DCADEC_EINVAL; spkr_map[spkr] = c->out_sample_buffer[ch]; } ch_mask |= c->ch_mask; } // Normalize to regular 5.1 layout if downmixing if (dca->flags & DCADEC_FLAG_KEEP_DMIX_MASK) { if (ch_mask & SPEAKER_MASK_Lss) { spkr_map[SPEAKER_Ls] = spkr_map[SPEAKER_Lss]; ch_mask = (ch_mask & ~SPEAKER_MASK_Lss) | SPEAKER_MASK_Ls; } if (ch_mask & SPEAKER_MASK_Rss) { spkr_map[SPEAKER_Rs] = spkr_map[SPEAKER_Rss]; ch_mask = (ch_mask & ~SPEAKER_MASK_Rss) | SPEAKER_MASK_Rs; } } // Downmix primary channel set to Lo/Ro if (dca->flags & DCADEC_FLAG_KEEP_DMIX_2CH) { if ((ret = down_mix_prim_chset(dca, p->dmix_embedded, p->dmix_type, p->dmix_coeff_cur, p->dmix_coeff_pre, spkr_map, xll->nframesamples << (xll->nfreqbands - 1), &ch_mask)) < 0) return ret; } // Reorder sample buffer pointers int nchannels; if ((nchannels = reorder_samples(dca, spkr_map, ch_mask)) <= 0) return -DCADEC_EINVAL; dca->nframesamples = xll->nframesamples << (xll->nfreqbands - 1); dca->sample_rate = p->freq << (xll->nfreqbands - 1); dca->bits_per_sample = p->storage_bit_res; dca->profile = DCADEC_PROFILE_HD_MA; // Shift and clip samples to account for storage bit width bool clipped = shift_and_clip(dca, nchannels, p->storage_bit_res, p->pcm_bit_res); // Warn if this frame has not been decoded losslessly if ((dca->packet & PACKET_RECOVERY) || xll->nfailedsegs > 0) return DCADEC_WXLLLOSSY; // Warn if clipping was detected in lossless output if (clipped && !(dca->flags & DCADEC_FLAG_KEEP_DMIX_MASK)) return DCADEC_WXLLCLIPPED; return 0; } static int filter_lbr_frame(struct dcadec_context *dca) { struct lbr_decoder *lbr = dca->lbr; int ret; if ((ret = lbr_filter(lbr)) < 0) return ret; if ((ret = reorder_samples(dca, lbr->output_samples, lbr->output_mask)) <= 0) return -DCADEC_EINVAL; dca->nframesamples = 1024 << lbr->freq_range; dca->sample_rate = lbr->sample_rate; dca->bits_per_sample = 24; dca->profile = DCADEC_PROFILE_EXPRESS; shift_and_clip(dca, ret, 24, 24); return 0; } static int alloc_core_decoder(struct dcadec_context *dca) { if (!dca->core) { if (!(dca->core = ta_znew(dca, struct core_decoder))) return -DCADEC_ENOMEM; dca->core->ctx = dca; dca->core->x96_rand = 1; } return 0; } static int alloc_exss_parser(struct dcadec_context *dca) { if (!dca->exss) { if (!(dca->exss = ta_znew(dca, struct exss_parser))) return -DCADEC_ENOMEM; dca->exss->ctx = dca; } return 0; } static int alloc_xll_decoder(struct dcadec_context *dca) { if (!dca->xll) { if (!(dca->xll = ta_znew(dca, struct xll_decoder))) return -DCADEC_ENOMEM; dca->xll->ctx = dca; dca->xll->flags = dca->flags; } return 0; } static int alloc_lbr_decoder(struct dcadec_context *dca) { if (!dca->lbr) { if (!(dca->lbr = ta_znew(dca, struct lbr_decoder))) return -DCADEC_ENOMEM; dca->lbr->ctx = dca; dca->lbr->ctx_flags = dca->flags; dca->lbr->lbr_rand = 1; } return 0; } DCADEC_API int dcadec_context_parse(struct dcadec_context *dca, uint8_t *data, size_t size) { int status = 0, ret; if (!dca || !data || size < 4 || size > MAX_PACKET_SIZE || ((uintptr_t)data & 3)) return -DCADEC_EINVAL; int prev_packet = dca->packet; dca->packet = 0; // Parse backward compatible core sub-stream if (DCA_MEM32NE(data) == DCA_32BE_C(SYNC_WORD_CORE)) { if ((ret = alloc_core_decoder(dca)) < 0) return ret; if ((ret = core_parse(dca->core, data, size, dca->flags, NULL)) < 0) { dca->core_residual_valid = false; return ret; } if (ret > status) status = ret; dca->packet |= PACKET_CORE; // EXXS data must be aligned on 4-byte boundary by the caller size_t frame_size = DCA_ALIGN(dca->core->frame_size, 4); if (size - 4 > frame_size) { data += frame_size; size -= frame_size; } } struct exss_asset *asset = NULL; // Parse extension sub-stream (EXSS) if (DCA_MEM32NE(data) == DCA_32BE_C(SYNC_WORD_EXSS)) { if ((ret = alloc_exss_parser(dca)) < 0) return ret; if ((ret = exss_parse(dca->exss, data, size)) < 0) { if (dca->flags & DCADEC_FLAG_STRICT) return ret; status = DCADEC_WEXSSFAILED; } else { dca->packet |= PACKET_EXSS; asset = &dca->exss->assets[0]; } } // Parse coding components in the first EXSS asset if (dca->packet & PACKET_EXSS) { // Parse core component in EXSS if (!(dca->packet & PACKET_CORE) && (asset->extension_mask & EXSS_CORE)) { if ((ret = alloc_core_decoder(dca)) < 0) return ret; if ((ret = core_parse(dca->core, data, size, dca->flags, asset)) < 0) { dca->core_residual_valid = false; return ret; } if (ret > status) status = ret; dca->packet |= PACKET_CORE; } // Parse XLL component in EXSS if (!(dca->flags & DCADEC_FLAG_CORE_ONLY) && (asset->extension_mask & EXSS_XLL)) { if ((ret = alloc_xll_decoder(dca)) < 0) return ret; if ((ret = xll_parse(dca->xll, data, asset)) < 0) { // Conceal XLL synchronization error if (ret == -DCADEC_ENOSYNC && (prev_packet & PACKET_XLL) && (dca->packet & PACKET_CORE)) { dca->packet |= PACKET_XLL | PACKET_RECOVERY; status = DCADEC_WXLLSYNCERR; } else { if (dca->flags & DCADEC_FLAG_STRICT) return ret; status = DCADEC_WXLLFAILED; } } else { dca->packet |= PACKET_XLL; if (dca->xll->nfailedsegs) status = DCADEC_WXLLBANDERR; } } // Parse LBR component in EXSS if (!(dca->flags & DCADEC_FLAG_CORE_ONLY) && (asset->extension_mask & EXSS_LBR)) { if ((ret = alloc_lbr_decoder(dca)) < 0) return ret; if ((ret = lbr_parse(dca->lbr, data, size, asset)) < 0) { if (dca->flags & DCADEC_FLAG_STRICT) return ret; } else { dca->packet |= PACKET_LBR; } } } if (!dca->packet) return -DCADEC_ENOSYNC; // Parse core extensions in EXSS or backward compatible core sub-stream if (!(dca->flags & DCADEC_FLAG_CORE_ONLY) && (dca->packet & PACKET_CORE)) { if ((ret = core_parse_exss(dca->core, data, dca->flags, asset)) < 0) return ret; if (ret > status) status = ret; } return status; } DCADEC_API struct dcadec_core_info *dcadec_context_get_core_info(struct dcadec_context *dca) { if (dca && (dca->packet & PACKET_CORE)) return core_get_info(dca->core); return NULL; } DCADEC_API void dcadec_context_free_core_info(struct dcadec_core_info *info) { ta_free(info); } DCADEC_API struct dcadec_exss_info *dcadec_context_get_exss_info(struct dcadec_context *dca) { if (dca) { if (dca->packet & PACKET_EXSS) return exss_get_info(dca->exss); if (dca->packet & PACKET_CORE) return core_get_info_exss(dca->core); } return NULL; } DCADEC_API void dcadec_context_free_exss_info(struct dcadec_exss_info *info) { ta_free(info); } DCADEC_API int dcadec_context_filter(struct dcadec_context *dca, int ***samples, int *nsamples, int *channel_mask, int *sample_rate, int *bits_per_sample, int *profile) { int ret; if (!dca) return -DCADEC_EINVAL; if (!(dca->packet & PACKET_FILTERED)) { if (dca->packet & PACKET_LBR) { if ((ret = filter_lbr_frame(dca)) < 0) return ret; } else if (dca->packet & PACKET_XLL) { if ((ret = validate_hd_ma_frame(dca)) < 0) { if (dca->flags & DCADEC_FLAG_STRICT) return ret; if (!(dca->packet & PACKET_CORE)) return ret; if ((ret = filter_core_frame(dca)) < 0) return ret; ret = DCADEC_WXLLCONFERR; } else { if ((ret = filter_hd_ma_frame(dca)) < 0) return ret; } } else if (dca->packet & PACKET_CORE) { if ((ret = filter_core_frame(dca)) < 0) return ret; } else { return -DCADEC_EINVAL; } dca->status = ret; dca->packet |= PACKET_FILTERED; } if (samples) *samples = dca->samples; if (nsamples) *nsamples = dca->nframesamples; if (channel_mask) *channel_mask = dca->channel_mask; if (sample_rate) *sample_rate = dca->sample_rate; if (bits_per_sample) *bits_per_sample = dca->bits_per_sample; if (profile) *profile = dca->profile; return dca->status; } DCADEC_API void dcadec_context_clear(struct dcadec_context *dca) { if (dca) { core_clear(dca->core); xll_clear(dca->xll); lbr_clear(dca->lbr); dca->core_residual_valid = false; } } DCADEC_API struct dcadec_context *dcadec_context_create(int flags) { struct dcadec_context *dca = ta_znew(NULL, struct dcadec_context); if (dca) dca->flags = flags; return dca; } DCADEC_API void dcadec_context_destroy(struct dcadec_context *dca) { ta_free(dca); } DCADEC_API void dcadec_context_set_log_cb(struct dcadec_context *dca, dcadec_log_cb log_cb, void *log_cbarg) { if (dca) { dca->log_cb = log_cb; dca->log_cbarg = log_cbarg; dca->log_shown = 0; } } DCADEC_API const char *dcadec_strerror(int errnum) { static const char * const errors[] = { "Invalid argument", "Invalid bitstream format", "CRC check failed", "Bitstream navigation error", "Synchronization error", "Unsupported feature", "Memory allocation error", "PCM output overflow", "I/O error", "PCM output parameters changed" }; static const char * const warnings[] = { "Failed to parse core auxiliary data", "Failed to parse core extension", "Failed to parse EXSS", "Failed to parse XLL", "XLL synchronization error", "XLL frequency band error", "XLL configuration error", "Clipping detected in XLL output", "XLL output not lossless" }; if (errnum < 0) { unsigned int err = -errnum - 1; if (err < dca_countof(errors)) return errors[err]; else return "Unspecified error"; } else if (errnum > 0) { unsigned int warn = errnum - 1; if (warn < dca_countof(warnings)) return warnings[warn]; else return "Unspecified warning"; } else { return "No error"; } } DCADEC_API unsigned int dcadec_version(void) { return DCADEC_API_VERSION; } ================================================ FILE: libdcadec/dca_context.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 DCA_CONTEXT_H #define DCA_CONTEXT_H #include #include #include /**@{*/ /** Make compact version code that can be compared easily */ #define DCADEC_VERSION_CODE(major, minor, patch) \ (((major) << 24) | ((minor) << 12) | (patch) | 0U) /** * Version of libdcadec API. Major number gets bumped at each API change that * breaks backward compatibility. Minor number gets bumped at each API change * that remains compatible. Patch is reserved for non-API related changes. */ #define DCADEC_API_VERSION_MAJOR 0 #define DCADEC_API_VERSION_MINOR 1 #define DCADEC_API_VERSION_PATCH 0 #define DCADEC_API_VERSION \ DCADEC_VERSION_CODE(DCADEC_API_VERSION_MAJOR, \ DCADEC_API_VERSION_MINOR, \ DCADEC_API_VERSION_PATCH) /**@}*/ /**@{*/ #if (defined _WIN32) #define DCADEC_SHARED_EXPORT __declspec(dllexport) #define DCADEC_SHARED_IMPORT __declspec(dllimport) #elif (__GNUC__ >= 4) #define DCADEC_SHARED_EXPORT __attribute__((visibility("default"))) #define DCADEC_SHARED_IMPORT __attribute__((visibility("default"))) #else #define DCADEC_SHARED_EXPORT #define DCADEC_SHARED_IMPORT #endif #ifdef DCADEC_SHARED #ifdef DCADEC_INTERNAL #define DCADEC_API DCADEC_SHARED_EXPORT #else #define DCADEC_API DCADEC_SHARED_IMPORT #endif #else #define DCADEC_API #endif /**@}*/ /**@{*/ #define DCADEC_EINVAL 1 /**< Invalid argument */ #define DCADEC_EBADDATA 2 /**< Invalid bitstream format */ #define DCADEC_EBADCRC 3 /**< CRC check failed */ #define DCADEC_EBADREAD 4 /**< Bitstream navigation error */ #define DCADEC_ENOSYNC 5 /**< Synchronization error */ #define DCADEC_ENOSUP 6 /**< Unsupported feature */ #define DCADEC_ENOMEM 7 /**< Memory allocation error */ #define DCADEC_EOVERFLOW 8 /**< PCM output overflow */ #define DCADEC_EIO 9 /**< I/O error */ #define DCADEC_EOUTCHG 10 /**< PCM output parameters changed */ #define DCADEC_EFAIL 32 /**< Unspecified error */ /**@}*/ /**@{*/ #define DCADEC_WCOREAUXFAILED 1 /**< Failed to parse core auxiliary data */ #define DCADEC_WCOREEXTFAILED 2 /**< Failed to parse core extension */ #define DCADEC_WEXSSFAILED 3 /**< Failed to parse EXSS */ #define DCADEC_WXLLFAILED 4 /**< Failed to parse XLL */ #define DCADEC_WXLLSYNCERR 5 /**< XLL synchronization error */ #define DCADEC_WXLLBANDERR 6 /**< XLL frequency band error */ #define DCADEC_WXLLCONFERR 7 /**< XLL configuration error */ #define DCADEC_WXLLCLIPPED 8 /**< Clipping detected in XLL output */ #define DCADEC_WXLLLOSSY 9 /**< XLL output not lossless */ /**@}*/ /**@{*/ /** Decode DTS core only without extensions */ #define DCADEC_FLAG_CORE_ONLY 0x01 /** Force bit exact DTS core decoding */ #define DCADEC_FLAG_CORE_BIT_EXACT 0x02 /** * Force DTS core synthesis using X96 filter, with high frequency subbands set * to zero. If actual X96 data is present, it is discarded when this flag is * set. Effectively doubles output sample rate. */ #define DCADEC_FLAG_CORE_SYNTH_X96 0x04 /** Use IIR filter for floating point DTS core LFE channel interpolation */ #define DCADEC_FLAG_CORE_LFE_IIR 0x08 /** Use FIR filter for floating point DTS core LFE channel interpolation */ #define DCADEC_FLAG_CORE_LFE_FIR 0x10 /** * Extract embedded 2.0 downmix if present (or perform 5.1 to 2.0 downmix if * custom downmixing coefficients are present), otherwise extract 5.1 downmix. */ #define DCADEC_FLAG_KEEP_DMIX_2CH 0x20 /** Extract embedded 5.1 downmix (always present for 6.1 and 7.1 content) */ #define DCADEC_FLAG_KEEP_DMIX_6CH 0x40 /** Output native DTS channel layout, not WAVEFORMATEXTENSIBLE layout */ #define DCADEC_FLAG_NATIVE_LAYOUT 0x80 /** Don't conceal errors */ #define DCADEC_FLAG_STRICT 0x100 /** Don't clip returned PCM samples to output bit depth */ #define DCADEC_FLAG_DONT_CLIP 0x200 /**@}*/ /**@{*/ #define DCADEC_PROFILE_UNKNOWN 0 /**< Unknown Profile */ #define DCADEC_PROFILE_DS 0x01 /**< Digital Surround */ #define DCADEC_PROFILE_DS_96_24 0x02 /**< Digital Surround 96/24 */ #define DCADEC_PROFILE_DS_ES 0x04 /**< Digital Surround ES */ #define DCADEC_PROFILE_HD_HRA 0x08 /**< High Resolution Audio */ #define DCADEC_PROFILE_HD_MA 0x10 /**< Master Audio */ #define DCADEC_PROFILE_EXPRESS 0x20 /**< Express */ /**@}*/ /**@{*/ /** Not matrix encoded */ #define DCADEC_MATRIX_ENCODING_NONE 0 /**< Encoded for matrix surround decoding */ #define DCADEC_MATRIX_ENCODING_SURROUND 1 /**< Audio processed for headphone playback */ #define DCADEC_MATRIX_ENCODING_HEADPHONE 2 /**@}*/ /**@{*/ #define DCADEC_LOG_ERROR 0 #define DCADEC_LOG_WARNING 1 #define DCADEC_LOG_INFO 2 #define DCADEC_LOG_VERBOSE 3 #define DCADEC_LOG_DEBUG 4 /**@}*/ /** * Size in bytes of empty padding that must be present after the end of input * buffer. libdcadec may overread the input buffer up to this number of bytes. */ #define DCADEC_BUFFER_PADDING 8 struct dcadec_context; struct dcadec_core_info { int nchannels; /**< Number of primary audio channels */ int audio_mode; /**< Core audio channel arrangement (AMODE) */ int lfe_present; /**< LFE channel presence flag (can be 0, 1 or 2) */ int sample_rate; /**< Core audio sample rate in Hz */ int source_pcm_res; /**< Source PCM resolution in bits */ bool es_format; /**< Extended surround (ES) mastering flag */ int bit_rate; /**< Core stream bit rate in bytes per second, zero or negative if unavailable */ int npcmblocks; /**< Number of audio sample blocks in a frame */ bool ext_audio_present; /**< Extended audio present */ int ext_audio_type; /**< Extended audio type (only meaningful when ext_audio_present is true) */ }; struct dcadec_exss_info { int nchannels; /**< Number of audio channels encoded among all extension sub-streams */ int sample_rate; /**< Maximum encoded audio sample rate in Hz */ int bits_per_sample; /**< Highest encoded PCM resolution in bits */ int profile; /**< Type of DTS profile encoded */ bool embedded_stereo; /**< 2.0 downmix has been embedded into the stream */ bool embedded_6ch; /**< 5.1 downmix has been embedded into the stream */ int spkr_mask; /**< Speaker activity mask, zero if unavailable */ int matrix_encoding; /**< Matrix encoding type */ }; typedef void (*dcadec_log_cb)(int level, const char *file, int line, const char *message, void *cbarg); /** * Parse DTS packet. Packet data must be already converted into 16-bit * big-endian format. Caller must have already established byte stream * synchronization. Packet must start with a valid 32-bit sync word. EXSS frame * must be aligned on 4-byte boundary if present in the packet. * * @param dca Pointer to decoder context. * * @param data Pointer to packet data buffer. Buffer must be aligned on 4-byte * boundary and padded at the end with DCADEC_BUFFER_PADDING bytes. * * @param size Size in bytes of packet data. Size should not include padding. * * @return 0 or positive warning code on success, negative error code on * failure. */ DCADEC_API int dcadec_context_parse(struct dcadec_context *dca, uint8_t *data, size_t size); /** * Get information about DTS core payload of the parsed packet. * * @param dca Pointer to decoder context. * * @return Pointer to DTS core information structure on success, * NULL on failure. Returned data should be freed with * dcadec_context_free_core_info() function. */ DCADEC_API struct dcadec_core_info *dcadec_context_get_core_info(struct dcadec_context *dca); /** * Free DTS core information structure. * * @param info Pointer to DTS core information structure. */ DCADEC_API void dcadec_context_free_core_info(struct dcadec_core_info *info); /** * Get information about extension sub-stream (EXSS) payload of the parsed * packet. When no EXSS is present information about extended audio in core * sub-stream is returned. * * @param dca Pointer to decoder context. * * @return Pointer to EXSS information structure on success, * NULL on failure. Returned data should be freed with * dcadec_context_free_exss_info() function. */ DCADEC_API struct dcadec_exss_info *dcadec_context_get_exss_info(struct dcadec_context *dca); /** * Free EXSS information structure. * * @param info Pointer to EXSS information structure. */ DCADEC_API void dcadec_context_free_exss_info(struct dcadec_exss_info *info); /** * Filter the parsed packet and return per-channel PCM data. All parameters * except decoder context are optional and can be NULL. This function should be * called at least once after each successfull call to dcadec_context_parse(). * Multiple calls per packet are allowed and return the same data. * * @param dca Pointer to decoder context. * * @param samples Filled with address of array of pointers to planes * containing PCM data for active channels. This data is valid * until the next call to dcadec_context_parse() or _destroy(). * Returned array is tightly packed, there are no gaps for * missing channels. Use channel_mask to determine total number * of channels and size of returned array. By default channels * are ordered according to WAVEFORMATEXTENSIBLE specification, * but if DCADEC_FLAG_NATIVE_LAYOUT flag was set when creating * decoder context, returned channels are in native DTS order. * * @param nsamples Filled with number of PCM samples in each returned plane. * * @param channel_mask Filled with bit mask indicating active channels. 1 at * the given bit position (counting from the least * significant bit) means that the channel is present in * the array of pointers to planes, 0 otherwise. Number of * bits set to 1 indicates the total number of planes * returned. * * @param sample_rate Filled with decoded audio sample rate in Hz. * * @param bits_per_sample Filled with decoded audio PCM resolution in bits. * * @param profile Filled with type of DTS profile actually decoded. * This can be different from encoded profile since * certain extensions may be not decoded. * * @return 0 or positive warning code on success, negative * error code on failure. Return value of 0 indicates * that no errors affecting audio integrity were * detected. When profile indicates Master Audio, * positive return value indicates that audio has not * been losslessly reconstructed for at least some part * of this frame. */ DCADEC_API int dcadec_context_filter(struct dcadec_context *dca, int ***samples, int *nsamples, int *channel_mask, int *sample_rate, int *bits_per_sample, int *profile); /** * Clear all inter-frame history of the decoder. Call this before parsing * packets out of sequence, e.g. after seeking to the arbitrary position within * the DTS stream. * * @param dca Pointer to decoder context. */ DCADEC_API void dcadec_context_clear(struct dcadec_context *dca); /** * Create DTS decoder context. * * @param flags Any number of DCADEC_FLAG_* constants OR'ed together. * * @return Pointer to decoder context on success, NULL on failure. */ DCADEC_API struct dcadec_context *dcadec_context_create(int flags); /** * Destroy DTS decoder context. * * @param dca Pointer to decoder context. */ DCADEC_API void dcadec_context_destroy(struct dcadec_context *dca); /** * Set or clear logging callback for decoder context. * * @param dca Pointer to decoder context. * * @param log_cb Pointer to logging callback function. Pass NULL to disable * logging. * * @param log_cbarg Opaque pointer that will be passed through to callback * function. */ DCADEC_API void dcadec_context_set_log_cb(struct dcadec_context *dca, dcadec_log_cb log_cb, void *log_cbarg); /** * Convert negative libdcadec error code or positive warning code into string. * * @param errnum Error or warning code returned by libdcadec function. * * @return Constant string describing error or warning code. */ DCADEC_API const char *dcadec_strerror(int errnum); /** * Get libdcadec API version. * * @return API version code of the currently running libdcadec. */ DCADEC_API unsigned int dcadec_version(void); #endif ================================================ FILE: libdcadec/dca_frame.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 "dca_frame.h" #define SRC_OP(E) \ uint16_t src_0 = DCA_16##E(_src[0]); \ uint16_t src_1 = DCA_16##E(_src[1]); \ uint16_t src_2 = DCA_16##E(_src[2]); \ uint16_t src_3 = DCA_16##E(_src[3]); \ uint16_t src_4 = DCA_16##E(_src[4]); \ uint16_t src_5 = DCA_16##E(_src[5]); \ uint16_t src_6 = DCA_16##E(_src[6]); \ uint16_t src_7 = DCA_16##E(_src[7]); #define DST_OP \ _dst[0] = DCA_16BE((src_0 << 2) | ((src_1 & 0x3fff) >> 12)); \ _dst[1] = DCA_16BE((src_1 << 4) | ((src_2 & 0x3fff) >> 10)); \ _dst[2] = DCA_16BE((src_2 << 6) | ((src_3 & 0x3fff) >> 8)); \ _dst[3] = DCA_16BE((src_3 << 8) | ((src_4 & 0x3fff) >> 6)); \ _dst[4] = DCA_16BE((src_4 << 10) | ((src_5 & 0x3fff) >> 4)); \ _dst[5] = DCA_16BE((src_5 << 12) | ((src_6 & 0x3fff) >> 2)); \ _dst[6] = DCA_16BE((src_6 << 14) | ((src_7 & 0x3fff) >> 0)); DCADEC_API int dcadec_frame_convert_bitstream(uint8_t *dst, size_t *dst_size, const uint8_t *src, size_t src_size) { const uint16_t *_src = (const uint16_t *)src; uint16_t *_dst = (uint16_t *)dst; size_t count; if (!dst || !dst_size || !src || src_size < 4 || ((uintptr_t)_dst & 3)) return -DCADEC_EINVAL; if ((uintptr_t)_src & 1) _src = memcpy(_dst, _src, src_size); switch (DCA_MEM32NE(_src)) { case DCA_32BE_C(SYNC_WORD_CORE): case DCA_32BE_C(SYNC_WORD_EXSS): if (_src != _dst) memcpy(_dst, _src, src_size); *dst_size = src_size; return DCADEC_BITSTREAM_BE16; case DCA_32BE_C(SYNC_WORD_CORE_LE): case DCA_32BE_C(SYNC_WORD_EXSS_LE): count = (src_size + 1) / 2; while (count--) *_dst++ = dca_bswap16(*_src++); *dst_size = src_size; return DCADEC_BITSTREAM_LE16; case DCA_32BE_C(SYNC_WORD_CORE_BE14): count = (src_size + 15) / 16; while (count--) { SRC_OP(BE) DST_OP _src += 8; _dst += 7; } *dst_size = src_size - src_size / 8; return DCADEC_BITSTREAM_BE14; case DCA_32BE_C(SYNC_WORD_CORE_LE14): count = (src_size + 15) / 16; while (count--) { SRC_OP(LE) DST_OP _src += 8; _dst += 7; } *dst_size = src_size - src_size / 8; return DCADEC_BITSTREAM_LE14; default: return -DCADEC_ENOSYNC; } } #undef SRC_OP #undef DST_OP DCADEC_API int dcadec_frame_parse_header(const uint8_t *data, size_t *size) { struct bitstream bits; uint8_t header[DCADEC_FRAME_HEADER_SIZE]; size_t header_size, frame_size; if (!data || !size) return -DCADEC_EINVAL; int ret; if ((ret = dcadec_frame_convert_bitstream(header, &header_size, data, DCADEC_FRAME_HEADER_SIZE)) < 0) return ret; bits_init(&bits, header, header_size); switch (bits_get(&bits, 32)) { case SYNC_WORD_CORE: { bool normal_frame = bits_get1(&bits); int deficit_samples = bits_get(&bits, 5) + 1; if (normal_frame && deficit_samples != 32) return -DCADEC_ENOSYNC; bits_skip1(&bits); int npcmblocks = bits_get(&bits, 7) + 1; if ((npcmblocks & 7) && (npcmblocks < 6 || normal_frame)) return -DCADEC_ENOSYNC; frame_size = bits_get(&bits, 14) + 1; if (frame_size < 96) return -DCADEC_ENOSYNC; if (ret & DCADEC_BITSTREAM_BE14) *size = frame_size * 8 / 14 * 2; else *size = frame_size; return DCADEC_FRAME_TYPE_CORE; } case SYNC_WORD_EXSS: { bits_skip(&bits, 10); bool wide_hdr = bits_get1(&bits); header_size = bits_get(&bits, 8 + 4 * wide_hdr) + 1; if ((header_size & 3) || header_size < DCADEC_FRAME_HEADER_SIZE) return -DCADEC_ENOSYNC; frame_size = bits_get(&bits, 16 + 4 * wide_hdr) + 1; if ((frame_size & 3) || frame_size < header_size) return -DCADEC_ENOSYNC; *size = frame_size; return DCADEC_FRAME_TYPE_EXSS; } default: return -DCADEC_ENOSYNC; } } DCADEC_API size_t dcadec_frame_buffer_size(size_t size) { size_t padding = -size & (DCADEC_FRAME_BUFFER_ALIGN - 1); if (padding < DCADEC_BUFFER_PADDING) padding = DCADEC_BUFFER_PADDING; if (padding > SIZE_MAX - size) padding = SIZE_MAX - size; return size + padding; } ================================================ FILE: libdcadec/dca_frame.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 DCA_FRAME_H #define DCA_FRAME_H #include "dca_context.h" /** * Minimum size alignment, in bytes, of source and destination buffers that must * be passed to dcadec_frame_convert_bitstream(). */ #define DCADEC_FRAME_BUFFER_ALIGN 16 /** * Minimum size of data buffer, in bytes, that must be passed to * dcadec_frame_parse_header(). */ #define DCADEC_FRAME_HEADER_SIZE 16 /**@{*/ #define DCADEC_BITSTREAM_BE16 0 #define DCADEC_BITSTREAM_LE16 1 #define DCADEC_BITSTREAM_BE14 2 #define DCADEC_BITSTREAM_LE14 3 /**@}*/ /**@{*/ #define DCADEC_FRAME_TYPE_CORE 0 /**< Backward compatible DTS core */ #define DCADEC_FRAME_TYPE_EXSS 1 /**< Extension sub-stream (EXSS) */ /**@}*/ /** * Convert the raw input frame into native 16-bit big-endian format understood * by dcadec_context_parse(). Can operate in-place when destination buffer * is the same as source buffer. In all other cases destination and source * buffers must not overlap. * * @param dst Pointer to destination buffer. Destination buffer size * must be no less than source buffer size, including * padding to the next multiple of DCADEC_FRAME_BUFFER_ALIGN. * Destination buffer must be aligned on 4-byte boundary in * memory. * * @param dst_size Filled with resulting frame size after conversion, in bytes. * * @param src Pointer to source buffer that must start with a valid sync * word. Source buffer size must be no less than src_size bytes * plus padding to the next multiple of * DCADEC_FRAME_BUFFER_ALIGN. Source buffer can have any * alignment in memory. * * @param src_size Size of raw frame data prior to conversion, in bytes. Size * should not include padding. * * @return Detected bitstream format on success, negative error code * on failure. */ DCADEC_API int dcadec_frame_convert_bitstream(uint8_t *dst, size_t *dst_size, const uint8_t *src, size_t src_size); /** * Check that the passed data buffer starts with a valid sync word and satisfies * the basic requirements to be a valid DTS core or EXSS frame header. * * @param data Pointer to data buffer that possibly contains the frame * header. The first DCADEC_FRAME_HEADER_SIZE bytes are read * from the buffer. * * @param size Filled with raw frame size, in bytes. Frame size includes * sync word and header bytes. * * @return Detected frame type on success, negative error code * on failure. */ DCADEC_API int dcadec_frame_parse_header(const uint8_t *data, size_t *size); /** * Given the raw frame size returned by dcadec_frame_parse_header(), calculate * minimum required buffer size for performing bitstream format conversion and * (possibly) parsing the frame. * * It is recommended to use this function instead of calculating buffer size * manually based on DCADEC_FRAME_BUFFER_ALIGN and DCADEC_BUFFER_PADDING * constants since padding requirements may change in the future and older * headers might not reflect this. * * @param size Raw frame size, in bytes. * * @return Buffer size, in bytes, padded to the minimum value that * satisfies both dcadec_frame_convert_bitstream() alignment * requirement and dcadec_context_parse() padding requirement. */ DCADEC_API size_t dcadec_frame_buffer_size(size_t size); #endif ================================================ FILE: libdcadec/dca_stream.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 "dca_frame.h" #include "dca_stream.h" #ifdef _WIN32 #include #include #include #else #include #endif #define BUFFER_ALIGN 4096 #define AUPR_HDR UINT64_C(0x415550522D484452) #define DTSHDHDR UINT64_C(0x4454534844484452) #define STRMDATA UINT64_C(0x5354524D44415441) #if (defined _WIN32) #define DCA_FGETC _fgetc_nolock #elif (defined _BSD_SOURCE) #define DCA_FGETC fgetc_unlocked #else #define DCA_FGETC fgetc #endif struct dcadec_stream { FILE *fp; ///< Input file off_t stream_size; ///< Size of stream data off_t stream_start; ///< Starting position of stream data in file off_t stream_end; ///< Ending position of stream data in file bool aupr_present; ///< Audio presentation header flag uint32_t aupr_sample_rate; ///< Audio sample rate in Hz uint32_t aupr_nframes; ///< Number of encoded frames uint32_t aupr_nframesamples; ///< Number of PCM samples in each encoded frame uint64_t aupr_npcmsamples; ///< Number of PCM samples in original audio uint32_t aupr_ch_mask; ///< Channel mask in EXSS format uint32_t aupr_ndelaysamples; ///< Codec delay in PCM samples uint8_t *buffer; ///< Packet buffer size_t packet_size; ///< Size of packet uint32_t backup_sync; ///< Backed-up sync word bool core_plus_exss; ///< Whether previous packet was core plus extension substream }; // Check for DTS-HD container format. Such files have an extra `blackout' // frame at the end that we don't wont to parse. Called only if the stream // is seekable. static int parse_hd_hdr(struct dcadec_stream *stream) { uint64_t header[2]; if (fread(header, sizeof(header), 1, stream->fp) != 1) return fseeko(stream->fp, 0, SEEK_SET); if (header[0] != DCA_64BE_C(DTSHDHDR)) return fseeko(stream->fp, 0, SEEK_SET); while (true) { uint64_t size = DCA_64BE(header[1]); if (size > INT64_MAX) return -1; switch (header[0]) { case DCA_64BE_C(STRMDATA): { off_t pos = ftello(stream->fp); if (pos < 0) return -1; stream->stream_size = size; stream->stream_start = pos; stream->stream_end = pos + size; return 1; } case DCA_64BE_C(AUPR_HDR): { uint8_t data[21]; if (size < sizeof(data)) return -1; if (fread(data, sizeof(data), 1, stream->fp) != 1) return -1; if (fseeko(stream->fp, size - sizeof(data), SEEK_CUR) < 0) return -1; stream->aupr_present = true; // Sample rate in Hz stream->aupr_sample_rate = DCA_MEM24BE(&data[3]); // Number of frames stream->aupr_nframes = DCA_MEM32BE(&data[6]); // Number of PCM samples per frame stream->aupr_nframesamples = DCA_MEM16BE(&data[10]); // Number of PCM samples encoded stream->aupr_npcmsamples = DCA_MEM40BE(&data[12]); // EXSS channel mask stream->aupr_ch_mask = DCA_MEM16BE(&data[17]); // Codec delay in samples stream->aupr_ndelaysamples = DCA_MEM16BE(&data[19]); break; } default: if (fseeko(stream->fp, size, SEEK_CUR) < 0) return -1; break; } if (fread(header, sizeof(header), 1, stream->fp) != 1) return -1; } return -1; } static int parse_wav_hdr(struct dcadec_stream *stream) { uint32_t header[2]; if (fread(header, sizeof(header), 1, stream->fp) != 1) goto rewind; if (header[0] != DCA_32LE_C(TAG_RIFF)) goto rewind; if (fread(header, sizeof(header[0]), 1, stream->fp) != 1) goto rewind; if (header[0] != DCA_32LE_C(TAG_WAVE)) goto rewind; while (true) { if (fread(header, sizeof(header), 1, stream->fp) != 1) return -1; uint32_t size = DCA_32LE(header[1]); if (header[0] == DCA_32LE_C(TAG_data)) { off_t pos = ftello(stream->fp); if (pos < 0) return -1; if (size) { stream->stream_size = size; stream->stream_start = pos; stream->stream_end = pos + size; } return 1; } if (fseeko(stream->fp, size, SEEK_CUR) < 0) return -1; } return -1; rewind: return fseeko(stream->fp, 0, SEEK_SET); } DCADEC_API struct dcadec_stream *dcadec_stream_open(const char *name, int flags) { (void)flags; struct dcadec_stream *stream = ta_znew(NULL, struct dcadec_stream); if (!stream) return NULL; if (name) { if (!(stream->fp = fopen(name, "rb"))) goto fail1; } else { int fd; #ifdef _WIN32 if ((fd = _dup(STDIN_FILENO)) < 0) goto fail1; if (_setmode(fd, _O_BINARY) < 0) { _close(fd); goto fail1; } if (!(stream->fp = _fdopen(fd, "rb"))) { _close(fd); goto fail1; } #else if ((fd = dup(STDIN_FILENO)) < 0) goto fail1; if (!(stream->fp = fdopen(fd, "rb"))) { close(fd); goto fail1; } #endif } bool can_seek = true; #ifdef _WIN32 can_seek = GetFileType((HANDLE)_get_osfhandle(_fileno(stream->fp))) == FILE_TYPE_DISK; #endif if (can_seek && !fseeko(stream->fp, 0, SEEK_END)) { off_t pos = ftello(stream->fp); if (pos > 0) stream->stream_size = pos; if (fseeko(stream->fp, 0, SEEK_SET) < 0) goto fail2; if (pos > 0) { int ret; if ((ret = parse_hd_hdr(stream)) < 0 || (!ret && parse_wav_hdr(stream) < 0)) goto fail2; } } if (!(stream->buffer = ta_zalloc_size(stream, BUFFER_ALIGN * 2))) goto fail2; return stream; fail2: fclose(stream->fp); fail1: ta_free(stream); return NULL; } DCADEC_API void dcadec_stream_close(struct dcadec_stream *stream) { if (stream) { fclose(stream->fp); ta_free(stream); } } static uint8_t *prepare_packet_buffer(struct dcadec_stream *stream, size_t size) { size_t old_size = ta_get_size(stream->buffer); size_t new_size = DCA_ALIGN(stream->packet_size + size, BUFFER_ALIGN); if (old_size < new_size) { uint8_t *buf = ta_realloc_size(stream, stream->buffer, new_size); if (buf) { memset(buf + old_size, 0, new_size - old_size); stream->buffer = buf; } else { return NULL; } } return stream->buffer + stream->packet_size; } static int read_frame(struct dcadec_stream *stream, uint32_t *sync_p) { uint8_t header[DCADEC_FRAME_HEADER_SIZE], *buf; size_t frame_size; int ret; // Stop at position indicated by STRMDATA if known if (stream->stream_end > 0 && ftello(stream->fp) >= stream->stream_end) return 0; // Start with a backed up sync word. If there is none, advance one byte at // a time until proper sync word is read from the input byte stream. uint32_t sync = stream->backup_sync; while (sync != SYNC_WORD_CORE && sync != SYNC_WORD_EXSS && sync != SYNC_WORD_CORE_LE && sync != SYNC_WORD_EXSS_LE && sync != SYNC_WORD_CORE_LE14 && sync != SYNC_WORD_CORE_BE14) { int c = DCA_FGETC(stream->fp); if (c == EOF) return 0; sync = (sync << 8) | c; } // Tried to read the second (EXSS) frame and it was core again. Back up // the sync word just read and return. if ((sync != SYNC_WORD_EXSS && sync != SYNC_WORD_EXSS_LE) && !sync_p) { stream->backup_sync = sync; return -DCADEC_ENOSYNC; } // Clear backed up sync word stream->backup_sync = 0; // Restore sync word header[0] = (sync >> 24) & 0xff; header[1] = (sync >> 16) & 0xff; header[2] = (sync >> 8) & 0xff; header[3] = (sync >> 0) & 0xff; // Read the frame header if (fread(header + 4, sizeof(header) - 4, 1, stream->fp) != 1) return 0; // Parse and validate the frame header if ((ret = dcadec_frame_parse_header(header, &frame_size)) < 0) return ret; // Reallocate packet buffer if (!(buf = prepare_packet_buffer(stream, dcadec_frame_buffer_size(frame_size)))) return -DCADEC_ENOMEM; // Restore frame header memcpy(buf, header, sizeof(header)); // Read the rest of the frame if (fread(buf + sizeof(header), frame_size - sizeof(header), 1, stream->fp) != 1) return 0; // Convert the frame in place if ((ret = dcadec_frame_convert_bitstream(buf, &frame_size, buf, frame_size)) < 0) return ret; // Align frame size to 4-byte boundary stream->packet_size += DCA_ALIGN(frame_size, 4); if (sync_p) *sync_p = sync; return 1; } DCADEC_API int dcadec_stream_read(struct dcadec_stream *stream, uint8_t **data, size_t *size) { uint32_t sync; int ret; if (!stream || !data || !size) return -DCADEC_EINVAL; // Loop until valid DTS core or standalone EXSS frame is read or EOF is // reached while (true) { ret = read_frame(stream, &sync); if (ret == 1) break; if (ret == 0) return ferror(stream->fp) ? -DCADEC_EIO : 0; if (ret < 0 && ret != -DCADEC_ENOSYNC) return ret; } // Check for EXSS that may follow core frame and try to concatenate both // frames into single packet if (sync == SYNC_WORD_CORE || sync == SYNC_WORD_CORE_LE) { ret = read_frame(stream, NULL); if (ret < 0 && ret != -DCADEC_ENOSYNC) return ret; // If the previous frame was core + EXSS, skip the incomplete (core // only) frame at end of file if (ret == 0 && stream->core_plus_exss) return 0; stream->core_plus_exss = (ret == 1); } else { stream->core_plus_exss = false; } *data = stream->buffer; *size = stream->packet_size; stream->packet_size = 0; return 1; } DCADEC_API int dcadec_stream_progress(struct dcadec_stream *stream) { if (stream && stream->stream_size > 0) { off_t pos = ftello(stream->fp); if (pos < stream->stream_start) return 0; if (pos >= stream->stream_start + stream->stream_size) return 100; return (int)((pos - stream->stream_start) * 100 / stream->stream_size); } return -1; } DCADEC_API struct dcadec_stream_info *dcadec_stream_get_info(struct dcadec_stream *stream) { if (!stream || !stream->aupr_present) return NULL; struct dcadec_stream_info *info = ta_znew(NULL, struct dcadec_stream_info); if (!info) return NULL; info->stream_size = stream->stream_size; info->sample_rate = stream->aupr_sample_rate; info->nframes = stream->aupr_nframes; info->nframesamples = stream->aupr_nframesamples; info->npcmsamples = stream->aupr_npcmsamples; info->ch_mask = stream->aupr_ch_mask; info->ndelaysamples = stream->aupr_ndelaysamples; return info; } DCADEC_API void dcadec_stream_free_info(struct dcadec_stream_info *info) { ta_free(info); } ================================================ FILE: libdcadec/dca_stream.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 DCA_STREAM_H #define DCA_STREAM_H #include "dca_context.h" struct dcadec_stream; struct dcadec_stream_info { uint64_t stream_size; /**< Size of encoded DTS stream data, in bytes */ uint32_t sample_rate; /**< Audio sample rate in Hz */ uint32_t nframes; /**< Total number of encoded frames */ uint32_t nframesamples; /**< Number of PCM samples in each encoded frame */ uint64_t npcmsamples; /**< Total number of PCM samples in original audio */ uint32_t ch_mask; /**< Channel mask in EXSS format */ uint32_t ndelaysamples; /**< Codec delay in PCM samples */ }; /** * Open DTS stream from file or standard input. * * @param name Name of the file to be opened. Pass NULL to open standard input. * * @param flags Currently unused, should be 0. * * @return Stream handle on success, NULL on failure. */ DCADEC_API struct dcadec_stream *dcadec_stream_open(const char *name, int flags); /** * Close DTS stream. * * @param stream Stream handle. */ DCADEC_API void dcadec_stream_close(struct dcadec_stream *stream); /** * Establish synchronization and read the next packet from DTS stream. * * @param stream Stream handle. * * @param data Filled with pointer to packet data. This data is only * valid until the next call to dcadec_stream_read() or * dcadec_stream_close() functions. Packet data is padded * with DCADEC_BUFFER_PADDING bytes at the end and can be * directly passed to dcadec_context_parse() function. * * @param size Filled with size of packet data, in bytes. * * @return Positive value on success, 0 on EOF, negative error code on * failure. */ DCADEC_API int dcadec_stream_read(struct dcadec_stream *stream, uint8_t **data, size_t *size); /** * Return DTS stream progress percentage based on current file position. * * @param stream Stream handle. * * @return Progress value in range 0-100 on success, -1 on failure. */ DCADEC_API int dcadec_stream_progress(struct dcadec_stream *stream); /** * Get audio presentation information from DTS-HD container. For raw DTS streams * this function always fails. * * @param stream Stream handle. * * @return Pointer to information structure on success, * NULL on failure. Returned data should be freed with * dcadec_stream_free_info() function. */ DCADEC_API struct dcadec_stream_info *dcadec_stream_get_info(struct dcadec_stream *stream); /** * Free audio presentation information structure. * * @param info Pointer to information structure. */ DCADEC_API void dcadec_stream_free_info(struct dcadec_stream_info *info); #endif ================================================ FILE: libdcadec/dca_waveout.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 "dca_waveout.h" #ifdef _WIN32 #include #include #include #else #include #endif struct dcadec_waveout { FILE *fp[SPEAKER_COUNT]; ///< Output file(s) uint64_t size; ///< Size of PCM data written uint8_t *buffer; ///< PCM data conversion buffer char *pattern; ///< Filename pattern for writing multiple mono files int flags; ///< Option flags passed to dcadec_waveout_open() int channel_mask; ///< WAVEFORMATEXTENSIBLE channel mask int nchannels; ///< Number of channels int sample_rate; ///< Audio sample rate int bits_per_sample; ///< Audio PCM resolution int bytes_per_sample; ///< Number of bytes per sample int block_align; ///< Alignment of PCM data block }; static const char * const dca_speaker_names[] = { "C", "L", "R", "Ls", "Rs", "LFE", "Cs", "Lsr", "Rsr", "Lss", "Rss", "Lc", "Rc", "Lh", "Ch", "Rh", "LFE2", "Lw", "Rw", "Oh", "Lhs", "Rhs", "Chr", "Lhr", "Rhr", "Cl", "Ll", "Rl", "RSV1", "RSV2", "RSV3", "RSV4" }; struct header_buf { uint8_t data[68]; size_t size; }; static void write_u16(struct header_buf *buf, int v) { assert(buf->size <= sizeof(buf->data) - 2); buf->data[buf->size + 0] = (v >> 0) & 0xff; buf->data[buf->size + 1] = (v >> 8) & 0xff; buf->size += 2; } static void write_u32(struct header_buf *buf, int v) { assert(buf->size <= sizeof(buf->data) - 4); buf->data[buf->size + 0] = (v >> 0) & 0xff; buf->data[buf->size + 1] = (v >> 8) & 0xff; buf->data[buf->size + 2] = (v >> 16) & 0xff; buf->data[buf->size + 3] = (v >> 24) & 0xff; buf->size += 4; } static int write_header(struct dcadec_waveout *wave, FILE *fp) { bool extensible = !(wave->flags & DCADEC_WAVEOUT_FLAG_MONO); struct header_buf buf; buf.size = 0; write_u32(&buf, TAG_RIFF); if (wave->size && wave->size <= UINT32_MAX - (36 + 24 * extensible)) write_u32(&buf, (uint32_t)(wave->size + 36 + 24 * extensible)); else write_u32(&buf, 0); write_u32(&buf, TAG_WAVE); write_u32(&buf, TAG_fmt); write_u32(&buf, 16 + 24 * extensible); // wFormatTag write_u16(&buf, extensible ? 0xfffe : 0x0001); // nChannels write_u16(&buf, extensible ? wave->nchannels : 1); // nSamplesPerSec write_u32(&buf, wave->sample_rate); // nAvgBytesPerSec write_u32(&buf, wave->sample_rate * wave->block_align); // nBlockAlign write_u16(&buf, wave->block_align); // wBitsPerSample write_u16(&buf, wave->bytes_per_sample << 3); if (extensible) { // cbSize write_u16(&buf, 22); // wValidBitsPerSample write_u16(&buf, wave->bits_per_sample); // dwChannelMask write_u32(&buf, wave->channel_mask); // SubFormat write_u32(&buf, 1); write_u32(&buf, 0x00100000); write_u32(&buf, 0xaa000080); write_u32(&buf, 0x719b3800); } write_u32(&buf, TAG_data); if (wave->size <= UINT32_MAX) write_u32(&buf, (uint32_t)wave->size); else write_u32(&buf, 0); if (fwrite(buf.data, buf.size, 1, fp) != 1) return -DCADEC_EIO; return 0; } static int write_data(struct dcadec_waveout *wave, FILE *fp, int **samples, int nsamples, int nchannels) { int limit = 1 << (wave->bits_per_sample - 1); int mask = ~((1 << wave->bits_per_sample) - 1); int bps = wave->bytes_per_sample; int nclipped = 0; uint8_t *dst = wave->buffer; for (int i = 0; i < nsamples; i++) { for (int j = 0; j < nchannels; j++) { int sample = samples[j][i]; if ((sample + limit) & mask) { sample = (sample >> 31) ^ (limit - 1); nclipped++; } switch (bps) { case 4: dst[0] = (sample >> 0) & 0xff; dst[1] = (sample >> 8) & 0xff; dst[2] = (sample >> 16) & 0xff; dst[3] = (sample >> 24) & 0xff; break; case 3: dst[0] = (sample >> 0) & 0xff; dst[1] = (sample >> 8) & 0xff; dst[2] = (sample >> 16) & 0xff; break; case 2: dst[0] = (sample >> 0) & 0xff; dst[1] = (sample >> 8) & 0xff; break; case 1: dst[0] = (sample >> 0) & 0xff; break; default: return -DCADEC_EINVAL; } dst += bps; } } if (nclipped && !(wave->flags & DCADEC_WAVEOUT_FLAG_CLIP)) return -DCADEC_EOVERFLOW; if (fwrite(wave->buffer, wave->block_align, nsamples, fp) != (size_t)nsamples) return -DCADEC_EIO; return nclipped; } DCADEC_API int dcadec_waveout_write(struct dcadec_waveout *wave, int **samples, int nsamples, int channel_mask, int sample_rate, int bits_per_sample) { int ret, nclipped; if (nsamples == 0) return 0; if (nsamples < 0) return -DCADEC_EINVAL; if (!wave) return -DCADEC_EINVAL; if (!samples) return -DCADEC_EINVAL; if (!channel_mask) return -DCADEC_EINVAL; if (sample_rate < 8000 || sample_rate > 384000) return -DCADEC_EINVAL; if (bits_per_sample < 8 || bits_per_sample > 32) return -DCADEC_EINVAL; if (!wave->size) { wave->channel_mask = channel_mask; wave->nchannels = dca_popcount(channel_mask); wave->sample_rate = sample_rate; wave->bits_per_sample = bits_per_sample; wave->bytes_per_sample = (bits_per_sample + 7) >> 3; if (wave->flags & DCADEC_WAVEOUT_FLAG_MONO) { wave->block_align = wave->bytes_per_sample; for (int i = 0, j = 0; i < SPEAKER_COUNT; i++) { if (!(wave->channel_mask & (1U << i))) continue; if (!wave->fp[j]) { char name[1024]; sprintf(name, wave->pattern, dca_speaker_names[i]); if (!(wave->fp[j] = fopen(name, "wb"))) return -DCADEC_EIO; } if ((ret = write_header(wave, wave->fp[j])) < 0) return ret; j++; } } else { wave->block_align = wave->nchannels * wave->bytes_per_sample; if ((ret = write_header(wave, wave->fp[0])) < 0) return ret; } } else { if (channel_mask != wave->channel_mask) return -DCADEC_EOUTCHG; if (sample_rate != wave->sample_rate) return -DCADEC_EOUTCHG; if (bits_per_sample != wave->bits_per_sample) return -DCADEC_EOUTCHG; } if (ta_alloc_fast(wave, &wave->buffer, nsamples, wave->block_align) < 0) return -DCADEC_ENOMEM; if (wave->flags & DCADEC_WAVEOUT_FLAG_MONO) { nclipped = 0; for (int i = 0; i < wave->nchannels; i++) { if ((ret = write_data(wave, wave->fp[i], &samples[i], nsamples, 1)) < 0) return ret; nclipped += ret; } } else { if ((ret = write_data(wave, wave->fp[0], samples, nsamples, wave->nchannels)) < 0) return ret; nclipped = ret; } wave->size += nsamples * wave->block_align; return nclipped; } DCADEC_API struct dcadec_waveout *dcadec_waveout_open(const char *name, int flags) { if (flags & DCADEC_WAVEOUT_FLAG_MONO) { if (!name || strlen(name) >= 1020) return NULL; char *p = strchr(name, '%'); if (!p || p[1] != 's' || strchr(p + 2, '%')) return NULL; } struct dcadec_waveout *wave = ta_znew(NULL, struct dcadec_waveout); if (!wave) return NULL; if (name) { if (flags & DCADEC_WAVEOUT_FLAG_MONO) { if (!(wave->pattern = ta_strdup(wave, name))) goto fail; } else { if (!(wave->fp[0] = fopen(name, "wb"))) goto fail; } } else { int fd; #ifdef _WIN32 if ((fd = _dup(STDOUT_FILENO)) < 0) goto fail; if (_setmode(fd, _O_BINARY) < 0) { _close(fd); goto fail; } if (!(wave->fp[0] = _fdopen(fd, "wb"))) { _close(fd); goto fail; } #else if ((fd = dup(STDOUT_FILENO)) < 0) goto fail; if (!(wave->fp[0] = fdopen(fd, "wb"))) { close(fd); goto fail; } #endif } wave->flags = flags; return wave; fail: ta_free(wave); return NULL; } DCADEC_API void dcadec_waveout_close(struct dcadec_waveout *wave) { if (!wave) return; for (int i = 0; i < SPEAKER_COUNT; i++) { if (wave->fp[i]) { bool can_seek = true; #ifdef _WIN32 can_seek = GetFileType((HANDLE)_get_osfhandle(_fileno(wave->fp[i]))) == FILE_TYPE_DISK; #endif if (wave->size && can_seek && !fseeko(wave->fp[i], 0, SEEK_SET)) write_header(wave, wave->fp[i]); fclose(wave->fp[i]); } } ta_free(wave); } ================================================ FILE: libdcadec/dca_waveout.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 WAVEOUT_H #define WAVEOUT_H #include "dca_context.h" /**@{*/ /** Write a mono WAV file for each native DTS channel */ #define DCADEC_WAVEOUT_FLAG_MONO 0x01 /** Clip instead of raising PCM overflow error */ #define DCADEC_WAVEOUT_FLAG_CLIP 0x02 /**@}*/ struct dcadec_waveout; /** * Write the block of PCM samples to WAV file. The first call to this function * writes the WAV header. Subsequent calls must have audio parameters identical * to the first call, excluding nsamples parameter which can change between * calls. * * @param wave Writer handle. * * @param samples Array of pointers to planes containing PCM data for active * channels. Normally, channels must be ordered according to * WAVEFORMATEXTENSIBLE specification. However, when * DCADEC_WAVEOUT_FLAG_MONO is set, native DTS channel layout * should be provided. * * @param nsamples Number of PCM samples in each plane. * * @param channel_mask Bit mask indicating active channels. Number of bits set * to 1 indicates the total number of planes to write. * * @param sample_rate Audio sample rate in Hz. * * @param bits_per_sample Audio PCM resolution in bits. * * @return 0 on success, negative error code on failure. Positive return * value indicates number of out-of-range PCM samples that were * clipped. */ DCADEC_API int dcadec_waveout_write(struct dcadec_waveout *wave, int **samples, int nsamples, int channel_mask, int sample_rate, int bits_per_sample); /** * Open WAV writer to file or standard output. * * @param name Name of the file to be opened. Pass NULL to open standard * output. When DCADEC_WAVEOUT_FLAG_MONO is set, name must be * non-NULL and must include `%s' sub-string that will be replaced * with DTS channel name. * * @param flags Any number of DCADEC_WAVEOUT_FLAG_* constants OR'ed together. * * @return Writer handle on success, NULL on failure. */ DCADEC_API struct dcadec_waveout *dcadec_waveout_open(const char *name, int flags); /** * Close WAV writer. This function updates the WAV header if possible. * * @param wave Writer handle. */ DCADEC_API void dcadec_waveout_close(struct dcadec_waveout *wave); #endif ================================================ FILE: libdcadec/dmix_tables.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 const uint16_t dmix_table[241] = { 33, 35, 37, 39, 41, 44, 46, 49, 52, 55, 58, 62, 65, 69, 73, 78, 82, 87, 92, 98, 104, 110, 116, 123, 130, 138, 146, 155, 164, 174, 184, 195, 207, 219, 232, 246, 260, 276, 292, 309, 328, 347, 368, 389, 413, 437, 463, 490, 519, 550, 583, 617, 654, 693, 734, 777, 823, 872, 924, 978, 1036, 1066, 1098, 1130, 1163, 1197, 1232, 1268, 1305, 1343, 1382, 1422, 1464, 1506, 1550, 1596, 1642, 1690, 1740, 1790, 1843, 1896, 1952, 2009, 2068, 2128, 2190, 2254, 2320, 2388, 2457, 2529, 2603, 2679, 2757, 2838, 2920, 3006, 3093, 3184, 3277, 3372, 3471, 3572, 3677, 3784, 3894, 4008, 4125, 4246, 4370, 4497, 4629, 4764, 4903, 5046, 5193, 5345, 5501, 5662, 5827, 5912, 5997, 6084, 6172, 6262, 6353, 6445, 6538, 6633, 6729, 6827, 6925, 7026, 7128, 7231, 7336, 7442, 7550, 7659, 7771, 7883, 7997, 8113, 8231, 8350, 8471, 8594, 8719, 8845, 8973, 9103, 9235, 9369, 9505, 9643, 9783, 9924, 10068, 10214, 10362, 10512, 10665, 10819, 10976, 11135, 11297, 11460, 11627, 11795, 11966, 12139, 12315, 12494, 12675, 12859, 13045, 13234, 13426, 13621, 13818, 14018, 14222, 14428, 14637, 14849, 15064, 15283, 15504, 15729, 15957, 16188, 16423, 16661, 16902, 17147, 17396, 17648, 17904, 18164, 18427, 18694, 18965, 19240, 19519, 19802, 20089, 20380, 20675, 20975, 21279, 21587, 21900, 22218, 22540, 22867, 23170, 23534, 23875, 24221, 24573, 24929, 25290, 25657, 26029, 26406, 26789, 27177, 27571, 27970, 28376, 28787, 29205, 29628, 30057, 30493, 30935, 31383, 31838, 32300, 32768 }; const uint32_t dmix_table_inv[201] = { 6553600, 6186997, 5840902, 5514167, 5205710, 4914507, 4639593, 4380059, 4135042, 3903731, 3685360, 3479204, 3284581, 3100844, 2927386, 2763630, 2609035, 2463088, 2325305, 2195230, 2072430, 2013631, 1956500, 1900990, 1847055, 1794651, 1743733, 1694260, 1646190, 1599484, 1554103, 1510010, 1467168, 1425542, 1385096, 1345798, 1307615, 1270515, 1234468, 1199444, 1165413, 1132348, 1100221, 1069005, 1038676, 1009206, 980573, 952752, 925721, 899456, 873937, 849141, 825049, 801641, 778897, 756798, 735326, 714463, 694193, 674497, 655360, 636766, 618700, 601146, 584090, 567518, 551417, 535772, 520571, 505801, 491451, 477507, 463959, 450796, 438006, 425579, 413504, 401772, 390373, 379297, 368536, 363270, 358080, 352964, 347920, 342949, 338049, 333219, 328458, 323765, 319139, 314579, 310084, 305654, 301287, 296982, 292739, 288556, 284433, 280369, 276363, 272414, 268522, 264685, 260904, 257176, 253501, 249879, 246309, 242790, 239321, 235901, 232531, 229208, 225933, 222705, 219523, 216386, 213295, 210247, 207243, 204282, 201363, 198486, 195650, 192855, 190099, 187383, 184706, 182066, 179465, 176901, 174373, 171882, 169426, 167005, 164619, 162267, 159948, 157663, 155410, 153190, 151001, 148844, 146717, 144621, 142554, 140517, 138510, 136531, 134580, 132657, 130762, 128893, 127052, 125236, 123447, 121683, 119944, 118231, 116541, 114876, 113235, 111617, 110022, 108450, 106901, 105373, 103868, 102383, 100921, 99479, 98057, 96656, 95275, 93914, 92682, 91249, 89946, 88660, 87394, 86145, 84914, 83701, 82505, 81326, 80164, 79019, 77890, 76777, 75680, 74598, 73533, 72482, 71446, 70425, 69419, 68427, 67450, 66486, 65536 }; const uint8_t dmix_primary_nch[7] = { 1, 2, 2, 3, 3, 4, 4 }; ================================================ FILE: libdcadec/dmix_tables.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 DMIX_TABLES_H #define DMIX_TABLES_H extern const uint16_t dmix_table[241]; extern const uint32_t dmix_table_inv[201]; extern const uint8_t dmix_primary_nch[7]; #endif ================================================ FILE: libdcadec/exss_parser.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 "exss_parser.h" // Table 8-5: Sample rate decoding const uint32_t exss_sample_rates[16] = { 8000, 16000, 32000, 64000, 128000, 22050, 44100, 88200, 176400, 352800, 12000, 24000, 48000, 96000, 192000, 384000 }; static void parse_xll_parameters(struct exss_asset *asset) { struct exss_parser *exss = asset->parser; // Size of XLL data in extension substream asset->xll_size = bits_get(&exss->bits, exss->exss_size_nbits) + 1; // XLL sync word present flag asset->xll_sync_present = bits_get1(&exss->bits); if (asset->xll_sync_present) { // Peak bit rate smoothing buffer size bits_skip(&exss->bits, 4); // Number of bits for XLL decoding delay int xll_delay_nbits = bits_get(&exss->bits, 5) + 1; // Initial XLL decoding delay in frames asset->xll_delay_nframes = bits_get(&exss->bits, xll_delay_nbits); // Number of bytes offset to XLL sync asset->xll_sync_offset = bits_get(&exss->bits, exss->exss_size_nbits); } else { asset->xll_delay_nframes = 0; asset->xll_sync_offset = 0; } } static void parse_lbr_parameters(struct exss_asset *asset) { struct exss_parser *exss = asset->parser; // Size of LBR component in extension substream asset->lbr_size = bits_get(&exss->bits, 14) + 1; // LBR sync word present flag if (bits_get1(&exss->bits)) // LBR sync distance bits_skip(&exss->bits, 2); } static int parse_descriptor(struct exss_asset *asset) { struct exss_parser *exss = asset->parser; int i, j, ret, descr_pos = exss->bits.index; // Size of audio asset descriptor in bytes int descr_size = bits_get(&exss->bits, 9) + 1; // Audio asset identifier asset->asset_index = bits_get(&exss->bits, 3); // // Per stream static metadata // if (exss->static_fields_present) { // Asset type descriptor presence if (bits_get1(&exss->bits)) // Asset type descriptor bits_skip(&exss->bits, 4); // Language descriptor presence if (bits_get1(&exss->bits)) // Language descriptor bits_skip(&exss->bits, 24); // Additional textual information presence if (bits_get1(&exss->bits)) { // Byte size of additional text info int text_size = bits_get(&exss->bits, 10) + 1; // Additional textual information string bits_skip(&exss->bits, text_size * 8); } // PCM bit resolution asset->pcm_bit_res = bits_get(&exss->bits, 5) + 1; // Maximum sample rate asset->max_sample_rate = exss_sample_rates[bits_get(&exss->bits, 4)]; // Total number of channels asset->nchannels_total = bits_get(&exss->bits, 8) + 1; // One to one map channel to speakers asset->one_to_one_map_ch_to_spkr = bits_get1(&exss->bits); if (asset->one_to_one_map_ch_to_spkr) { // Embedded stereo flag if (asset->nchannels_total > 2) asset->embedded_stereo = bits_get1(&exss->bits); // Embedded 6 channels flag if (asset->nchannels_total > 6) asset->embedded_6ch = bits_get1(&exss->bits); // Speaker mask enabled flag asset->spkr_mask_enabled = bits_get1(&exss->bits); int spkr_mask_nbits = 0; if (asset->spkr_mask_enabled) { // Number of bits for speaker activity mask spkr_mask_nbits = (bits_get(&exss->bits, 2) + 1) << 2; // Loudspeaker activity mask asset->spkr_mask = bits_get(&exss->bits, spkr_mask_nbits); } // Number of speaker remapping sets int spkr_remap_nsets = bits_get(&exss->bits, 3); if (spkr_remap_nsets && !spkr_mask_nbits) { exss_err("Speaker mask disabled yet there are remapping sets"); return -DCADEC_EBADDATA; } // Standard loudspeaker layout mask int nspeakers[8]; for (i = 0; i < spkr_remap_nsets; i++) nspeakers[i] = count_chs_for_mask(bits_get(&exss->bits, spkr_mask_nbits)); for (i = 0; i < spkr_remap_nsets; i++) { // Number of channels to be decoded for speaker remapping int nch_for_remaps = bits_get(&exss->bits, 5) + 1; for (j = 0; j < nspeakers[i]; j++) { // Decoded channels to output speaker mapping mask int remap_ch_mask = bits_get(&exss->bits, nch_for_remaps); // Loudspeaker remapping codes int ncodes = dca_popcount(remap_ch_mask); bits_skip(&exss->bits, ncodes * 5); } } } else { asset->embedded_stereo = false; asset->embedded_6ch = false; asset->spkr_mask_enabled = false; asset->spkr_mask = 0; // Representation type asset->representation_type = bits_get(&exss->bits, 3); } } // // DRC, DNC and mixing metadata // // Dynamic range coefficient presence flag bool drc_present = bits_get1(&exss->bits); // Code for dynamic range coefficient if (drc_present) bits_skip(&exss->bits, 8); // Dialog normalization presence flag if (bits_get1(&exss->bits)) // Dialog normalization code bits_skip(&exss->bits, 5); // DRC for stereo downmix if (drc_present && asset->embedded_stereo) bits_skip(&exss->bits, 8); // Mixing metadata presence flag if (exss->mix_metadata_enabled && bits_get1(&exss->bits)) { // External mixing flag bits_skip1(&exss->bits); // Post mixing / replacement gain adjustment bits_skip(&exss->bits, 6); // DRC prior to mixing if (bits_get(&exss->bits, 2) == 3) // Custom code for mixing DRC bits_skip(&exss->bits, 8); else // Limit for mixing DRC bits_skip(&exss->bits, 3); // Scaling type for channels of main audio // Scaling parameters of main audio if (bits_get1(&exss->bits)) for (i = 0; i < exss->nmixoutconfigs; i++) bits_skip(&exss->bits, 6 * exss->nmixoutchs[i]); else bits_skip(&exss->bits, 6 * exss->nmixoutconfigs); int nchannels_dmix = asset->nchannels_total; if (asset->embedded_6ch) nchannels_dmix += 6; if (asset->embedded_stereo) nchannels_dmix += 2; for (i = 0; i < exss->nmixoutconfigs; i++) { for (j = 0; j < nchannels_dmix; j++) { if (!exss->nmixoutchs[i]) { exss_err("Invalid speaker layout mask for mixing configuration"); return -DCADEC_EBADDATA; } // Mix output mask int mix_map_mask = bits_get(&exss->bits, exss->nmixoutchs[i]); // Mixing coefficients int nmixcoefs = dca_popcount(mix_map_mask); bits_skip(&exss->bits, 6 * nmixcoefs); } } } // // Decoder navigation data // // Coding mode for the asset asset->coding_mode = bits_get(&exss->bits, 2); // Coding components used in asset switch (asset->coding_mode) { case 0: // Coding mode that may contain multiple coding components asset->extension_mask = bits_get(&exss->bits, 12); if (asset->extension_mask & EXSS_CORE) { // Size of core component in extension substream asset->core_size = bits_get(&exss->bits, 14) + 1; // Core sync word present flag if (bits_get1(&exss->bits)) // Core sync distance bits_skip(&exss->bits, 2); } if (asset->extension_mask & EXSS_XBR) // Size of XBR extension in extension substream asset->xbr_size = bits_get(&exss->bits, 14) + 1; if (asset->extension_mask & EXSS_XXCH) // Size of XXCH extension in extension substream asset->xxch_size = bits_get(&exss->bits, 14) + 1; if (asset->extension_mask & EXSS_X96) // Size of X96 extension in extension substream asset->x96_size = bits_get(&exss->bits, 12) + 1; if (asset->extension_mask & EXSS_LBR) parse_lbr_parameters(asset); if (asset->extension_mask & EXSS_XLL) parse_xll_parameters(asset); if (asset->extension_mask & EXSS_RSV1) bits_skip(&exss->bits, 16); if (asset->extension_mask & EXSS_RSV2) bits_skip(&exss->bits, 16); break; case 1: // Loss-less coding mode without CBR component asset->extension_mask = EXSS_XLL; parse_xll_parameters(asset); break; case 2: // Low bit rate mode asset->extension_mask = EXSS_LBR; parse_lbr_parameters(asset); break; case 3: // Auxiliary coding mode asset->extension_mask = 0; // Size of auxiliary coded data bits_skip(&exss->bits, 14); // Auxiliary codec identification bits_skip(&exss->bits, 8); // Aux sync word present flag if (bits_get1(&exss->bits)) // Aux sync distance bits_skip(&exss->bits, 3); break; } if (asset->extension_mask & EXSS_XLL) // DTS-HD stream ID asset->hd_stream_id = bits_get(&exss->bits, 3); // One to one mixing flag // Per channel main audio scaling flag // Main audio scaling codes // Decode asset in secondary decoder flag // Revision 2 DRC metadata // Reserved // Zero pad if ((ret = bits_seek(&exss->bits, descr_pos + descr_size * 8)) < 0) exss_err("Read past end of asset descriptor"); return ret; } static int set_exss_offsets(struct exss_asset *asset) { int offs = asset->asset_offset; int size = asset->asset_size; if (asset->extension_mask & EXSS_CORE) { asset->core_offset = offs; if (offs & 3 || asset->core_size > size) return -DCADEC_EBADREAD; offs += asset->core_size; size -= asset->core_size; } if (asset->extension_mask & EXSS_XBR) { asset->xbr_offset = offs; if (offs & 3 || asset->xbr_size > size) return -DCADEC_EBADREAD; offs += asset->xbr_size; size -= asset->xbr_size; } if (asset->extension_mask & EXSS_XXCH) { asset->xxch_offset = offs; if (offs & 3 || asset->xxch_size > size) return -DCADEC_EBADREAD; offs += asset->xxch_size; size -= asset->xxch_size; } if (asset->extension_mask & EXSS_X96) { asset->x96_offset = offs; if (offs & 3 || asset->x96_size > size) return -DCADEC_EBADREAD; offs += asset->x96_size; size -= asset->x96_size; } if (asset->extension_mask & EXSS_LBR) { asset->lbr_offset = offs; if (offs & 3 || asset->lbr_size > size) return -DCADEC_EBADREAD; offs += asset->lbr_size; size -= asset->lbr_size; } if (asset->extension_mask & EXSS_XLL) { asset->xll_offset = offs; if (offs & 3 || asset->xll_size > size) return -DCADEC_EBADREAD; offs += asset->xll_size; size -= asset->xll_size; } return 0; } int exss_parse(struct exss_parser *exss, uint8_t *data, int size) { int i, j, ret; bits_init(&exss->bits, data, size); // Extension substream sync word bits_skip(&exss->bits, 32); // User defined bits bits_skip(&exss->bits, 8); // Extension substream index exss->exss_index = bits_get(&exss->bits, 2); // Flag indicating short or long header size bool wide_hdr = bits_get1(&exss->bits); // Extension substream header length int header_size = bits_get(&exss->bits, 8 + 4 * wide_hdr) + 1; // Check CRC if ((ret = bits_check_crc(&exss->bits, 32 + 8, header_size * 8)) < 0) { exss_err("Invalid EXSS header checksum"); return ret; } exss->exss_size_nbits = 16 + 4 * wide_hdr; // Number of bytes of extension substream exss->exss_size = bits_get(&exss->bits, exss->exss_size_nbits) + 1; if (exss->exss_size > size) { exss_err("Packet too short for EXSS frame"); return -DCADEC_EBADDATA; } // Per stream static fields presence flag exss->static_fields_present = bits_get1(&exss->bits); if (exss->static_fields_present) { // Reference clock code bits_skip(&exss->bits, 2); // Extension substream frame duration bits_skip(&exss->bits, 3); // Timecode presence flag if (bits_get1(&exss->bits)) { // Timecode data bits_skip(&exss->bits, 32); bits_skip(&exss->bits, 4); } // Number of defined audio presentations exss->npresents = bits_get(&exss->bits, 3) + 1; // Number of audio assets in extension substream exss->nassets = bits_get(&exss->bits, 3) + 1; // Reject unsupported features for now if (exss->npresents > 1 || exss->nassets > 1) { exss_err_once("Multiple audio presentations " "and/or assets are not supported"); return -DCADEC_ENOSUP; } // Active extension substream mask for audio presentation int active_exss_mask[8]; for (i = 0; i < exss->npresents; i++) active_exss_mask[i] = bits_get(&exss->bits, exss->exss_index + 1); // Active audio asset mask for (i = 0; i < exss->npresents; i++) for (j = 0; j <= exss->exss_index; j++) if (active_exss_mask[i] & (1 << j)) bits_skip(&exss->bits, 8); // Mixing metadata enable flag exss->mix_metadata_enabled = bits_get1(&exss->bits); if (exss->mix_metadata_enabled) { // Mixing metadata adjustment level bits_skip(&exss->bits, 2); // Number of bits for mixer output speaker activity mask int spkr_mask_nbits = (bits_get(&exss->bits, 2) + 1) << 2; // Number of mixing configurations exss->nmixoutconfigs = bits_get(&exss->bits, 2) + 1; // Speaker layout mask for mixer output channels for (i = 0; i < exss->nmixoutconfigs; i++) exss->nmixoutchs[i] = count_chs_for_mask(bits_get(&exss->bits, spkr_mask_nbits)); } } else { exss->npresents = 1; exss->nassets = 1; } // Reallocate assets if (ta_zalloc_fast(exss, &exss->assets, exss->nassets, sizeof(struct exss_asset)) < 0) return -DCADEC_ENOMEM; // Size of encoded asset data in bytes int offset = header_size; for (i = 0; i < exss->nassets; i++) { exss->assets[i].asset_offset = offset; exss->assets[i].asset_size = bits_get(&exss->bits, exss->exss_size_nbits) + 1; offset += exss->assets[i].asset_size; if (offset > exss->exss_size) { exss_err("Asset out of bounds"); return -DCADEC_EBADDATA; } } // Audio asset descriptor for (i = 0; i < exss->nassets; i++) { exss->assets[i].parser = exss; if ((ret = parse_descriptor(&exss->assets[i])) < 0) return ret; if ((ret = set_exss_offsets(&exss->assets[i])) < 0) { exss_err("Invalid extension size in asset descriptor"); return ret; } } // Backward compatible core present // Backward compatible core substream index // Backward compatible core asset index // Reserved // Byte align // CRC16 of extension substream header if ((ret = bits_seek(&exss->bits, header_size * 8)) < 0) exss_err("Read past end of EXSS header"); return ret; } struct dcadec_exss_info *exss_get_info(struct exss_parser *exss) { struct dcadec_exss_info *info = ta_znew(NULL, struct dcadec_exss_info); if (!info) return NULL; struct exss_asset *asset = &exss->assets[0]; info->nchannels = asset->nchannels_total; info->sample_rate = asset->max_sample_rate; info->bits_per_sample = asset->pcm_bit_res; if (asset->extension_mask & EXSS_XLL) info->profile = DCADEC_PROFILE_HD_MA; else if (asset->extension_mask & (EXSS_XBR | EXSS_XXCH | EXSS_X96)) info->profile = DCADEC_PROFILE_HD_HRA; else if (asset->extension_mask & EXSS_LBR) info->profile = DCADEC_PROFILE_EXPRESS; else info->profile = DCADEC_PROFILE_UNKNOWN; info->embedded_stereo = asset->embedded_stereo; info->embedded_6ch = asset->embedded_6ch; if (asset->spkr_mask_enabled) info->spkr_mask = asset->spkr_mask; else if (asset->nchannels_total == 2) info->spkr_mask = SPEAKER_PAIR_LR; if (!asset->one_to_one_map_ch_to_spkr) { if (asset->representation_type == REPR_TYPE_LtRt) info->matrix_encoding = DCADEC_MATRIX_ENCODING_SURROUND; else if (asset->representation_type == REPR_TYPE_LhRh) info->matrix_encoding = DCADEC_MATRIX_ENCODING_HEADPHONE; } return info; } ================================================ FILE: libdcadec/exss_parser.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 EXSS_PARSER_H #define EXSS_PARSER_H #include "bitstream.h" #define exss_err(...) dca_log(exss, ERROR, __VA_ARGS__) #define exss_err_once(...) dca_log_once(exss, ERROR, __VA_ARGS__) struct exss_parser; struct exss_asset { struct exss_parser *parser; ///< Parent context int asset_offset; ///< Offset to asset data from start of substream int asset_size; ///< Size of encoded asset data int asset_index; ///< Audio asset identifier int pcm_bit_res; ///< PCM bit resolution int max_sample_rate; ///< Maximum sample rate int nchannels_total; ///< Total number of channels bool one_to_one_map_ch_to_spkr; ///< One to one channel to speaker mapping flag bool embedded_stereo; ///< Embedded stereo flag bool embedded_6ch; ///< Embedded 6 channels flag bool spkr_mask_enabled; ///< Speaker mask enabled flag int spkr_mask; ///< Loudspeaker activity mask int representation_type; ///< Representation type int coding_mode; ///< Coding mode for the asset int extension_mask; ///< Coding components used in asset int core_offset; ///< Offset to core component from start of substream int core_size; ///< Size of core component in extension substream int xbr_offset; ///< Offset to XBR extension from start of substream int xbr_size; ///< Size of XBR extension in extension substream int xxch_offset; ///< Offset to XXCH extension from start of substream int xxch_size; ///< Size of XXCH extension in extension substream int x96_offset; ///< Offset to X96 extension from start of substream int x96_size; ///< Size of X96 extension in extension substream int lbr_offset; ///< Offset to LBR component from start of substream int lbr_size; ///< Size of LBR component in extension substream int xll_offset; ///< Offset to XLL data from start of substream int xll_size; ///< Size of XLL data in extension substream bool xll_sync_present; ///< XLL sync word present flag int xll_delay_nframes; ///< Initial XLL decoding delay in frames int xll_sync_offset; ///< Number of bytes offset to XLL sync int hd_stream_id; ///< DTS-HD stream ID }; struct exss_parser { struct dcadec_context *ctx; ///< Parent context struct bitstream bits; ///< Bitstream reader int exss_index; ///< Extension substream index int exss_size_nbits; ///< Number of bits for extension substream size int exss_size; ///< Number of bytes of extension substream bool static_fields_present; ///< Per stream static fields presence flag int npresents; ///< Number of defined audio presentations int nassets; ///< Number of audio assets in extension substream bool mix_metadata_enabled; ///< Mixing metadata enable flag int nmixoutconfigs; ///< Number of mixing configurations int nmixoutchs[4]; ///< Speaker layout mask for mixer output channels struct exss_asset *assets; ///< Audio asset descriptors }; extern const uint32_t exss_sample_rates[16]; int exss_parse(struct exss_parser *exss, uint8_t *data, int size); struct dcadec_exss_info *exss_get_info(struct exss_parser *exss) __attribute__((cold)); #endif ================================================ FILE: libdcadec/fir_fixed.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 */ // floor(fir_float.band_fir_perfect[i] * SQRT2 * (1 << 28) + 0.5), (i & 63) < 16 // -floor(fir_float.band_fir_perfect[i] * SQRT2 * (1 << 28) + 0.5), (i & 63) >= 16 static const int32_t band_fir_perfect[512] = { 0, 0, -3, -10, -35, -105, -218, -141, -170, -216, -239, -254, -257, -251, -235, -212, -267, -317, -362, -400, -425, -434, -427, -373, -339, -593, -321, -120, -39, -16, 0, 1, 1, 1, -3, -1, -6, -38, -93, -496, -723, -970, -1235, -1501, -1753, -1978, -2163, -2295, -2891, -2915, -2860, -2726, -2517, -2243, -1915, -1590, -1192, -252, -117, -22, -6, -13, 12, 14, 32, 25, 469, 942, 1403, 1421, 1239, 2838, 3539, 4259, 5002, 5716, 6365, 6908, 7311, 7545, 11680, 12355, 12785, 12951, 12841, 12453, 11803, 10864, 9762, 7099, 6725, 5954, 4284, 2584, 215, 379, 557, 701, -29, -687, -1578, -2749, -4076, -7933, -10049, -12133, -14039, -15752, -17213, -18400, -19291, -19878, -1444, -3005, -4523, -5927, -7143, -8093, -8713, -8939, -8700, -9481, -7515, -5279, -2725, 61, 5763, 6113, 7571, 6735, 17126, 20165, 23328, 26775, 30310, 32639, 35464, 38064, 40423, 42512, 44261, 45632, 46578, 46974, -45572, -45008, -43753, -41661, -38655, -34660, -29587, -23375, -15998, -7631, 2472, 13757, 26188, 39942, 49789, 67293, 84699, 101701, 127325, 148404, 170391, 193280, 217044, 241451, 266537, 292144, 318161, 344417, 370786, 397082, 423133, 448757, 475085, 499136, 522007, 543516, 563424, 581467, 597422, 611005, 621975, 630083, 634996, 636457, 634311, 628147, 619871, 604524, 585077, 561301, 529204, 494129, 453552, 407189, 354920, 296502, 231916, 161012, 83700, -86, -90377, -187193, -290528, -400329, 516487, 639054, 767835, 902710, 1043512, 1190048, 1342100, 1499418, 1661729, 1828700, 2000071, 2175433, 2354437, 2536630, 2721120, 2908704, 3098059, 3288764, 3480801, 3672922, 3864970, 4056432, 4246767, 4435454, 4621921, 4805642, 4986073, 5162677, 5334921, 5502279, 5664239, 5820300, 5969913, 6112723, 6248225, 6375985, 6495593, 6606663, 6708832, 6801769, 6885168, 6958762, 7022294, 7075566, 7118382, 7150633, 7172314, 7183082, 7183082, 7172314, 7150633, 7118382, 7075566, 7022294, 6958762, 6885168, 6801769, 6708832, 6606663, 6495593, 6375985, 6248225, 6112723, 5969913, -5820300, -5664239, -5502279, -5334921, -5162677, -4986073, -4805642, -4621921, -4435454, -4246767, -4056432, -3864970, -3672922, -3480801, -3288764, -3098059, -2908704, -2721120, -2536630, -2354437, -2175433, -2000071, -1828700, -1661729, -1499418, -1342100, -1190048, -1043512, -902710, -767835, -639054, -516487, -400329, -290528, -187193, -90377, -86, 83700, 161012, 231916, 296502, 354920, 407189, 453552, 494129, 529204, 561301, 585077, 604524, 619871, 628147, 634311, 636457, 634996, 630083, 621975, 611005, 597422, 581467, 563424, 543516, 522007, 499136, 475085, -448757, -423133, -397082, -370786, -344417, -318161, -292144, -266537, -241451, -217044, -193280, -170391, -148404, -127325, -101701, -84699, -67293, -49789, -39942, -26188, -13757, -2472, 7631, 15998, 23375, 29587, 34660, 38655, 41661, 43753, 45008, 45572, 46974, 46578, 45632, 44261, 42512, 40423, 38064, 35464, 32639, 30310, 26775, 23328, 20165, 17126, 6735, 7571, 6113, 5763, 61, -2725, -5279, -7515, -9481, -8700, -8939, -8713, -8093, -7143, -5927, -4523, -3005, -1444, 19878, 19291, 18400, 17213, 15752, 14039, 12133, 10049, 7933, 4076, 2749, 1578, 687, 29, -701, -557, -379, -215, -2584, -4284, -5954, -6725, -7099, -9762, -10864, -11803, -12453, -12841, -12951, -12785, -12355, -11680, 7545, 7311, 6908, 6365, 5716, 5002, 4259, 3539, 2838, 1239, 1421, 1403, 942, 469, 25, 32, 14, 12, -13, -6, -22, -117, -252, -1192, -1590, -1915, -2243, -2517, -2726, -2860, -2915, -2891, 2295, 2163, 1978, 1753, 1501, 1235, 970, 723, 496, 93, 38, 6, 1, 3, -1, -1, -1, 0, 16, 39, 120, 321, 593, 339, 373, 427, 434, 425, 400, 362, 317, 267, -212, -235, -251, -257, -254, -239, -216, -170, -141, -218, -105, -35, -10, -3, 0, 0 }; // floor(fir_float.band_fir_nonperfect[i] * SQRT2 * (1 << 28) + 0.5), (i & 63) < 16 // -floor(fir_float.band_fir_nonperfect[i] * SQRT2 * (1 << 28) + 0.5), (i & 63) >= 16 static const int32_t band_fir_nonperfect[512] = { -53, -64, -77, -91, -107, -124, -144, -165, -189, -215, -244, -277, -313, -353, -397, -447, 502, 563, 631, 706, 789, 881, 983, 1095, 1218, 1354, 1502, 1665, 1843, 2036, 2247, 2475, 2723, 2990, 3277, 3586, 3916, 4270, 4646, 5046, 5470, 5918, 6390, 6886, 7405, 7947, 8510, 9094, 9698, 10319, 10955, 11605, 12265, 12933, 13605, 14277, 14945, 15604, 16250, 16877, 17480, 18051, 18585, 19075, 19513, 19891, 20202, 20436, 20587, 20643, 20597, 20439, 20160, 19749, 19198, 18496, 17634, 16603, 15393, 13996, -12403, -10605, -8595, -6366, -3911, -1225, 1697, 4860, 8265, 11916, 15812, 19953, 24337, 28961, 33819, 38904, 44210, 49725, 55437, 61334, 67398, 73614, 79961, 86417, 92960, 99563, 106198, 112837, 119446, 125994, 132443, 138758, 144898, 150823, 156491, 161858, 166879, 171507, 175697, 179400, 182566, 185149, 187097, 188363, 188899, 188654, 187581, 185635, 182770, 178943, 174112, 168238, 161285, 153218, 144007, 133624, 122046, 109254, 95232, 79969, 63462, 45709, 26715, 6492, 14943, 37567, 61350, 86256, 112242, 139258, 167246, 196143, 225877, 256368, 287532, 319275, 351496, 384088, 416936, 449919, 482909, 515770, 548362, 580539, 612148, 643030, 673024, 701963, 729674, 755985, 780717, 803690, 824721, 843628, 860226, 874332, 885761, 894330, 899861, 902174, 901096, 896456, 888088, 875832, 859535, 839050, 814237, 784966, 751116, 712574, 669239, 621021, 567840, 509632, 446341, 377927, 304365, 225641, 141757, 52732, -41403, -140599, -244793, -353905, -467840, -586486, -709716, -837385, 969336, 1105393, 1245366, 1389049, 1536224, 1686655, 1840096, 1996285, 2154949, 2315802, 2478547, 2642877, 2808475, 2975015, 3142163, 3309579, 3476914, 3643818, 3809934, 3974901, 4138360, 4299948, 4459303, 4616064, 4769873, 4920374, 5067219, 5210063, 5348569, 5482406, 5611255, 5734805, 5852757, 5964823, 6070729, 6170216, 6263037, 6348961, 6427777, 6499286, 6563310, 6619688, 6668279, 6708963, 6741632, 6766206, 6782623, 6790843, 6790843, 6782623, 6766206, 6741632, 6708963, 6668279, 6619688, 6563310, 6499286, 6427777, 6348961, 6263037, 6170216, 6070729, 5964823, 5852757, -5734805, -5611255, -5482406, -5348569, -5210063, -5067219, -4920374, -4769873, -4616064, -4459303, -4299948, -4138360, -3974901, -3809934, -3643818, -3476914, -3309579, -3142163, -2975015, -2808475, -2642877, -2478547, -2315802, -2154949, -1996285, -1840096, -1686655, -1536224, -1389049, -1245366, -1105393, -969336, -837385, -709716, -586486, -467840, -353905, -244793, -140599, -41403, 52732, 141757, 225641, 304365, 377927, 446341, 509632, 567840, 621021, 669239, 712574, 751116, 784966, 814237, 839050, 859535, 875832, 888088, 896456, 901096, 902174, 899861, 894330, 885761, -874332, -860226, -843628, -824721, -803690, -780717, -755985, -729674, -701963, -673024, -643030, -612148, -580539, -548362, -515770, -482909, -449919, -416936, -384088, -351496, -319275, -287532, -256368, -225877, -196143, -167246, -139258, -112242, -86256, -61350, -37567, -14943, 6492, 26715, 45709, 63462, 79969, 95232, 109254, 122046, 133624, 144007, 153218, 161285, 168238, 174112, 178943, 182770, 185635, 187581, 188654, 188899, 188363, 187097, 185149, 182566, 179400, 175697, 171507, 166879, 161858, 156491, 150823, 144898, -138758, -132443, -125994, -119446, -112837, -106198, -99563, -92960, -86417, -79961, -73614, -67398, -61334, -55437, -49725, -44210, -38904, -33819, -28961, -24337, -19953, -15812, -11916, -8265, -4860, -1697, 1225, 3911, 6366, 8595, 10605, 12403, 13996, 15393, 16603, 17634, 18496, 19198, 19749, 20160, 20439, 20597, 20643, 20587, 20436, 20202, 19891, 19513, 19075, 18585, 18051, 17480, 16877, 16250, 15604, 14945, 14277, 13605, 12933, 12265, 11605, 10955, 10319, 9698, -9094, -8510, -7947, -7405, -6886, -6390, -5918, -5470, -5046, -4646, -4270, -3916, -3586, -3277, -2990, -2723, -2475, -2247, -2036, -1843, -1665, -1502, -1354, -1218, -1095, -983, -881, -789, -706, -631, -563, -502, -447, -397, -353, -313, -277, -244, -215, -189, -165, -144, -124, -107, -91, -77, -64, -53 }; static const int32_t lfe_fir_64[256] = { 6103, 52170, -558064, 1592440, 6290049, 1502534, -546669, 53047, 1930, 51089, -568920, 1683709, 6286575, 1414057, -534782, 53729, 2228, 49794, -579194, 1776276, 6279634, 1327070, -522445, 54228, 2552, 48275, -588839, 1870070, 6269231, 1241632, -509702, 54550, 2904, 46523, -597808, 1965017, 6255380, 1157798, -496595, 54708, 3287, 44529, -606054, 2061044, 6238099, 1075621, -483164, 54710, 3704, 42282, -613529, 2158071, 6217408, 995149, -469451, 54566, 4152, 39774, -620186, 2256019, 6193332, 916430, -455494, 54285, 4631, 36995, -625976, 2354805, 6165900, 839507, -441330, 53876, 5139, 33937, -630850, 2454343, 6135146, 764419, -426998, 53348, 5682, 30591, -634759, 2554547, 6101107, 691203, -412531, 52711, 6264, 26948, -637655, 2655326, 6063824, 619894, -397966, 51972, 6886, 23001, -639488, 2756591, 6023343, 550521, -383335, 51140, 7531, 18741, -640210, 2858248, 5979711, 483113, -368671, 50224, 8230, 14162, -639772, 2960201, 5932981, 417692, -354003, 49231, 8959, 9257, -638125, 3062355, 5883210, 354281, -339362, 48168, 9727, 4018, -635222, 3164612, 5830457, 292897, -324777, 47044, 10535, -1558, -631014, 3266872, 5774785, 233555, -310273, 45866, 11381, -7480, -625455, 3369035, 5716260, 176267, -295877, 44640, 12267, -13750, -618499, 3471000, 5654952, 121042, -281613, 43373, 13190, -20372, -610098, 3572664, 5590933, 67886, -267505, 42072, 14152, -27352, -600209, 3673924, 5524280, 16800, -253574, 40743, 15153, -34691, -588788, 3774676, 5455069, -32214, -239840, 39391, 16192, -42390, -575791, 3874816, 5383383, -79159, -226323, 38022, 17267, -50453, -561178, 3974239, 5309305, -124041, -213041, 36642, 18377, -58879, -544906, 4072841, 5232922, -166869, -200010, 35256, 19525, -67667, -526937, 4170517, 5154321, -207653, -187246, 33866, 20704, -76817, -507233, 4267162, 5073593, -246406, -174764, 32480, 21915, -86327, -485757, 4362672, 4990831, -283146, -162575, 31101, 23157, -96193, -462476, 4456942, 4906129, -317890, -150692, 29732, 24426, -106412, -437356, 4549871, 4819584, -350658, -139125, 28376, 25721, -116977, -410365, 4641355, 4731293, -381475, -127884, 27038 }; // floor(fir_float.band_fir_x96[i] * (1 << 29) + 0.5), (i & 127) < 32 // -floor(fir_float.band_fir_x96[i] * (1 << 29) + 0.5), (i & 127) >= 32 static const int32_t band_fir_x96[1024] = { -38, -38, -43, -48, -52, -57, -62, -67, -73, -79, -85, -91, -98, -105, -113, -121, -129, -138, -147, -157, -167, -178, -190, -202, -215, -228, -242, -257, -273, -289, -307, -325, 345, 365, 387, 410, 433, 459, 485, 513, 543, 574, 606, 640, 676, 714, 753, 795, 839, 884, 932, 983, 1035, 1090, 1148, 1208, 1271, 1336, 1405, 1476, 1550, 1628, 1709, 1793, 1880, 1971, 2065, 2163, 2265, 2370, 2479, 2592, 2709, 2830, 2955, 3084, 3217, 3354, 3496, 3642, 3791, 3946, 4104, 4267, 4433, 4604, 4780, 4959, 5143, 5330, 5522, 5717, 5916, 6119, 6326, 6536, 6749, 6966, 7186, 7408, 7633, 7861, 8090, 8322, 8556, 8791, 9027, 9264, 9501, 9739, 9977, 10214, 10450, 10685, 10918, 11149, 11377, 11603, 11825, 12042, 12255, 12463, 12665, 12861, 13050, 13231, 13405, 13569, 13724, 13869, 14002, 14125, 14235, 14331, 14415, 14483, 14536, 14573, 14594, 14596, 14580, 14544, 14488, 14412, 14313, 14191, 14046, 13877, 13682, 13461, 13213, 12937, 12632, 12298, 11934, 11538, 11111, 10650, 10156, 9628, -9065, -8466, -7830, -7158, -6447, -5698, -4910, -4083, -3215, -2306, -1357, -366, 668, 1743, 2861, 4022, 5226, 6474, 7764, 9098, 10476, 11897, 13361, 14868, 16418, 18011, 19645, 21322, 23039, 24798, 26596, 28433, 30309, 32222, 34172, 36158, 38177, 40231, 42315, 44431, 46575, 48747, 50945, 53167, 55411, 57676, 59959, 62258, 64571, 66897, 69231, 71573, 73919, 76268, 78615, 80959, 83296, 85624, 87939, 90239, 92519, 94778, 97011, 99215, 101386, 103521, 105616, 107668, 109673, 111626, 113524, 115362, 117138, 118847, 120484, 122045, 123527, 124925, 126234, 127451, 128571, 129591, 130504, 131308, 131997, 132568, 133016, 133338, 133528, 133582, 133495, 133265, 132886, 132355, 131668, 130820, 129807, 128626, 127274, 125746, 124038, 122148, 120071, 117806, 115348, 112694, 109843, 106790, 103534, 100071, 96401, 92520, 88426, 84119, 79597, 74857, 69900, 64723, 59327, 53711, 47875, 41818, 35542, 29045, 22330, 15397, 8247, 881, 6697, 14487, 22487, 30692, 39101, 47711, 56517, 65516, 74704, 84076, 93628, 103355, 113251, 123311, 133528, 143897, 154410, 165061, 175843, 186747, 197766, 208892, 220116, 231429, 242822, 254285, 265810, 277384, 288999, 300644, 312306, 323976, 335641, 347289, 358909, 370488, 382013, 393471, 404848, 416133, 427310, 438366, 449286, 460057, 470663, 481090, 491323, 501347, 511147, 520707, 530011, 539044, 547790, 556233, 564357, 572146, 579584, 586654, 593341, 599627, 605498, 610936, 615925, 620449, 624491, 628037, 631069, 633571, 635529, 636925, 637745, 637972, 637593, 636592, 634953, 632662, 629705, 626068, 621737, 616698, 610938, 604443, 597202, 589202, 580431, 570877, 560530, 549378, 537411, 524620, 510994, 496525, 481205, 465026, 447979, 430058, 411256, 391569, 370989, 349514, 327137, 303857, 279670, 254573, 228564, 201644, 173811, 145065, 115408, 84840, 53365, 20984, -12298, -46478, -81550, -117508, -154347, -192060, -230638, -270073, -310356, -351478, -393427, -436192, -479762, -524124, -569264, -615168, 661821, 709209, 757314, 806121, 855611, 905766, 956569, 1007998, 1060035, 1112658, 1165846, 1219578, 1273830, 1328580, 1383805, 1439479, 1495578, 1552077, 1608950, 1666171, 1723714, 1781550, 1839653, 1897995, 1956546, 2015279, 2074163, 2133170, 2192270, 2251432, 2310626, 2369822, 2428988, 2488093, 2547106, 2605996, 2664731, 2723279, 2781607, 2839685, 2897481, 2954962, 3012096, 3068851, 3125195, 3181097, 3236524, 3291445, 3345829, 3399643, 3452858, 3505441, 3557362, 3608591, 3659098, 3708853, 3757825, 3805987, 3853309, 3899763, 3945322, 3989957, 4033642, 4076350, 4118055, 4158733, 4198357, 4236904, 4274351, 4310673, 4345850, 4379859, 4412678, 4444289, 4474670, 4503803, 4531671, 4558255, 4583539, 4607508, 4630146, 4651438, 4671373, 4689936, 4707117, 4722905, 4737290, 4750262, 4761813, 4771936, 4780625, 4787874, 4793679, 4798036, 4800943, 4802396, 4802396, 4800943, 4798036, 4793679, 4787874, 4780625, 4771936, 4761813, 4750262, 4737290, 4722905, 4707117, 4689936, 4671373, 4651438, 4630146, 4607508, 4583539, 4558255, 4531671, 4503803, 4474670, 4444289, 4412678, 4379859, 4345850, 4310673, 4274351, 4236904, 4198357, 4158733, 4118055, -4076350, -4033642, -3989957, -3945322, -3899763, -3853309, -3805987, -3757825, -3708853, -3659098, -3608591, -3557362, -3505441, -3452858, -3399643, -3345829, -3291445, -3236524, -3181097, -3125195, -3068851, -3012096, -2954962, -2897481, -2839685, -2781607, -2723279, -2664731, -2605996, -2547106, -2488093, -2428988, -2369822, -2310626, -2251432, -2192270, -2133170, -2074163, -2015279, -1956546, -1897995, -1839653, -1781550, -1723714, -1666171, -1608950, -1552077, -1495578, -1439479, -1383805, -1328580, -1273830, -1219578, -1165846, -1112658, -1060035, -1007998, -956569, -905766, -855611, -806121, -757314, -709209, -661821, -615168, -569264, -524124, -479762, -436192, -393427, -351478, -310356, -270073, -230638, -192060, -154347, -117508, -81550, -46478, -12298, 20984, 53365, 84840, 115408, 145065, 173811, 201644, 228564, 254573, 279670, 303857, 327137, 349514, 370989, 391569, 411256, 430058, 447979, 465026, 481205, 496525, 510994, 524620, 537411, 549378, 560530, 570877, 580431, 589202, 597202, 604443, 610938, 616698, 621737, 626068, 629705, 632662, 634953, 636592, 637593, 637972, 637745, 636925, 635529, 633571, 631069, 628037, 624491, -620449, -615925, -610936, -605498, -599627, -593341, -586654, -579584, -572146, -564357, -556233, -547790, -539044, -530011, -520707, -511147, -501347, -491323, -481090, -470663, -460057, -449286, -438366, -427310, -416133, -404848, -393471, -382013, -370488, -358909, -347289, -335641, -323976, -312306, -300644, -288999, -277384, -265810, -254285, -242822, -231429, -220116, -208892, -197766, -186747, -175843, -165061, -154410, -143897, -133528, -123311, -113251, -103355, -93628, -84076, -74704, -65516, -56517, -47711, -39101, -30692, -22487, -14487, -6697, 881, 8247, 15397, 22330, 29045, 35542, 41818, 47875, 53711, 59327, 64723, 69900, 74857, 79597, 84119, 88426, 92520, 96401, 100071, 103534, 106790, 109843, 112694, 115348, 117806, 120071, 122148, 124038, 125746, 127274, 128626, 129807, 130820, 131668, 132355, 132886, 133265, 133495, 133582, 133528, 133338, 133016, 132568, 131997, 131308, 130504, 129591, 128571, 127451, 126234, 124925, 123527, 122045, 120484, 118847, 117138, 115362, 113524, 111626, 109673, 107668, 105616, 103521, 101386, -99215, -97011, -94778, -92519, -90239, -87939, -85624, -83296, -80959, -78615, -76268, -73919, -71573, -69231, -66897, -64571, -62258, -59959, -57676, -55411, -53167, -50945, -48747, -46575, -44431, -42315, -40231, -38177, -36158, -34172, -32222, -30309, -28433, -26596, -24798, -23039, -21322, -19645, -18011, -16418, -14868, -13361, -11897, -10476, -9098, -7764, -6474, -5226, -4022, -2861, -1743, -668, 366, 1357, 2306, 3215, 4083, 4910, 5698, 6447, 7158, 7830, 8466, 9065, 9628, 10156, 10650, 11111, 11538, 11934, 12298, 12632, 12937, 13213, 13461, 13682, 13877, 14046, 14191, 14313, 14412, 14488, 14544, 14580, 14596, 14594, 14573, 14536, 14483, 14415, 14331, 14235, 14125, 14002, 13869, 13724, 13569, 13405, 13231, 13050, 12861, 12665, 12463, 12255, 12042, 11825, 11603, 11377, 11149, 10918, 10685, 10450, 10214, 9977, 9739, 9501, 9264, 9027, 8791, 8556, 8322, 8090, 7861, 7633, 7408, 7186, 6966, 6749, -6536, -6326, -6119, -5916, -5717, -5522, -5330, -5143, -4959, -4780, -4604, -4433, -4267, -4104, -3946, -3791, -3642, -3496, -3354, -3217, -3084, -2955, -2830, -2709, -2592, -2479, -2370, -2265, -2163, -2065, -1971, -1880, -1793, -1709, -1628, -1550, -1476, -1405, -1336, -1271, -1208, -1148, -1090, -1035, -983, -932, -884, -839, -795, -753, -714, -676, -640, -606, -574, -543, -513, -485, -459, -433, -410, -387, -365, -345, -325, -307, -289, -273, -257, -242, -228, -215, -202, -190, -178, -167, -157, -147, -138, -129, -121, -113, -105, -98, -91, -85, -79, -73, -67, -62, -57, -52, -48, -43, -38, -38 }; ================================================ FILE: libdcadec/fir_float.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 */ #define SCALE(x) ((x) * M_SQRT2 * 128) // Annex D.8 - 32-band interpolation FIR, perfect reconstruction static const double band_fir_perfect[512] = { SCALE( 1.140033200E-10), SCALE( 7.138742100E-11), SCALE(-8.358679600E-09), SCALE(-2.529296600E-08), SCALE(-9.130198800E-08), SCALE(-2.771560000E-07), SCALE(-5.746147600E-07), SCALE(-3.712986200E-07), SCALE(-4.468735700E-07), SCALE(-5.697322600E-07), SCALE(-6.300390500E-07), SCALE(-6.677818900E-07), SCALE(-6.770656500E-07), SCALE(-6.601852300E-07), SCALE(-6.193701600E-07), SCALE(-5.586146700E-07), -SCALE( 7.034745600E-07), -SCALE( 8.348606100E-07), -SCALE( 9.544782800E-07), -SCALE( 1.052683900E-06), -SCALE( 1.119829700E-06), -SCALE( 1.144180200E-06), -SCALE( 1.124542400E-06), -SCALE( 9.822894700E-07), -SCALE( 8.920065800E-07), -SCALE( 1.560941800E-06), -SCALE( 8.454480100E-07), -SCALE( 3.167104300E-07), -SCALE( 1.028149000E-07), -SCALE( 4.147967800E-08), -SCALE(-6.821591800E-10), -SCALE(-1.611726200E-09), -SCALE(-2.668096400E-09), -SCALE(-3.377455500E-09), -SCALE( 6.820855300E-09), -SCALE( 3.715261200E-09), -SCALE( 1.643020800E-08), -SCALE( 1.007547900E-07), -SCALE( 2.448299500E-07), -SCALE( 1.306777300E-06), -SCALE( 1.904890000E-06), -SCALE( 2.555774300E-06), -SCALE( 3.253336000E-06), -SCALE( 3.953604500E-06), -SCALE( 4.617880200E-06), -SCALE( 5.210775600E-06), -SCALE( 5.696789700E-06), -SCALE( 6.046428700E-06), -SCALE( 7.614387900E-06), -SCALE( 7.678809700E-06), -SCALE( 7.533601500E-06), -SCALE( 7.179758900E-06), -SCALE( 6.629955000E-06), -SCALE( 5.908209500E-06), -SCALE( 5.044609200E-06), -SCALE( 4.187209700E-06), -SCALE( 3.139397100E-06), -SCALE( 6.650809100E-07), -SCALE( 3.073465500E-07), -SCALE( 5.699348500E-08), -SCALE( 1.510238900E-08), -SCALE( 3.384827600E-08), -SCALE(-3.227406600E-08), -SCALE(-3.772031200E-08), SCALE( 8.454083600E-08), SCALE( 6.479789100E-08), SCALE( 1.236415900E-06), SCALE( 2.480143600E-06), SCALE( 3.694976800E-06), SCALE( 3.742137100E-06), SCALE( 3.262621300E-06), SCALE( 7.476824700E-06), SCALE( 9.321632700E-06), SCALE( 1.121856000E-05), SCALE( 1.317522400E-05), SCALE( 1.505747500E-05), SCALE( 1.676702500E-05), SCALE( 1.819741000E-05), SCALE( 1.925789500E-05), SCALE( 1.987389300E-05), -SCALE(-3.076839000E-05), -SCALE(-3.254459900E-05), -SCALE(-3.367812600E-05), -SCALE(-3.411568400E-05), -SCALE(-3.382472000E-05), -SCALE(-3.280414400E-05), -SCALE(-3.109003600E-05), -SCALE(-2.861654300E-05), -SCALE(-2.571454500E-05), -SCALE(-1.870056200E-05), -SCALE(-1.771374800E-05), -SCALE(-1.568432200E-05), -SCALE(-1.128458200E-05), -SCALE(-6.805568100E-06), -SCALE(-5.671807300E-07), -SCALE(-9.974569000E-07), -SCALE(-1.466421500E-06), -SCALE(-1.846174800E-06), -SCALE( 7.763173700E-08), -SCALE( 1.809597500E-06), -SCALE( 4.157326000E-06), -SCALE( 7.240269200E-06), -SCALE( 1.073666400E-05), -SCALE( 2.089583800E-05), -SCALE( 2.647159500E-05), -SCALE( 3.196094400E-05), -SCALE( 3.698112500E-05), -SCALE( 4.149260300E-05), -SCALE( 4.534151200E-05), -SCALE( 4.846834800E-05), -SCALE( 5.081695700E-05), -SCALE( 5.236303900E-05), -SCALE( 3.803557300E-06), -SCALE( 7.916183300E-06), -SCALE( 1.191309700E-05), -SCALE( 1.561346600E-05), -SCALE( 1.881671400E-05), -SCALE( 2.131957100E-05), -SCALE( 2.295038200E-05), -SCALE( 2.354812700E-05), -SCALE( 2.291622100E-05), -SCALE( 2.497457200E-05), -SCALE( 1.979628700E-05), -SCALE( 1.390508100E-05), -SCALE( 7.179248900E-06), -SCALE(-1.614022200E-07), -SCALE(-1.518084500E-05), -SCALE(-1.610369300E-05), SCALE( 1.994364800E-05), SCALE( 1.774116500E-05), SCALE( 4.511232400E-05), SCALE( 5.311715600E-05), SCALE( 6.144976200E-05), SCALE( 7.052899300E-05), SCALE( 7.984114900E-05), SCALE( 8.597821200E-05), SCALE( 9.341758200E-05), SCALE( 1.002681400E-04), SCALE( 1.064814700E-04), SCALE( 1.119841200E-04), SCALE( 1.165901700E-04), SCALE( 1.202018700E-04), SCALE( 1.226936800E-04), SCALE( 1.237377900E-04), -SCALE( 1.200453700E-04), -SCALE( 1.185602000E-04), -SCALE( 1.152534400E-04), -SCALE( 1.097435100E-04), -SCALE( 1.018237000E-04), -SCALE( 9.130172200E-05), -SCALE( 7.793692700E-05), -SCALE( 6.157321800E-05), -SCALE( 4.214289700E-05), -SCALE( 2.010055900E-05), -SCALE(-6.512868000E-06), -SCALE(-3.623958500E-05), -SCALE(-6.898332300E-05), -SCALE(-1.052143400E-04), -SCALE(-1.311540500E-04), -SCALE(-1.772621900E-04), -SCALE(-2.231129500E-04), -SCALE(-2.678985000E-04), -SCALE(-3.353960600E-04), -SCALE(-3.909221300E-04), -SCALE(-4.488403900E-04), -SCALE(-5.091327500E-04), -SCALE(-5.717321000E-04), -SCALE(-6.360244700E-04), -SCALE(-7.021067600E-04), -SCALE(-7.695597500E-04), -SCALE(-8.380918900E-04), -SCALE(-9.072555100E-04), -SCALE(-9.767158300E-04), -SCALE(-1.045985500E-03), -SCALE(-1.114606900E-03), -SCALE(-1.182107000E-03), -SCALE(-1.251459700E-03), -SCALE(-1.314813200E-03), -SCALE(-1.375058300E-03), -SCALE(-1.431717500E-03), -SCALE(-1.484159500E-03), -SCALE(-1.531686400E-03), -SCALE(-1.573715600E-03), -SCALE(-1.609496400E-03), -SCALE(-1.638393400E-03), -SCALE(-1.659751400E-03), -SCALE(-1.672691700E-03), -SCALE(-1.676540900E-03), -SCALE(-1.670887400E-03), -SCALE(-1.654649800E-03), -SCALE(-1.632849400E-03), -SCALE(-1.592423900E-03), SCALE( 1.541196600E-03), SCALE( 1.478566700E-03), SCALE( 1.394017000E-03), SCALE( 1.301623400E-03), SCALE( 1.194737700E-03), SCALE( 1.072608600E-03), SCALE( 9.349224800E-04), SCALE( 7.810380900E-04), SCALE( 6.109076600E-04), SCALE( 4.241331700E-04), SCALE( 2.204804700E-04), SCALE(-2.272228400E-07), SCALE(-2.380696500E-04), SCALE(-4.930996000E-04), SCALE(-7.653038000E-04), SCALE(-1.054538000E-03), -SCALE(-1.360519200E-03), -SCALE(-1.683383000E-03), -SCALE(-2.022614600E-03), -SCALE(-2.377899500E-03), -SCALE(-2.748797700E-03), -SCALE(-3.134797500E-03), -SCALE(-3.535329200E-03), -SCALE(-3.949734800E-03), -SCALE(-4.377291000E-03), -SCALE(-4.817122000E-03), -SCALE(-5.268542300E-03), -SCALE(-5.730478300E-03), -SCALE(-6.202005100E-03), -SCALE(-6.681936000E-03), -SCALE(-7.167914500E-03), -SCALE(-7.662045500E-03), -SCALE(-8.160839200E-03), -SCALE(-8.663190500E-03), -SCALE(-9.169050700E-03), -SCALE(-9.675131500E-03), -SCALE(-1.018101800E-02), -SCALE(-1.068536400E-02), -SCALE(-1.118674000E-02), -SCALE(-1.168377500E-02), -SCALE(-1.217496400E-02), -SCALE(-1.265891600E-02), -SCALE(-1.313420500E-02), -SCALE(-1.359941000E-02), -SCALE(-1.405313100E-02), -SCALE(-1.449398400E-02), -SCALE(-1.492061500E-02), -SCALE(-1.533170500E-02), -SCALE(-1.572581500E-02), -SCALE(-1.610200000E-02), -SCALE(-1.645893800E-02), -SCALE(-1.679548100E-02), -SCALE(-1.711054800E-02), -SCALE(-1.740312600E-02), -SCALE(-1.767225900E-02), -SCALE(-1.791707200E-02), -SCALE(-1.813675700E-02), -SCALE(-1.833061700E-02), -SCALE(-1.849797400E-02), -SCALE(-1.863830100E-02), -SCALE(-1.875108700E-02), -SCALE(-1.883604000E-02), -SCALE(-1.889315300E-02), -SCALE(-1.892151600E-02), SCALE( 1.892151600E-02), SCALE( 1.889315300E-02), SCALE( 1.883604000E-02), SCALE( 1.875108700E-02), SCALE( 1.863830100E-02), SCALE( 1.849797400E-02), SCALE( 1.833061700E-02), SCALE( 1.813675700E-02), SCALE( 1.791707200E-02), SCALE( 1.767225900E-02), SCALE( 1.740312600E-02), SCALE( 1.711054800E-02), SCALE( 1.679548100E-02), SCALE( 1.645893800E-02), SCALE( 1.610200000E-02), SCALE( 1.572581500E-02), -SCALE( 1.533170500E-02), -SCALE( 1.492061500E-02), -SCALE( 1.449398400E-02), -SCALE( 1.405313100E-02), -SCALE( 1.359941000E-02), -SCALE( 1.313420500E-02), -SCALE( 1.265891600E-02), -SCALE( 1.217496400E-02), -SCALE( 1.168377500E-02), -SCALE( 1.118674000E-02), -SCALE( 1.068536400E-02), -SCALE( 1.018101800E-02), -SCALE( 9.675131500E-03), -SCALE( 9.169050700E-03), -SCALE( 8.663190500E-03), -SCALE( 8.160839200E-03), -SCALE( 7.662045500E-03), -SCALE( 7.167914500E-03), -SCALE( 6.681936000E-03), -SCALE( 6.202005100E-03), -SCALE( 5.730478300E-03), -SCALE( 5.268542300E-03), -SCALE( 4.817122000E-03), -SCALE( 4.377291000E-03), -SCALE( 3.949734800E-03), -SCALE( 3.535329200E-03), -SCALE( 3.134797500E-03), -SCALE( 2.748797700E-03), -SCALE( 2.377899500E-03), -SCALE( 2.022614600E-03), -SCALE( 1.683383000E-03), -SCALE( 1.360519200E-03), -SCALE( 1.054538000E-03), -SCALE( 7.653038000E-04), -SCALE( 4.930996000E-04), -SCALE( 2.380696500E-04), -SCALE( 2.272228400E-07), -SCALE(-2.204804700E-04), -SCALE(-4.241331700E-04), -SCALE(-6.109076600E-04), -SCALE(-7.810380900E-04), -SCALE(-9.349224800E-04), -SCALE(-1.072608600E-03), -SCALE(-1.194737700E-03), -SCALE(-1.301623400E-03), -SCALE(-1.394017000E-03), -SCALE(-1.478566700E-03), -SCALE(-1.541196600E-03), SCALE( 1.592423900E-03), SCALE( 1.632849400E-03), SCALE( 1.654649800E-03), SCALE( 1.670887400E-03), SCALE( 1.676540900E-03), SCALE( 1.672691700E-03), SCALE( 1.659751400E-03), SCALE( 1.638393400E-03), SCALE( 1.609496400E-03), SCALE( 1.573715600E-03), SCALE( 1.531686400E-03), SCALE( 1.484159500E-03), SCALE( 1.431717500E-03), SCALE( 1.375058300E-03), SCALE( 1.314813200E-03), SCALE( 1.251459700E-03), -SCALE( 1.182107000E-03), -SCALE( 1.114606900E-03), -SCALE( 1.045985500E-03), -SCALE( 9.767158300E-04), -SCALE( 9.072555100E-04), -SCALE( 8.380918900E-04), -SCALE( 7.695597500E-04), -SCALE( 7.021067600E-04), -SCALE( 6.360244700E-04), -SCALE( 5.717321000E-04), -SCALE( 5.091327500E-04), -SCALE( 4.488403900E-04), -SCALE( 3.909221300E-04), -SCALE( 3.353960600E-04), -SCALE( 2.678985000E-04), -SCALE( 2.231129500E-04), -SCALE( 1.772621900E-04), -SCALE( 1.311540500E-04), -SCALE( 1.052143400E-04), -SCALE( 6.898332300E-05), -SCALE( 3.623958500E-05), -SCALE( 6.512868000E-06), -SCALE(-2.010055900E-05), -SCALE(-4.214289700E-05), -SCALE(-6.157321800E-05), -SCALE(-7.793692700E-05), -SCALE(-9.130172200E-05), -SCALE(-1.018237000E-04), -SCALE(-1.097435100E-04), -SCALE(-1.152534400E-04), -SCALE(-1.185602000E-04), -SCALE(-1.200453700E-04), -SCALE(-1.237377900E-04), -SCALE(-1.226936800E-04), -SCALE(-1.202018700E-04), -SCALE(-1.165901700E-04), -SCALE(-1.119841200E-04), -SCALE(-1.064814700E-04), -SCALE(-1.002681400E-04), -SCALE(-9.341758200E-05), -SCALE(-8.597821200E-05), -SCALE(-7.984114900E-05), -SCALE(-7.052899300E-05), -SCALE(-6.144976200E-05), -SCALE(-5.311715600E-05), -SCALE(-4.511232400E-05), -SCALE(-1.774116500E-05), -SCALE(-1.994364800E-05), SCALE( 1.610369300E-05), SCALE( 1.518084500E-05), SCALE( 1.614022200E-07), SCALE(-7.179248900E-06), SCALE(-1.390508100E-05), SCALE(-1.979628700E-05), SCALE(-2.497457200E-05), SCALE(-2.291622100E-05), SCALE(-2.354812700E-05), SCALE(-2.295038200E-05), SCALE(-2.131957100E-05), SCALE(-1.881671400E-05), SCALE(-1.561346600E-05), SCALE(-1.191309700E-05), SCALE(-7.916183300E-06), SCALE(-3.803557300E-06), -SCALE(-5.236303900E-05), -SCALE(-5.081695700E-05), -SCALE(-4.846834800E-05), -SCALE(-4.534151200E-05), -SCALE(-4.149260300E-05), -SCALE(-3.698112500E-05), -SCALE(-3.196094400E-05), -SCALE(-2.647159500E-05), -SCALE(-2.089583800E-05), -SCALE(-1.073666400E-05), -SCALE(-7.240269200E-06), -SCALE(-4.157326000E-06), -SCALE(-1.809597500E-06), -SCALE(-7.763173700E-08), -SCALE( 1.846174800E-06), -SCALE( 1.466421500E-06), -SCALE( 9.974569000E-07), -SCALE( 5.671807300E-07), -SCALE( 6.805568100E-06), -SCALE( 1.128458200E-05), -SCALE( 1.568432200E-05), -SCALE( 1.771374800E-05), -SCALE( 1.870056200E-05), -SCALE( 2.571454500E-05), -SCALE( 2.861654300E-05), -SCALE( 3.109003600E-05), -SCALE( 3.280414400E-05), -SCALE( 3.382472000E-05), -SCALE( 3.411568400E-05), -SCALE( 3.367812600E-05), -SCALE( 3.254459900E-05), -SCALE( 3.076839000E-05), -SCALE(-1.987389300E-05), -SCALE(-1.925789500E-05), -SCALE(-1.819741000E-05), -SCALE(-1.676702500E-05), -SCALE(-1.505747500E-05), -SCALE(-1.317522400E-05), -SCALE(-1.121856000E-05), -SCALE(-9.321632700E-06), -SCALE(-7.476824700E-06), -SCALE(-3.262621300E-06), -SCALE(-3.742137100E-06), -SCALE(-3.694976800E-06), -SCALE(-2.480143600E-06), -SCALE(-1.236415900E-06), -SCALE(-6.479789100E-08), -SCALE(-8.454083600E-08), SCALE( 3.772031200E-08), SCALE( 3.227406600E-08), SCALE(-3.384827600E-08), SCALE(-1.510238900E-08), SCALE(-5.699348500E-08), SCALE(-3.073465500E-07), SCALE(-6.650809100E-07), SCALE(-3.139397100E-06), SCALE(-4.187209700E-06), SCALE(-5.044609200E-06), SCALE(-5.908209500E-06), SCALE(-6.629955000E-06), SCALE(-7.179758900E-06), SCALE(-7.533601500E-06), SCALE(-7.678809700E-06), SCALE(-7.614387900E-06), -SCALE(-6.046428700E-06), -SCALE(-5.696789700E-06), -SCALE(-5.210775600E-06), -SCALE(-4.617880200E-06), -SCALE(-3.953604500E-06), -SCALE(-3.253336000E-06), -SCALE(-2.555774300E-06), -SCALE(-1.904890000E-06), -SCALE(-1.306777300E-06), -SCALE(-2.448299500E-07), -SCALE(-1.007547900E-07), -SCALE(-1.643020800E-08), -SCALE(-3.715261200E-09), -SCALE(-6.820855300E-09), -SCALE( 3.377455500E-09), -SCALE( 2.668096400E-09), -SCALE( 1.611726200E-09), -SCALE( 6.821591800E-10), -SCALE(-4.147967800E-08), -SCALE(-1.028149000E-07), -SCALE(-3.167104300E-07), -SCALE(-8.454480100E-07), -SCALE(-1.560941800E-06), -SCALE(-8.920065800E-07), -SCALE(-9.822894700E-07), -SCALE(-1.124542400E-06), -SCALE(-1.144180200E-06), -SCALE(-1.119829700E-06), -SCALE(-1.052683900E-06), -SCALE(-9.544782800E-07), -SCALE(-8.348606100E-07), -SCALE(-7.034745600E-07), -SCALE( 5.586146700E-07), -SCALE( 6.193701600E-07), -SCALE( 6.601852300E-07), -SCALE( 6.770656500E-07), -SCALE( 6.677818900E-07), -SCALE( 6.300390500E-07), -SCALE( 5.697322600E-07), -SCALE( 4.468735700E-07), -SCALE( 3.712986200E-07), -SCALE( 5.746147600E-07), -SCALE( 2.771560000E-07), -SCALE( 9.130198800E-08), -SCALE( 2.529296600E-08), -SCALE( 8.358679600E-09), -SCALE(-7.138742100E-11), -SCALE(-1.140033200E-10) }; // Annex D.8 - 32-band interpolation FIR, non-perfect reconstruction static const double band_fir_nonperfect[512] = { SCALE(-1.390191784E-07), SCALE(-1.693738625E-07), SCALE(-2.030677564E-07), SCALE(-2.404238444E-07), SCALE(-2.818143514E-07), SCALE(-3.276689142E-07), SCALE(-3.784752209E-07), SCALE(-4.347855338E-07), SCALE(-4.972276315E-07), SCALE(-5.665120852E-07), SCALE(-6.434325428E-07), SCALE(-7.288739425E-07), SCALE(-8.238164355E-07), SCALE(-9.293416952E-07), SCALE(-1.046637067E-06), SCALE(-1.176999604E-06), -SCALE(-1.321840614E-06), -SCALE(-1.482681114E-06), -SCALE(-1.661159786E-06), -SCALE(-1.859034001E-06), -SCALE(-2.078171747E-06), -SCALE(-2.320550948E-06), -SCALE(-2.588257530E-06), -SCALE(-2.883470643E-06), -SCALE(-3.208459020E-06), -SCALE(-3.565570978E-06), -SCALE(-3.957220997E-06), -SCALE(-4.385879038E-06), -SCALE(-4.854050530E-06), -SCALE(-5.364252502E-06), -SCALE(-5.918994248E-06), -SCALE(-6.520755960E-06), -SCALE(-7.171964626E-06), -SCALE(-7.874960829E-06), -SCALE(-8.631964192E-06), -SCALE(-9.445050637E-06), -SCALE(-1.031611009E-05), -SCALE(-1.124680875E-05), -SCALE(-1.223855270E-05), -SCALE(-1.329243969E-05), -SCALE(-1.440921824E-05), -SCALE(-1.558924305E-05), -SCALE(-1.683242772E-05), -SCALE(-1.813820381E-05), -SCALE(-1.950545993E-05), -SCALE(-2.093250441E-05), -SCALE(-2.241701623E-05), -SCALE(-2.395598858E-05), -SCALE(-2.554569073E-05), -SCALE(-2.718161704E-05), -SCALE(-2.885844333E-05), -SCALE(-3.056998685E-05), -SCALE(-3.230916263E-05), -SCALE(-3.406793985E-05), -SCALE(-3.583733633E-05), -SCALE(-3.760734762E-05), -SCALE(-3.936696885E-05), -SCALE(-4.110412556E-05), -SCALE(-4.280570283E-05), -SCALE(-4.445751256E-05), -SCALE(-4.604430433E-05), -SCALE(-4.754976908E-05), -SCALE(-4.895655002E-05), -SCALE(-5.024627535E-05), SCALE( 5.139957648E-05), SCALE( 5.239612074E-05), SCALE( 5.321469871E-05), SCALE( 5.383323878E-05), SCALE( 5.422891263E-05), SCALE( 5.437819709E-05), SCALE( 5.425697600E-05), SCALE( 5.384063843E-05), SCALE( 5.310418419E-05), SCALE( 5.202236207E-05), SCALE( 5.056979353E-05), SCALE( 4.872112549E-05), SCALE( 4.645117951E-05), SCALE( 4.373511547E-05), SCALE( 4.054862075E-05), SCALE( 3.686808850E-05), -SCALE( 3.267079956E-05), -SCALE( 2.793515523E-05), -SCALE( 2.264085742E-05), -SCALE( 1.676913780E-05), -SCALE( 1.030297699E-05), -SCALE( 3.227306706E-06), -SCALE(-4.470633485E-06), -SCALE(-1.280130618E-05), -SCALE(-2.177240640E-05), -SCALE(-3.138873581E-05), -SCALE(-4.165195787E-05), -SCALE(-5.256036457E-05), -SCALE(-6.410864444E-05), -SCALE(-7.628766616E-05), -SCALE(-8.908427117E-05), -SCALE(-1.024810626E-04), -SCALE(-1.164562127E-04), -SCALE(-1.309833024E-04), -SCALE(-1.460311323E-04), -SCALE(-1.615635992E-04), -SCALE(-1.775395358E-04), -SCALE(-1.939126523E-04), -SCALE(-2.106313768E-04), -SCALE(-2.276388550E-04), -SCALE(-2.448728774E-04), -SCALE(-2.622658503E-04), -SCALE(-2.797449124E-04), -SCALE(-2.972317743E-04), -SCALE(-3.146430245E-04), -SCALE(-3.318900708E-04), -SCALE(-3.488793736E-04), -SCALE(-3.655125911E-04), -SCALE(-3.816867538E-04), -SCALE(-3.972945851E-04), -SCALE(-4.122247046E-04), -SCALE(-4.263620067E-04), -SCALE(-4.395879805E-04), -SCALE(-4.517810594E-04), -SCALE(-4.628172028E-04), -SCALE(-4.725702747E-04), -SCALE(-4.809123348E-04), -SCALE(-4.877146275E-04), -SCALE(-4.928477574E-04), -SCALE(-4.961824161E-04), -SCALE(-4.975944757E-04), -SCALE(-4.969481961E-04), -SCALE(-4.941228544E-04), -SCALE(-4.889960401E-04), SCALE( 4.814492422E-04), SCALE( 4.713678791E-04), SCALE( 4.586426076E-04), SCALE( 4.431701091E-04), SCALE( 4.248536134E-04), SCALE( 4.036037717E-04), SCALE( 3.793396754E-04), SCALE( 3.519894381E-04), SCALE( 3.214911267E-04), SCALE( 2.877934603E-04), SCALE( 2.508567995E-04), SCALE( 2.106537577E-04), SCALE( 1.671699720E-04), SCALE( 1.204049113E-04), SCALE( 7.037253090E-05), SCALE( 1.710198012E-05), -SCALE(-3.936182839E-05), -SCALE(-9.895755647E-05), -SCALE(-1.616069785E-04), -SCALE(-2.272142592E-04), -SCALE(-2.956659591E-04), -SCALE(-3.668301215E-04), -SCALE(-4.405563814E-04), -SCALE(-5.166754709E-04), -SCALE(-5.949990009E-04), -SCALE(-6.753197522E-04), -SCALE(-7.574109477E-04), -SCALE(-8.410271257E-04), -SCALE(-9.259034996E-04), -SCALE(-1.011756598E-03), -SCALE(-1.098284614E-03), -SCALE(-1.185167348E-03), -SCALE(-1.272067428E-03), -SCALE(-1.358630019E-03), -SCALE(-1.444484224E-03), -SCALE(-1.529243193E-03), -SCALE(-1.612505526E-03), -SCALE(-1.693855622E-03), -SCALE(-1.772865304E-03), -SCALE(-1.849094522E-03), -SCALE(-1.922092517E-03), -SCALE(-1.991399564E-03), -SCALE(-2.056547208E-03), -SCALE(-2.117061289E-03), -SCALE(-2.172462177E-03), -SCALE(-2.222266514E-03), -SCALE(-2.265989315E-03), -SCALE(-2.303145360E-03), -SCALE(-2.333251061E-03), -SCALE(-2.355825622E-03), -SCALE(-2.370394068E-03), -SCALE(-2.376487479E-03), -SCALE(-2.373647178E-03), -SCALE(-2.361423569E-03), -SCALE(-2.339380793E-03), -SCALE(-2.307097195E-03), -SCALE(-2.264167881E-03), -SCALE(-2.210205887E-03), -SCALE(-2.144844970E-03), -SCALE(-2.067740774E-03), -SCALE(-1.978572691E-03), -SCALE(-1.877046190E-03), -SCALE(-1.762894331E-03), -SCALE(-1.635878929E-03), SCALE( 1.495792647E-03), SCALE( 1.342460280E-03), SCALE( 1.175740734E-03), SCALE( 9.955273708E-04), SCALE( 8.017504588E-04), SCALE( 5.943773431E-04), SCALE( 3.734139318E-04), SCALE( 1.389056415E-04), SCALE(-1.090620208E-04), SCALE(-3.703625989E-04), SCALE(-6.448282511E-04), SCALE(-9.322494152E-04), SCALE(-1.232374110E-03), SCALE(-1.544908970E-03), SCALE(-1.869517611E-03), SCALE(-2.205822384E-03), -SCALE(-2.553403843E-03), -SCALE(-2.911801683E-03), -SCALE(-3.280514618E-03), -SCALE(-3.659002949E-03), -SCALE(-4.046686925E-03), -SCALE(-4.442950245E-03), -SCALE(-4.847140983E-03), -SCALE(-5.258570891E-03), -SCALE(-5.676518660E-03), -SCALE(-6.100233644E-03), -SCALE(-6.528933067E-03), -SCALE(-6.961807609E-03), -SCALE(-7.398022339E-03), -SCALE(-7.836719044E-03), -SCALE(-8.277016692E-03), -SCALE(-8.718019351E-03), -SCALE(-9.158811532E-03), -SCALE(-9.598465636E-03), -SCALE(-1.003604382E-02), -SCALE(-1.047059800E-02), -SCALE(-1.090117730E-02), -SCALE(-1.132682897E-02), -SCALE(-1.174659748E-02), -SCALE(-1.215953380E-02), -SCALE(-1.256469358E-02), -SCALE(-1.296114177E-02), -SCALE(-1.334795821E-02), -SCALE(-1.372423489E-02), -SCALE(-1.408908330E-02), -SCALE(-1.444163360E-02), -SCALE(-1.478104480E-02), -SCALE(-1.510649733E-02), -SCALE(-1.541720331E-02), -SCALE(-1.571240649E-02), -SCALE(-1.599138230E-02), -SCALE(-1.625344716E-02), -SCALE(-1.649795473E-02), -SCALE(-1.672429405E-02), -SCALE(-1.693190821E-02), -SCALE(-1.712027565E-02), -SCALE(-1.728892699E-02), -SCALE(-1.743743755E-02), -SCALE(-1.756543480E-02), -SCALE(-1.767260395E-02), -SCALE(-1.775865816E-02), -SCALE(-1.782339066E-02), -SCALE(-1.786663756E-02), -SCALE(-1.788828894E-02), SCALE( 1.788828894E-02), SCALE( 1.786663756E-02), SCALE( 1.782339066E-02), SCALE( 1.775865816E-02), SCALE( 1.767260395E-02), SCALE( 1.756543480E-02), SCALE( 1.743743755E-02), SCALE( 1.728892699E-02), SCALE( 1.712027565E-02), SCALE( 1.693190821E-02), SCALE( 1.672429405E-02), SCALE( 1.649795473E-02), SCALE( 1.625344716E-02), SCALE( 1.599138230E-02), SCALE( 1.571240649E-02), SCALE( 1.541720331E-02), -SCALE( 1.510649733E-02), -SCALE( 1.478104480E-02), -SCALE( 1.444163360E-02), -SCALE( 1.408908330E-02), -SCALE( 1.372423489E-02), -SCALE( 1.334795821E-02), -SCALE( 1.296114177E-02), -SCALE( 1.256469358E-02), -SCALE( 1.215953380E-02), -SCALE( 1.174659748E-02), -SCALE( 1.132682897E-02), -SCALE( 1.090117730E-02), -SCALE( 1.047059800E-02), -SCALE( 1.003604382E-02), -SCALE( 9.598465636E-03), -SCALE( 9.158811532E-03), -SCALE( 8.718019351E-03), -SCALE( 8.277016692E-03), -SCALE( 7.836719044E-03), -SCALE( 7.398022339E-03), -SCALE( 6.961807609E-03), -SCALE( 6.528933067E-03), -SCALE( 6.100233644E-03), -SCALE( 5.676518660E-03), -SCALE( 5.258570891E-03), -SCALE( 4.847140983E-03), -SCALE( 4.442950245E-03), -SCALE( 4.046686925E-03), -SCALE( 3.659002949E-03), -SCALE( 3.280514618E-03), -SCALE( 2.911801683E-03), -SCALE( 2.553403843E-03), -SCALE( 2.205822384E-03), -SCALE( 1.869517611E-03), -SCALE( 1.544908970E-03), -SCALE( 1.232374110E-03), -SCALE( 9.322494152E-04), -SCALE( 6.448282511E-04), -SCALE( 3.703625989E-04), -SCALE( 1.090620208E-04), -SCALE(-1.389056415E-04), -SCALE(-3.734139318E-04), -SCALE(-5.943773431E-04), -SCALE(-8.017504588E-04), -SCALE(-9.955273708E-04), -SCALE(-1.175740734E-03), -SCALE(-1.342460280E-03), -SCALE(-1.495792647E-03), SCALE( 1.635878929E-03), SCALE( 1.762894331E-03), SCALE( 1.877046190E-03), SCALE( 1.978572691E-03), SCALE( 2.067740774E-03), SCALE( 2.144844970E-03), SCALE( 2.210205887E-03), SCALE( 2.264167881E-03), SCALE( 2.307097195E-03), SCALE( 2.339380793E-03), SCALE( 2.361423569E-03), SCALE( 2.373647178E-03), SCALE( 2.376487479E-03), SCALE( 2.370394068E-03), SCALE( 2.355825622E-03), SCALE( 2.333251061E-03), -SCALE( 2.303145360E-03), -SCALE( 2.265989315E-03), -SCALE( 2.222266514E-03), -SCALE( 2.172462177E-03), -SCALE( 2.117061289E-03), -SCALE( 2.056547208E-03), -SCALE( 1.991399564E-03), -SCALE( 1.922092517E-03), -SCALE( 1.849094522E-03), -SCALE( 1.772865304E-03), -SCALE( 1.693855622E-03), -SCALE( 1.612505526E-03), -SCALE( 1.529243193E-03), -SCALE( 1.444484224E-03), -SCALE( 1.358630019E-03), -SCALE( 1.272067428E-03), -SCALE( 1.185167348E-03), -SCALE( 1.098284614E-03), -SCALE( 1.011756598E-03), -SCALE( 9.259034996E-04), -SCALE( 8.410271257E-04), -SCALE( 7.574109477E-04), -SCALE( 6.753197522E-04), -SCALE( 5.949990009E-04), -SCALE( 5.166754709E-04), -SCALE( 4.405563814E-04), -SCALE( 3.668301215E-04), -SCALE( 2.956659591E-04), -SCALE( 2.272142592E-04), -SCALE( 1.616069785E-04), -SCALE( 9.895755647E-05), -SCALE( 3.936182839E-05), -SCALE(-1.710198012E-05), -SCALE(-7.037253090E-05), -SCALE(-1.204049113E-04), -SCALE(-1.671699720E-04), -SCALE(-2.106537577E-04), -SCALE(-2.508567995E-04), -SCALE(-2.877934603E-04), -SCALE(-3.214911267E-04), -SCALE(-3.519894381E-04), -SCALE(-3.793396754E-04), -SCALE(-4.036037717E-04), -SCALE(-4.248536134E-04), -SCALE(-4.431701091E-04), -SCALE(-4.586426076E-04), -SCALE(-4.713678791E-04), -SCALE(-4.814492422E-04), SCALE( 4.889960401E-04), SCALE( 4.941228544E-04), SCALE( 4.969481961E-04), SCALE( 4.975944757E-04), SCALE( 4.961824161E-04), SCALE( 4.928477574E-04), SCALE( 4.877146275E-04), SCALE( 4.809123348E-04), SCALE( 4.725702747E-04), SCALE( 4.628172028E-04), SCALE( 4.517810594E-04), SCALE( 4.395879805E-04), SCALE( 4.263620067E-04), SCALE( 4.122247046E-04), SCALE( 3.972945851E-04), SCALE( 3.816867538E-04), -SCALE( 3.655125911E-04), -SCALE( 3.488793736E-04), -SCALE( 3.318900708E-04), -SCALE( 3.146430245E-04), -SCALE( 2.972317743E-04), -SCALE( 2.797449124E-04), -SCALE( 2.622658503E-04), -SCALE( 2.448728774E-04), -SCALE( 2.276388550E-04), -SCALE( 2.106313768E-04), -SCALE( 1.939126523E-04), -SCALE( 1.775395358E-04), -SCALE( 1.615635992E-04), -SCALE( 1.460311323E-04), -SCALE( 1.309833024E-04), -SCALE( 1.164562127E-04), -SCALE( 1.024810626E-04), -SCALE( 8.908427117E-05), -SCALE( 7.628766616E-05), -SCALE( 6.410864444E-05), -SCALE( 5.256036457E-05), -SCALE( 4.165195787E-05), -SCALE( 3.138873581E-05), -SCALE( 2.177240640E-05), -SCALE( 1.280130618E-05), -SCALE( 4.470633485E-06), -SCALE(-3.227306706E-06), -SCALE(-1.030297699E-05), -SCALE(-1.676913780E-05), -SCALE(-2.264085742E-05), -SCALE(-2.793515523E-05), -SCALE(-3.267079956E-05), -SCALE(-3.686808850E-05), -SCALE(-4.054862075E-05), -SCALE(-4.373511547E-05), -SCALE(-4.645117951E-05), -SCALE(-4.872112549E-05), -SCALE(-5.056979353E-05), -SCALE(-5.202236207E-05), -SCALE(-5.310418419E-05), -SCALE(-5.384063843E-05), -SCALE(-5.425697600E-05), -SCALE(-5.437819709E-05), -SCALE(-5.422891263E-05), -SCALE(-5.383323878E-05), -SCALE(-5.321469871E-05), -SCALE(-5.239612074E-05), -SCALE(-5.139957648E-05), SCALE( 5.024627535E-05), SCALE( 4.895655002E-05), SCALE( 4.754976908E-05), SCALE( 4.604430433E-05), SCALE( 4.445751256E-05), SCALE( 4.280570283E-05), SCALE( 4.110412556E-05), SCALE( 3.936696885E-05), SCALE( 3.760734762E-05), SCALE( 3.583733633E-05), SCALE( 3.406793985E-05), SCALE( 3.230916263E-05), SCALE( 3.056998685E-05), SCALE( 2.885844333E-05), SCALE( 2.718161704E-05), SCALE( 2.554569073E-05), -SCALE( 2.395598858E-05), -SCALE( 2.241701623E-05), -SCALE( 2.093250441E-05), -SCALE( 1.950545993E-05), -SCALE( 1.813820381E-05), -SCALE( 1.683242772E-05), -SCALE( 1.558924305E-05), -SCALE( 1.440921824E-05), -SCALE( 1.329243969E-05), -SCALE( 1.223855270E-05), -SCALE( 1.124680875E-05), -SCALE( 1.031611009E-05), -SCALE( 9.445050637E-06), -SCALE( 8.631964192E-06), -SCALE( 7.874960829E-06), -SCALE( 7.171964626E-06), -SCALE( 6.520755960E-06), -SCALE( 5.918994248E-06), -SCALE( 5.364252502E-06), -SCALE( 4.854050530E-06), -SCALE( 4.385879038E-06), -SCALE( 3.957220997E-06), -SCALE( 3.565570978E-06), -SCALE( 3.208459020E-06), -SCALE( 2.883470643E-06), -SCALE( 2.588257530E-06), -SCALE( 2.320550948E-06), -SCALE( 2.078171747E-06), -SCALE( 1.859034001E-06), -SCALE( 1.661159786E-06), -SCALE( 1.482681114E-06), -SCALE( 1.321840614E-06), -SCALE( 1.176999604E-06), -SCALE( 1.046637067E-06), -SCALE( 9.293416952E-07), -SCALE( 8.238164355E-07), -SCALE( 7.288739425E-07), -SCALE( 6.434325428E-07), -SCALE( 5.665120852E-07), -SCALE( 4.972276315E-07), -SCALE( 4.347855338E-07), -SCALE( 3.784752209E-07), -SCALE( 3.276689142E-07), -SCALE( 2.818143514E-07), -SCALE( 2.404238444E-07), -SCALE( 2.030677564E-07), -SCALE( 1.693738625E-07), -SCALE( 1.390191784E-07) }; #undef SCALE // Annex D.8 - LFE interpolation FIR, 64x interpolation static const double lfe_fir_64[256] = { 2.658434387E-04, 9.029330686E-03, 7.939263433E-02, 2.425158769E-01, 3.430179358E-01, 2.398228943E-01, 7.746443897E-02, 8.622321300E-03, 8.179365250E-05, 9.450953454E-03, 8.134882897E-02, 2.451938838E-01, 3.429597318E-01, 2.371159792E-01, 7.556436211E-02, 8.229630999E-03, 9.439323912E-05, 9.887560271E-03, 8.333285898E-02, 2.478559017E-01, 3.428434134E-01, 2.343961596E-01, 7.369252294E-02, 7.850865833E-03, 1.082170274E-04, 1.033949479E-02, 8.534456789E-02, 2.505008876E-01, 3.426689506E-01, 2.316644788E-01, 7.184901088E-02, 7.485736627E-03, 1.233371440E-04, 1.080708485E-02, 8.738376945E-02, 2.531278133E-01, 3.424364924E-01, 2.289219648E-01, 7.003392279E-02, 7.133882027E-03, 1.397485757E-04, 1.129068248E-02, 8.945026249E-02, 2.557355762E-01, 3.421461284E-01, 2.261696160E-01, 6.824731827E-02, 6.794991903E-03, 1.575958013E-04, 1.179065090E-02, 9.154383838E-02, 2.583232224E-01, 3.417979777E-01, 2.234084606E-01, 6.648923457E-02, 6.468691397E-03, 1.769922383E-04, 1.230732165E-02, 9.366425127E-02, 2.608896792E-01, 3.413922191E-01, 2.206395119E-01, 6.475970894E-02, 6.154712290E-03, 1.981738606E-04, 1.284105983E-02, 9.581124038E-02, 2.634339035E-01, 3.409290314E-01, 2.178637981E-01, 6.305878609E-02, 5.852684379E-03, 2.211847313E-04, 1.339218579E-02, 9.798453748E-02, 2.659549415E-01, 3.404086530E-01, 2.150822729E-01, 6.138643622E-02, 5.562345497E-03, 2.460231190E-04, 1.396108977E-02, 1.001838669E-01, 2.684516609E-01, 3.398312926E-01, 2.122959495E-01, 5.974265561E-02, 5.283284001E-03, 2.726115927E-04, 1.454808749E-02, 1.024089083E-01, 2.709231377E-01, 3.391972482E-01, 2.095058411E-01, 5.812742189E-02, 5.015311297E-03, 3.013863170E-04, 1.515355054E-02, 1.046593264E-01, 2.733682692E-01, 3.385068178E-01, 2.067128718E-01, 5.654069409E-02, 4.758012015E-03, 3.328395542E-04, 1.577781141E-02, 1.069347933E-01, 2.757860720E-01, 3.377602994E-01, 2.039180547E-01, 5.498242006E-02, 4.511159845E-03, 3.658991191E-04, 1.642123051E-02, 1.092349365E-01, 2.781755328E-01, 3.369580209E-01, 2.011223286E-01, 5.345252529E-02, 4.274417181E-03, 4.018281470E-04, 1.708412915E-02, 1.115593687E-01, 2.805356979E-01, 3.361004293E-01, 1.983266175E-01, 5.195093155E-02, 4.047499038E-03, 4.401875485E-04, 1.776690222E-02, 1.139076948E-01, 2.828655839E-01, 3.351879120E-01, 1.955319196E-01, 5.047753453E-02, 3.830091329E-03, 4.812776169E-04, 1.846982725E-02, 1.162794977E-01, 2.851640880E-01, 3.342207968E-01, 1.927391142E-01, 4.903224111E-02, 3.621967277E-03, 5.252459669E-04, 1.919330470E-02, 1.186743453E-01, 2.874303460E-01, 3.331996202E-01, 1.899491698E-01, 4.761491716E-02, 3.422776936E-03, 5.721592461E-04, 1.993762329E-02, 1.210917681E-01, 2.896633744E-01, 3.321248591E-01, 1.871629506E-01, 4.622544348E-02, 3.232272575E-03, 6.222130032E-04, 2.070316114E-02, 1.235313043E-01, 2.918621898E-01, 3.309969604E-01, 1.843813360E-01, 4.486365616E-02, 3.050152911E-03, 6.755515351E-04, 2.149021253E-02, 1.259924471E-01, 2.940258980E-01, 3.298164308E-01, 1.816052496E-01, 4.352942482E-02, 2.876190469E-03, 7.324148901E-04, 2.229913883E-02, 1.284746826E-01, 2.961534858E-01, 3.285838962E-01, 1.788355410E-01, 4.222255200E-02, 2.710093278E-03, 7.928516716E-04, 2.313023806E-02, 1.309774816E-01, 2.982441187E-01, 3.272998929E-01, 1.760730892E-01, 4.094288871E-02, 2.551567042E-03, 8.570110658E-04, 2.398385666E-02, 1.335003078E-01, 3.002967536E-01, 3.259649575E-01, 1.733186990E-01, 3.969023004E-02, 2.400433412E-03, 9.251192096E-04, 2.486028522E-02, 1.360425949E-01, 3.023106754E-01, 3.245797157E-01, 1.705732346E-01, 3.846437484E-02, 2.256359672E-03, 9.974770946E-04, 2.575986087E-02, 1.386037618E-01, 3.042849004E-01, 3.231448531E-01, 1.678375006E-01, 3.726511076E-02, 2.119151875E-03, 1.073930296E-03, 2.668286115E-02, 1.411831975E-01, 3.062185347E-01, 3.216609657E-01, 1.651122719E-01, 3.609224036E-02, 1.988604199E-03, 1.155023579E-03, 2.762960829E-02, 1.437802613E-01, 3.081108034E-01, 3.201287389E-01, 1.623983532E-01, 3.494550660E-02, 1.864377526E-03, 1.240676851E-03, 2.860039286E-02, 1.463943720E-01, 3.099608123E-01, 3.185488880E-01, 1.596965194E-01, 3.382468969E-02, 1.746327500E-03, 1.331258914E-03, 2.959549613E-02, 1.490248144E-01, 3.117676973E-01, 3.169221282E-01, 1.570075154E-01, 3.272953629E-02, 1.634211512E-03, 1.426893868E-03, 3.061520495E-02, 1.516709626E-01, 3.135308027E-01, 3.152491748E-01, 1.543320864E-01, 3.165979683E-02, 1.527829794E-03 }; // Annex D.8 - LFE interpolation FIR, 128x interpolation static const double lfe_fir_128[256] = { 5.316857100E-04, 1.587849557E-01, 6.860344410E-01, 1.549285650E-01, 1.635869100E-04, 1.626973301E-01, 6.859180331E-01, 1.511284113E-01, 1.887860900E-04, 1.666653752E-01, 6.856853962E-01, 1.473847479E-01, 2.164336300E-04, 1.706887931E-01, 6.853365302E-01, 1.436977387E-01, 2.466738200E-04, 1.747671962E-01, 6.848715544E-01, 1.400675476E-01, 2.794966000E-04, 1.789001823E-01, 6.842908263E-01, 1.364943385E-01, 3.151909600E-04, 1.830873191E-01, 6.835945249E-01, 1.329781860E-01, 3.539837500E-04, 1.873281151E-01, 6.827830076E-01, 1.295191795E-01, 3.963469100E-04, 1.916220933E-01, 6.818566918E-01, 1.261173040E-01, 4.423685900E-04, 1.959686577E-01, 6.808158755E-01, 1.227726117E-01, 4.920452500E-04, 2.003673166E-01, 6.796611548E-01, 1.194850579E-01, 5.452220800E-04, 2.048173845E-01, 6.783930659E-01, 1.162546203E-01, 6.027714100E-04, 2.093182206E-01, 6.770122051E-01, 1.130811572E-01, 6.656776500E-04, 2.138691545E-01, 6.755192280E-01, 1.099646092E-01, 7.317967800E-04, 2.184694260E-01, 6.739146709E-01, 1.069048345E-01, 8.036546600E-04, 2.231182903E-01, 6.721994877E-01, 1.039016470E-01, 8.803732300E-04, 2.278149277E-01, 6.703743935E-01, 1.009548605E-01, 9.625531400E-04, 2.325585187E-01, 6.684402227E-01, 9.806428105E-02, 1.050489840E-03, 2.373482138E-01, 6.663978696E-01, 9.522963315E-02, 1.144316160E-03, 2.421830446E-01, 6.642482877E-01, 9.245070815E-02, 1.244423330E-03, 2.470620573E-01, 6.619924903E-01, 8.972713351E-02, 1.351100280E-03, 2.519843280E-01, 6.596315503E-01, 8.705867827E-02, 1.464826870E-03, 2.569487989E-01, 6.571664810E-01, 8.444493264E-02, 1.585700080E-03, 2.619544268E-01, 6.545983553E-01, 8.188561350E-02, 1.714018640E-03, 2.670000792E-01, 6.519285440E-01, 7.938029617E-02, 1.850234690E-03, 2.720846236E-01, 6.491580606E-01, 7.692859322E-02, 1.994950230E-03, 2.772069275E-01, 6.462883353E-01, 7.453006506E-02, 2.147856400E-03, 2.823657692E-01, 6.433205605E-01, 7.218432426E-02, 2.310042500E-03, 2.875599265E-01, 6.402561665E-01, 6.989086419E-02, 2.481348810E-03, 2.927881181E-01, 6.370964646E-01, 6.764923781E-02, 2.662512240E-03, 2.980490029E-01, 6.338429451E-01, 6.545893103E-02, 2.853781920E-03, 3.033412695E-01, 6.304970384E-01, 6.331945211E-02, 3.055653300E-03, 3.086635172E-01, 6.270602942E-01, 6.123027951E-02, 3.268416510E-03, 3.140144050E-01, 6.235341430E-01, 5.919086933E-02, 3.492647550E-03, 3.193923831E-01, 6.199202538E-01, 5.720067024E-02, 3.728747140E-03, 3.247960210E-01, 6.162202954E-01, 5.525910854E-02, 3.977200480E-03, 3.302238286E-01, 6.124358177E-01, 5.336561054E-02, 4.238294900E-03, 3.356742859E-01, 6.085684896E-01, 5.151961371E-02, 4.512710030E-03, 3.411457539E-01, 6.046201587E-01, 4.972046614E-02, 4.800856580E-03, 3.466366828E-01, 6.005923152E-01, 4.796761274E-02, 5.103122910E-03, 3.521454632E-01, 5.964869261E-01, 4.626038298E-02, 5.420174920E-03, 3.576703668E-01, 5.923057795E-01, 4.459818453E-02, 5.752369300E-03, 3.632097244E-01, 5.880505443E-01, 4.298033938E-02, 6.100293250E-03, 3.687619269E-01, 5.837231875E-01, 4.140623659E-02, 6.464532110E-03, 3.743250966E-01, 5.793255568E-01, 3.987516090E-02, 6.845539900E-03, 3.798975349E-01, 5.748594403E-01, 3.838652745E-02, 7.243919190E-03, 3.854774535E-01, 5.703269839E-01, 3.693958372E-02, 7.660165890E-03, 3.910630047E-01, 5.657299161E-01, 3.553372994E-02, 8.094980380E-03, 3.966524303E-01, 5.610702634E-01, 3.416819125E-02, 8.548815730E-03, 4.022437930E-01, 5.563499928E-01, 3.284239396E-02, 9.022301060E-03, 4.078352153E-01, 5.515710115E-01, 3.155555204E-02, 9.516004470E-03, 4.134248793E-01, 5.467353463E-01, 3.030703776E-02, 1.003060210E-02, 4.190107882E-01, 5.418450832E-01, 2.909611352E-02, 1.056654565E-02, 4.245910645E-01, 5.369022489E-01, 2.792212367E-02, 1.112466771E-02, 4.301636219E-01, 5.319088101E-01, 2.678431384E-02, 1.170534454E-02, 4.357266724E-01, 5.268667936E-01, 2.568206564E-02, 1.230939943E-02, 4.412781000E-01, 5.217782855E-01, 2.461459488E-02, 1.293735672E-02, 4.468160272E-01, 5.166453719E-01, 2.358125709E-02, 1.358995494E-02, 4.523383081E-01, 5.114701390E-01, 2.258131653E-02, 1.426773332E-02, 4.578429461E-01, 5.062545538E-01, 2.161412500E-02, 1.497144438E-02, 4.633280039E-01, 5.010007620E-01, 2.067894675E-02, 1.570170000E-02, 4.687913656E-01, 4.957108200E-01, 1.977507770E-02, 1.645922661E-02, 4.742309451E-01, 4.903867543E-01, 1.890186779E-02, 1.724460535E-02, 4.796448052E-01, 4.850307405E-01, 1.805862412E-02 }; #define SCALE(x) ((x) * M_SQRT2 * 256) // Annex D.9 - 1024 tap FIR for X96 synthesis QMF static const double band_fir_x96[1024] = { SCALE(-7.127938986604168E-08), SCALE(-7.095090315087499E-08), SCALE(-7.952503432137510E-08), SCALE(-8.932687128137479E-08), SCALE(-9.748319049487465E-08), SCALE(-1.058665951072195E-07), SCALE(-1.152736341186576E-07), SCALE(-1.252310964561535E-07), SCALE(-1.355563613797138E-07), SCALE(-1.464093182119164E-07), SCALE(-1.578742499812371E-07), SCALE(-1.699459292657122E-07), SCALE(-1.826418431101815E-07), SCALE(-1.960059458775785E-07), SCALE(-2.100789970600680E-07), SCALE(-2.248975904755362E-07), SCALE(-2.405024587792340E-07), SCALE(-2.569387461577766E-07), SCALE(-2.742537030854958E-07), SCALE(-2.924966254175760E-07), SCALE(-3.117198196826890E-07), SCALE(-3.319786404047318E-07), SCALE(-3.533313458884360E-07), SCALE(-3.758391046541218E-07), SCALE(-3.995662812166919E-07), SCALE(-4.245804529615933E-07), SCALE(-4.509524956369838E-07), SCALE(-4.787565911260676E-07), SCALE(-5.080703129463105E-07), SCALE(-5.389746422333555E-07), SCALE(-5.715542338879300E-07), SCALE(-6.058974119201980E-07), -SCALE(-6.420958008785305E-07), -SCALE(-6.802443284999140E-07), -SCALE(-7.204416525901345E-07), -SCALE(-7.627901817207720E-07), -SCALE(-8.073961036828060E-07), -SCALE(-8.543693702029365E-07), -SCALE(-9.038233322489550E-07), -SCALE(-9.558747254049829E-07), -SCALE(-1.010643712821376E-06), -SCALE(-1.068253890614633E-06), -SCALE(-1.128832363715543E-06), -SCALE(-1.192509718464610E-06), -SCALE(-1.259419343863326E-06), -SCALE(-1.329697405230052E-06), -SCALE(-1.403482943378026E-06), -SCALE(-1.480917863497994E-06), -SCALE(-1.562146591398006E-06), -SCALE(-1.647316037754536E-06), -SCALE(-1.736575155397134E-06), -SCALE(-1.830074910452612E-06), -SCALE(-1.927968090232205E-06), -SCALE(-2.030409266099076E-06), -SCALE(-2.137554168666232E-06), -SCALE(-2.249559625377646E-06), -SCALE(-2.366582812095056E-06), -SCALE(-2.488781197085654E-06), -SCALE(-2.616312057164482E-06), -SCALE(-2.749332426639114E-06), -SCALE(-2.887998457950138E-06), -SCALE(-3.032465363920388E-06), -SCALE(-3.182886786597464E-06), -SCALE(-3.339414724085582E-06), -SCALE(-3.502198552003754E-06), -SCALE(-3.671384926229468E-06), -SCALE(-3.847116621801583E-06), -SCALE(-4.029532465769980E-06), -SCALE(-4.218767020985225E-06), -SCALE(-4.414950504331232E-06), -SCALE(-4.618207304054390E-06), -SCALE(-4.828655865889468E-06), -SCALE(-5.046407670500340E-06), -SCALE(-5.271567145540585E-06), -SCALE(-5.504230753545810E-06), -SCALE(-5.744486878502875E-06), -SCALE(-5.992414242480480E-06), -SCALE(-6.248081786307280E-06), -SCALE(-6.511547627860400E-06), -SCALE(-6.782858956580495E-06), -SCALE(-7.062050754515410E-06), -SCALE(-7.349145669714490E-06), -SCALE(-7.644152509859200E-06), -SCALE(-7.947066136436549E-06), -SCALE(-8.257866642922776E-06), -SCALE(-8.576519215476810E-06), -SCALE(-8.902971890012200E-06), -SCALE(-9.237155419546841E-06), -SCALE(-9.578982598825311E-06), -SCALE(-9.928348166726454E-06), -SCALE(-1.028512733460845E-05), -SCALE(-1.064917563432859E-05), -SCALE(-1.102032704633465E-05), -SCALE(-1.139839388088106E-05), -SCALE(-1.178316603669356E-05), -SCALE(-1.217441088925653E-05), -SCALE(-1.257187157446922E-05), -SCALE(-1.297526685803031E-05), -SCALE(-1.338428997824206E-05), -SCALE(-1.379860854096596E-05), -SCALE(-1.421786336584378E-05), -SCALE(-1.464166838349645E-05), -SCALE(-1.506960952767971E-05), -SCALE(-1.550124459778260E-05), -SCALE(-1.593610134164050E-05), -SCALE(-1.637367742646690E-05), -SCALE(-1.681344171653956E-05), -SCALE(-1.725483414306857E-05), -SCALE(-1.769726156360750E-05), -SCALE(-1.814009771461820E-05), -SCALE(-1.858268630848355E-05), -SCALE(-1.902434097009924E-05), -SCALE(-1.946434074488017E-05), -SCALE(-1.990193003014108E-05), -SCALE(-2.033632155746451E-05), -SCALE(-2.076669641777394E-05), -SCALE(-2.119220163057428E-05), -SCALE(-2.161195008423191E-05), -SCALE(-2.202502165289463E-05), -SCALE(-2.243046323951717E-05), -SCALE(-2.282728860550347E-05), -SCALE(-2.321447837191817E-05), -SCALE(-2.359098021649775E-05), -SCALE(-2.395570893976328E-05), -SCALE(-2.430754772248991E-05), -SCALE(-2.464534820090372E-05), -SCALE(-2.496793086354262E-05), -SCALE(-2.527408508232496E-05), SCALE( 2.556256939919902E-05), SCALE( 2.583211172456204E-05), SCALE( 2.608141341583320E-05), SCALE( 2.630914939052064E-05), SCALE( 2.651396653512446E-05), SCALE( 2.669448385046480E-05), SCALE( 2.684929723999712E-05), SCALE( 2.697697975324517E-05), SCALE( 2.707608215301207E-05), SCALE( 2.714513310366389E-05), SCALE( 2.718264274615772E-05), SCALE( 2.718710298053676E-05), SCALE( 2.715699010579455E-05), SCALE( 2.709076506473594E-05), SCALE( 2.698687619105470E-05), SCALE( 2.684375953903512E-05), SCALE( 2.665984338990853E-05), SCALE( 2.643354859248296E-05), SCALE( 2.616329155063932E-05), SCALE( 2.584748457743932E-05), SCALE( 2.548454069800296E-05), SCALE( 2.507287405244726E-05), SCALE( 2.461090395766135E-05), SCALE( 2.409705530058412E-05), SCALE( 2.352976312853915E-05), SCALE( 2.290747311740374E-05), SCALE( 2.222864728099456E-05), SCALE( 2.149176446183214E-05), SCALE( 2.069532541857637E-05), SCALE( 1.983785326550204E-05), SCALE( 1.891789805352808E-05), SCALE( 1.793403733553470E-05), -SCALE( 1.688488402231131E-05), -SCALE( 1.576908692157790E-05), -SCALE( 1.458533474050792E-05), -SCALE( 1.333235659026308E-05), -SCALE( 1.200892908323512E-05), -SCALE( 1.061387697354165E-05), -SCALE( 9.146080150692231E-06), -SCALE( 7.604474075726550E-06), -SCALE( 5.988052382589700E-06), -SCALE( 4.295867784770884E-06), -SCALE( 2.527049419980207E-06), -SCALE( 6.808031538695990E-07), -SCALE(-1.243599082783966E-06), -SCALE(-3.246818706694593E-06), -SCALE(-5.329426896805280E-06), -SCALE(-7.491903655942790E-06), -SCALE(-9.734640752487110E-06), -SCALE(-1.205794140863581E-05), -SCALE(-1.446201050055097E-05), -SCALE(-1.694695384810771E-05), -SCALE(-1.951277238921524E-05), -SCALE(-2.215936159729271E-05), -SCALE(-2.488650449141616E-05), -SCALE(-2.769387104186206E-05), -SCALE(-3.058101208191696E-05), -SCALE(-3.354735876525904E-05), -SCALE(-3.659221671654097E-05), -SCALE(-3.971476548553926E-05), -SCALE(-4.291405238785664E-05), -SCALE(-4.618899196172456E-05), -SCALE(-4.953836017695434E-05), -SCALE(-5.296079400014060E-05), -SCALE(-5.645478762018535E-05), -SCALE(-6.001869197279105E-05), -SCALE(-6.365070805378855E-05), -SCALE(-6.734888652588270E-05), -SCALE(-7.111112575372286E-05), -SCALE(-7.493517141117804E-05), -SCALE(-7.881860980632000E-05), -SCALE(-8.275886762862380E-05), -SCALE(-8.675321306240340E-05), -SCALE(-9.079875548213924E-05), -SCALE(-9.489243763625400E-05), -SCALE(-9.903103541547551E-05), -SCALE(-1.032111605730492E-04), -SCALE(-1.074292607067401E-04), -SCALE(-1.116816161426427E-04), -SCALE(-1.159643396677203E-04), -SCALE(-1.202733737618488E-04), -SCALE(-1.246044908903475E-04), -SCALE(-1.289533027076185E-04), -SCALE(-1.333152598388584E-04), -SCALE(-1.376856378740834E-04), -SCALE(-1.420595376057812E-04), -SCALE(-1.464319042632354E-04), -SCALE(-1.507975279169229E-04), -SCALE(-1.551510331409437E-04), -SCALE(-1.594868790905897E-04), -SCALE(-1.637993715464274E-04), -SCALE(-1.680826635644682E-04), -SCALE(-1.723307577358468E-04), -SCALE(-1.765375064656002E-04), -SCALE(-1.806966158461229E-04), -SCALE(-1.848016463895374E-04), -SCALE(-1.888460252663805E-04), -SCALE(-1.928230469653129E-04), -SCALE(-1.967258755680427E-04), -SCALE(-2.005475454710861E-04), -SCALE(-2.042809749895736E-04), -SCALE(-2.079189673565927E-04), -SCALE(-2.114542191049128E-04), -SCALE(-2.148793208048870E-04), -SCALE(-2.181867649165566E-04), -SCALE(-2.213689470691719E-04), -SCALE(-2.244181863585484E-04), -SCALE(-2.273267267668629E-04), -SCALE(-2.300867481008122E-04), -SCALE(-2.326903665352515E-04), -SCALE(-2.351296356350780E-04), -SCALE(-2.373965479929124E-04), -SCALE(-2.394830702362197E-04), -SCALE(-2.413811459337238E-04), -SCALE(-2.430827245294182E-04), -SCALE(-2.445797571768798E-04), -SCALE(-2.458640761601700E-04), -SCALE(-2.469274156993822E-04), -SCALE(-2.477619902517768E-04), -SCALE(-2.483604609263728E-04), -SCALE(-2.487146183038166E-04), -SCALE(-2.488154045724704E-04), -SCALE(-2.486547177024881E-04), -SCALE(-2.482254333360894E-04), -SCALE(-2.475200821995122E-04), -SCALE(-2.465308179417657E-04), -SCALE(-2.452500321752444E-04), -SCALE(-2.436703743734102E-04), SCALE( 2.417845745791980E-04), SCALE( 2.395854398583434E-04), SCALE( 2.370659535642138E-04), SCALE( 2.342192800869662E-04), SCALE( 2.310387700701966E-04), SCALE( 2.275179613297294E-04), SCALE( 2.236505938503120E-04), SCALE( 2.194306115956788E-04), SCALE( 2.148521873332429E-04), SCALE( 2.099097253875555E-04), SCALE( 2.045978973917164E-04), SCALE( 1.989116442431618E-04), SCALE( 1.928461833795790E-04), SCALE( 1.863970107085474E-04), SCALE( 1.795599357837175E-04), SCALE( 1.723310839515549E-04), SCALE( 1.647069084035198E-04), SCALE( 1.566841923938267E-04), SCALE( 1.482600859779846E-04), SCALE( 1.394321081840759E-04), SCALE( 1.301981580423545E-04), SCALE( 1.205565161870574E-04), SCALE( 1.105058690666598E-04), SCALE( 1.000453111637885E-04), SCALE( 8.917436962303755E-05), SCALE( 7.789300610544491E-05), SCALE( 6.620163295915880E-05), SCALE( 5.410111500896320E-05), SCALE( 4.159279275517104E-05), SCALE( 2.867848400338988E-05), SCALE( 1.536049652046955E-05), SCALE( 1.641629701930447E-06), -SCALE(-1.247480140056488E-05), -SCALE(-2.698496475767416E-05), -SCALE(-4.188450631602256E-05), -SCALE(-5.716854816951505E-05), -SCALE(-7.283165337456365E-05), -SCALE(-8.886782533520320E-05), -SCALE(-1.052705294604104E-04), -SCALE(-1.220326918528753E-04), -SCALE(-1.391466488046540E-04), -SCALE(-1.566041455665768E-04), -SCALE(-1.743963597795672E-04), -SCALE(-1.925139014261300E-04), -SCALE(-2.109467883317648E-04), -SCALE(-2.296844445765594E-04), -SCALE(-2.487156900488424E-04), -SCALE(-2.680287412777888E-04), -SCALE(-2.876112401970844E-04), -SCALE(-3.074502529716603E-04), -SCALE(-3.275322154221950E-04), -SCALE(-3.478429334738513E-04), -SCALE(-3.683676476039790E-04), -SCALE(-3.890910333571532E-04), -SCALE(-4.099971482282953E-04), -SCALE(-4.310694309740984E-04), -SCALE(-4.522907395812775E-04), -SCALE(-4.736433535042661E-04), -SCALE(-4.951089849262823E-04), -SCALE(-5.166687782268060E-04), -SCALE(-5.383032870049990E-04), -SCALE(-5.599924762541345E-04), -SCALE(-5.817157931755955E-04), -SCALE(-6.034521681004050E-04), -SCALE(-6.251799639488680E-04), -SCALE(-6.468769776333065E-04), -SCALE(-6.685205214586190E-04), -SCALE(-6.900874252648055E-04), -SCALE(-7.115540021619675E-04), -SCALE(-7.328960503543460E-04), -SCALE(-7.540889275341360E-04), -SCALE(-7.751075532553095E-04), -SCALE(-7.959263867639895E-04), -SCALE(-8.165194293666030E-04), -SCALE(-8.368602986989685E-04), -SCALE(-8.569222323017155E-04), -SCALE(-8.766780920104490E-04), -SCALE(-8.961003654734095E-04), -SCALE(-9.151611951498600E-04), -SCALE(-9.338323832499584E-04), -SCALE(-9.520854714135470E-04), -SCALE(-9.698917421439440E-04), -SCALE(-9.872221706725139E-04), -SCALE(-1.004047429744579E-03), -SCALE(-1.020338043044835E-03), -SCALE(-1.036064390096491E-03), -SCALE(-1.051196660616898E-03), -SCALE(-1.065704855603833E-03), -SCALE(-1.079558856878201E-03), -SCALE(-1.092728433285052E-03), -SCALE(-1.105183307573424E-03), -SCALE(-1.116893160529398E-03), -SCALE(-1.127827655023416E-03), -SCALE(-1.137956440566105E-03), -SCALE(-1.147249229489164E-03), -SCALE(-1.155675800049931E-03), -SCALE(-1.163205988551180E-03), -SCALE(-1.169809696015420E-03), -SCALE(-1.175457042899868E-03), -SCALE(-1.180118372021201E-03), -SCALE(-1.183764158185287E-03), -SCALE(-1.186365015306024E-03), -SCALE(-1.187891943390233E-03), -SCALE(-1.188316331684390E-03), -SCALE(-1.187609780917844E-03), -SCALE(-1.185744107237668E-03), -SCALE(-1.182691606532144E-03), -SCALE(-1.178425062841502E-03), -SCALE(-1.172917669070769E-03), -SCALE(-1.166143029435388E-03), -SCALE(-1.158075292551968E-03), -SCALE(-1.148689156870073E-03), -SCALE(-1.137959857080735E-03), -SCALE(-1.125863169053070E-03), -SCALE(-1.112375532031342E-03), -SCALE(-1.097474054394210E-03), -SCALE(-1.081136518161085E-03), -SCALE(-1.063341381932592E-03), -SCALE(-1.044067841074319E-03), -SCALE(-1.023295833844173E-03), -SCALE(-1.001006116010387E-03), -SCALE(-9.771802661360279E-04), -SCALE(-9.518007272200706E-04), -SCALE(-9.248508094554660E-04), -SCALE(-8.963147092655810E-04), -SCALE(-8.661775139092965E-04), -SCALE(-8.344252837566670E-04), -SCALE(-8.010450565557860E-04), SCALE( 7.660248590280630E-04), SCALE( 7.293537115784970E-04), SCALE( 6.910217203263935E-04), SCALE( 6.510200794896010E-04), SCALE( 6.093410318069875E-04), SCALE( 5.659778724459110E-04), SCALE( 5.209250745440945E-04), SCALE( 4.741782930361297E-04), SCALE( 4.257343232947606E-04), SCALE( 3.755911023931640E-04), SCALE( 3.237477782338944E-04), SCALE( 2.702047136138704E-04), SCALE( 2.149635065251304E-04), SCALE( 1.580269916310419E-04), SCALE( 9.939925244214647E-05), SCALE( 3.908562327914961E-05), SCALE(-2.290727971715371E-05), SCALE(-8.657155665857780E-05), SCALE(-1.518980125188441E-04), SCALE(-2.188761566878072E-04), SCALE(-2.874942045551261E-04), SCALE(-3.577390751948810E-04), SCALE(-4.295963388434640E-04), SCALE(-5.030502185326690E-04), SCALE(-5.780836785397680E-04), SCALE(-6.546784227970995E-04), SCALE(-7.328147714529330E-04), SCALE(-8.124716609148709E-04), SCALE(-8.936267682438125E-04), SCALE(-9.762565135043539E-04), SCALE(-1.060335987079630E-03), SCALE(-1.145838949770837E-03), -SCALE(-1.232737907672045E-03), -SCALE(-1.321004112591985E-03), -SCALE(-1.410607496458753E-03), -SCALE(-1.501516675908098E-03), -SCALE(-1.593699118821068E-03), -SCALE(-1.687121144658436E-03), -SCALE(-1.781747765280413E-03), -SCALE(-1.877542686278472E-03), -SCALE(-1.974468495455718E-03), -SCALE(-2.072486671719865E-03), -SCALE(-2.171557592248277E-03), -SCALE(-2.271640530170194E-03), -SCALE(-2.372693596410548E-03), -SCALE(-2.474673741849360E-03), -SCALE(-2.577536862984530E-03), -SCALE(-2.681237815643306E-03), -SCALE(-2.785730610971646E-03), -SCALE(-2.890968412999295E-03), -SCALE(-2.996903289082014E-03), -SCALE(-3.103486213203266E-03), -SCALE(-3.210667388169048E-03), -SCALE(-3.318396256656389E-03), -SCALE(-3.426621422085545E-03), -SCALE(-3.535290652053989E-03), -SCALE(-3.644351033012211E-03), -SCALE(-3.753748970963593E-03), -SCALE(-3.863430052185924E-03), -SCALE(-3.973339058810391E-03), -SCALE(-4.083420450837847E-03), -SCALE(-4.193618368607346E-03), -SCALE(-4.303876205087690E-03), -SCALE(-4.414136605908662E-03), -SCALE(-4.524341897756710E-03), -SCALE(-4.634434107578317E-03), -SCALE(-4.744354956658913E-03), -SCALE(-4.854045856535885E-03), -SCALE(-4.963447825006078E-03), -SCALE(-5.072501497871895E-03), -SCALE(-5.181147471348025E-03), -SCALE(-5.289326317382795E-03), -SCALE(-5.396978578320565E-03), -SCALE(-5.504044759237560E-03), -SCALE(-5.610465164666585E-03), -SCALE(-5.716179914026345E-03), -SCALE(-5.821129444341225E-03), -SCALE(-5.925254521610190E-03), -SCALE(-6.028495988202895E-03), -SCALE(-6.130794760236025E-03), -SCALE(-6.232092022456570E-03), -SCALE(-6.332329249242580E-03), -SCALE(-6.431448471736440E-03), -SCALE(-6.529392276231145E-03), -SCALE(-6.626103501535170E-03), -SCALE(-6.721525246692210E-03), -SCALE(-6.815601343450995E-03), -SCALE(-6.908276363015645E-03), -SCALE(-6.999495292082720E-03), -SCALE(-7.089203549057705E-03), -SCALE(-7.177347664780630E-03), -SCALE(-7.263875283956655E-03), -SCALE(-7.348734515904140E-03), -SCALE(-7.431873934100050E-03), -SCALE(-7.513243215430925E-03), -SCALE(-7.592793162768140E-03), -SCALE(-7.670475562372150E-03), -SCALE(-7.746243173811765E-03), -SCALE(-7.820049650783600E-03), -SCALE(-7.891849558781685E-03), -SCALE(-7.961598843009079E-03), -SCALE(-8.029254840905250E-03), -SCALE(-8.094776089836320E-03), -SCALE(-8.158122302753560E-03), -SCALE(-8.219254024989381E-03), -SCALE(-8.278132675268024E-03), -SCALE(-8.334721791143661E-03), -SCALE(-8.388987020627474E-03), -SCALE(-8.440894692545369E-03), -SCALE(-8.490411808784576E-03), -SCALE(-8.537507303362359E-03), -SCALE(-8.582152067202975E-03), -SCALE(-8.624318234161430E-03), -SCALE(-8.663979162716030E-03), -SCALE(-8.701109747179411E-03), -SCALE(-8.735686465917280E-03), -SCALE(-8.767688130949044E-03), -SCALE(-8.797095815255481E-03), -SCALE(-8.823890503946285E-03), -SCALE(-8.848053147748315E-03), -SCALE(-8.869568188578319E-03), -SCALE(-8.888423592735640E-03), -SCALE(-8.904608055568560E-03), -SCALE(-8.918110931856005E-03), -SCALE(-8.928923499538055E-03), -SCALE(-8.937039001090346E-03), -SCALE(-8.942452290029211E-03), -SCALE(-8.945159822376361E-03), SCALE( 8.945159822376361E-03), SCALE( 8.942452290029211E-03), SCALE( 8.937039001090346E-03), SCALE( 8.928923499538055E-03), SCALE( 8.918110931856005E-03), SCALE( 8.904608055568560E-03), SCALE( 8.888423592735640E-03), SCALE( 8.869568188578319E-03), SCALE( 8.848053147748315E-03), SCALE( 8.823890503946285E-03), SCALE( 8.797095815255481E-03), SCALE( 8.767688130949044E-03), SCALE( 8.735686465917280E-03), SCALE( 8.701109747179411E-03), SCALE( 8.663979162716030E-03), SCALE( 8.624318234161430E-03), SCALE( 8.582152067202975E-03), SCALE( 8.537507303362359E-03), SCALE( 8.490411808784576E-03), SCALE( 8.440894692545369E-03), SCALE( 8.388987020627474E-03), SCALE( 8.334721791143661E-03), SCALE( 8.278132675268024E-03), SCALE( 8.219254024989381E-03), SCALE( 8.158122302753560E-03), SCALE( 8.094776089836320E-03), SCALE( 8.029254840905250E-03), SCALE( 7.961598843009079E-03), SCALE( 7.891849558781685E-03), SCALE( 7.820049650783600E-03), SCALE( 7.746243173811765E-03), SCALE( 7.670475562372150E-03), -SCALE( 7.592793162768140E-03), -SCALE( 7.513243215430925E-03), -SCALE( 7.431873934100050E-03), -SCALE( 7.348734515904140E-03), -SCALE( 7.263875283956655E-03), -SCALE( 7.177347664780630E-03), -SCALE( 7.089203549057705E-03), -SCALE( 6.999495292082720E-03), -SCALE( 6.908276363015645E-03), -SCALE( 6.815601343450995E-03), -SCALE( 6.721525246692210E-03), -SCALE( 6.626103501535170E-03), -SCALE( 6.529392276231145E-03), -SCALE( 6.431448471736440E-03), -SCALE( 6.332329249242580E-03), -SCALE( 6.232092022456570E-03), -SCALE( 6.130794760236025E-03), -SCALE( 6.028495988202895E-03), -SCALE( 5.925254521610190E-03), -SCALE( 5.821129444341225E-03), -SCALE( 5.716179914026345E-03), -SCALE( 5.610465164666585E-03), -SCALE( 5.504044759237560E-03), -SCALE( 5.396978578320565E-03), -SCALE( 5.289326317382795E-03), -SCALE( 5.181147471348025E-03), -SCALE( 5.072501497871895E-03), -SCALE( 4.963447825006078E-03), -SCALE( 4.854045856535885E-03), -SCALE( 4.744354956658913E-03), -SCALE( 4.634434107578317E-03), -SCALE( 4.524341897756710E-03), -SCALE( 4.414136605908662E-03), -SCALE( 4.303876205087690E-03), -SCALE( 4.193618368607346E-03), -SCALE( 4.083420450837847E-03), -SCALE( 3.973339058810391E-03), -SCALE( 3.863430052185924E-03), -SCALE( 3.753748970963593E-03), -SCALE( 3.644351033012211E-03), -SCALE( 3.535290652053989E-03), -SCALE( 3.426621422085545E-03), -SCALE( 3.318396256656389E-03), -SCALE( 3.210667388169048E-03), -SCALE( 3.103486213203266E-03), -SCALE( 2.996903289082014E-03), -SCALE( 2.890968412999295E-03), -SCALE( 2.785730610971646E-03), -SCALE( 2.681237815643306E-03), -SCALE( 2.577536862984530E-03), -SCALE( 2.474673741849360E-03), -SCALE( 2.372693596410548E-03), -SCALE( 2.271640530170194E-03), -SCALE( 2.171557592248277E-03), -SCALE( 2.072486671719865E-03), -SCALE( 1.974468495455718E-03), -SCALE( 1.877542686278472E-03), -SCALE( 1.781747765280413E-03), -SCALE( 1.687121144658436E-03), -SCALE( 1.593699118821068E-03), -SCALE( 1.501516675908098E-03), -SCALE( 1.410607496458753E-03), -SCALE( 1.321004112591985E-03), -SCALE( 1.232737907672045E-03), -SCALE( 1.145838949770837E-03), -SCALE( 1.060335987079630E-03), -SCALE( 9.762565135043539E-04), -SCALE( 8.936267682438125E-04), -SCALE( 8.124716609148709E-04), -SCALE( 7.328147714529330E-04), -SCALE( 6.546784227970995E-04), -SCALE( 5.780836785397680E-04), -SCALE( 5.030502185326690E-04), -SCALE( 4.295963388434640E-04), -SCALE( 3.577390751948810E-04), -SCALE( 2.874942045551261E-04), -SCALE( 2.188761566878072E-04), -SCALE( 1.518980125188441E-04), -SCALE( 8.657155665857780E-05), -SCALE( 2.290727971715371E-05), -SCALE(-3.908562327914961E-05), -SCALE(-9.939925244214647E-05), -SCALE(-1.580269916310419E-04), -SCALE(-2.149635065251304E-04), -SCALE(-2.702047136138704E-04), -SCALE(-3.237477782338944E-04), -SCALE(-3.755911023931640E-04), -SCALE(-4.257343232947606E-04), -SCALE(-4.741782930361297E-04), -SCALE(-5.209250745440945E-04), -SCALE(-5.659778724459110E-04), -SCALE(-6.093410318069875E-04), -SCALE(-6.510200794896010E-04), -SCALE(-6.910217203263935E-04), -SCALE(-7.293537115784970E-04), -SCALE(-7.660248590280630E-04), SCALE( 8.010450565557860E-04), SCALE( 8.344252837566670E-04), SCALE( 8.661775139092965E-04), SCALE( 8.963147092655810E-04), SCALE( 9.248508094554660E-04), SCALE( 9.518007272200706E-04), SCALE( 9.771802661360279E-04), SCALE( 1.001006116010387E-03), SCALE( 1.023295833844173E-03), SCALE( 1.044067841074319E-03), SCALE( 1.063341381932592E-03), SCALE( 1.081136518161085E-03), SCALE( 1.097474054394210E-03), SCALE( 1.112375532031342E-03), SCALE( 1.125863169053070E-03), SCALE( 1.137959857080735E-03), SCALE( 1.148689156870073E-03), SCALE( 1.158075292551968E-03), SCALE( 1.166143029435388E-03), SCALE( 1.172917669070769E-03), SCALE( 1.178425062841502E-03), SCALE( 1.182691606532144E-03), SCALE( 1.185744107237668E-03), SCALE( 1.187609780917844E-03), SCALE( 1.188316331684390E-03), SCALE( 1.187891943390233E-03), SCALE( 1.186365015306024E-03), SCALE( 1.183764158185287E-03), SCALE( 1.180118372021201E-03), SCALE( 1.175457042899868E-03), SCALE( 1.169809696015420E-03), SCALE( 1.163205988551180E-03), -SCALE( 1.155675800049931E-03), -SCALE( 1.147249229489164E-03), -SCALE( 1.137956440566105E-03), -SCALE( 1.127827655023416E-03), -SCALE( 1.116893160529398E-03), -SCALE( 1.105183307573424E-03), -SCALE( 1.092728433285052E-03), -SCALE( 1.079558856878201E-03), -SCALE( 1.065704855603833E-03), -SCALE( 1.051196660616898E-03), -SCALE( 1.036064390096491E-03), -SCALE( 1.020338043044835E-03), -SCALE( 1.004047429744579E-03), -SCALE( 9.872221706725139E-04), -SCALE( 9.698917421439440E-04), -SCALE( 9.520854714135470E-04), -SCALE( 9.338323832499584E-04), -SCALE( 9.151611951498600E-04), -SCALE( 8.961003654734095E-04), -SCALE( 8.766780920104490E-04), -SCALE( 8.569222323017155E-04), -SCALE( 8.368602986989685E-04), -SCALE( 8.165194293666030E-04), -SCALE( 7.959263867639895E-04), -SCALE( 7.751075532553095E-04), -SCALE( 7.540889275341360E-04), -SCALE( 7.328960503543460E-04), -SCALE( 7.115540021619675E-04), -SCALE( 6.900874252648055E-04), -SCALE( 6.685205214586190E-04), -SCALE( 6.468769776333065E-04), -SCALE( 6.251799639488680E-04), -SCALE( 6.034521681004050E-04), -SCALE( 5.817157931755955E-04), -SCALE( 5.599924762541345E-04), -SCALE( 5.383032870049990E-04), -SCALE( 5.166687782268060E-04), -SCALE( 4.951089849262823E-04), -SCALE( 4.736433535042661E-04), -SCALE( 4.522907395812775E-04), -SCALE( 4.310694309740984E-04), -SCALE( 4.099971482282953E-04), -SCALE( 3.890910333571532E-04), -SCALE( 3.683676476039790E-04), -SCALE( 3.478429334738513E-04), -SCALE( 3.275322154221950E-04), -SCALE( 3.074502529716603E-04), -SCALE( 2.876112401970844E-04), -SCALE( 2.680287412777888E-04), -SCALE( 2.487156900488424E-04), -SCALE( 2.296844445765594E-04), -SCALE( 2.109467883317648E-04), -SCALE( 1.925139014261300E-04), -SCALE( 1.743963597795672E-04), -SCALE( 1.566041455665768E-04), -SCALE( 1.391466488046540E-04), -SCALE( 1.220326918528753E-04), -SCALE( 1.052705294604104E-04), -SCALE( 8.886782533520320E-05), -SCALE( 7.283165337456365E-05), -SCALE( 5.716854816951505E-05), -SCALE( 4.188450631602256E-05), -SCALE( 2.698496475767416E-05), -SCALE( 1.247480140056488E-05), -SCALE(-1.641629701930447E-06), -SCALE(-1.536049652046955E-05), -SCALE(-2.867848400338988E-05), -SCALE(-4.159279275517104E-05), -SCALE(-5.410111500896320E-05), -SCALE(-6.620163295915880E-05), -SCALE(-7.789300610544491E-05), -SCALE(-8.917436962303755E-05), -SCALE(-1.000453111637885E-04), -SCALE(-1.105058690666598E-04), -SCALE(-1.205565161870574E-04), -SCALE(-1.301981580423545E-04), -SCALE(-1.394321081840759E-04), -SCALE(-1.482600859779846E-04), -SCALE(-1.566841923938267E-04), -SCALE(-1.647069084035198E-04), -SCALE(-1.723310839515549E-04), -SCALE(-1.795599357837175E-04), -SCALE(-1.863970107085474E-04), -SCALE(-1.928461833795790E-04), -SCALE(-1.989116442431618E-04), -SCALE(-2.045978973917164E-04), -SCALE(-2.099097253875555E-04), -SCALE(-2.148521873332429E-04), -SCALE(-2.194306115956788E-04), -SCALE(-2.236505938503120E-04), -SCALE(-2.275179613297294E-04), -SCALE(-2.310387700701966E-04), -SCALE(-2.342192800869662E-04), -SCALE(-2.370659535642138E-04), -SCALE(-2.395854398583434E-04), -SCALE(-2.417845745791980E-04), SCALE( 2.436703743734102E-04), SCALE( 2.452500321752444E-04), SCALE( 2.465308179417657E-04), SCALE( 2.475200821995122E-04), SCALE( 2.482254333360894E-04), SCALE( 2.486547177024881E-04), SCALE( 2.488154045724704E-04), SCALE( 2.487146183038166E-04), SCALE( 2.483604609263728E-04), SCALE( 2.477619902517768E-04), SCALE( 2.469274156993822E-04), SCALE( 2.458640761601700E-04), SCALE( 2.445797571768798E-04), SCALE( 2.430827245294182E-04), SCALE( 2.413811459337238E-04), SCALE( 2.394830702362197E-04), SCALE( 2.373965479929124E-04), SCALE( 2.351296356350780E-04), SCALE( 2.326903665352515E-04), SCALE( 2.300867481008122E-04), SCALE( 2.273267267668629E-04), SCALE( 2.244181863585484E-04), SCALE( 2.213689470691719E-04), SCALE( 2.181867649165566E-04), SCALE( 2.148793208048870E-04), SCALE( 2.114542191049128E-04), SCALE( 2.079189673565927E-04), SCALE( 2.042809749895736E-04), SCALE( 2.005475454710861E-04), SCALE( 1.967258755680427E-04), SCALE( 1.928230469653129E-04), SCALE( 1.888460252663805E-04), -SCALE( 1.848016463895374E-04), -SCALE( 1.806966158461229E-04), -SCALE( 1.765375064656002E-04), -SCALE( 1.723307577358468E-04), -SCALE( 1.680826635644682E-04), -SCALE( 1.637993715464274E-04), -SCALE( 1.594868790905897E-04), -SCALE( 1.551510331409437E-04), -SCALE( 1.507975279169229E-04), -SCALE( 1.464319042632354E-04), -SCALE( 1.420595376057812E-04), -SCALE( 1.376856378740834E-04), -SCALE( 1.333152598388584E-04), -SCALE( 1.289533027076185E-04), -SCALE( 1.246044908903475E-04), -SCALE( 1.202733737618488E-04), -SCALE( 1.159643396677203E-04), -SCALE( 1.116816161426427E-04), -SCALE( 1.074292607067401E-04), -SCALE( 1.032111605730492E-04), -SCALE( 9.903103541547551E-05), -SCALE( 9.489243763625400E-05), -SCALE( 9.079875548213924E-05), -SCALE( 8.675321306240340E-05), -SCALE( 8.275886762862380E-05), -SCALE( 7.881860980632000E-05), -SCALE( 7.493517141117804E-05), -SCALE( 7.111112575372286E-05), -SCALE( 6.734888652588270E-05), -SCALE( 6.365070805378855E-05), -SCALE( 6.001869197279105E-05), -SCALE( 5.645478762018535E-05), -SCALE( 5.296079400014060E-05), -SCALE( 4.953836017695434E-05), -SCALE( 4.618899196172456E-05), -SCALE( 4.291405238785664E-05), -SCALE( 3.971476548553926E-05), -SCALE( 3.659221671654097E-05), -SCALE( 3.354735876525904E-05), -SCALE( 3.058101208191696E-05), -SCALE( 2.769387104186206E-05), -SCALE( 2.488650449141616E-05), -SCALE( 2.215936159729271E-05), -SCALE( 1.951277238921524E-05), -SCALE( 1.694695384810771E-05), -SCALE( 1.446201050055097E-05), -SCALE( 1.205794140863581E-05), -SCALE( 9.734640752487110E-06), -SCALE( 7.491903655942790E-06), -SCALE( 5.329426896805280E-06), -SCALE( 3.246818706694593E-06), -SCALE( 1.243599082783966E-06), -SCALE(-6.808031538695990E-07), -SCALE(-2.527049419980207E-06), -SCALE(-4.295867784770884E-06), -SCALE(-5.988052382589700E-06), -SCALE(-7.604474075726550E-06), -SCALE(-9.146080150692231E-06), -SCALE(-1.061387697354165E-05), -SCALE(-1.200892908323512E-05), -SCALE(-1.333235659026308E-05), -SCALE(-1.458533474050792E-05), -SCALE(-1.576908692157790E-05), -SCALE(-1.688488402231131E-05), -SCALE(-1.793403733553470E-05), -SCALE(-1.891789805352808E-05), -SCALE(-1.983785326550204E-05), -SCALE(-2.069532541857637E-05), -SCALE(-2.149176446183214E-05), -SCALE(-2.222864728099456E-05), -SCALE(-2.290747311740374E-05), -SCALE(-2.352976312853915E-05), -SCALE(-2.409705530058412E-05), -SCALE(-2.461090395766135E-05), -SCALE(-2.507287405244726E-05), -SCALE(-2.548454069800296E-05), -SCALE(-2.584748457743932E-05), -SCALE(-2.616329155063932E-05), -SCALE(-2.643354859248296E-05), -SCALE(-2.665984338990853E-05), -SCALE(-2.684375953903512E-05), -SCALE(-2.698687619105470E-05), -SCALE(-2.709076506473594E-05), -SCALE(-2.715699010579455E-05), -SCALE(-2.718710298053676E-05), -SCALE(-2.718264274615772E-05), -SCALE(-2.714513310366389E-05), -SCALE(-2.707608215301207E-05), -SCALE(-2.697697975324517E-05), -SCALE(-2.684929723999712E-05), -SCALE(-2.669448385046480E-05), -SCALE(-2.651396653512446E-05), -SCALE(-2.630914939052064E-05), -SCALE(-2.608141341583320E-05), -SCALE(-2.583211172456204E-05), -SCALE(-2.556256939919902E-05), SCALE( 2.527408508232496E-05), SCALE( 2.496793086354262E-05), SCALE( 2.464534820090372E-05), SCALE( 2.430754772248991E-05), SCALE( 2.395570893976328E-05), SCALE( 2.359098021649775E-05), SCALE( 2.321447837191817E-05), SCALE( 2.282728860550347E-05), SCALE( 2.243046323951717E-05), SCALE( 2.202502165289463E-05), SCALE( 2.161195008423191E-05), SCALE( 2.119220163057428E-05), SCALE( 2.076669641777394E-05), SCALE( 2.033632155746451E-05), SCALE( 1.990193003014108E-05), SCALE( 1.946434074488017E-05), SCALE( 1.902434097009924E-05), SCALE( 1.858268630848355E-05), SCALE( 1.814009771461820E-05), SCALE( 1.769726156360750E-05), SCALE( 1.725483414306857E-05), SCALE( 1.681344171653956E-05), SCALE( 1.637367742646690E-05), SCALE( 1.593610134164050E-05), SCALE( 1.550124459778260E-05), SCALE( 1.506960952767971E-05), SCALE( 1.464166838349645E-05), SCALE( 1.421786336584378E-05), SCALE( 1.379860854096596E-05), SCALE( 1.338428997824206E-05), SCALE( 1.297526685803031E-05), SCALE( 1.257187157446922E-05), -SCALE( 1.217441088925653E-05), -SCALE( 1.178316603669356E-05), -SCALE( 1.139839388088106E-05), -SCALE( 1.102032704633465E-05), -SCALE( 1.064917563432859E-05), -SCALE( 1.028512733460845E-05), -SCALE( 9.928348166726454E-06), -SCALE( 9.578982598825311E-06), -SCALE( 9.237155419546841E-06), -SCALE( 8.902971890012200E-06), -SCALE( 8.576519215476810E-06), -SCALE( 8.257866642922776E-06), -SCALE( 7.947066136436549E-06), -SCALE( 7.644152509859200E-06), -SCALE( 7.349145669714490E-06), -SCALE( 7.062050754515410E-06), -SCALE( 6.782858956580495E-06), -SCALE( 6.511547627860400E-06), -SCALE( 6.248081786307280E-06), -SCALE( 5.992414242480480E-06), -SCALE( 5.744486878502875E-06), -SCALE( 5.504230753545810E-06), -SCALE( 5.271567145540585E-06), -SCALE( 5.046407670500340E-06), -SCALE( 4.828655865889468E-06), -SCALE( 4.618207304054390E-06), -SCALE( 4.414950504331232E-06), -SCALE( 4.218767020985225E-06), -SCALE( 4.029532465769980E-06), -SCALE( 3.847116621801583E-06), -SCALE( 3.671384926229468E-06), -SCALE( 3.502198552003754E-06), -SCALE( 3.339414724085582E-06), -SCALE( 3.182886786597464E-06), -SCALE( 3.032465363920388E-06), -SCALE( 2.887998457950138E-06), -SCALE( 2.749332426639114E-06), -SCALE( 2.616312057164482E-06), -SCALE( 2.488781197085654E-06), -SCALE( 2.366582812095056E-06), -SCALE( 2.249559625377646E-06), -SCALE( 2.137554168666232E-06), -SCALE( 2.030409266099076E-06), -SCALE( 1.927968090232205E-06), -SCALE( 1.830074910452612E-06), -SCALE( 1.736575155397134E-06), -SCALE( 1.647316037754536E-06), -SCALE( 1.562146591398006E-06), -SCALE( 1.480917863497994E-06), -SCALE( 1.403482943378026E-06), -SCALE( 1.329697405230052E-06), -SCALE( 1.259419343863326E-06), -SCALE( 1.192509718464610E-06), -SCALE( 1.128832363715543E-06), -SCALE( 1.068253890614633E-06), -SCALE( 1.010643712821376E-06), -SCALE( 9.558747254049829E-07), -SCALE( 9.038233322489550E-07), -SCALE( 8.543693702029365E-07), -SCALE( 8.073961036828060E-07), -SCALE( 7.627901817207720E-07), -SCALE( 7.204416525901345E-07), -SCALE( 6.802443284999140E-07), -SCALE( 6.420958008785305E-07), -SCALE( 6.058974119201980E-07), -SCALE( 5.715542338879300E-07), -SCALE( 5.389746422333555E-07), -SCALE( 5.080703129463105E-07), -SCALE( 4.787565911260676E-07), -SCALE( 4.509524956369838E-07), -SCALE( 4.245804529615933E-07), -SCALE( 3.995662812166919E-07), -SCALE( 3.758391046541218E-07), -SCALE( 3.533313458884360E-07), -SCALE( 3.319786404047318E-07), -SCALE( 3.117198196826890E-07), -SCALE( 2.924966254175760E-07), -SCALE( 2.742537030854958E-07), -SCALE( 2.569387461577766E-07), -SCALE( 2.405024587792340E-07), -SCALE( 2.248975904755362E-07), -SCALE( 2.100789970600680E-07), -SCALE( 1.960059458775785E-07), -SCALE( 1.826418431101815E-07), -SCALE( 1.699459292657122E-07), -SCALE( 1.578742499812371E-07), -SCALE( 1.464093182119164E-07), -SCALE( 1.355563613797138E-07), -SCALE( 1.252310964561535E-07), -SCALE( 1.152736341186576E-07), -SCALE( 1.058665951072195E-07), -SCALE( 9.748319049487465E-08), -SCALE( 8.932687128137479E-08), -SCALE( 7.952503432137510E-08), -SCALE( 7.095090315087499E-08), -SCALE( 7.127938986604168E-08) }; #undef SCALE ================================================ FILE: libdcadec/fixed_math.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 FIXED_MATH_H #define FIXED_MATH_H static inline int64_t round__(int64_t a, int bits) { if (bits > 0) return (a + (INT64_C(1) << (bits - 1))) & ~((INT64_C(1) << bits) - 1); else return a; } static inline int32_t norm__(int64_t a, int bits) { if (bits > 0) return (int32_t)((a + (INT64_C(1) << (bits - 1))) >> bits); else return (int32_t)a; } static inline int32_t mul__(int32_t a, int32_t b, int bits) { return norm__((int64_t)a * b, bits); } static inline int32_t clip__(int32_t a, int bits) { #ifdef __ARM_FEATURE_SAT int x; __asm__("ssat %0, %2, %1" : "=r"(x) : "r"(a), "i"(bits + 1)); return x; #else if ((a + (1 << bits)) & ~((1 << (bits + 1)) - 1)) return (a >> 31) ^ ((1 << bits) - 1); else return a; #endif } static inline int64_t round20(int64_t a) { return round__(a, 20); } static inline int64_t round21(int64_t a) { return round__(a, 21); } static inline int32_t norm13(int64_t a) { return norm__(a, 13); } static inline int32_t norm16(int64_t a) { return norm__(a, 16); } static inline int32_t norm20(int64_t a) { return norm__(a, 20); } static inline int32_t norm21(int64_t a) { return norm__(a, 21); } static inline int32_t norm23(int64_t a) { return norm__(a, 23); } static inline int32_t mul3(int32_t a, int32_t b) { return (a * b + (1 << 2)) >> 3; } static inline int32_t mul4(int32_t a, int32_t b) { return (a * b + (1 << 3)) >> 4; } static inline int32_t mul15(int32_t a, int32_t b) { return mul__(a, b, 15); } static inline int32_t mul16(int32_t a, int32_t b) { return mul__(a, b, 16); } static inline int32_t mul17(int32_t a, int32_t b) { return mul__(a, b, 17); } static inline int32_t mul22(int32_t a, int32_t b) { return mul__(a, b, 22); } static inline int32_t mul23(int32_t a, int32_t b) { return mul__(a, b, 23); } static inline int32_t mul31(int32_t a, int32_t b) { return mul__(a, b, 31); } static inline int32_t clip23(int32_t a) { return clip__(a, 23); } #endif ================================================ FILE: libdcadec/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 */ #ifndef HUFFMAN_H #define HUFFMAN_H struct huffman { const uint8_t *len; const uint16_t *code; int size; }; #endif ================================================ FILE: libdcadec/idct.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 IDCT_H #define IDCT_H #define IDCT_BITS 7 #define IDCT_SIZE (1 << IDCT_BITS) struct idct_context { double cs[IDCT_SIZE / 2]; double ac[IDCT_SIZE / 2]; double as[IDCT_SIZE / 2]; uint8_t permute[IDCT_SIZE / 2]; int nbits; }; struct idct_context *idct_init(void *parent, int nbits, double scale) __attribute__((cold)); void idct_fast(const struct idct_context *s, const double *input, double *output); void imdct_fast(const struct idct_context *s, const float *input, float *output); void idct_fixed32(int * restrict input, int * restrict output); void idct_fixed64(int * restrict input, int * restrict output); #endif ================================================ FILE: libdcadec/idct_fixed.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 "fixed_math.h" #include "idct.h" static void sum_a(const int * restrict input, int * restrict output, int len) { for (int i = 0; i < len; i++) output[i] = input[2 * i] + input[2 * i + 1]; } static void sum_b(const int * restrict input, int * restrict output, int len) { output[0] = input[0]; for (int i = 1; i < len; i++) output[i] = input[2 * i] + input[2 * i - 1]; } static void sum_c(const int * restrict input, int * restrict output, int len) { for (int i = 0; i < len; i++) output[i] = input[2 * i]; } static void sum_d(const int * restrict input, int * restrict output, int len) { output[0] = input[1]; for (int i = 1; i < len; i++) output[i] = input[2 * i - 1] + input[2 * i + 1]; } static void dct_a(const int * restrict input, int * restrict output) { // floor(sin((2 * i + 1) * (2 * (7 - j) + 1) * PI / 32) * (1 << 23) + 0.5), i = 2 * k // -floor(sin((2 * i + 1) * (2 * (7 - j) + 1) * PI / 32) * (1 << 23) + 0.5), i = 2 * k + 1 static const int cos_mod[8][8] = { { 8348215, 8027397, 7398092, 6484482, 5321677, 3954362, 2435084, 822227 }, { 8027397, 5321677, 822227, -3954362, -7398092, -8348215, -6484482, -2435084 }, { 7398092, 822227, -6484482, -8027397, -2435084, 5321677, 8348215, 3954362 }, { 6484482, -3954362, -8027397, 822227, 8348215, 2435084, -7398092, -5321677 }, { 5321677, -7398092, -2435084, 8348215, -822227, -8027397, 3954362, 6484482 }, { 3954362, -8348215, 5321677, 2435084, -8027397, 6484482, 822227, -7398092 }, { 2435084, -6484482, 8348215, -7398092, 3954362, 822227, -5321677, 8027397 }, { 822227, -2435084, 3954362, -5321677, 6484482, -7398092, 8027397, -8348215 } }; for (int i = 0; i < 8; i++) { int64_t res = INT64_C(0); for (int j = 0; j < 8; j++) res += (int64_t)cos_mod[i][j] * input[j]; output[i] = norm23(res); } } static void dct_b(const int * restrict input, int * restrict output) { // floor(cos((2 * i + 1) * (j + 1) * PI / 16) * (1 << 23) + 0.5) static const int cos_mod[8][7] = { { 8227423, 7750063, 6974873, 5931642, 4660461, 3210181, 1636536 }, { 6974873, 3210181, -1636536, -5931642, -8227423, -7750063, -4660461 }, { 4660461, -3210181, -8227423, -5931642, 1636536, 7750063, 6974873 }, { 1636536, -7750063, -4660461, 5931642, 6974873, -3210181, -8227423 }, { -1636536, -7750063, 4660461, 5931642, -6974873, -3210181, 8227423 }, { -4660461, -3210181, 8227423, -5931642, -1636536, 7750063, -6974873 }, { -6974873, 3210181, 1636536, -5931642, 8227423, -7750063, 4660461 }, { -8227423, 7750063, -6974873, 5931642, -4660461, 3210181, -1636536 } }; for (int i = 0; i < 8; i++) { int64_t res = (int64_t)input[0] * (1 << 23); for (int j = 0; j < 7; j++) res += (int64_t)cos_mod[i][j] * input[1 + j]; output[i] = norm23(res); } } static void mod_a(const int * restrict input, int * restrict output) { // floor(0.5 / cos((2 * ( i) + 1) * PI / 64) * (1 << 23) + 0.5), i = 0 .. 8 // -floor(0.5 / sin((2 * (15 - i) + 1) * PI / 64) * (1 << 23) + 0.5), i = 8 .. 16 static const int cos_mod[16] = { 4199362, 4240198, 4323885, 4454708, 4639772, 4890013, 5221943, 5660703, -6245623, -7040975, -8158494, -9809974, -12450076, -17261920, -28585092, -85479984 }; for (int i = 0; i < 8; i++) output[i] = mul23(cos_mod[i], input[i] + input[8 + i]); for (int i = 8, k = 7; i < 16; i++, k--) output[i] = mul23(cos_mod[i], input[k] - input[8 + k]); } static void mod_b(int * restrict input, int * restrict output) { // floor(0.5 / cos((2 * ( i) + 1) * PI / 32) * (1 << 23) + 0.5), i = 0 .. 4 // floor(0.5 / sin((2 * (7 - i) + 1) * PI / 32) * (1 << 23) + 0.5), i = 4 .. 8 static const int cos_mod[8] = { 4214598, 4383036, 4755871, 5425934, 6611520, 8897610, 14448934, 42791536 }; for (int i = 0; i < 8; i++) input[8 + i] = mul23(cos_mod[i], input[8 + i]); for (int i = 0; i < 8; i++) output[i] = input[i] + input[8 + i]; for (int i = 8, k = 7; i < 16; i++, k--) output[i] = input[k] - input[8 + k]; } static void mod_c(const int * restrict input, int * restrict output) { // floor(0.125 / cos((2 * ( i) + 1) * PI / 128) * (1 << 23) + 0.5), i = 0 .. 16 // -floor(0.125 / sin((2 * (31 - i) + 1) * PI / 128) * (1 << 23) + 0.5), i = 16 .. 32 static const int cos_mod[32] = { 1048892, 1051425, 1056522, 1064244, 1074689, 1087987, 1104313, 1123884, 1146975, 1173922, 1205139, 1241133, 1282529, 1330095, 1384791, 1447815, -1520688, -1605358, -1704360, -1821051, -1959964, -2127368, -2332183, -2587535, -2913561, -3342802, -3931480, -4785806, -6133390, -8566050, -14253820, -42727120 }; for (int i = 0; i < 16; i++) output[i] = mul23(cos_mod[i], input[i] + input[16 + i]); for (int i = 16, k = 15; i < 32; i++, k--) output[i] = mul23(cos_mod[i], input[k] - input[16 + k]); } static void clp_v(int *input, int len) { for (int i = 0; i < len; i++) input[i] = clip23(input[i]); } void idct_fixed32(int * restrict input, int * restrict output) { int mag = 0; for (int i = 0; i < 32; i++) mag += abs(input[i]); int shift = mag > 0x400000 ? 2 : 0; int round = shift > 0 ? 1 << (shift - 1) : 0; for (int i = 0; i < 32; i++) input[i] = (input[i] + round) >> shift; sum_a(input, output + 0, 16); sum_b(input, output + 16, 16); clp_v(output, 32); sum_a(output + 0, input + 0, 8); sum_b(output + 0, input + 8, 8); sum_c(output + 16, input + 16, 8); sum_d(output + 16, input + 24, 8); clp_v(input, 32); dct_a(input + 0, output + 0); dct_b(input + 8, output + 8); dct_b(input + 16, output + 16); dct_b(input + 24, output + 24); clp_v(output, 32); mod_a(output + 0, input + 0); mod_b(output + 16, input + 16); clp_v(input, 32); mod_c(input, output); for (int i = 0; i < 32; i++) output[i] = clip23(output[i] * (1 << shift)); } static void mod64_a(const int * restrict input, int * restrict output) { // floor(0.5 / cos((2 * ( i) + 1) * PI / 128) * (1 << 23) + 0.5), i = 0 .. 16 // -floor(0.5 / sin((2 * (31 - i) + 1) * PI / 128) * (1 << 23) + 0.5), i = 16 .. 32 static const int cos_mod[32] = { 4195568, 4205700, 4226086, 4256977, 4298755, 4351949, 4417251, 4495537, 4587901, 4695690, 4820557, 4964534, 5130115, 5320382, 5539164, 5791261, -6082752, -6421430, -6817439, -7284203, -7839855, -8509474, -9328732, -10350140, -11654242, -13371208, -15725922, -19143224, -24533560, -34264200, -57015280, -170908480 }; for (int i = 0; i < 16; i++) output[i] = mul23(cos_mod[i], input[i] + input[16 + i]); for (int i = 16, k = 15; i < 32; i++, k--) output[i] = mul23(cos_mod[i], input[k] - input[16 + k]); } static void mod64_b(int * restrict input, int * restrict output) { // floor(0.5 / cos((2 * ( i) + 1) * PI / 64) * (1 << 23) + 0.5), i = 0 .. 8 // floor(0.5 / sin((2 * (15 - i) + 1) * PI / 64) * (1 << 23) + 0.5), i = 8 .. 16 static const int cos_mod[16] = { 4199362, 4240198, 4323885, 4454708, 4639772, 4890013, 5221943, 5660703, 6245623, 7040975, 8158494, 9809974, 12450076, 17261920, 28585092, 85479984 }; for (int i = 0; i < 16; i++) input[16 + i] = mul23(cos_mod[i], input[16 + i]); for (int i = 0; i < 16; i++) output[i] = input[i] + input[16 + i]; for (int i = 16, k = 15; i < 32; i++, k--) output[i] = input[k] - input[16 + k]; } static void mod64_c(const int * restrict input, int * restrict output) { // floor(0.125 / SQRT2 / cos((2 * ( i) + 1) * PI / 256) * (1 << 23) + 0.5), i = 0 .. 32 // -floor(0.125 / SQRT2 / sin((2 * (63 - i) + 1) * PI / 256) * (1 << 23) + 0.5), i = 32 .. 64 static const int cos_mod[64] = { 741511, 741958, 742853, 744199, 746001, 748262, 750992, 754197, 757888, 762077, 766777, 772003, 777772, 784105, 791021, 798546, 806707, 815532, 825054, 835311, 846342, 858193, 870912, 884554, 899181, 914860, 931667, 949686, 969011, 989747, 1012012, 1035941, -1061684, -1089412, -1119320, -1151629, -1186595, -1224511, -1265719, -1310613, -1359657, -1413400, -1472490, -1537703, -1609974, -1690442, -1780506, -1881904, -1996824, -2128058, -2279225, -2455101, -2662128, -2909200, -3208956, -3579983, -4050785, -4667404, -5509372, -6726913, -8641940, -12091426, -20144284, -60420720 }; for (int i = 0; i < 32; i++) output[i] = mul23(cos_mod[i], input[i] + input[32 + i]); for (int i = 32, k = 31; i < 64; i++, k--) output[i] = mul23(cos_mod[i], input[k] - input[32 + k]); } void idct_fixed64(int * restrict input, int * restrict output) { int mag = 0; for (int i = 0; i < 64; i++) mag += abs(input[i]); int shift = mag > 0x400000 ? 2 : 0; int round = shift > 0 ? 1 << (shift - 1) : 0; for (int i = 0; i < 64; i++) input[i] = (input[i] + round) >> shift; sum_a(input, output + 0, 32); sum_b(input, output + 32, 32); clp_v(output, 64); sum_a(output + 0, input + 0, 16); sum_b(output + 0, input + 16, 16); sum_c(output + 32, input + 32, 16); sum_d(output + 32, input + 48, 16); clp_v(input, 64); sum_a(input + 0, output + 0, 8); sum_b(input + 0, output + 8, 8); sum_c(input + 16, output + 16, 8); sum_d(input + 16, output + 24, 8); sum_c(input + 32, output + 32, 8); sum_d(input + 32, output + 40, 8); sum_c(input + 48, output + 48, 8); sum_d(input + 48, output + 56, 8); clp_v(output, 64); dct_a(output + 0, input + 0); dct_b(output + 8, input + 8); dct_b(output + 16, input + 16); dct_b(output + 24, input + 24); dct_b(output + 32, input + 32); dct_b(output + 40, input + 40); dct_b(output + 48, input + 48); dct_b(output + 56, input + 56); clp_v(input, 64); mod_a(input + 0, output + 0); mod_b(input + 16, output + 16); mod_b(input + 32, output + 32); mod_b(input + 48, output + 48); clp_v(output, 64); mod64_a(output + 0, input + 0); mod64_b(output + 32, input + 32); clp_v(input, 64); mod64_c(input, output); for (int i = 0; i < 64; i++) output[i] = clip23(output[i] * (1 << shift)); } ================================================ FILE: libdcadec/idct_float.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 "idct.h" struct idct_context *idct_init(void *parent, int nbits, double scale) { int i, j, k, p, base; if (nbits < 2 || nbits > IDCT_BITS) return NULL; struct idct_context *s = ta_new(parent, struct idct_context); if (!s) return NULL; int m = nbits; int n = 1 << m; int n2 = n >> 1; int n4 = n >> 2; for (i = base = 0; i < m - 1; i++, base += p) { p = 1 << i; for (j = 0; j < p; j++) s->cs[base + j] = cos(M_PI * (4 * j + 1) * (n4 >> i) / n); } for (i = 0; i < n2; i++) { double a = M_PI * (1.0 / (n << 2) + 1.0 * i / (n << 1)); s->ac[i] = scale * cos(a); s->as[i] = scale * sin(a); } for (i = 1; i < n2 - 1; i++) { for (j = k = 0; j < m - 1; j++) k = (k << 1) | ((i >> j) & 1); s->permute[i] = k; } s->nbits = nbits; return s; } static void proc(const struct idct_context *s, double *x, int flag) { double y[IDCT_SIZE / 2], tmp; int i, j, k, p, q, base; int m = s->nbits - 1; int n = 1 << m; int n2 = n >> 1; for (i = 0; i < n; i++) y[i] = x[i]; for (i = m - 2; i >= 0; i--) { int f0 = n >> i; int f1 = f0 >> 1; int f2 = f1 >> 1; int f3 = ((1 << i) - 1) << 1; for (j = f2; j > 0; j--) { for (k = f3; k >= 0; k--) { p = f0 - j + k * f1; q = f1 - j + k * f1; y[q] -= y[p]; y[p] += y[p]; } } } for (i = 1; i < n - 1; i++) { k = s->permute[i]; if (i < k) { tmp = y[i]; y[i] = y[k]; y[k] = tmp; } } for (i = base = 0; i < m; i++, base += p) { p = 1 << i; q = 2 << i; for (j = 0; j < p; j++) { for (k = j; k < n; k += q) { tmp = y[k + p] * s->cs[base + j]; y[k + p] = y[k] - tmp; y[k] += tmp; } } } for (i = 0; i < n2; i++) { x[2 * i] = y[i]; if (flag) x[2 * i + 1] = -y[n - 1 - i]; else x[2 * i + 1] = y[n - 1 - i]; } } void idct_fast(const struct idct_context *s, const double *input, double *output) { double a[IDCT_SIZE / 2]; double b[IDCT_SIZE / 2]; int i; int m = s->nbits; int n = 1 << m; int n2 = n >> 1; a[0] = input[0]; b[0] = input[n - 1]; for (i = 1; i < n2; i++) { a[ i] = input[2 * i - 1] + input[2 * i]; b[n2 - i] = input[2 * i - 1] - input[2 * i]; } proc(s, a, 0); proc(s, b, 1); for (i = 0; i < n2; i++) { output[ i ] = a[i] * s->ac[i] + b[i] * s->as[i]; output[n - i - 1] = a[i] * s->as[i] - b[i] * s->ac[i]; } } void imdct_fast(const struct idct_context *s, const float *input, float *output) { double a[IDCT_SIZE / 2]; double b[IDCT_SIZE / 2]; int i; int m = s->nbits + 1; int n = 1 << m; int n2 = n >> 1; int n4 = n >> 2; a[0] = input[0]; b[0] = input[n2 - 1]; for (i = 1; i < n4; i++) { a[ i] = input[2 * i - 1] + input[2 * i]; b[n4 - i] = input[2 * i - 1] - input[2 * i]; } proc(s, a, 0); proc(s, b, 1); for (i = 0; i < n4; i++) { output[ n4 + i ] = -a[i] * s->as[i] + b[i] * s->ac[i]; output[n - n4 - i - 1] = -a[i] * s->ac[i] - b[i] * s->as[i]; } for (i = 0; i < n4; i++) { output[ i ] = -output[n2 - i - 1]; output[n - i - 1] = output[n2 + i ]; } } ================================================ FILE: libdcadec/interpolator.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 "interpolator.h" struct interpolator *interpolator_create(struct idct_context *parent, int flags) { struct interpolator *dsp = ta_new(parent, struct interpolator); if (!dsp) return NULL; dsp->idct = parent; dsp->history = ta_znew_array_size(dsp, (flags & DCADEC_FLAG_CORE_BIT_EXACT) ? sizeof(int) : sizeof(double), (flags & DCADEC_FLAG_CORE_SYNTH_X96) ? 1024 : 512); if (!dsp->history) { ta_free(dsp); return NULL; } if (flags & DCADEC_FLAG_CORE_BIT_EXACT) { if (flags & DCADEC_FLAG_CORE_SYNTH_X96) dsp->interpolate = interpolate_sub64_fixed; else dsp->interpolate = interpolate_sub32_fixed; } else { if (flags & DCADEC_FLAG_CORE_SYNTH_X96) dsp->interpolate = interpolate_sub64_float; else dsp->interpolate = interpolate_sub32_float; } return dsp; } void interpolator_clear(struct interpolator *dsp) { if (dsp) memset(dsp->history, 0, ta_get_size(dsp->history)); } ================================================ FILE: libdcadec/interpolator.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 INTERPOLATOR_H #define INTERPOLATOR_H #define MAX_LFE_HISTORY 12 struct interpolator; struct idct_context; typedef void (*interpolate_lfe_cb)(int *pcm_samples, int *lfe_samples, int npcmblocks, bool dec_select); typedef void (*interpolate_sub_cb)(struct interpolator *dsp, int *pcm_samples, int **subband_samples_lo, int **subband_samples_hi, int nsamples, bool perfect); struct interpolator { struct idct_context *idct; void *history; interpolate_sub_cb interpolate; }; struct interpolator *interpolator_create(struct idct_context *parent, int flags) __attribute__((cold)); void interpolator_clear(struct interpolator *dsp) __attribute__((cold)); #define INTERPOLATE_LFE(x) \ void interpolate_##x(int *pcm_samples, int *lfe_samples, \ int npcmblocks, bool dec_select) #define INTERPOLATE_SUB(x) \ void interpolate_##x(struct interpolator *dsp, int *pcm_samples, \ int **subband_samples_lo, \ int **subband_samples_hi, \ int nsamples, bool perfect) INTERPOLATE_LFE(lfe_float_fir); INTERPOLATE_LFE(lfe_float_fir_2x); INTERPOLATE_LFE(lfe_float_iir); INTERPOLATE_SUB(sub32_float); INTERPOLATE_SUB(sub64_float); INTERPOLATE_LFE(lfe_fixed_fir); INTERPOLATE_SUB(sub32_fixed); INTERPOLATE_SUB(sub64_fixed); #endif ================================================ FILE: libdcadec/interpolator_fixed.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 "interpolator.h" #include "idct.h" #include "fixed_math.h" #include "fir_fixed.h" INTERPOLATE_LFE(lfe_fixed_fir) { (void)dec_select; assert(!dec_select); // Select decimation factor int nlfesamples = npcmblocks >> 1; // Interpolation for (int i = 0; i < nlfesamples; i++) { int *src = lfe_samples + MAX_LFE_HISTORY + i; // One decimated sample generates 64 interpolated ones for (int j = 0; j < 32; j++) { // Clear accumulation int64_t res1 = INT64_C(0); int64_t res2 = INT64_C(0); // Accumulate for (int k = 0; k < 8; k++) { res1 += (int64_t)lfe_fir_64[ j * 8 + k] * src[-k]; res2 += (int64_t)lfe_fir_64[255 - j * 8 - k] * src[-k]; } // Save interpolated samples pcm_samples[ j] = clip23(norm23(res1)); pcm_samples[32 + j] = clip23(norm23(res2)); } // Advance output pointer pcm_samples += 64; } // Update history for (int n = MAX_LFE_HISTORY - 1; n >= MAX_LFE_HISTORY - 8; n--) lfe_samples[n] = lfe_samples[nlfesamples + n]; } INTERPOLATE_SUB(sub32_fixed) { (void)subband_samples_hi; assert(!subband_samples_hi); // Get history pointer int *history = dsp->history; // Select filter const int32_t *filter_coeff = perfect ? band_fir_perfect : band_fir_nonperfect; // Interpolation begins for (int sample = 0; sample < nsamples; sample++) { int i, j, k; // Load in one sample from each subband int input[32]; for (i = 0; i < 32; i++) input[i] = subband_samples_lo[i][sample]; // Inverse DCT int output[32]; idct_fixed32(input, output); // Store history for (i = 0, k = 31; i < 16; i++, k--) { history[ i] = clip23(output[i] - output[k]); history[16 + i] = clip23(output[i] + output[k]); } // One subband sample generates 32 interpolated ones for (i = 0, k = 15; i < 16; i++, k--) { // Clear accumulation int64_t res1 = INT64_C(0); int64_t res2 = INT64_C(0); // Accumulate for (j = 32; j < 512; j += 64) { res1 += (int64_t)history[16 + i + j] * filter_coeff[ i + j]; res2 += (int64_t)history[16 + k + j] * filter_coeff[16 + i + j]; } res1 = round21(res1); res2 = round21(res2); for (j = 0; j < 512; j += 64) { res1 += (int64_t)history[i + j] * filter_coeff[ i + j]; res2 += (int64_t)history[k + j] * filter_coeff[16 + i + j]; } // Save interpolated samples pcm_samples[ i] = clip23(norm21(res1)); pcm_samples[16 + i] = clip23(norm21(res2)); } // Advance output pointer pcm_samples += 32; // Shift history for (i = 511; i >= 32; i--) history[i] = history[i - 32]; } } INTERPOLATE_SUB(sub64_fixed) { (void)perfect; // Get history pointer int *history = dsp->history; // Interpolation begins for (int sample = 0; sample < nsamples; sample++) { int i, j, k; // Load in one sample from each subband int input[64]; if (subband_samples_hi) { // Full 64 subbands, first 32 are residual coded for (i = 0; i < 32; i++) input[i] = subband_samples_lo[i][sample] + subband_samples_hi[i][sample]; for (i = 32; i < 64; i++) input[i] = subband_samples_hi[i][sample]; } else { // Only first 32 subbands for (i = 0; i < 32; i++) input[i] = subband_samples_lo[i][sample]; for (i = 32; i < 64; i++) input[i] = 0; } // Inverse DCT int output[64]; idct_fixed64(input, output); // Store history for (i = 0, k = 63; i < 32; i++, k--) { history[ i] = clip23(output[i] - output[k]); history[32 + i] = clip23(output[i] + output[k]); } // One subband sample generates 64 interpolated ones for (i = 0, k = 31; i < 32; i++, k--) { // Clear accumulation int64_t res1 = INT64_C(0); int64_t res2 = INT64_C(0); // Accumulate for (j = 64; j < 1024; j += 128) { res1 += (int64_t)history[32 + i + j] * band_fir_x96[ i + j]; res2 += (int64_t)history[32 + k + j] * band_fir_x96[32 + i + j]; } res1 = round20(res1); res2 = round20(res2); for (j = 0; j < 1024; j += 128) { res1 += (int64_t)history[i + j] * band_fir_x96[ i + j]; res2 += (int64_t)history[k + j] * band_fir_x96[32 + i + j]; } // Save interpolated samples pcm_samples[ i] = clip23(norm20(res1)); pcm_samples[32 + i] = clip23(norm20(res2)); } // Advance output pointer pcm_samples += 64; // Shift history for (i = 1023; i >= 64; i--) history[i] = history[i - 64]; } } ================================================ FILE: libdcadec/interpolator_float.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 "interpolator.h" #include "idct.h" #include "fixed_math.h" #include "fir_float.h" static const double lfe_iir_scale = 0.001985816114019982; static const double lfe_iir[12] = { -0.9698530866436986, 1.9696040724997900, 0.9999999999999996, -1.9643358221499630, -0.9787938538720836, 1.9785545764679620, 1.0000000000000020, -1.9951847249255470, -0.9925096137076496, 1.9922787089263100, 1.0000000000000000, -1.9974180593495760 }; static inline int convert(double a) { return clip23(lrint(a)); } static void interpolate_lfe(int *pcm_samples, int *lfe_samples, int npcmblocks, const double *filter_coeff, bool dec_select) { // Select decimation factor int factor = 64 << dec_select; int ncoeffs = 8 >> dec_select; int nlfesamples = npcmblocks >> (dec_select + 1); // Interpolation for (int i = 0; i < nlfesamples; i++) { int *src = lfe_samples + MAX_LFE_HISTORY + i; // One decimated sample generates 64 or 128 interpolated ones for (int j = 0; j < factor / 2; j++) { // Clear accumulation double res1 = 0.0; double res2 = 0.0; // Accumulate for (int k = 0; k < ncoeffs; k++) { res1 += filter_coeff[ j * ncoeffs + k] * src[-k]; res2 += filter_coeff[255 - j * ncoeffs - k] * src[-k]; } // Save interpolated samples pcm_samples[ j] = convert(res1); pcm_samples[factor / 2 + j] = convert(res2); } // Advance output pointer pcm_samples += factor; } // Update history for (int n = MAX_LFE_HISTORY - 1; n >= MAX_LFE_HISTORY - 8; n--) lfe_samples[n] = lfe_samples[nlfesamples + n]; } INTERPOLATE_LFE(lfe_float_fir) { (void)dec_select; assert(!dec_select); interpolate_lfe(pcm_samples, lfe_samples, npcmblocks, lfe_fir_64, false); } INTERPOLATE_LFE(lfe_float_fir_2x) { (void)dec_select; assert(dec_select); interpolate_lfe(pcm_samples, lfe_samples, npcmblocks, lfe_fir_128, true); } INTERPOLATE_LFE(lfe_float_iir) { // Select decimation factor int factor = 64 << dec_select; int nlfesamples = npcmblocks >> (dec_select + 1); // Load history double lfe_history[6]; for (int i = 0; i < 6; i++) lfe_history[i] = ((double *)lfe_samples)[i]; // Interpolation for (int i = 0; i < nlfesamples; i++) { double res1 = lfe_samples[MAX_LFE_HISTORY + i] * lfe_iir_scale; double res2; // One decimated sample generates 64 or 128 interpolated ones for (int j = 0; j < factor; j++) { // Filter for (int k = 0; k < 3; k++) { double tmp1 = lfe_history[k * 2 + 0]; double tmp2 = lfe_history[k * 2 + 1]; res2 = tmp1 * lfe_iir[k * 4 + 0] + tmp2 * lfe_iir[k * 4 + 1] + res1; res1 = tmp1 * lfe_iir[k * 4 + 2] + tmp2 * lfe_iir[k * 4 + 3] + res2; lfe_history[k * 2 + 0] = tmp2; lfe_history[k * 2 + 1] = res2; } // Save interpolated samples *pcm_samples++ = convert(res1); res1 = 0.0; } } // Store history for (int i = 0; i < 6; i++) ((double *)lfe_samples)[i] = lfe_history[i]; } INTERPOLATE_SUB(sub32_float) { (void)subband_samples_hi; assert(!subband_samples_hi); // Get history pointer double *history = dsp->history; // Select filter const double *filter_coeff = perfect ? band_fir_perfect : band_fir_nonperfect; // Interpolation begins for (int sample = 0; sample < nsamples; sample++) { int i, j, k; // Load in one sample from each subband double input[32]; for (i = 0; i < 32; i++) input[i] = subband_samples_lo[i][sample]; // Inverse DCT double output[32]; idct_fast(dsp->idct, input, output); // Store history for (i = 0, k = 31; i < 16; i++, k--) { history[ i] = output[i] - output[k]; history[16 + i] = output[i] + output[k]; } // One subband sample generates 32 interpolated ones for (i = 0, k = 15; i < 16; i++, k--) { // Clear accumulation double res1 = 0.0; double res2 = 0.0; // Accumulate for (j = 0; j < 512; j += 64) { res1 += history[i + j] * filter_coeff[ i + j]; res2 += history[k + j] * filter_coeff[16 + i + j]; } for (j = 32; j < 512; j += 64) { res1 += history[16 + i + j] * filter_coeff[ i + j]; res2 += history[16 + k + j] * filter_coeff[16 + i + j]; } // Save interpolated samples pcm_samples[ i] = convert(res1); pcm_samples[16 + i] = convert(res2); } // Advance output pointer pcm_samples += 32; // Shift history for (i = 511; i >= 32; i--) history[i] = history[i - 32]; } } INTERPOLATE_SUB(sub64_float) { (void)perfect; // Get history pointer double *history = dsp->history; // Interpolation begins for (int sample = 0; sample < nsamples; sample++) { int i, j, k; // Load in one sample from each subband double input[64]; if (subband_samples_hi) { // Full 64 subbands, first 32 are residual coded for (i = 0; i < 32; i++) input[i] = subband_samples_lo[i][sample] + subband_samples_hi[i][sample]; for (i = 32; i < 64; i++) input[i] = subband_samples_hi[i][sample]; } else { // Only first 32 subbands for (i = 0; i < 32; i++) input[i] = subband_samples_lo[i][sample]; for (i = 32; i < 64; i++) input[i] = 0; } // Inverse DCT double output[64]; idct_fast(dsp->idct, input, output); // Store history for (i = 0, k = 63; i < 32; i++, k--) { history[ i] = output[i] - output[k]; history[32 + i] = output[i] + output[k]; } // One subband sample generates 64 interpolated ones for (i = 0, k = 31; i < 32; i++, k--) { // Clear accumulation double res1 = 0.0; double res2 = 0.0; // Accumulate for (j = 0; j < 1024; j += 128) { res1 += history[i + j] * band_fir_x96[ i + j]; res2 += history[k + j] * band_fir_x96[32 + i + j]; } for (j = 64; j < 1024; j += 128) { res1 += history[32 + i + j] * band_fir_x96[ i + j]; res2 += history[32 + k + j] * band_fir_x96[32 + i + j]; } // Save interpolated samples pcm_samples[ i] = convert(res1); pcm_samples[32 + i] = convert(res2); } // Advance output pointer pcm_samples += 64; // Shift history for (i = 1023; i >= 64; i--) history[i] = history[i - 64]; } } ================================================ FILE: libdcadec/lbr_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 */ struct bytestream { uint8_t *data; int total; int index; }; static void bits2_init(struct bitstream2 *bits, uint8_t *data, size_t size) { bits->data = data; bits->index = 0; bits->accum = 0; bits->avail = 0; bits->count = size << 3; } static int bits2_peek(struct bitstream2 *bits, int n) { assert(n > 0 && n <= 32); while (bits->avail < n) { bits->accum |= bits->data[bits->index++] << bits->avail; bits->avail += 8; } return bits->accum & (0xffffffff >> (32 - n)); } static void bits2_skip(struct bitstream2 *bits, int n) { assert(n > 0 && n <= bits->avail); bits->accum >>= n; bits->avail -= n; bits->count -= n; } static int bits2_get(struct bitstream2 *bits, int n) { int v = bits2_peek(bits, n); bits2_skip(bits, n); return v; } static int bits2_getz(struct bitstream2 *bits, int n) { if (n == 0) return 0; return bits2_get(bits, n); } static bool bits2_get1(struct bitstream2 *bits) { return bits2_get(bits, 1); } #if 0 static void bits2_skip_long(struct bitstream2 *bits, int n) { if (n > bits->count) n = bits->count; bits->count -= n; if (n <= bits->avail) { bits->accum >>= n; bits->avail -= n; return; } n -= bits->avail; bits->index += n >> 3; bits->accum = 0; bits->avail = 0; n &= 7; if (n) { bits->accum = bits->data[bits->index++] >> n; bits->avail = 8 - n; } } #endif static int bits2_get_vlc(struct bitstream2 *bits, const uint8_t *table, size_t size) { size_t index = 0; assert(size && !(size & 1)); while (table[index] != 0xff) { if (bits->count < 1) return -1; assert(table[index] == 1); index += 2 * table[index + bits2_get1(bits)]; if (index >= size) return -1; } if (table[index + 1]) return table[index + 1] - 1; if (bits->count < 3) return -1; int n = bits2_get(bits, 3) + 1; if (bits->count < n) return -1; return bits2_get(bits, n); } static void bytes_init(struct bytestream *bytes, uint8_t *data, size_t size) { bytes->data = data; bytes->total = size; bytes->index = 0; } static int bytes_get(struct bytestream *bytes) { uint8_t v = 0; if (bytes->index < bytes->total) v = bytes->data[bytes->index]; bytes->index++; return v; } static int bytes_get16le(struct bytestream *bytes) { uint16_t v = 0; if (bytes->index + 1 < bytes->total) v = DCA_MEM16LE(&bytes->data[bytes->index]); bytes->index += 2; return v; } static int bytes_get16be(struct bytestream *bytes) { uint16_t v = 0; if (bytes->index + 1 < bytes->total) v = DCA_MEM16BE(&bytes->data[bytes->index]); bytes->index += 2; return v; } static int bytes_get32be(struct bytestream *bytes) { uint32_t v = 0; if (bytes->index + 3 < bytes->total) v = DCA_MEM32BE(&bytes->data[bytes->index]); bytes->index += 4; return v; } ================================================ FILE: libdcadec/lbr_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 "exss_parser.h" #include "lbr_decoder.h" #include "idct.h" #include "lbr_bitstream.h" #include "lbr_tables.h" #include "lbr_huffman.h" #include "fixed_math.h" enum LBRHeader { LBR_HEADER_SYNC_ONLY = 1, LBR_HEADER_DECODER_INIT = 2 }; enum LBRFlags { LBR_FLAG_24_BIT = 0x01, LBR_FLAG_LFE_PRESENT = 0x02, LBR_FLAG_BAND_LIMIT_2_3 = 0x04, LBR_FLAG_BAND_LIMIT_1_2 = 0x08, LBR_FLAG_BAND_LIMIT_1_3 = 0x0c, LBR_FLAG_BAND_LIMIT_1_4 = 0x10, LBR_FLAG_BAND_LIMIT_1_8 = 0x18, LBR_FLAG_BAND_LIMIT_NONE = 0x14, LBR_FLAG_BAND_LIMIT_MASK = 0x1c, LBR_FLAG_DMIX_STEREO = 0x20, LBR_FLAG_DMIX_MULTI_CH = 0x40 }; enum LBRChunks { LBR_CHUNK_NULL = 0x00, LBR_CHUNK_PAD = 0x01, LBR_CHUNK_FRAME = 0x04, LBR_CHUNK_FRAME_NO_CSUM = 0x06, LBR_CHUNK_LFE = 0x0a, LBR_CHUNK_ECS = 0x0b, LBR_CHUNK_RESERVED_1 = 0x0c, LBR_CHUNK_RESERVED_2 = 0x0d, LBR_CHUNK_SCF = 0x0e, LBR_CHUNK_TONAL = 0x10, LBR_CHUNK_TONAL_GRP_1 = 0x11, LBR_CHUNK_TONAL_GRP_2 = 0x12, LBR_CHUNK_TONAL_GRP_3 = 0x13, LBR_CHUNK_TONAL_GRP_4 = 0x14, LBR_CHUNK_TONAL_GRP_5 = 0x15, LBR_CHUNK_TONAL_SCF = 0x16, LBR_CHUNK_TONAL_SCF_GRP_1 = 0x17, LBR_CHUNK_TONAL_SCF_GRP_2 = 0x18, LBR_CHUNK_TONAL_SCF_GRP_3 = 0x19, LBR_CHUNK_TONAL_SCF_GRP_4 = 0x1a, LBR_CHUNK_TONAL_SCF_GRP_5 = 0x1b, LBR_CHUNK_RES_GRID_LR = 0x30, LBR_CHUNK_RES_GRID_LR_LAST = 0x3f, LBR_CHUNK_RES_GRID_HR = 0x40, LBR_CHUNK_RES_GRID_HR_LAST = 0x4f, LBR_CHUNK_RES_TS_1 = 0x50, LBR_CHUNK_RES_TS_1_LAST = 0x5f, LBR_CHUNK_RES_TS_2 = 0x60, LBR_CHUNK_RES_TS_2_LAST = 0x6f, LBR_CHUNK_EXTENSION = 0x7f }; struct lbr_chunk { int id, len; uint8_t *data; }; static int parse_lfe_24(struct lbr_decoder *lbr) { int ps = bits2_get(&lbr->bits, 24); int si = ps >> 23; float value = (((ps & 0x7fffff) ^ -si) + si) * (1.0 / 0x7fffff); int step_i = bits2_get(&lbr->bits, 8); if (step_i > 143) return -1; float step = lfe_step_size_24[step_i]; for (int i = 0; i < 64; i++) { int code = bits2_get(&lbr->bits, 6); float delta = step * 0.03125; if (code & 16) delta += step; if (code & 8) delta += step * 0.5; if (code & 4) delta += step * 0.25; if (code & 2) delta += step * 0.125; if (code & 1) delta += step * 0.0625; if (code & 32) { value -= delta; if (value < -3.0) value = -3.0; } else { value += delta; if (value > 3.0) value = 3.0; } step_i += lfe_delta_index_24[code & 31]; if (step_i < 0) step_i = 0; else if (step_i > 143) step_i = 143; step = lfe_step_size_24[step_i]; lbr->lfe_data[i] = value; } return 0; } static int parse_lfe_16(struct lbr_decoder *lbr) { int ps = bits2_get(&lbr->bits, 16); int si = ps >> 15; float value = (((ps & 0x7fff) ^ -si) + si) * (1.0 / 0x7fff); int step_i = bits2_get(&lbr->bits, 8); if (step_i > 100) return -1; float step = lfe_step_size_16[step_i]; for (int i = 0; i < 64; i++) { int code = bits2_get(&lbr->bits, 4); float delta = step * 0.125; if (code & 4) delta += step; if (code & 2) delta += step * 0.5; if (code & 1) delta += step * 0.25; if (code & 8) { value -= delta; if (value < -3.0) value = -3.0; } else { value += delta; if (value > 3.0) value = 3.0; } step_i += lfe_delta_index_16[code & 7]; if (step_i < 0) step_i = 0; else if (step_i > 100) step_i = 100; step = lfe_step_size_16[step_i]; lbr->lfe_data[i] = value; } return 0; } static int parse_lfe_chunk(struct lbr_decoder *lbr, struct lbr_chunk *chunk) { if (!chunk->len) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); if (chunk->len >= 52) return parse_lfe_24(lbr); if (chunk->len >= 35) return parse_lfe_16(lbr); lbr_warn("LFE chunk too small"); return 0; } static int parse_ecs_chunk(struct lbr_decoder *lbr, struct lbr_chunk *chunk) { if (chunk->len < 2) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); int start_sb = bits2_get(&lbr->bits, 7); int end_sb = bits2_get(&lbr->bits, 7); if (end_sb < start_sb || end_sb > lbr->nsubbands) return -1; for (int i = 0; i < lbr->nchannels * lbr->nsubbands * 4; i++) { int sb = (i / 4) & (lbr->nsubbands - 1); if (sb >= start_sb && sb < end_sb && bits2_get1(&lbr->bits)) { DCA_SET_BIT(lbr->can_replace_sf, i); if (bits2_get1(&lbr->bits)) DCA_SET_BIT(lbr->can_replace_ch, i); if (lbr->bits.count < 2) break; } } return 0; } static int parse_tonal(struct lbr_decoder *lbr, int group) { int first_ch = lbr->undo_dmix * 2; int amp[LBR_CHANNELS]; int phs[LBR_CHANNELS]; unsigned int diff; for (int sf = 0; sf < 1 << group; sf += diff ? 8 : 1) { int sf_idx = ((lbr->framenum << group) + sf) & 31; lbr->tonal_bounds[group][sf_idx][0] = lbr->ntones; for (int freq = 1;; freq++) { diff = bits2_get_vlc(&lbr->bits, huff_tnl_grp[group], huff_tnl_size[group]); if (diff >= dca_countof(fst_amp)) return -1; diff = bits2_getz(&lbr->bits, diff >> 2) + fst_amp[diff]; if (diff <= 1) break; freq += diff - 2; if (freq >> (5 - group) > lbr->nsubbands * 4 - 5) return -1; int main_ch = bits2_getz(&lbr->bits, bits_for_ch_num[lbr->nchannels_total - 1]); int value = bits2_get_vlc(&lbr->bits, huff_tnl_scf, sizeof(huff_tnl_scf)); if (value < 0) return -1; value += lbr->tonal_scf[freq_to_sf[freq >> (7 - group)]]; value += lbr->limited_range - 2; if (value > 55) return -1; if (value < 0) value = 0; amp[main_ch] = value; phs[main_ch] = bits2_get(&lbr->bits, 3); for (int ch = 0; ch < lbr->nchannels_total; ch++) { if (ch == main_ch) continue; if (bits2_get1(&lbr->bits)) { if ((value = bits2_get_vlc(&lbr->bits, huff_damp, sizeof(huff_damp))) < 0) return -1; value = amp[main_ch] - value; if (value < 0) value = 0; amp[ch] = value; if ((value = bits2_get_vlc(&lbr->bits, huff_dph, sizeof(huff_dph))) < 0) return -1; phs[ch] = (phs[main_ch] - value) & 7; } else { amp[ch] = 0; phs[ch] = 0; } } struct lbr_tone *t = &lbr->tones[lbr->ntones]; lbr->ntones = (lbr->ntones + 1) & (LBR_TONES - 1); t->x_freq = freq >> (5 - group); t->f_delt = (freq & ((1 << (5 - group)) - 1)) << group; t->ph_rot = 256 - (t->x_freq & 1) * 128 - t->f_delt * 4; value = ph0_shift[(t->x_freq & 3) * 2 + (freq & 1)]; value -= (t->ph_rot << (5 - group)) - t->ph_rot; for (int ch = 0; ch < lbr->nchannels; ch++) { t->amp[ch] = amp[first_ch + ch]; t->phs[ch] = 128 - phs[first_ch + ch] * 32 + value; } } lbr->tonal_bounds[group][sf_idx][1] = lbr->ntones; } return 0; } static int parse_tonal_chunk(struct lbr_decoder *lbr, struct lbr_chunk *chunk) { if (!chunk->len) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); if (chunk->id == LBR_CHUNK_SCF || chunk->id == LBR_CHUNK_TONAL_SCF) { if (lbr->bits.count < 36) return -1; for (int sb = 0; sb < 6; sb++) { lbr->tonal_scf[sb] = bits2_get(&lbr->bits, 6); if (lbr->tonal_scf[sb] > 55) return -1; } } if (chunk->id == LBR_CHUNK_TONAL || chunk->id == LBR_CHUNK_TONAL_SCF) for (int group = 0; group < 5; group++) if (parse_tonal(lbr, group) < 0) return -1; return 0; } static int parse_tonal_group(struct lbr_decoder *lbr, struct lbr_chunk *chunk) { if (!chunk->len) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); return parse_tonal(lbr, chunk->id); } static int parse_scale_factors(struct lbr_decoder *lbr, uint8_t *scf) { int sf = 0, prev, next, dist; if (lbr->bits.count < 20) return 0; if ((prev = bits2_get_vlc(&lbr->bits, huff_fst_rsd_amp, sizeof(huff_fst_rsd_amp))) < 0) return -1; if (prev > 56) return -1; scf[sf] = prev; while (true) { if (lbr->bits.count < 20) return 0; if ((dist = bits2_get_vlc(&lbr->bits, huff_rsd_apprx, sizeof(huff_rsd_apprx))) < 0) return -1; dist++; if (sf + dist > 7) return -1; if (lbr->bits.count < 20) return 0; if ((next = bits2_get_vlc(&lbr->bits, huff_rsd_amp, sizeof(huff_rsd_amp))) < 0) return -1; if (next > 112) return -1; if (next & 1) next = prev + ((next + 1) >> 1); else next = prev - ( next >> 1); switch (dist) { case 2: if (next > prev) scf[sf + 1] = prev + ((next - prev) >> 1); else scf[sf + 1] = prev - ((prev - next) >> 1); break; case 4: if (next > prev) { scf[sf + 1] = prev + ( (next - prev) >> 2); scf[sf + 2] = prev + ( (next - prev) >> 1); scf[sf + 3] = prev + (((next - prev) * 3) >> 2); } else { scf[sf + 1] = prev - ( (prev - next) >> 2); scf[sf + 2] = prev - ( (prev - next) >> 1); scf[sf + 3] = prev - (((prev - next) * 3) >> 2); } break; default: for (int i = 1; i < dist; i++) scf[sf + i] = prev + (next - prev) * i / dist; break; } scf[sf += dist] = next; if (sf == 7) break; prev = next; } return 0; } static int parse_st_code(struct bitstream2 *bits, int min_v) { int v; if ((v = bits2_get_vlc(bits, huff_st_grid, sizeof(huff_st_grid))) < 0) return -1; if (v > 31) return -1; v += min_v; if (v & 1) v = 16 + (v >> 1); else v = 16 - (v >> 1); if (v > 33) v = 16; return v; } static int parse_grid_1_chunk(struct lbr_decoder *lbr, struct lbr_chunk *chunk, int ch1, int ch2) { int ch, sb, sf, value; if (chunk->len < 3) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); // Scale factors int nsubbands = scf_to_grid_1[lbr->nsubbands - 1] + 1; for (sb = 2; sb < nsubbands; sb++) { if (parse_scale_factors(lbr, lbr->grid_1_scf[ch1][sb]) < 0) return -1; if (ch1 != ch2 && grid_1_to_scf[sb] < lbr->min_mono_subband) if (parse_scale_factors(lbr, lbr->grid_1_scf[ch2][sb]) < 0) return -1; } if (lbr->bits.count < 20) return 0; // Average values for third grid for (sb = 0; sb < lbr->nsubbands - 4; sb++) { if ((value = bits2_get_vlc(&lbr->bits, huff_avg_g3, sizeof(huff_avg_g3))) < 0) return -1; if (value > 72) return -1; lbr->grid_3_avg[ch1][sb] = value - 16; if (ch1 != ch2) { if (sb + 4 < lbr->min_mono_subband) { if ((value = bits2_get_vlc(&lbr->bits, huff_avg_g3, sizeof(huff_avg_g3))) < 0) return -1; if (value > 72) return -1; lbr->grid_3_avg[ch2][sb] = value - 16; } else { lbr->grid_3_avg[ch2][sb] = lbr->grid_3_avg[ch1][sb]; } } } if (lbr->bits.count < 8) return 0; // Stereo image for partial mono mode if (ch1 != ch2) { int min_v[2]; min_v[0] = bits2_get(&lbr->bits, 4); min_v[1] = bits2_get(&lbr->bits, 4); int nsubbands = (lbr->nsubbands - lbr->min_mono_subband + 3) / 4; for (sb = 0; sb < nsubbands; sb++) { for (ch = ch1; ch <= ch2; ch++) { for (sf = 1; sf <= 4; sf++) { if ((value = parse_st_code(&lbr->bits, min_v[ch - ch1])) < 0) return -1; lbr->part_stereo[ch][sb][sf] = value; } } } if (lbr->bits.count >= 0) lbr->part_stereo_pres |= 1 << ch1; } if (lbr->bits.count < 8) return 0; // Low resolution spatial information if (ch1 == 0) { for (ch = 2; ch < lbr->nchannels; ch++) { if (lbr->bits.count < 8) break; int min_v = bits2_get(&lbr->bits, 4); for (sb = 0; sb < lbr->nsubbands / 4; sb++) { for (sf = 1; sf <= 4; sf++) { if ((value = parse_st_code(&lbr->bits, min_v)) < 0) return -1; lbr->spatial_info[ch - 2][sb][sf] = value; } } if (lbr->bits.count >= 0) lbr->spatial_info_pres |= 1 << ch; } } return 0; } static int parse_grid_1_sec_ch(struct lbr_decoder *lbr, int ch2) { int value; if (lbr->bits.count < 20) return 0; // Scale factors int nsubbands = scf_to_grid_1[lbr->nsubbands - 1] + 1; for (int sb = 2; sb < nsubbands; sb++) { if (grid_1_to_scf[sb] >= lbr->min_mono_subband) if (parse_scale_factors(lbr, lbr->grid_1_scf[ch2][sb]) < 0) return -1; } if (lbr->bits.count < 20) return 0; // Average values for third grid for (int sb = 0; sb < lbr->nsubbands - 4; sb++) { if (sb + 4 >= lbr->min_mono_subband) { if ((value = bits2_get_vlc(&lbr->bits, huff_avg_g3, sizeof(huff_avg_g3))) < 0) return -1; if (value > 72) return -1; lbr->grid_3_avg[ch2][sb] = value - 16; if (lbr->bits.count < 20) break; } } return 0; } static int parse_grid_code(struct bitstream2 *bits, const uint8_t *table, int n) { int v = table[bits2_peek(bits, n)]; bits2_skip(bits, v >> 5); return v & 31; } static int parse_grid_3_code(struct bitstream2 *bits) { int v; if ((v = parse_grid_code(bits, grid_3_codes_1, 5)) < 31) return v; if ((v = parse_grid_code(bits, grid_3_codes_2, 3)) < 31) return v; if ((v = parse_grid_code(bits, grid_3_codes_3, 4)) < 31) return v; v = bits2_get(bits, bits2_get(bits, 3) + 1); if (v > 56) v = 16; return v; } static void parse_grid_3(struct lbr_decoder *lbr, int ch1, int ch2, int sb, bool flag) { for (int ch = ch1; ch <= ch2; ch++) { if ((ch != ch1 && sb + 4 >= lbr->min_mono_subband) != flag) continue; if (lbr->grid_3_pres[ch] & (1U << sb)) continue; for (int i = 0; i < 8; i++) { if (lbr->bits.count < 20) return; lbr->grid_3_scf[ch][sb][i] = parse_grid_3_code(&lbr->bits) - 16; } lbr->grid_3_pres[ch] |= 1U << sb; } } static float lbr_rand(struct lbr_decoder *lbr, int sb) { lbr->lbr_rand = 1103515245U * lbr->lbr_rand + 12345U; return lbr->lbr_rand * lbr->sb_scf[sb]; } static void parse_ch(struct lbr_decoder *lbr, int ch, int sb, int quant_level) { int i, j, sf, ofs, code = -1, coding_method = -1; if (lbr->bits.count < 20) { lbr->bits.count = 0; return; } for (sf = 0, ofs = 0; sf < 4; sf++, ofs += 32) { float *samples = &lbr->time_samples[ch][sb][LBR_TIME_HISTORY + sf * 32]; if (lbr->undo_dmix && ch < lbr->nchannels) { unsigned int bit = (ch * lbr->nsubbands + sb) * 4 + sf; if (DCA_TEST_BIT(lbr->can_replace_sf, bit)) { ofs = -32; continue; } } if (coding_method == -1) coding_method = bits2_get1(&lbr->bits); switch (quant_level) { case 1: for (i = 0; i < 4; i++, samples += 8) { if (lbr->bits.count >= 8) { code = bits2_get(&lbr->bits, 8); for (j = 0; j < 8; j++) samples[j] = residual_level_2a[(code >> j) & 1]; } else { for (j = 0; j < 8; j++) samples[j] = lbr_rand(lbr, sb); } } break; case 2: if (coding_method) { for (i = 0; i < 32; i++) { if (lbr->bits.count < 2) samples[i] = lbr_rand(lbr, sb); else if (bits2_get1(&lbr->bits)) samples[i] = residual_level_2b[bits2_get1(&lbr->bits)]; else samples[i] = 0; } break; } for (i = 0; i < 32; i++) { int mod = (ofs + i) % 5; if (!mod) { if (lbr->bits.count >= 8) { code = bits2_get(&lbr->bits, 8); if (code > 242) code = 121; } else { code = 121; } code = residual_pack_5_in_8[code]; } samples[i] = residual_level_3[(code >> mod * 2) & 3]; } break; case 3: for (i = 0; i < 32; i++) { int mod = (ofs + i) % 3; if (!mod) { if (lbr->bits.count >= 7) { code = bits2_get(&lbr->bits, 7); if (code > 124) code = 62; } else { code = 62; } } samples[i] = residual_level_5[residual_pack_3_in_7[code][mod]]; } break; case 4: for (i = 0; i < 32; i++) { if (lbr->bits.count >= 6) { code = bits2_peek(&lbr->bits, 6); samples[i] = residual_level_8[residual_code_val[code]]; bits2_skip(&lbr->bits, residual_code_len[code]); } else { samples[i] = lbr_rand(lbr, sb); } } break; case 5: for (i = 0; i < 32; i++) { if (lbr->bits.count >= 4) samples[i] = residual_level_16[bits2_get(&lbr->bits, 4)]; else samples[i] = lbr_rand(lbr, sb); } break; } } lbr->ch_pres[ch] |= 1U << sb; } static int parse_ts(struct lbr_decoder *lbr, int ch1, int ch2, int start_sb, int end_sb, bool flag) { int sb_reorder; for (int sb = start_sb; sb < end_sb; sb++) { if (lbr->bits.count < 28) { lbr->bits.count = 0; break; } if (sb < 6) { sb_reorder = sb; } else if (flag && sb < lbr->max_mono_subband) { sb_reorder = lbr->sb_indices[sb]; } else { sb_reorder = bits2_get(&lbr->bits, lbr->limited_range + 3); if (sb_reorder < 6) sb_reorder = 6; lbr->sb_indices[sb] = sb_reorder; } if (sb_reorder >= lbr->nsubbands) return -1; if (sb == 12) { for (int sb = 0; sb < lbr->g3_avg_only_start_sb - 4; sb++) parse_grid_3(lbr, ch1, ch2, sb, flag); } else if (sb < 12 && sb_reorder >= 4) { parse_grid_3(lbr, ch1, ch2, sb_reorder - 4, flag); } if (lbr->bits.count < 20) { lbr->bits.count = 0; break; } if (ch1 != ch2) { if (!flag || sb_reorder >= lbr->max_mono_subband) lbr->sec_ch_sbms[ch1 / 2][sb_reorder] = bits2_get(&lbr->bits, 8); if (flag && sb_reorder >= lbr->min_mono_subband) lbr->sec_ch_lrms[ch1 / 2][sb_reorder] = bits2_get(&lbr->bits, 8); } int quant_level = lbr->quant_levels[ch1 / 2][sb]; if (!quant_level) return -1; if (sb < lbr->max_mono_subband && sb_reorder >= lbr->min_mono_subband) { if (!flag) parse_ch(lbr, ch1, sb_reorder, quant_level); else if (ch1 != ch2) parse_ch(lbr, ch2, sb_reorder, quant_level); } else { parse_ch(lbr, ch1, sb_reorder, quant_level); if (ch1 != ch2) parse_ch(lbr, ch2, sb_reorder, quant_level); } } return 0; } static void convert_lpc(float *coeff, const int *codes, const float *table) { for (int i = 0; i < 8; i++) { float rc = table[codes[i]]; for (int j = 0; j < (i + 1) / 2; j++) { float tmp1 = coeff[ j ]; float tmp2 = coeff[i - j - 1]; coeff[ j ] = tmp1 + rc * tmp2; coeff[i - j - 1] = tmp2 + rc * tmp1; } coeff[i] = rc; } } static int parse_lpc(struct lbr_decoder *lbr, int ch1, int ch2, int start_sb, int end_sb) { int f = lbr->framenum & 1; int codes[16]; for (int sb = start_sb; sb < end_sb; sb++) { int ncodes = 8 * (1 + (sb < 2)); for (int ch = ch1; ch <= ch2; ch++) { if (lbr->bits.count < 4 * ncodes) { memset(lbr->lpc_coeff[ch][sb][f], 0, sizeof(lbr->lpc_coeff[0][0][0])); lbr->bits.count = 0; return 0; } for (int i = 0; i < ncodes; i++) codes[i] = bits2_get(&lbr->bits, 4); for (int i = 0; i < ncodes / 8; i++) convert_lpc(lbr->lpc_coeff[ch][sb][f][i], &codes[i * 8], lbr->lpc_tab); } } return 0; } static int parse_high_res_grid(struct lbr_decoder *lbr, struct lbr_chunk *chunk, int ch1, int ch2) { if (!chunk->len) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); // Quantizer profile int profile = bits2_get(&lbr->bits, 8); int ol = (profile >> 3) & 7; int st = profile >> 6; int sb, max_sb = profile & 7; // Calculate quantization levels int quant_levels[LBR_SUBBANDS]; for (sb = 0; sb < lbr->nsubbands; sb++) { int f = sb * lbr->limited_rate / lbr->nsubbands; int a = 18000 / (12 * f / 1000 + 100 + 40 * st) + 20 * ol; if (a <= 95) quant_levels[sb] = 1; else if (a <= 140) quant_levels[sb] = 2; else if (a <= 180) quant_levels[sb] = 3; else if (a <= 230) quant_levels[sb] = 4; else quant_levels[sb] = 5; } // Reorder quantization levels for lower subbands for (sb = 0; sb < 8; sb++) lbr->quant_levels[ch1 / 2][sb] = quant_levels[sb_reorder[max_sb][sb]]; for (; sb < lbr->nsubbands; sb++) lbr->quant_levels[ch1 / 2][sb] = quant_levels[sb]; // LPC for the first two subbands if (parse_lpc(lbr, ch1, ch2, 0, 2) < 0) return -1; // Time-samples for the first two subbands of main channel if (parse_ts(lbr, ch1, ch2, 0, 2, false) < 0) return -1; // First two bands of the first grid for (sb = 0; sb < 2; sb++) for (int ch = ch1; ch <= ch2; ch++) if (parse_scale_factors(lbr, lbr->grid_1_scf[ch][sb]) < 0) return -1; return 0; } static int parse_grid_2_code(struct bitstream2 *bits) { int v; if ((v = parse_grid_code(bits, grid_2_codes_1, 5)) < 31) return v; if ((v = parse_grid_code(bits, grid_2_codes_2, 4)) < 31) return v; if ((v = parse_grid_code(bits, grid_2_codes_3, 5)) < 31) return v; v = bits2_get(bits, bits2_get(bits, 3) + 1); if (v > 56) v = 0; return v; } static int parse_grid_2(struct lbr_decoder *lbr, int ch1, int ch2, int start_sb, int end_sb, bool flag) { int nsubbands2 = scf_to_grid_2[lbr->nsubbands - 1] + 1; if (end_sb > nsubbands2) end_sb = nsubbands2; for (int sb = start_sb; sb < end_sb; sb++) { for (int ch = ch1; ch <= ch2; ch++) { if ((ch != ch1 && grid_2_to_scf[sb] >= lbr->min_mono_subband) != flag) { if (!flag) memcpy(lbr->grid_2_scf[ch2][sb], lbr->grid_2_scf[ch1][sb], sizeof(lbr->grid_2_scf[0][0])); continue; } uint8_t *g2_scf = lbr->grid_2_scf[ch][sb]; for (int i = 0; i < 8; i++) { if (lbr->bits.count > 1 && bits2_get1(&lbr->bits)) { for (int j = 0; j < 8; j++) { if (lbr->bits.count < 20) break; g2_scf[j] = parse_grid_2_code(&lbr->bits); } } else { memset(g2_scf, 0, 8 * sizeof(*g2_scf)); } g2_scf += 8; } } } return 0; } static int parse_ts1_chunk(struct lbr_decoder *lbr, struct lbr_chunk *chunk, int ch1, int ch2) { if (!chunk->len) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); if (parse_lpc(lbr, ch1, ch2, 2, 3) < 0) return -1; if (parse_ts(lbr, ch1, ch2, 2, 4, false) < 0) return -1; if (parse_grid_2(lbr, ch1, ch2, 0, 1, false) < 0) return -1; if (parse_ts(lbr, ch1, ch2, 4, 6, false) < 0) return -1; return 0; } static int parse_ts2_chunk(struct lbr_decoder *lbr, struct lbr_chunk *chunk, int ch1, int ch2) { if (!chunk->len) return 0; bits2_init(&lbr->bits, chunk->data, chunk->len); if (parse_grid_2(lbr, ch1, ch2, 1, 3, false) < 0) return -1; if (parse_ts(lbr, ch1, ch2, 6, lbr->max_mono_subband, false) < 0) return -1; if (ch1 != ch2) { if (parse_grid_1_sec_ch(lbr, ch2) < 0) return -1; if (parse_grid_2(lbr, ch1, ch2, 0, 3, true) < 0) return -1; } if (parse_ts(lbr, ch1, ch2, lbr->min_mono_subband, lbr->nsubbands, true) < 0) return -1; return 0; } static int init_tables(struct lbr_decoder *lbr) { float scale = 256.0 * 0.25 * sqrt(1 << (2 - lbr->limited_range)); int i; ta_free(lbr->imdct); if (!(lbr->imdct = idct_init(lbr, lbr->freq_range + 5, scale))) return -1; for (i = 0; i < 256; i++) lbr->sin_tab[i] = cos(M_PI * i / 128); for (i = 0; i < 16; i++) lbr->lpc_tab[i] = sin((i - 8) * (M_PI / ((i < 8) ? 17 : 15))); int br_per_ch = lbr->bit_rate_scaled / lbr->nchannels; if (br_per_ch < 14000) scale = 0.85; else if (br_per_ch < 32000) scale = (br_per_ch - 14000) * (1.0 / 120000) + 0.85; else scale = 1.0; scale *= 1.0 / INT_MAX; for (i = 0; i < lbr->nsubbands; i++) { if (i < 2) lbr->sb_scf[i] = 0; else if (i < 5) lbr->sb_scf[i] = (i - 1) * 0.25 * 0.785 * scale; else lbr->sb_scf[i] = 0.785 * scale; } return 0; } static int parse_decoder_init(struct lbr_decoder *lbr, struct bytestream *bytes) { int old_rate = lbr->sample_rate; int old_band_limit = lbr->band_limit; // Sample rate of LBR audio unsigned int code = bytes_get(bytes); if (code >= dca_countof(exss_sample_rates) || exss_sample_rates[code] > 48000) { lbr_err("Invalid LBR sample rate"); return -DCADEC_EBADDATA; } lbr->sample_rate = exss_sample_rates[code]; // LBR speaker mask lbr->ch_mask = bytes_get16le(bytes); // LBR bitstream version if ((bytes_get16le(bytes) & 0xff00) != 0x0800) { lbr_err("Unsupported LBR version"); return -DCADEC_ENOSUP; } // Flags for LBR decoder initialization lbr->flags = bytes_get(bytes); if (lbr->flags & LBR_FLAG_DMIX_MULTI_CH) { lbr_err("Unsupported multi-channel downmix"); return -DCADEC_ENOSUP; } if (lbr->sample_rate != 48000) lbr->flags &= ~LBR_FLAG_LFE_PRESENT; // Most significant bit rate nibbles int bit_rate_hi = bytes_get(bytes); // Least significant original bit rate word lbr->bit_rate_orig = bytes_get16le(bytes) | ((bit_rate_hi & 0x0F) << 16); // Least significant scaled bit rate word lbr->bit_rate_scaled = bytes_get16le(bytes) | ((bit_rate_hi & 0xF0) << 12); lbr->nchannels = count_chs_for_mask(lbr->ch_mask & ~SPEAKER_PAIR_LFE1); if (lbr->nchannels < 1 || lbr->nchannels > LBR_CHANNELS) { lbr_err("Invalid LBR channel mask"); return -DCADEC_EBADDATA; } switch (lbr->flags & LBR_FLAG_BAND_LIMIT_MASK) { case LBR_FLAG_BAND_LIMIT_1_2: lbr->band_limit = 1; break; case LBR_FLAG_BAND_LIMIT_1_4: lbr->band_limit = 2; break; case LBR_FLAG_BAND_LIMIT_NONE: lbr->band_limit = 0; break; default: lbr_err("Invalid LBR band limit"); return -DCADEC_EBADDATA; } if (lbr->sample_rate < 14000) lbr->freq_range = 0; else if (lbr->sample_rate < 28000) lbr->freq_range = 1; else lbr->freq_range = 2; if (lbr->bit_rate_orig >= 44000 * (lbr->nchannels + 2)) lbr->res_profile = 2; else if (lbr->bit_rate_orig >= 25000 * (lbr->nchannels + 2)) lbr->res_profile = 1; else lbr->res_profile = 0; lbr->limited_rate = lbr->sample_rate >> lbr->band_limit; lbr->limited_range = lbr->freq_range - lbr->band_limit; if (lbr->limited_range < 0) { lbr_err("Invalid LBR band limit"); return -DCADEC_EBADDATA; } lbr->nsubbands = 8 << lbr->limited_range; static const uint16_t freq[3] = { 16000, 18000, 24000 }; lbr->g3_avg_only_start_sb = lbr->nsubbands * freq[lbr->res_profile] / (lbr->limited_rate / 2); if (lbr->g3_avg_only_start_sb > lbr->nsubbands) lbr->g3_avg_only_start_sb = lbr->nsubbands; lbr->min_mono_subband = lbr->nsubbands * 2000 / (lbr->limited_rate / 2); if (lbr->min_mono_subband > lbr->nsubbands) lbr->min_mono_subband = lbr->nsubbands; lbr->max_mono_subband = lbr->nsubbands * 14000 / (lbr->limited_rate / 2); if (lbr->max_mono_subband > lbr->nsubbands) lbr->max_mono_subband = lbr->nsubbands; if (old_rate != lbr->sample_rate || old_band_limit != lbr->band_limit) { lbr_clear(lbr); if (init_tables(lbr) < 0) return -DCADEC_ENOMEM; } lbr->nchannels_total = lbr->nchannels; lbr->undo_dmix = false; if (lbr->flags & LBR_FLAG_DMIX_STEREO) { if (lbr->nchannels < 3 || lbr->nchannels > LBR_CHANNELS - 2) { lbr_err("Invalid number of channels for stereo downmix"); return -DCADEC_EBADDATA; } lbr->nchannels_total += 2; if (lbr->ctx_flags & DCADEC_FLAG_KEEP_DMIX_2CH) { lbr->nchannels = 2; lbr->ch_mask = SPEAKER_PAIR_LR; lbr->flags &= ~LBR_FLAG_LFE_PRESENT; } else { lbr->undo_dmix = true; } } return 0; } int lbr_parse(struct lbr_decoder *lbr, uint8_t *data, size_t size, struct exss_asset *asset) { int i, ret; (void)size; struct bytestream bytes; bytes_init(&bytes, data + asset->lbr_offset, asset->lbr_size); // LBR sync word if (bytes_get32be(&bytes) != SYNC_WORD_LBR) { lbr_err("Invalid LBR sync word"); return -DCADEC_ENOSYNC; } // LBR header type switch (bytes_get(&bytes)) { case LBR_HEADER_SYNC_ONLY: if (!lbr->sample_rate) { lbr_err("LBR decoder not initialized"); return -DCADEC_EBADDATA; } break; case LBR_HEADER_DECODER_INIT: if ((ret = parse_decoder_init(lbr, &bytes)) < 0) { lbr->sample_rate = 0; return ret; } break; default: lbr_err("Invalid LBR header type"); return -DCADEC_EBADDATA; } int chunk_id = bytes_get(&bytes); int chunk_len = (chunk_id & 0x80) ? bytes_get16be(&bytes) : bytes_get(&bytes); if (bytes.index + chunk_len > bytes.total) { lbr_err("Invalid LBR frame chunk size"); return -DCADEC_EBADREAD; } bytes_init(&bytes, bytes.data + bytes.index, chunk_len); switch (chunk_id & 0x7f) { case LBR_CHUNK_FRAME: { int checksum = bytes_get16be(&bytes); uint16_t res = chunk_id; res += (chunk_len >> 8) & 0xff; res += chunk_len & 0xff; for (int i = 0; i < chunk_len - 2; i++) res += bytes.data[bytes.index + i]; if (checksum != res) { lbr_err("Invalid LBR checksum"); return -DCADEC_EBADCRC; } break; } case LBR_CHUNK_FRAME_NO_CSUM: break; default: lbr_err("Invalid LBR frame chunk ID"); return -DCADEC_EBADDATA; } memset(lbr->can_replace_sf, 0, sizeof(lbr->can_replace_sf)); memset(lbr->can_replace_ch, 0, sizeof(lbr->can_replace_ch)); memset(lbr->quant_levels, 0, sizeof(lbr->quant_levels)); memset(lbr->sb_indices, 0xff, sizeof(lbr->sb_indices)); memset(lbr->sec_ch_sbms, 0, sizeof(lbr->sec_ch_sbms)); memset(lbr->sec_ch_lrms, 0, sizeof(lbr->sec_ch_lrms)); memset(lbr->ch_pres, 0, sizeof(lbr->ch_pres)); memset(lbr->grid_1_scf, 0, sizeof(lbr->grid_1_scf)); memset(lbr->grid_2_scf, 0, sizeof(lbr->grid_2_scf)); memset(lbr->grid_3_avg, 0, sizeof(lbr->grid_3_avg)); memset(lbr->grid_3_scf, 0, sizeof(lbr->grid_3_scf)); memset(lbr->grid_3_pres, 0, sizeof(lbr->grid_3_pres)); memset(lbr->tonal_scf, 0, sizeof(lbr->tonal_scf)); memset(lbr->lfe_data, 0, sizeof(lbr->lfe_data)); lbr->part_stereo_pres = 0; lbr->spatial_info_pres = 0; lbr->framenum = (lbr->framenum + 1) & 31; for (int ch = 0; ch < lbr->nchannels; ch++) { for (int sb = 0; sb < lbr->nsubbands / 4; sb++) { lbr->part_stereo[ch][sb][0] = lbr->part_stereo[ch][sb][4]; lbr->part_stereo[ch][sb][4] = 16; } } for (int ch = 0; ch < lbr->nchannels - 2; ch++) { for (int sb = 0; sb < lbr->nsubbands / 4; sb++) { lbr->spatial_info[ch][sb][0] = lbr->spatial_info[ch][sb][4]; lbr->spatial_info[ch][sb][4] = 16; } } for (int group = 0; group < 5; group++) { for (int sf = 0; sf < 1 << group; sf++) { int sf_idx = ((lbr->framenum << group) + sf) & 31; lbr->tonal_bounds[group][sf_idx][0] = lbr->tonal_bounds[group][sf_idx][1] = lbr->ntones; } } struct { struct lbr_chunk lfe; struct lbr_chunk ecs; struct lbr_chunk tonal; struct lbr_chunk tonal_grp[5]; struct lbr_chunk grid1[LBR_CHANNELS / 2]; struct lbr_chunk hr_grid[LBR_CHANNELS / 2]; struct lbr_chunk ts1[LBR_CHANNELS / 2]; struct lbr_chunk ts2[LBR_CHANNELS / 2]; } chunk; memset(&chunk, 0, sizeof(chunk)); while (bytes.index < bytes.total) { int chunk_id = bytes_get(&bytes); int chunk_len = (chunk_id & 0x80) ? bytes_get16be(&bytes) : bytes_get(&bytes); if (chunk_len > bytes.total - bytes.index) { chunk_len = bytes.total - bytes.index; if (chunk_len < 0) break; } chunk_id &= 0x7f; switch (chunk_id) { case LBR_CHUNK_LFE: chunk.lfe.len = chunk_len; chunk.lfe.data = bytes.data + bytes.index; break; case LBR_CHUNK_ECS: chunk.ecs.len = chunk_len; chunk.ecs.data = bytes.data + bytes.index; break; case LBR_CHUNK_SCF: case LBR_CHUNK_TONAL: case LBR_CHUNK_TONAL_SCF: chunk.tonal.id = chunk_id; chunk.tonal.len = chunk_len; chunk.tonal.data = bytes.data + bytes.index; break; case LBR_CHUNK_TONAL_GRP_1: case LBR_CHUNK_TONAL_GRP_2: case LBR_CHUNK_TONAL_GRP_3: case LBR_CHUNK_TONAL_GRP_4: case LBR_CHUNK_TONAL_GRP_5: i = LBR_CHUNK_TONAL_GRP_5 - chunk_id; chunk.tonal_grp[i].id = i; chunk.tonal_grp[i].len = chunk_len; chunk.tonal_grp[i].data = bytes.data + bytes.index; break; case LBR_CHUNK_TONAL_SCF_GRP_1: case LBR_CHUNK_TONAL_SCF_GRP_2: case LBR_CHUNK_TONAL_SCF_GRP_3: case LBR_CHUNK_TONAL_SCF_GRP_4: case LBR_CHUNK_TONAL_SCF_GRP_5: i = LBR_CHUNK_TONAL_SCF_GRP_5 - chunk_id; chunk.tonal_grp[i].id = i; chunk.tonal_grp[i].len = chunk_len; chunk.tonal_grp[i].data = bytes.data + bytes.index; break; case LBR_CHUNK_RES_GRID_LR: case LBR_CHUNK_RES_GRID_LR + 1: case LBR_CHUNK_RES_GRID_LR + 2: case LBR_CHUNK_RES_GRID_LR + 3: i = chunk_id - LBR_CHUNK_RES_GRID_LR; chunk.grid1[i].len = chunk_len; chunk.grid1[i].data = bytes.data + bytes.index; break; case LBR_CHUNK_RES_GRID_HR: case LBR_CHUNK_RES_GRID_HR + 1: case LBR_CHUNK_RES_GRID_HR + 2: case LBR_CHUNK_RES_GRID_HR + 3: i = chunk_id - LBR_CHUNK_RES_GRID_HR; chunk.hr_grid[i].len = chunk_len; chunk.hr_grid[i].data = bytes.data + bytes.index; break; case LBR_CHUNK_RES_TS_1: case LBR_CHUNK_RES_TS_1 + 1: case LBR_CHUNK_RES_TS_1 + 2: case LBR_CHUNK_RES_TS_1 + 3: i = chunk_id - LBR_CHUNK_RES_TS_1; chunk.ts1[i].len = chunk_len; chunk.ts1[i].data = bytes.data + bytes.index; break; case LBR_CHUNK_RES_TS_2: case LBR_CHUNK_RES_TS_2 + 1: case LBR_CHUNK_RES_TS_2 + 2: case LBR_CHUNK_RES_TS_2 + 3: i = chunk_id - LBR_CHUNK_RES_TS_2; chunk.ts2[i].len = chunk_len; chunk.ts2[i].data = bytes.data + bytes.index; break; } bytes.index += chunk_len; } #define CHECK(x, s) \ if (x < 0) { \ lbr_err("Error parsing %s chunk", s); \ return -DCADEC_EBADDATA; \ } // LFE chunk if (lbr->flags & LBR_FLAG_LFE_PRESENT) CHECK(parse_lfe_chunk(lbr, &chunk.lfe), "LFE"); // Tonal chunks CHECK(parse_tonal_chunk(lbr, &chunk.tonal), "tonal"); for (i = 0; i < 5; i++) CHECK(parse_tonal_group(lbr, &chunk.tonal_grp[i]), "tonal group"); // ECS chunk and downmixed channel pair if (lbr->undo_dmix) { // Decode into unused channel pair at the end of array int ch1 = LBR_CHANNELS - 2; int ch2 = LBR_CHANNELS - 1; CHECK(parse_ecs_chunk(lbr, &chunk.ecs), "ECS"); CHECK(parse_high_res_grid(lbr, &chunk.hr_grid[0], ch1, ch2), "high-res grid"); if (chunk.hr_grid[0].len) { CHECK(parse_ts1_chunk(lbr, &chunk.ts1[0], ch1, ch2), "TS 1"); if (chunk.ts1[0].len) CHECK(parse_ts2_chunk(lbr, &chunk.ts2[0], ch1, ch2), "TS 2"); } } // Residual chunks for (int pair = 0; pair < (lbr->nchannels + 1) / 2; pair++) { int ch1 = pair * 2; int ch2 = DCA_MIN(ch1 + 1, lbr->nchannels - 1); // Skip the first downmixed channel pair i = pair + lbr->undo_dmix; CHECK(parse_grid_1_chunk(lbr, &chunk.grid1[i], ch1, ch2), "grid 1"); CHECK(parse_high_res_grid(lbr, &chunk.hr_grid[i], ch1, ch2), "high-res grid"); if (chunk.grid1[i].len && chunk.hr_grid[i].len) { CHECK(parse_ts1_chunk(lbr, &chunk.ts1[i], ch1, ch2), "TS 1"); if (chunk.ts1[i].len) CHECK(parse_ts2_chunk(lbr, &chunk.ts2[i], ch1, ch2), "TS 2"); } } #undef CHECK return 0; } static void decode_grid(struct lbr_decoder *lbr, int ch) { for (int sb = 0; sb < lbr->nsubbands; sb++) { int g1_sb = scf_to_grid_1[sb]; uint8_t *g1_scf_a = lbr->grid_1_scf[ch][g1_sb ]; uint8_t *g1_scf_b = lbr->grid_1_scf[ch][g1_sb + 1]; int w1 = grid_1_weights[g1_sb ][sb]; int w2 = grid_1_weights[g1_sb + 1][sb]; uint8_t *hr_scf = lbr->high_res_scf[ch][sb]; if (sb < 4) { for (int i = 0; i < 8; i++) { int scf = w1 * g1_scf_a[i] + w2 * g1_scf_b[i]; hr_scf[i] = scf >> 7; } } else { int8_t *g3_scf = lbr->grid_3_scf[ch][sb - 4]; int g3_avg = lbr->grid_3_avg[ch][sb - 4]; for (int i = 0; i < 8; i++) { int scf = w1 * g1_scf_a[i] + w2 * g1_scf_b[i]; hr_scf[i] = (scf >> 7) - g3_avg - g3_scf[i]; } } } } static void replace_ts(struct lbr_decoder *lbr, int ch1) { for (int sb = 0; sb < lbr->nsubbands; sb++) { for (int sf = 0; sf < 4; sf++) { unsigned int bit = (ch1 * lbr->nsubbands + sb) * 4 + sf; if (DCA_TEST_BIT(lbr->can_replace_sf, bit)) { int ch2 = LBR_CHANNELS - 2 + DCA_TEST_BIT(lbr->can_replace_ch, bit); float *samples1 = &lbr->time_samples[ch1][sb][LBR_TIME_HISTORY + sf * 32]; float *samples2 = &lbr->time_samples[ch2][sb][LBR_TIME_HISTORY + sf * 32]; memcpy(samples1, samples2, 32 * sizeof(*samples1)); } } } } static void random_ts(struct lbr_decoder *lbr, int ch) { for (int sb = 0; sb < lbr->nsubbands; sb++) { float *samples = &lbr->time_samples[ch][sb][LBR_TIME_HISTORY]; int i, j; if (lbr->ch_pres[ch] & (1U << sb)) continue; if (sb < 2) { memset(samples, 0, LBR_TIME_SAMPLES * sizeof(*samples)); } else if (sb < 10) { for (i = 0; i < LBR_TIME_SAMPLES; i++) samples[i] = lbr_rand(lbr, sb); } else { for (i = 0; i < LBR_TIME_SAMPLES / 8; i++, samples += 8) { float accum[8] = { 0 }; for (int sb = 2; sb < 6; sb++) { float *other = &lbr->time_samples[ch][sb][LBR_TIME_HISTORY + i * 8]; for (j = 0; j < 8; j++) accum[j] += fabs(other[j]); } for (j = 0; j < 8; j++) samples[j] = (accum[j] * 0.25 + 0.5) * lbr_rand(lbr, sb); } } } } static void predict(float *samples, const float *coeff, int nsamples) { for (int i = 0; i < nsamples; i++) { double res = 0.0; for (int j = 0; j < 8; j++) res += coeff[j] * samples[i - j - 1]; samples[i] -= res; } } static void synth_lpc(struct lbr_decoder *lbr, int ch, int sb) { float *samples = &lbr->time_samples[ch][sb][LBR_TIME_HISTORY]; int f = lbr->framenum & 1; if (!(lbr->ch_pres[ch] & (1U << sb))) return; if (sb < 2) { predict(samples, lbr->lpc_coeff[ch][sb][f^1][1], 16); predict(samples + 16, lbr->lpc_coeff[ch][sb][f ][0], 64); predict(samples + 80, lbr->lpc_coeff[ch][sb][f ][1], 48); } else { predict(samples, lbr->lpc_coeff[ch][sb][f^1][0], 16); predict(samples + 16, lbr->lpc_coeff[ch][sb][f ][0], 112); } } static void filter_ts(struct lbr_decoder *lbr, int ch1, int ch2) { int i, j; for (int sb = 0; sb < lbr->nsubbands; sb++) { // Scale factors for (int ch = ch1; ch <= ch2; ch++) { float *samples = &lbr->time_samples[ch][sb][LBR_TIME_HISTORY]; uint8_t *hr_scf = lbr->high_res_scf[ch][sb]; if (sb < 4) { for (i = 0; i < LBR_TIME_SAMPLES / 16; i++, samples += 16) { unsigned int scf = hr_scf[i]; if (scf > 56) scf = 56; for (j = 0; j < 16; j++) samples[j] *= quant_amp[scf]; } } else { uint8_t *g2_scf = lbr->grid_2_scf[ch][scf_to_grid_2[sb]]; for (i = 0; i < LBR_TIME_SAMPLES / 2; i++, samples += 2) { unsigned int scf = hr_scf[i / 8] - g2_scf[i]; if (scf > 56) scf = 56; samples[0] *= quant_amp[scf]; samples[1] *= quant_amp[scf]; } } } // Mid-side stereo if (ch1 != ch2) { float *samples_l = &lbr->time_samples[ch1][sb][LBR_TIME_HISTORY]; float *samples_r = &lbr->time_samples[ch2][sb][LBR_TIME_HISTORY]; int ch2_pres = lbr->ch_pres[ch2] & (1U << sb); for (i = 0; i < LBR_TIME_SAMPLES / 16; i++) { int sbms = (lbr->sec_ch_sbms[ch1 / 2][sb] >> i) & 1; int lrms = (lbr->sec_ch_lrms[ch1 / 2][sb] >> i) & 1; if (sb >= lbr->min_mono_subband) { if (lrms && ch2_pres) { if (sbms) { for (j = 0; j < 16; j++) { float tmp = samples_l[j]; samples_l[j] = samples_r[j]; samples_r[j] = -tmp; } } else { for (j = 0; j < 16; j++) { float tmp = samples_l[j]; samples_l[j] = samples_r[j]; samples_r[j] = tmp; } } } else if (!ch2_pres) { if (sbms && (lbr->part_stereo_pres & (1 << ch1))) { for (j = 0; j < 16; j++) samples_r[j] = -samples_l[j]; } else { for (j = 0; j < 16; j++) samples_r[j] = samples_l[j]; } } } else if (sbms && ch2_pres) { for (j = 0; j < 16; j++) { float tmp = samples_l[j]; samples_l[j] = (tmp + samples_r[j]) * 0.5; samples_r[j] = (tmp - samples_r[j]) * 0.5; } } samples_l += 16; samples_r += 16; } } // Inverse prediciton if (sb < 3) { synth_lpc(lbr, ch1, sb); if (ch1 != ch2) synth_lpc(lbr, ch2, sb); } } } static void decode_part_stereo(struct lbr_decoder *lbr, int ch1, int ch2) { for (int ch = ch1; ch <= ch2; ch++) { for (int sb = lbr->min_mono_subband; sb < lbr->nsubbands; sb++) { if (lbr->ch_pres[ch2] & (1U << sb)) continue; float *samples = &lbr->time_samples[ch][sb][LBR_TIME_HISTORY]; int pt_sb = (sb - lbr->min_mono_subband) / 4; for (int sf = 1; sf <= 4; sf++) { float prev = st_coeff[lbr->part_stereo[ch][pt_sb][sf - 1]]; float next = st_coeff[lbr->part_stereo[ch][pt_sb][sf ]]; for (int i = 0; i < 32; i++) samples[i] *= (32 - i) * prev + i * next; samples += 32; } } } } static void decode_spatial_info(struct lbr_decoder *lbr, int ch1, int ch2) { int ch_pres = ~lbr->ch_pres[ch1] | lbr->ch_pres[ch2]; for (int sb = 0; sb < lbr->nsubbands; sb++) { if (ch_pres & (1U << sb)) continue; float *samples_l = &lbr->time_samples[ch1][sb][LBR_TIME_HISTORY]; float *samples_r = &lbr->time_samples[ch2][sb][LBR_TIME_HISTORY]; for (int sf = 1; sf <= 4; sf++) { float prev = st_coeff[lbr->spatial_info[ch2 - 2][sb / 4][sf - 1]]; float next = st_coeff[lbr->spatial_info[ch2 - 2][sb / 4][sf ]]; for (int i = 0; i < 32; i++) samples_r[i] = ((32 - i) * prev + i * next) * samples_l[i]; samples_l += 32; samples_r += 32; } } } static void synth_tones(struct lbr_decoder *lbr, int ch, float *values, int group, int group_sf, int synth_idx) { if (synth_idx < 0) return; int start = lbr->tonal_bounds[group][group_sf][0]; int count = (lbr->tonal_bounds[group][group_sf][1] - start) & (LBR_TONES - 1); for (int i = 0; i < count; i++) { struct lbr_tone *t = &lbr->tones[(start + i) & (LBR_TONES - 1)]; if (t->amp[ch]) { float amp = synth_env[synth_idx] * quant_amp[t->amp[ch]]; float s = amp * lbr->sin_tab[(t->phs[ch] ) & 255]; float c = amp * lbr->sin_tab[(t->phs[ch] + 64) & 255]; const float *cf = corr_cf[t->f_delt]; int x_freq = t->x_freq; switch (x_freq) { case 0: goto p0; case 1: values[3] += cf[0] * -c; values[2] += cf[1] * s; values[1] += cf[2] * c; values[0] += cf[3] * -s; goto p1; case 2: values[2] += cf[0] * -c; values[1] += cf[1] * s; values[0] += cf[2] * c; goto p2; case 3: values[1] += cf[0] * -c; values[0] += cf[1] * s; goto p3; case 4: values[0] += cf[0] * -c; goto p4; } values[x_freq - 5] += cf[ 0] * -c; p4: values[x_freq - 4] += cf[ 1] * s; p3: values[x_freq - 3] += cf[ 2] * c; p2: values[x_freq - 2] += cf[ 3] * -s; p1: values[x_freq - 1] += cf[ 4] * -c; p0: values[x_freq ] += cf[ 5] * s; values[x_freq + 1] += cf[ 6] * c; values[x_freq + 2] += cf[ 7] * -s; values[x_freq + 3] += cf[ 8] * -c; values[x_freq + 4] += cf[ 9] * s; values[x_freq + 5] += cf[10] * c; } t->phs[ch] += t->ph_rot; } } static void base_func_synth(struct lbr_decoder *lbr, int ch, float *values, int sf) { for (int group = 0; group < 5; group++) { int group_sf = (lbr->framenum << group) + ((sf - 22) >> (5 - group)); int synth_idx = ((((sf - 22) & 31) << group) & 31) + (1 << group) - 1; synth_tones(lbr, ch, values, group, (group_sf - 1) & 31, 30 - synth_idx); synth_tones(lbr, ch, values, group, (group_sf ) & 31, synth_idx); } } #define SW0 0.022810893 #define SW1 0.41799772 #define SW2 0.9084481 #define SW3 0.99973983 #define C1 0.068974845 #define C2 0.34675997 #define C3 0.29396889 #define C4 0.19642374 #define AL1 0.30865827 #define AL2 0.038060233 static void transform_channel(struct lbr_decoder *lbr, int ch) { float values[LBR_SUBBANDS * 2][4]; int *output = lbr->channel_buffer[ch]; int noutsubbands = 8 << lbr->freq_range; int step = 1 << (2 - lbr->freq_range); int i, sf, nsubbands = lbr->nsubbands; for (sf = 0; sf < LBR_TIME_SAMPLES / 4; sf++) { // Short window and 8 point forward MDCT for (i = 0; i < nsubbands; i++) { float *samples = &lbr->time_samples[ch][i][LBR_TIME_HISTORY + sf * 4]; float a = samples[-4] * SW0 - samples[-1] * SW3; float b = samples[-3] * SW1 - samples[-2] * SW2; float c = samples[ 2] * SW1 + samples[ 1] * SW2; float d = samples[ 3] * SW0 + samples[ 0] * SW3; values[i][0] = C1 * b - C2 * c + C4 * a - C3 * d; values[i][1] = C1 * d - C2 * a - C4 * b - C3 * c; values[i][2] = C3 * b + C2 * d - C4 * c + C1 * a; values[i][3] = C3 * a - C2 * b + C4 * d - C1 * c; } // Aliasing cancellation for high frequencies for (i = 12; i < nsubbands - 1; i++) { float a = values[i ][3] * AL1; float b = values[i+1][0] * AL1; values[i ][3] += b - a; values[i+1][0] -= b + a; a = values[i ][2] * AL2; b = values[i+1][1] * AL2; values[i ][2] += b - a; values[i+1][1] -= b + a; } // Clear inactive subbands if (nsubbands < noutsubbands) memset(values[nsubbands], 0, (noutsubbands - nsubbands) * sizeof(values[0])); base_func_synth(lbr, ch, values[0], sf); imdct_fast(lbr->imdct, values[0], values[0]); // Long window and overlap-add const float *w1 = &long_window[0]; const float *w2 = &long_window[128 - 4 * step]; float *history = lbr->imdct_history[ch]; for (i = 0; i < noutsubbands; i++) { output[0] = lrintf(w1[0 * step] * values[i][0] + history[0]); output[1] = lrintf(w1[1 * step] * values[i][1] + history[1]); output[2] = lrintf(w1[2 * step] * values[i][2] + history[2]); output[3] = lrintf(w1[3 * step] * values[i][3] + history[3]); history[0] = w2[3 * step] * values[noutsubbands + i][0]; history[1] = w2[2 * step] * values[noutsubbands + i][1]; history[2] = w2[1 * step] * values[noutsubbands + i][2]; history[3] = w2[0 * step] * values[noutsubbands + i][3]; output += 4; history += 4; w1 += 4 * step; w2 -= 4 * step; } } // Update history for LPC and forward MDCT for (i = 0; i < nsubbands; i++) { float *samples = lbr->time_samples[ch][i]; memcpy(samples, samples + LBR_TIME_SAMPLES, LBR_TIME_HISTORY * sizeof(*samples)); } } #define LFE_IIR_SCALE (64 * 0x7fffff * 0.0000078265894) static void interpolate_lfe(struct lbr_decoder *lbr) { int *output = lbr->output_samples[SPEAKER_LFE1]; for (int i = 0; i < 64; i++) { float res1 = lbr->lfe_data[i] * LFE_IIR_SCALE; float res2; for (int j = 0; j < 64; j++) { for (int k = 0; k < 5; k++) { float tmp1 = lbr->lfe_history[k][0]; float tmp2 = lbr->lfe_history[k][1]; res2 = tmp1 * lfe_iir[k][0] + tmp2 * lfe_iir[k][1] + res1; res1 = tmp1 * lfe_iir[k][2] + tmp2 * lfe_iir[k][3] + res2; lbr->lfe_history[k][0] = tmp2; lbr->lfe_history[k][1] = res2; } *output++ = lrintf(res1); res1 = 0.0; } } } int lbr_filter(struct lbr_decoder *lbr) { if (lbr->undo_dmix) { random_ts(lbr, LBR_CHANNELS - 2); random_ts(lbr, LBR_CHANNELS - 1); } for (int pair = 0; pair < (lbr->nchannels + 1) / 2; pair++) { int ch1 = pair * 2; int ch2 = DCA_MIN(ch1 + 1, lbr->nchannels - 1); decode_grid(lbr, ch1); if (ch1 != ch2) decode_grid(lbr, ch2); if (lbr->undo_dmix) { replace_ts(lbr, ch1); if (ch1 != ch2) replace_ts(lbr, ch2); } random_ts(lbr, ch1); if (ch1 != ch2) random_ts(lbr, ch2); filter_ts(lbr, ch1, ch2); if (ch1 != ch2 && (lbr->part_stereo_pres & (1 << ch1)) && 1) decode_part_stereo(lbr, ch1, ch2); if (ch1 >= 2 && (lbr->spatial_info_pres & (1 << ch1)) && 0) { decode_spatial_info(lbr, 0, ch1); if (ch1 != ch2 && (lbr->spatial_info_pres & (1 << ch2))) decode_spatial_info(lbr, 1, ch2); } transform_channel(lbr, ch1); if (ch1 != ch2) transform_channel(lbr, ch2); } int ch = 0; lbr->output_mask = 0; if (lbr->ch_mask & SPEAKER_PAIR_LR) { lbr->output_samples[SPEAKER_L] = lbr->channel_buffer[ch++]; lbr->output_samples[SPEAKER_R] = lbr->channel_buffer[ch++]; lbr->output_mask |= SPEAKER_MASK_L | SPEAKER_MASK_R; } if (lbr->ch_mask & SPEAKER_PAIR_LsRs) { lbr->output_samples[SPEAKER_Ls] = lbr->channel_buffer[ch++]; lbr->output_samples[SPEAKER_Rs] = lbr->channel_buffer[ch++]; lbr->output_mask |= SPEAKER_MASK_Ls | SPEAKER_MASK_Rs; } if (lbr->ch_mask & SPEAKER_PAIR_C) { lbr->output_samples[SPEAKER_C] = lbr->channel_buffer[ch++]; lbr->output_mask |= SPEAKER_MASK_C; } if (lbr->flags & LBR_FLAG_LFE_PRESENT) { lbr->output_samples[SPEAKER_LFE1] = lbr->channel_buffer[ch++]; lbr->output_mask |= SPEAKER_MASK_LFE1; interpolate_lfe(lbr); } return 0; } void lbr_clear(struct lbr_decoder *lbr) { if (lbr) { memset(lbr->part_stereo, 16, sizeof(lbr->part_stereo)); memset(lbr->spatial_info, 16, sizeof(lbr->spatial_info)); memset(lbr->lpc_coeff, 0, sizeof(lbr->lpc_coeff)); memset(lbr->time_samples, 0, sizeof(lbr->time_samples)); memset(lbr->imdct_history, 0, sizeof(lbr->imdct_history)); memset(lbr->tonal_bounds, 0, sizeof(lbr->tonal_bounds)); memset(lbr->lfe_history, 0, sizeof(lbr->lfe_history)); lbr->framenum = 0; lbr->ntones = 0; } } ================================================ FILE: libdcadec/lbr_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 LBR_DECODER_H #define LBR_DECODER_H #define LBR_CHANNELS 8 #define LBR_SUBBANDS 32 #define LBR_TONES 512 #define LBR_TIME_SAMPLES 128 #define LBR_TIME_HISTORY 8 #define lbr_err(...) dca_log(lbr, ERROR, __VA_ARGS__) #define lbr_warn(...) dca_log(lbr, WARNING, __VA_ARGS__) #define lbr_info(...) dca_log(lbr, INFO, __VA_ARGS__) #define lbr_debug(...) dca_log(lbr, DEBUG, __VA_ARGS__) struct exss_asset; struct bitstream2 { uint8_t *data; int index; uint32_t accum; int avail; int count; }; struct lbr_tone { uint8_t x_freq; uint8_t f_delt; uint8_t ph_rot; uint8_t pad; uint8_t amp[LBR_CHANNELS]; uint8_t phs[LBR_CHANNELS]; }; struct lbr_decoder { struct dcadec_context *ctx; ///< Parent context struct bitstream2 bits; ///< Bitstream reader int ctx_flags; int sample_rate; int ch_mask; int flags; int bit_rate_orig; int bit_rate_scaled; int nchannels; int nchannels_total; int undo_dmix; int freq_range; int band_limit; int limited_rate; int limited_range; int res_profile; int nsubbands; int g3_avg_only_start_sb; int min_mono_subband; int max_mono_subband; int framenum; int lbr_rand; uint8_t can_replace_sf[LBR_CHANNELS * LBR_SUBBANDS * 4 / 8]; uint8_t can_replace_ch[LBR_CHANNELS * LBR_SUBBANDS * 4 / 8]; uint8_t quant_levels[LBR_CHANNELS / 2][LBR_SUBBANDS]; uint8_t sb_indices[LBR_SUBBANDS]; uint8_t sec_ch_sbms[LBR_CHANNELS / 2][LBR_SUBBANDS]; uint8_t sec_ch_lrms[LBR_CHANNELS / 2][LBR_SUBBANDS]; uint32_t ch_pres[LBR_CHANNELS]; uint8_t grid_1_scf[LBR_CHANNELS][12][8]; uint8_t grid_2_scf[LBR_CHANNELS][6][64]; int8_t grid_3_avg[LBR_CHANNELS][28]; int8_t grid_3_scf[LBR_CHANNELS][28][8]; uint32_t grid_3_pres[LBR_CHANNELS]; uint8_t high_res_scf[LBR_CHANNELS][LBR_SUBBANDS][8]; uint8_t part_stereo[LBR_CHANNELS][LBR_SUBBANDS / 4][5]; uint8_t spatial_info[LBR_CHANNELS - 2][LBR_SUBBANDS / 4][5]; uint8_t part_stereo_pres; uint8_t spatial_info_pres; float lpc_coeff[LBR_CHANNELS][3][2][2][8]; float sb_scf[LBR_SUBBANDS]; float time_samples[LBR_CHANNELS][LBR_SUBBANDS][LBR_TIME_HISTORY + LBR_TIME_SAMPLES]; float imdct_history[LBR_CHANNELS][LBR_SUBBANDS * 4]; uint8_t tonal_scf[6]; uint16_t tonal_bounds[5][32][2]; struct lbr_tone tones[LBR_TONES]; int ntones; float lfe_data[64]; float lfe_history[5][2]; struct idct_context *imdct; float sin_tab[256]; float lpc_tab[16]; int channel_buffer[LBR_CHANNELS][LBR_TIME_SAMPLES * LBR_SUBBANDS]; int *output_samples[SPEAKER_COUNT]; int output_mask; }; int lbr_parse(struct lbr_decoder *lbr, uint8_t *data, size_t size, struct exss_asset *asset); int lbr_filter(struct lbr_decoder *lbr); void lbr_clear(struct lbr_decoder *lbr) __attribute__((cold)); #endif ================================================ FILE: libdcadec/lbr_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 */ static const uint8_t huff_tnl_grp_0[] = { 0x01, 0x38, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x05, 0xFF, 0x04, 0x01, 0x26, 0x01, 0x24, 0x01, 0x22, 0x01, 0x20, 0x01, 0x18, 0x01, 0x02, 0xFF, 0x13, 0x01, 0x14, 0x01, 0x06, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x21, 0xFF, 0x1F, 0xFF, 0x1C, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x22, 0xFF, 0x25, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x23, 0xFF, 0x00, 0xFF, 0x24, 0xFF, 0x20, 0xFF, 0x1E, 0xFF, 0x18, 0x01, 0x02, 0xFF, 0x16, 0x01, 0x02, 0xFF, 0x17, 0x01, 0x02, 0xFF, 0x1D, 0xFF, 0x1B, 0xFF, 0x11, 0xFF, 0x0E, 0xFF, 0x07, 0x01, 0x0C, 0x01, 0x02, 0xFF, 0x0C, 0x01, 0x02, 0xFF, 0x01, 0x01, 0x06, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x1A, 0xFF, 0x03, 0xFF, 0x19, 0xFF, 0x14, 0xFF, 0x08, 0x01, 0x0E, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0A, 0xFF, 0x0D, 0x01, 0x08, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0F, 0xFF, 0x10, 0x01, 0x02, 0xFF, 0x12, 0xFF, 0x15, 0xFF, 0x0B, 0x01, 0x02, 0xFF, 0x09, 0xFF, 0x06 }; static const uint8_t huff_tnl_grp_1[] = { 0x01, 0x30, 0x01, 0x16, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x04, 0xFF, 0x07, 0x01, 0x02, 0xFF, 0x0A, 0x01, 0x0E, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x08, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x03, 0xFF, 0x1B, 0x01, 0x02, 0xFF, 0x1D, 0xFF, 0x1C, 0xFF, 0x16, 0xFF, 0x15, 0xFF, 0x0F, 0xFF, 0x0E, 0x01, 0x18, 0x01, 0x02, 0xFF, 0x08, 0x01, 0x14, 0x01, 0x02, 0xFF, 0x10, 0x01, 0x02, 0xFF, 0x13, 0x01, 0x02, 0xFF, 0x17, 0x01, 0x02, 0xFF, 0x1A, 0x01, 0x02, 0xFF, 0x1E, 0x01, 0x08, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x21, 0x01, 0x02, 0xFF, 0x22, 0xFF, 0x00, 0xFF, 0x20, 0xFF, 0x1F, 0xFF, 0x0C, 0xFF, 0x05, 0x01, 0x0E, 0x01, 0x02, 0xFF, 0x09, 0x01, 0x02, 0xFF, 0x01, 0x01, 0x08, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x14, 0x01, 0x02, 0xFF, 0x19, 0xFF, 0x18, 0xFF, 0x12, 0xFF, 0x11, 0x01, 0x02, 0xFF, 0x06, 0x01, 0x02, 0xFF, 0x0B, 0xFF, 0x0D }; static const uint8_t huff_tnl_grp_2[] = { 0x01, 0x38, 0x01, 0x1C, 0x01, 0x18, 0x01, 0x16, 0x01, 0x14, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0E, 0xFF, 0x11, 0x01, 0x02, 0xFF, 0x0F, 0x01, 0x0C, 0x01, 0x02, 0xFF, 0x17, 0x01, 0x02, 0xFF, 0x1C, 0x01, 0x02, 0xFF, 0x1D, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x1E, 0xFF, 0x00, 0xFF, 0x1F, 0xFF, 0x19, 0xFF, 0x0A, 0xFF, 0x08, 0x01, 0x02, 0xFF, 0x09, 0xFF, 0x04, 0x01, 0x1A, 0x01, 0x0E, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x16, 0xFF, 0x03, 0x01, 0x02, 0xFF, 0x15, 0x01, 0x02, 0xFF, 0x1A, 0xFF, 0x1B, 0xFF, 0x0C, 0xFF, 0x0B, 0x01, 0x0A, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x10, 0xFF, 0x12, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x14, 0xFF, 0x18, 0xFF, 0x13, 0xFF, 0x0D, 0xFF, 0x05, 0x01, 0x02, 0xFF, 0x01, 0x01, 0x02, 0xFF, 0x06, 0xFF, 0x07 }; static const uint8_t huff_tnl_grp_3[] = { 0x01, 0x36, 0x01, 0x22, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x08, 0xFF, 0x02, 0x01, 0x02, 0xFF, 0x07, 0x01, 0x02, 0xFF, 0x17, 0xFF, 0x0C, 0xFF, 0x05, 0x01, 0x10, 0x01, 0x0E, 0x01, 0x02, 0xFF, 0x0A, 0x01, 0x0A, 0x01, 0x02, 0xFF, 0x14, 0x01, 0x02, 0xFF, 0x19, 0x01, 0x02, 0xFF, 0x1A, 0x01, 0x02, 0xFF, 0x1B, 0xFF, 0x00, 0xFF, 0x16, 0xFF, 0x09, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0D, 0xFF, 0x11, 0xFF, 0x04, 0x01, 0x12, 0x01, 0x0A, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x0E, 0x01, 0x02, 0xFF, 0x13, 0xFF, 0x18, 0x01, 0x02, 0xFF, 0x03, 0xFF, 0x0B, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x15, 0xFF, 0x12, 0x01, 0x02, 0xFF, 0x10, 0xFF, 0x0F, 0xFF, 0x06, 0xFF, 0x01 }; static const uint8_t huff_tnl_grp_4[] = { 0x01, 0x2C, 0x01, 0x02, 0xFF, 0x02, 0x01, 0x12, 0x01, 0x10, 0x01, 0x08, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x07, 0x01, 0x02, 0xFF, 0x0F, 0xFF, 0x15, 0xFF, 0x03, 0x01, 0x02, 0xFF, 0x06, 0x01, 0x02, 0xFF, 0x0D, 0x01, 0x02, 0xFF, 0x0E, 0xFF, 0x12, 0xFF, 0x04, 0x01, 0x08, 0x01, 0x02, 0xFF, 0x05, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0B, 0xFF, 0x0A, 0xFF, 0x14, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x08, 0x01, 0x02, 0xFF, 0x0C, 0x01, 0x02, 0xFF, 0x10, 0x01, 0x02, 0xFF, 0x16, 0xFF, 0x00, 0xFF, 0x11, 0xFF, 0x13, 0x01, 0x02, 0xFF, 0x08, 0xFF, 0x09, 0xFF, 0x01 }; static const uint8_t huff_tnl_scf[] = { 0x01, 0x1A, 0x01, 0x16, 0x01, 0x02, 0xFF, 0x03, 0x01, 0x12, 0x01, 0x10, 0x01, 0x02, 0xFF, 0x0B, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x02, 0xFF, 0x10, 0x01, 0x02, 0xFF, 0x11, 0x01, 0x02, 0xFF, 0x12, 0x01, 0x02, 0xFF, 0x13, 0xFF, 0x00, 0xFF, 0x0F, 0xFF, 0x0E, 0xFF, 0x09, 0xFF, 0x07, 0x01, 0x02, 0xFF, 0x02, 0xFF, 0x04, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x01, 0xFF, 0x05, 0x01, 0x08, 0x01, 0x06, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0C, 0xFF, 0x0D, 0xFF, 0x0A, 0xFF, 0x08, 0xFF, 0x06 }; static const uint8_t huff_damp[] = { 0x01, 0x0C, 0x01, 0x02, 0xFF, 0x02, 0x01, 0x02, 0xFF, 0x03, 0x01, 0x02, 0xFF, 0x04, 0x01, 0x02, 0xFF, 0x05, 0x01, 0x02, 0xFF, 0x06, 0xFF, 0x00, 0xFF, 0x01 }; static const uint8_t huff_dph[] = { 0x01, 0x04, 0x01, 0x02, 0xFF, 0x02, 0xFF, 0x01, 0x01, 0x0C, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x03, 0xFF, 0x07, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x06, 0x01, 0x02, 0xFF, 0x05, 0xFF, 0x00, 0xFF, 0x04, 0xFF, 0x08 }; static const uint8_t huff_fst_rsd_amp[] = { 0x01, 0x26, 0x01, 0x1C, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0C, 0xFF, 0x11, 0x01, 0x06, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x01, 0xFF, 0x08, 0xFF, 0x09, 0x01, 0x06, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x14, 0xFF, 0x03, 0xFF, 0x05, 0x01, 0x02, 0xFF, 0x06, 0x01, 0x02, 0xFF, 0x02, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x16, 0x01, 0x02, 0xFF, 0x17, 0xFF, 0x00, 0xFF, 0x15, 0x01, 0x08, 0x01, 0x02, 0xFF, 0x0B, 0x01, 0x02, 0xFF, 0x13, 0x01, 0x02, 0xFF, 0x07, 0xFF, 0x04, 0xFF, 0x10, 0x01, 0x06, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x0A, 0xFF, 0x12, 0xFF, 0x0F, 0x01, 0x02, 0xFF, 0x0D, 0xFF, 0x0E }; static const uint8_t huff_rsd_apprx[] = { 0x01, 0x02, 0xFF, 0x01, 0x01, 0x02, 0xFF, 0x02, 0x01, 0x02, 0xFF, 0x03, 0x01, 0x02, 0xFF, 0x04, 0x01, 0x02, 0xFF, 0x05, 0xFF, 0x00 }; static const uint8_t huff_rsd_amp[] = { 0x01, 0x20, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x02, 0xFF, 0x01, 0x01, 0x02, 0xFF, 0x05, 0x01, 0x18, 0x01, 0x16, 0x01, 0x12, 0x01, 0x0C, 0x01, 0x02, 0xFF, 0x0E, 0x01, 0x02, 0xFF, 0x14, 0x01, 0x02, 0xFF, 0x1A, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x19, 0xFF, 0x20, 0xFF, 0x13, 0x01, 0x02, 0xFF, 0x10, 0x01, 0x02, 0xFF, 0x18, 0xFF, 0x11, 0x01, 0x02, 0xFF, 0x0C, 0xFF, 0x0D, 0xFF, 0x09, 0xFF, 0x07, 0x01, 0x02, 0xFF, 0x03, 0x01, 0x02, 0xFF, 0x04, 0x01, 0x1C, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x08, 0xFF, 0x0B, 0x01, 0x16, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x12, 0xFF, 0x0F, 0x01, 0x10, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x02, 0xFF, 0x1E, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x24, 0xFF, 0x22, 0x01, 0x02, 0xFF, 0x1D, 0xFF, 0x00, 0xFF, 0x15, 0x01, 0x02, 0xFF, 0x1C, 0xFF, 0x17, 0xFF, 0x16, 0xFF, 0x0A, 0xFF, 0x06 }; static const uint8_t huff_avg_g3[] = { 0x01, 0x20, 0x01, 0x1E, 0x01, 0x0A, 0x01, 0x02, 0xFF, 0x0E, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x0B, 0x01, 0x02, 0xFF, 0x13, 0xFF, 0x09, 0xFF, 0x0D, 0x01, 0x12, 0x01, 0x10, 0x01, 0x02, 0xFF, 0x0A, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x14, 0xFF, 0x08, 0x01, 0x08, 0x01, 0x06, 0x01, 0x02, 0xFF, 0x06, 0x01, 0x02, 0xFF, 0x17, 0xFF, 0x00, 0xFF, 0x15, 0xFF, 0x07, 0xFF, 0x0C, 0xFF, 0x12, 0xFF, 0x10, 0x01, 0x02, 0xFF, 0x0F, 0xFF, 0x11 }; static const uint8_t huff_st_grid[] = { 0x01, 0x2A, 0x01, 0x28, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x04, 0xFF, 0x03, 0x01, 0x02, 0xFF, 0x08, 0x01, 0x20, 0x01, 0x0A, 0x01, 0x08, 0x01, 0x02, 0xFF, 0x0E, 0x01, 0x02, 0xFF, 0x07, 0x01, 0x02, 0xFF, 0x09, 0xFF, 0x16, 0xFF, 0x0C, 0x01, 0x14, 0x01, 0x0E, 0x01, 0x02, 0xFF, 0x10, 0x01, 0x02, 0xFF, 0x0B, 0x01, 0x02, 0xFF, 0x0D, 0x01, 0x04, 0x01, 0x02, 0xFF, 0x11, 0xFF, 0x0F, 0x01, 0x02, 0xFF, 0x18, 0xFF, 0x00, 0x01, 0x02, 0xFF, 0x12, 0x01, 0x02, 0xFF, 0x14, 0xFF, 0x02, 0xFF, 0x05, 0xFF, 0x0A, 0xFF, 0x01, 0xFF, 0x06 }; static const uint8_t * const huff_tnl_grp[] = { huff_tnl_grp_0, huff_tnl_grp_1, huff_tnl_grp_2, huff_tnl_grp_3, huff_tnl_grp_4 }; static const size_t huff_tnl_size[] = { sizeof(huff_tnl_grp_0), sizeof(huff_tnl_grp_1), sizeof(huff_tnl_grp_2), sizeof(huff_tnl_grp_3), sizeof(huff_tnl_grp_4) }; ================================================ FILE: libdcadec/lbr_tables.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 */ static const uint16_t fst_amp[44] = { 0, 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 36, 44, 52, 60, 76, 92, 108, 124, 156, 188, 220, 252, 316, 380, 444, 508, 636, 764, 892, 1020, 1276, 1532, 1788, 2044, 2556, 3068, 3580, 4092, 5116, 6140, 7164 }; static const uint8_t freq_to_sf[32] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; static const int8_t ph0_shift[8] = { -32, +96, -96, +32, +96, -32, +32, -96 }; static const uint8_t bits_for_ch_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }; static const uint8_t grid_1_to_scf[11] = { 0, 1, 2, 3, 4, 6, 7, 10, 14, 19, 26 }; static const uint8_t grid_2_to_scf[3] = { 4, 10, 18 }; static const uint8_t scf_to_grid_1[32] = { 0, 1, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10 }; static const uint8_t scf_to_grid_2[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; static const uint8_t grid_2_codes_1[32] = { 66, 99, 65, 64, 66, 132, 65, 64, 66, 99, 65, 64, 66, 165, 65, 64, 66, 99, 65, 64, 66, 132, 65, 64, 66, 99, 65, 64, 66, 191, 65, 64 }; static const uint8_t grid_2_codes_2[16] = { 159, 38, 71, 38, 104, 38, 71, 38, 137, 38, 71, 38, 104, 38, 71, 38 }; static const uint8_t grid_2_codes_3[32] = { 74, 178, 108, 75, 74, 142, 112, 75, 74, 145, 108, 75, 74, 175, 112, 75, 74, 173, 108, 75, 74, 142, 112, 75, 74, 145, 108, 75, 74, 191, 112, 75 }; static const uint8_t grid_3_codes_1[32] = { 113, 48, 79, 48, 142, 48, 79, 48, 113, 48, 79, 48, 178, 48, 79, 48, 113, 48, 79, 48, 142, 48, 79, 48, 113, 48, 79, 48, 191, 48, 79, 48 }; static const uint8_t grid_3_codes_2[8] = { 45, 108, 45, 83, 45, 127, 45, 83 }; static const uint8_t grid_3_codes_3[16] = { 75, 52, 138, 52, 75, 52, 117, 52, 75, 52, 159, 52, 75, 52, 117, 52 }; static const uint8_t grid_1_weights[12][32] = { { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 0, 0, 128, 85, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 0, 0, 0, 43, 85, 128, 96, 64, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 64, 96, 128, 102, 77, 51, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 51, 77, 102, 128, 107, 85, 64, 43, 21, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 43, 64, 85, 107, 128, 110, 91, 73, 55, 37, 18, 0, }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 37, 55, 73, 91, 110, 128, } }; static const uint8_t sb_reorder[8][8] = { { 0, 1, 2, 3, 4, 5, 6, 7 }, { 1, 0, 2, 3, 4, 5, 6, 7 }, { 3, 1, 0, 2, 4, 5, 6, 7 }, { 1, 2, 3, 0, 4, 5, 6, 7 }, { 1, 2, 5, 3, 0, 4, 6, 7 }, { 1, 2, 2, 5, 3, 0, 4, 6 }, { 1, 2, 2, 6, 5, 3, 0, 4 }, { 1, 2, 2, 6, 5, 4, 0, 3 } }; static const int8_t lfe_delta_index_16[8] = { -4, -3, -2, -1, 2, 4, 6, 8 }; static const int8_t lfe_delta_index_24[32] = { -8, -8, -7, -7, -6, -6, -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 }; static const uint8_t residual_code_len[64] = { 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 3, 2, 6, 2, 3, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 3, 2, 6, 2, 3, 2 }; static const uint8_t residual_code_val[64] = { 1, 2, 4, 3, 5, 2, 0, 3, 1, 2, 4, 3, 6, 2, 0, 3, 1, 2, 4, 3, 5, 2, 0, 3, 1, 2, 4, 3, 7, 2, 0, 3, 1, 2, 4, 3, 5, 2, 0, 3, 1, 2, 4, 3, 6, 2, 0, 3, 1, 2, 4, 3, 5, 2, 0, 3, 1, 2, 4, 3, 4, 2, 0, 3 }; static const uint16_t residual_pack_5_in_8[256] = { 0x0000, 0x0100, 0x0200, 0x0040, 0x0140, 0x0240, 0x0080, 0x0180, 0x0280, 0x0010, 0x0110, 0x0210, 0x0050, 0x0150, 0x0250, 0x0090, 0x0190, 0x0290, 0x0020, 0x0120, 0x0220, 0x0060, 0x0160, 0x0260, 0x00a0, 0x01a0, 0x02a0, 0x0004, 0x0104, 0x0204, 0x0044, 0x0144, 0x0244, 0x0084, 0x0184, 0x0284, 0x0014, 0x0114, 0x0214, 0x0054, 0x0154, 0x0254, 0x0094, 0x0194, 0x0294, 0x0024, 0x0124, 0x0224, 0x0064, 0x0164, 0x0264, 0x00a4, 0x01a4, 0x02a4, 0x0008, 0x0108, 0x0208, 0x0048, 0x0148, 0x0248, 0x0088, 0x0188, 0x0288, 0x0018, 0x0118, 0x0218, 0x0058, 0x0158, 0x0258, 0x0098, 0x0198, 0x0298, 0x0028, 0x0128, 0x0228, 0x0068, 0x0168, 0x0268, 0x00a8, 0x01a8, 0x02a8, 0x0001, 0x0101, 0x0201, 0x0041, 0x0141, 0x0241, 0x0081, 0x0181, 0x0281, 0x0011, 0x0111, 0x0211, 0x0051, 0x0151, 0x0251, 0x0091, 0x0191, 0x0291, 0x0021, 0x0121, 0x0221, 0x0061, 0x0161, 0x0261, 0x00a1, 0x01a1, 0x02a1, 0x0005, 0x0105, 0x0205, 0x0045, 0x0145, 0x0245, 0x0085, 0x0185, 0x0285, 0x0015, 0x0115, 0x0215, 0x0055, 0x0155, 0x0255, 0x0095, 0x0195, 0x0295, 0x0025, 0x0125, 0x0225, 0x0065, 0x0165, 0x0265, 0x00a5, 0x01a5, 0x02a5, 0x0009, 0x0109, 0x0209, 0x0049, 0x0149, 0x0249, 0x0089, 0x0189, 0x0289, 0x0019, 0x0119, 0x0219, 0x0059, 0x0159, 0x0259, 0x0099, 0x0199, 0x0299, 0x0029, 0x0129, 0x0229, 0x0069, 0x0169, 0x0269, 0x00a9, 0x01a9, 0x02a9, 0x0002, 0x0102, 0x0202, 0x0042, 0x0142, 0x0242, 0x0082, 0x0182, 0x0282, 0x0012, 0x0112, 0x0212, 0x0052, 0x0152, 0x0252, 0x0092, 0x0192, 0x0292, 0x0022, 0x0122, 0x0222, 0x0062, 0x0162, 0x0262, 0x00a2, 0x01a2, 0x02a2, 0x0006, 0x0106, 0x0206, 0x0046, 0x0146, 0x0246, 0x0086, 0x0186, 0x0286, 0x0016, 0x0116, 0x0216, 0x0056, 0x0156, 0x0256, 0x0096, 0x0196, 0x0296, 0x0026, 0x0126, 0x0226, 0x0066, 0x0166, 0x0266, 0x00a6, 0x01a6, 0x02a6, 0x000a, 0x010a, 0x020a, 0x004a, 0x014a, 0x024a, 0x008a, 0x018a, 0x028a, 0x001a, 0x011a, 0x021a, 0x005a, 0x015a, 0x025a, 0x009a, 0x019a, 0x029a, 0x002a, 0x012a, 0x022a, 0x006a, 0x016a, 0x026a, 0x00aa, 0x01aa, 0x02aa, 0x0003, 0x0103, 0x0203, 0x0043, 0x0143, 0x0243, 0x0083, 0x0183, 0x0283, 0x0013, 0x0113, 0x0213, 0x0053 }; static const uint8_t residual_pack_3_in_7[128][3] = { { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 2 }, { 0, 0, 3 }, { 0, 0, 4 }, { 0, 1, 0 }, { 0, 1, 1 }, { 0, 1, 2 }, { 0, 1, 3 }, { 0, 1, 4 }, { 0, 2, 0 }, { 0, 2, 1 }, { 0, 2, 2 }, { 0, 2, 3 }, { 0, 2, 4 }, { 0, 3, 0 }, { 0, 3, 1 }, { 0, 3, 2 }, { 0, 3, 3 }, { 0, 3, 4 }, { 0, 4, 0 }, { 0, 4, 1 }, { 0, 4, 2 }, { 0, 4, 3 }, { 0, 4, 4 }, { 1, 0, 0 }, { 1, 0, 1 }, { 1, 0, 2 }, { 1, 0, 3 }, { 1, 0, 4 }, { 1, 1, 0 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 3 }, { 1, 1, 4 }, { 1, 2, 0 }, { 1, 2, 1 }, { 1, 2, 2 }, { 1, 2, 3 }, { 1, 2, 4 }, { 1, 3, 0 }, { 1, 3, 1 }, { 1, 3, 2 }, { 1, 3, 3 }, { 1, 3, 4 }, { 1, 4, 0 }, { 1, 4, 1 }, { 1, 4, 2 }, { 1, 4, 3 }, { 1, 4, 4 }, { 2, 0, 0 }, { 2, 0, 1 }, { 2, 0, 2 }, { 2, 0, 3 }, { 2, 0, 4 }, { 2, 1, 0 }, { 2, 1, 1 }, { 2, 1, 2 }, { 2, 1, 3 }, { 2, 1, 4 }, { 2, 2, 0 }, { 2, 2, 1 }, { 2, 2, 2 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 0 }, { 2, 3, 1 }, { 2, 3, 2 }, { 2, 3, 3 }, { 2, 3, 4 }, { 2, 4, 0 }, { 2, 4, 1 }, { 2, 4, 2 }, { 2, 4, 3 }, { 2, 4, 4 }, { 3, 0, 0 }, { 3, 0, 1 }, { 3, 0, 2 }, { 3, 0, 3 }, { 3, 0, 4 }, { 3, 1, 0 }, { 3, 1, 1 }, { 3, 1, 2 }, { 3, 1, 3 }, { 3, 1, 4 }, { 3, 2, 0 }, { 3, 2, 1 }, { 3, 2, 2 }, { 3, 2, 3 }, { 3, 2, 4 }, { 3, 3, 0 }, { 3, 3, 1 }, { 3, 3, 2 }, { 3, 3, 3 }, { 3, 3, 4 }, { 3, 4, 0 }, { 3, 4, 1 }, { 3, 4, 2 }, { 3, 4, 3 }, { 3, 4, 4 }, { 4, 0, 0 }, { 4, 0, 1 }, { 4, 0, 2 }, { 4, 0, 3 }, { 4, 0, 4 }, { 4, 1, 0 }, { 4, 1, 1 }, { 4, 1, 2 }, { 4, 1, 3 }, { 4, 1, 4 }, { 4, 2, 0 }, { 4, 2, 1 }, { 4, 2, 2 }, { 4, 2, 3 }, { 4, 2, 4 }, { 4, 3, 0 }, { 4, 3, 1 }, { 4, 3, 2 }, { 4, 3, 3 }, { 4, 3, 4 }, { 4, 4, 0 }, { 4, 4, 1 }, { 4, 4, 2 }, { 4, 4, 3 }, { 4, 4, 4 }, { 5, 0, 0 }, { 5, 0, 1 }, { 5, 0, 2 } }; static const float residual_level_2a[2] = { -0.47, 0.47 }; static const float residual_level_2b[2] = { -0.645, 0.645 }; static const float residual_level_3[3] = { -0.645, 0.0, 0.645 }; static const float residual_level_5[5] = { -0.875, -0.375, 0.0, 0.375, 0.875 }; static const float residual_level_8[8] = { -1.0, -0.625, -0.291666667, 0.0, 0.25, 0.5, 0.75, 1.0 }; static const float residual_level_16[16] = { -1.3125, -1.1375, -0.9625, -0.7875, -0.6125, -0.4375, -0.2625, -0.0875, 0.0875, 0.2625, 0.4375, 0.6125, 0.7875, 0.9625, 1.1375, 1.3125 }; static const float synth_env[32] = { 0.00240763666390, 0.00960735979838, 0.02152983213390, 0.03806023374436, 0.05903936782582, 0.08426519384873, 0.11349477331863, 0.14644660940673, 0.18280335791818, 0.22221488349020, 0.26430163158700, 0.30865828381746, 0.35485766137277, 0.40245483899194, 0.45099142983522, 0.5, 0.54900857016478, 0.59754516100806, 0.64514233862723, 0.69134171618254, 0.73569836841300, 0.77778511650980, 0.81719664208182, 0.85355339059327, 0.88650522668137, 0.91573480615127, 0.94096063217418, 0.96193976625564, 0.97847016786610, 0.99039264020162, 0.99759236333610, 1.0 }; static const float corr_cf[32][11] = { { -0.01179, 0.04281, 0.46712, 0.46345, -3.94525, 3.94525, -0.46345, -0.46712, -0.04281, 0.01179, -0.00299 }, { -0.00929, 0.04882, 0.45252, 0.37972, -3.85446, 4.03189, -0.55069, -0.4804, -0.03599, 0.01445, -0.00229 }, { -0.00696, 0.05403, 0.43674, 0.29961, -3.75975, 4.11413, -0.64135, -0.49221, -0.02834, 0.01726, -0.00156 }, { -0.00481, 0.05847, 0.41993, 0.22319, -3.66138, 4.19175, -0.73529, -0.50241, -0.01983, 0.02021, -0.0008 }, { -0.00284, 0.06216, 0.40224, 0.15053, -3.55963, 4.26452, -0.83239, -0.51085, -0.01047, 0.02328, -0.00003 }, { -0.00105, 0.06515, 0.38378, 0.08168, -3.45475, 4.33225, -0.93249, -0.51738, -0.00024, 0.02646, 0.00074 }, { 0.00054, 0.06745, 0.36471, 0.01668, -3.34703, 4.39475, -1.03543, -0.52184, 0.01085, 0.02973, 0.00152 }, { 0.00195, 0.06912, 0.34515, -0.04445, -3.23676, 4.45185, -1.14105, -0.5241, 0.0228, 0.03306, 0.00228 }, { 0.00318, 0.07017, 0.32521, -0.10168, -3.12422, 4.50339, -1.24914, -0.524, 0.03561, 0.03643, 0.00302 }, { 0.00422, 0.07065, 0.30503, -0.15503, -3.00969, 4.54921, -1.35952, -0.52141, 0.04925, 0.03981, 0.00373 }, { 0.00508, 0.07061, 0.28471, -0.2045, -2.89348, 4.58919, -1.47197, -0.51618, 0.0637, 0.04319, 0.0044 }, { 0.00577, 0.07007, 0.26436, -0.25013, -2.77587, 4.62321, -1.58627, -0.50818, 0.07895, 0.04652, 0.00501 }, { 0.00629, 0.06909, 0.2441, -0.29194, -2.65716, 4.65118, -1.70219, -0.49727, 0.09494, 0.04979, 0.00556 }, { 0.00666, 0.06769, 0.224, -0.33, -2.53764, 4.67302, -1.81949, -0.48335, 0.11166, 0.05295, 0.00604 }, { 0.00687, 0.06592, 0.20416, -0.36435, -2.4176, 4.68866, -1.93791, -0.46627, 0.12904, 0.05597, 0.00642 }, { 0.00694, 0.06383, 0.18468, -0.39506, -2.29732, 4.69806, -2.0572, -0.44593, 0.14705, 0.05881, 0.00671 }, { 0.00689, 0.06144, 0.16561, -0.42223, -2.1771, 4.7012, -2.1771, -0.42223, 0.16561, 0.06144, 0.00689 }, { 0.00671, 0.05881, 0.14705, -0.44593, -2.0572, 4.69806, -2.29732, -0.39506, 0.18468, 0.06383, 0.00694 }, { 0.00642, 0.05597, 0.12904, -0.46627, -1.93791, 4.68865, -2.41759, -0.36435, 0.20416, 0.06592, 0.00687 }, { 0.00604, 0.05295, 0.11166, -0.48334, -1.81949, 4.67301, -2.53763, -0.33, 0.224, 0.06769, 0.00666 }, { 0.00556, 0.04979, 0.09494, -0.49727, -1.70219, 4.65117, -2.65715, -0.29194, 0.24409, 0.06909, 0.00629 }, { 0.00501, 0.04652, 0.07894, -0.50818, -1.58627, 4.62321, -2.77587, -0.25013, 0.26436, 0.07007, 0.00577 }, { 0.0044, 0.04319, 0.0637, -0.51618, -1.47197, 4.58919, -2.89348, -0.2045, 0.28471, 0.07061, 0.00508 }, { 0.00373, 0.03981, 0.04925, -0.52141, -1.35952, 4.54921, -3.0097, -0.15503, 0.30503, 0.07065, 0.00422 }, { 0.00302, 0.03643, 0.03561, -0.524, -1.24915, 4.50339, -3.12422, -0.10168, 0.32521, 0.07017, 0.00318 }, { 0.00228, 0.03306, 0.0228, -0.5241, -1.14105, 4.45186, -3.23677, -0.04445, 0.34515, 0.06912, 0.00195 }, { 0.00152, 0.02973, 0.01085, -0.52184, -1.03544, 4.39477, -3.34704, 0.01668, 0.36471, 0.06745, 0.00054 }, { 0.00074, 0.02646, -0.00024, -0.51738, -0.93249, 4.33226, -3.45476, 0.08168, 0.38378, 0.06515, -0.00105 }, { -0.00003, 0.02328, -0.01047, -0.51085, -0.83239, 4.26452, -3.55963, 0.15053, 0.40224, 0.06216, -0.00284 }, { -0.0008, 0.02021, -0.01983, -0.50241, -0.73529, 4.19174, -3.66138, 0.22319, 0.41993, 0.05847, -0.00481 }, { -0.00156, 0.01726, -0.02834, -0.49221, -0.64135, 4.11413, -3.75974, 0.29961, 0.43674, 0.05403, -0.00696 }, { -0.00229, 0.01445, -0.03599, -0.4804, -0.55069, 4.03188, -3.85445, 0.37972, 0.45251, 0.04882, -0.00929 }, }; static const float quant_amp[57] = { 0.00048828125, 0.0014648438, 0.0023226703, 0.0032847517, 0.0046453401, 0.0065695033, 0.0092906803, 0.013139007, 0.018581361, 0.026278013, 0.037162721, 0.052556027, 0.074325442, 0.10511205, 0.14865088, 0.21022411, 0.29730177, 0.42044821, 0.59460354, 0.84089643, 1.1892071, 1.6817929, 2.3784142, 3.3635857, 4.7568283, 6.7271714, 9.5136566, 13.454343, 19.027313, 26.908686, 38.054626, 53.817371, 76.109253, 107.63474, 152.21851, 215.26949, 304.43701, 430.53897, 608.87402, 861.07794, 1217.748, 1722.1559, 2435.4961, 3444.3118, 4870.9922, 6888.6235, 9741.9844, 13777.247, 19483.969, 27554.494, 38967.938, 55108.988, 77935.875, 110217.98, 155871.75, 220435.95, 0.0 }; static const float st_coeff[34] = { 26.908686, 26.908686, 13.454342, 6.7271714, 3.3635857, 1.6817929, 0.84089643, 0.59460348, 0.42044821, 0.2973018, 0.21022411, 0.1486509, 0.1051121, 0.074325398, 0.052556001, 0.037162699, 0.03125, 0.026278, 0.0185814, 0.013139, 0.0092906998, 0.0065695001, 0.0046453001, 0.0032848001, 0.0023227001, 0.0016424, 0.0011613, 0.0005807, 0.0002903, 0.0001452, 0.0000726, 0.0000363, 0.0000182, 0.0 }; static const float long_window[128] = { 0.0, 0.0000074288241, 0.000052802097, 0.00017100701, 0.00039665322, 0.0007639461, 0.0013065579, 0.0020575011, 0.0030490046, 0.0043123914, 0.0058779628, 0.0077748829, 0.010031069, 0.012673087, 0.015726056, 0.019213546, 0.023157494, 0.027578127, 0.032493874, 0.037921317, 0.043875102, 0.05036791, 0.0574104, 0.065011166, 0.073176719, 0.081911445, 0.091217607, 0.10109533, 0.1115426, 0.12255528, 0.13412713, 0.14624982, 0.15891297, 0.17210421, 0.18580918, 0.20001164, 0.21469352, 0.22983496, 0.24541442, 0.26140878, 0.27779338, 0.29454213, 0.31162769, 0.32902139, 0.34669363, 0.36461368, 0.38275006, 0.40107045, 0.41954198, 0.43813133, 0.45680472, 0.47552827, 0.49426794, 0.5129897, 0.53165978, 0.55024469, 0.56871128, 0.58702713, 0.60516042, 0.62308013, 0.64075619, 0.65815955, 0.67526239, 0.69203806, 0.70846134, 0.72450846, 0.74015719, 0.75538683, 0.77017856, 0.78451514, 0.79838127, 0.81176347, 0.82465017, 0.8370316, 0.84890026, 0.86025023, 0.87107784, 0.88138127, 0.89116055, 0.90041775, 0.90915662, 0.91738296, 0.92510408, 0.932329, 0.93906844, 0.94533449, 0.95114064, 0.95650178, 0.96143377, 0.96595365, 0.9700793, 0.97382939, 0.97722322, 0.98028058, 0.98302156, 0.98546654, 0.98763585, 0.98954982, 0.9912284, 0.99269134, 0.99395788, 0.99504662, 0.99597543, 0.99676138, 0.99742073, 0.99796873, 0.99841964, 0.99878657, 0.99908173, 0.99931598, 0.99949932, 0.99964064, 0.99974757, 0.99982697, 0.99988467, 0.99992549, 0.99995363, 0.99997234, 0.99998432, 0.99999166, 0.99999589, 0.99999815, 0.99999928, 0.99999976, 0.99999994, 1.0, 1.0, 1.0 }; static const float lfe_step_size_16[101] = { 2.1362956633198035E-004, 2.4414807580797754E-004, 2.7466658528397473E-004, 2.7466658528397473E-004, 3.0518509475997192E-004, 3.3570360423596911E-004, 3.9674062318796350E-004, 4.2725913266396069E-004, 4.5777764213995788E-004, 5.1881466109195227E-004, 5.7985168004394665E-004, 6.1037018951994385E-004, 6.7140720847193823E-004, 7.6296273689992981E-004, 8.2399975585192419E-004, 9.1555528427991577E-004, 1.0071108127079073E-003, 1.0986663411358989E-003, 1.2207403790398877E-003, 1.3428144169438765E-003, 1.4648884548478652E-003, 1.6174810022278512E-003, 1.7700735496078372E-003, 1.9531846064638203E-003, 2.1362956633198035E-003, 2.3499252296517838E-003, 2.5940733054597613E-003, 2.8687398907437361E-003, 3.1434064760277108E-003, 3.4485915707876827E-003, 3.7842951750236518E-003, 4.1810357982116153E-003, 4.6082949308755760E-003, 5.0660725730155339E-003, 5.5543687246314890E-003, 6.1037018951994385E-003, 6.7445905941953795E-003, 7.4159978026673177E-003, 8.1484420300912512E-003, 8.9419232764671782E-003, 9.8574785607470940E-003, 1.0834070863979004E-002, 1.1932737205114903E-002, 1.3122959074678793E-002, 1.4435254982146673E-002, 1.5869624927518540E-002, 1.7456587420270394E-002, 1.9196142460402233E-002, 2.1118808557390057E-002, 2.3224585711233862E-002, 2.5543992431409649E-002, 2.8107547227393413E-002, 3.0915250099185155E-002, 3.4028138065736867E-002, 3.7415692617572556E-002, 4.1169469283120215E-002, 4.5258949552903834E-002, 4.9806207464827418E-002, 5.4780724509414958E-002, 6.0274056215094456E-002, 6.6286202581865905E-002, 7.2908719138157288E-002, 8.0202642902920618E-002, 8.8229010895107887E-002, 9.7048860133671075E-002, 1.0675374614703818E-001, 1.1743522446363720E-001, 1.2918485061189611E-001, 1.4209418012024294E-001, 1.5628528702658162E-001, 1.7191076387829218E-001, 1.8912320322275461E-001, 2.0804467909787286E-001, 2.2882778405102694E-001, 2.5171666615802485E-001, 2.7689443647572254E-001, 3.0457472457045198E-001, 3.3503219702749720E-001, 3.6854152043214211E-001, 4.0537736136967073E-001, 4.4593646046327096E-001, 4.9052400280770286E-001, 5.3956724753563035E-001, 5.9352397228919340E-001, 6.5288247322000792E-001, 7.1816156498916595E-001, 7.9000213629566329E-001, 8.6898403881954400E-001, 9.5590075380718409E-001, 1.0514847254860074E+000, 1.1566209906308176E+000, 1.2722861415448470E+000, 1.3995178075502792E+000, 1.5394756920072024E+000, 1.6934110538041323E+000, 1.8627582628864405E+000, 2.0490432447279274E+000, 2.2539445173497725E+000, 2.4793237098300120E+000, 2.7272865993224893E+000, 3.0000000000000000E+000 }; static const float lfe_step_size_24[144] = { 3.5762791128491298E-006, 3.9339070241340428E-006, 4.4107442391805934E-006, 4.7683721504655064E-006, 5.2452093655120570E-006, 5.8412558843202453E-006, 6.4373024031284336E-006, 7.0333489219366219E-006, 7.7486047445064479E-006, 8.4638605670762738E-006, 9.4175349971693751E-006, 1.0252000123500839E-005, 1.1324883857355578E-005, 1.2516976894971954E-005, 1.3709069932588331E-005, 1.5139581577727983E-005, 1.6570093222867636E-005, 1.8239023475530564E-005, 2.0146372335716766E-005, 2.2053721195902969E-005, 2.4318697967374082E-005, 2.6702884042606836E-005, 2.9444698029124504E-005, 3.2305721319403807E-005, 3.5643581824729662E-005, 3.9100651633817152E-005, 4.3034558657951193E-005, 4.7326093593370149E-005, 5.2094465743835655E-005, 5.7339675109347712E-005, 6.3061721689906320E-005, 6.9379814789273121E-005, 7.6293954407448102E-005, 8.3923349848192912E-005, 9.2268001111507552E-005, 1.0156632680491529E-004, 1.1169911762465449E-004, 1.2290479217824841E-004, 1.3518335046569711E-004, 1.4865400179076216E-004, 1.6355516476096688E-004, 1.7988683937631122E-004, 1.9788744424431852E-004, 2.1767618866875036E-004, 2.3949149125713007E-004, 2.6345256131321922E-004, 2.8979781744454115E-004, 3.1876567825861912E-004, 3.5059456236297636E-004, 3.8564209766889782E-004, 4.2426591208766842E-004, 4.6670442422681142E-004, 5.1331526199761173E-004, 5.6469447191887759E-004, 6.2108047259813216E-004, 6.8318851985794547E-004, 7.5149545091336386E-004, 8.2671652158695713E-004, 9.0932856909377204E-004, 1.0002852678639017E-003, 1.1003018737199156E-003, 1.2103320610919071E-003, 1.3314487137137310E-003, 1.4646055060154803E-003, 1.6109945310347714E-003, 1.7721655097205054E-003, 1.9493105351102991E-003, 2.1442177467605765E-003, 2.3586752842277626E-003, 2.5945904963720436E-003, 2.8539899413573674E-003, 3.1393770145627278E-003, 3.4533743206708813E-003, 3.7987236736683454E-003, 4.1785245154529228E-003, 4.5963531251374630E-003, 5.0560242004423382E-003, 5.5617100669992049E-003, 6.1178214690472445E-003, 6.7296036159519689E-003, 7.4025401356864135E-003, 8.1428299120461841E-003, 8.9571486660419298E-003, 9.8527681652031147E-003, 1.0838033060793050E-002, 1.1921884050593860E-002, 1.3114096297513997E-002, 1.4425517848195773E-002, 1.5868069633015350E-002, 1.7454864675386508E-002, 1.9200327301064409E-002, 2.1120431556753107E-002, 2.3232462791498040E-002, 2.5555613703204836E-002, 2.8111222757246822E-002, 3.0922297349250002E-002, 3.4014586688826884E-002, 3.7415985753057691E-002, 4.1157608170224208E-002, 4.5273428591898514E-002, 4.9800759530157987E-002, 5.4780847404104160E-002, 6.0258872539862694E-002, 6.6284783635709721E-002, 7.2913297762071824E-002, 8.0204615617348624E-002, 8.8225017574431602E-002, 9.7047578936526643E-002, 1.0675228914645780E-001, 1.1742748229831246E-001, 1.2917031397465634E-001, 1.4208735729305236E-001, 1.5629603341770570E-001, 1.7192568444319778E-001, 1.8911816944100493E-001, 2.0803001022696618E-001, 2.2883310661710579E-001, 2.5171640535788598E-001, 2.7688804589367461E-001, 3.0457679087839018E-001, 3.3503452957088109E-001, 3.6853794676517804E-001, 4.0539174144169587E-001, 4.4593089174400469E-001, 4.9052399283933557E-001, 5.3957635636047796E-001, 5.9353406352210802E-001, 6.5288742219059737E-001, 7.1817609288407480E-001, 7.8999373793527339E-001, 8.6899314749159184E-001, 9.5589243839889027E-001, 1.0514817299225008E+000, 1.1566298194682383E+000, 1.2722928848615747E+000, 1.3995221137430804E+000, 1.5394743131964581E+000, 1.6934218041207556E+000, 1.8627639845328312E+000, 2.0490403233814627E+000, 2.2539444272451910E+000, 2.4793389414952922E+000, 2.7272728356448215E+000, 2.9999998807906962E+000 }; static const float lfe_iir[5][4] = { { -0.98618466, 1.9861259, 1.0, -1.9840510 }, { -0.98883152, 1.9887193, 1.0, -1.9979848 }, { -0.99252087, 1.9923381, 1.0, -1.9990897 }, { -0.99591690, 1.9956781, 1.0, -1.9993745 }, { -0.99872285, 1.9984550, 1.0, -1.9994639 } }; ================================================ FILE: libdcadec/ta.c ================================================ /* Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include "compiler.h" #include "ta.h" // Note: the actual minimum alignment is dictated by malloc(). It doesn't // make sense to set this value higher than malloc's alignment. #define MIN_ALIGN 16 struct ta_header { size_t size; // size of the user allocation struct ta_header *prev; // ring list containing siblings struct ta_header *next; struct ta_ext_header *ext; }; union aligned_header { struct ta_header ta; // Make sure to satisfy typical alignment requirements void *align_ptr; int align_int; double align_d; long long align_ll; char align_min[(sizeof(struct ta_header) + MIN_ALIGN - 1) & ~(MIN_ALIGN - 1)]; }; #define PTR_TO_HEADER(ptr) (&((union aligned_header *)(ptr) - 1)->ta) #define PTR_FROM_HEADER(h) ((void *)((union aligned_header *)(h) + 1)) #define MAX_ALLOC (((size_t)-1) - sizeof(union aligned_header)) // Needed for non-leaf allocations, or extended features such as destructors. struct ta_ext_header { struct ta_header *header; // points back to normal header struct ta_header children; // list of children, with this as sentinel void (*destructor)(void *); }; // ta_ext_header.children.size is set to this #define CHILDREN_SENTINEL ((size_t)-1) static struct ta_header *get_header(void *ptr) { return ptr ? PTR_TO_HEADER(ptr) : NULL; } static struct ta_ext_header *get_or_alloc_ext_header(void *ptr) { struct ta_header *h = get_header(ptr); if (!h) return NULL; if (!h->ext) { h->ext = malloc(sizeof(struct ta_ext_header)); if (!h->ext) return NULL; *h->ext = (struct ta_ext_header) { .header = h, .children = { .next = &h->ext->children, .prev = &h->ext->children, // Needed by ta_find_parent(): .size = CHILDREN_SENTINEL, .ext = h->ext, }, }; } return h->ext; } /* Set the parent allocation of ptr. If parent==NULL, remove the parent. * Setting parent==NULL (with ptr!=NULL) always succeeds, and unsets the * parent of ptr. Operations ptr==NULL always succeed and do nothing. * Returns true on success, false on OOM. * * Warning: if ta_parent is a direct or indirect child of ptr, things will go * wrong. The function will apparently succeed, but creates circular * parent links, which are not allowed. */ bool ta_set_parent(void *ptr, void *ta_parent) { struct ta_header *ch = get_header(ptr); if (!ch) return true; struct ta_ext_header *parent_eh = get_or_alloc_ext_header(ta_parent); if (ta_parent && !parent_eh) // do nothing on OOM return false; // Unlink from previous parent if (ch->next) { ch->next->prev = ch->prev; ch->prev->next = ch->next; ch->next = ch->prev = NULL; } // Link to new parent - insert at end of list (possibly orders destructors) if (parent_eh) { struct ta_header *children = &parent_eh->children; ch->next = children; ch->prev = children->prev; children->prev->next = ch; children->prev = ch; } return true; } /* Allocate size bytes of memory. If ta_parent is not NULL, this is used as * parent allocation (if ta_parent is freed, this allocation is automatically * freed as well). size==0 allocates a block of size 0 (i.e. returns non-NULL). * Returns NULL on OOM. */ void *ta_alloc_size(void *ta_parent, size_t size) { if (size >= MAX_ALLOC) return NULL; struct ta_header *h = malloc(sizeof(union aligned_header) + size); if (!h) return NULL; *h = (struct ta_header) {.size = size}; void *ptr = PTR_FROM_HEADER(h); if (!ta_set_parent(ptr, ta_parent)) { ta_free(ptr); return NULL; } return ptr; } /* Exactly the same as ta_alloc_size(), but the returned memory block is * initialized to 0. */ void *ta_zalloc_size(void *ta_parent, size_t size) { if (size >= MAX_ALLOC) return NULL; struct ta_header *h = calloc(1, sizeof(union aligned_header) + size); if (!h) return NULL; *h = (struct ta_header) {.size = size}; void *ptr = PTR_FROM_HEADER(h); if (!ta_set_parent(ptr, ta_parent)) { ta_free(ptr); return NULL; } return ptr; } /* Reallocate the allocation given by ptr and return a new pointer. Much like * realloc(), the returned pointer can be different, and on OOM, NULL is * returned. * * size==0 is equivalent to ta_free(ptr). * ptr==NULL is equivalent to ta_alloc_size(ta_parent, size). * * ta_parent is used only in the ptr==NULL case. * * Returns NULL if the operation failed. * NULL is also returned if size==0. */ void *ta_realloc_size(void *ta_parent, void *ptr, size_t size) { if (size >= MAX_ALLOC) return NULL; if (!size) { ta_free(ptr); return NULL; } if (!ptr) return ta_alloc_size(ta_parent, size); struct ta_header *h = get_header(ptr); struct ta_header *old_h = h; if (h->size == size) return ptr; h = realloc(h, sizeof(union aligned_header) + size); if (!h) return NULL; h->size = size; if (h != old_h) { if (h->next) { // Relink siblings h->next->prev = h; h->prev->next = h; } if (h->ext) { // Relink children h->ext->header = h; h->ext->children.next->prev = &h->ext->children; h->ext->children.prev->next = &h->ext->children; } } return PTR_FROM_HEADER(h); } /* Return the allocated size of ptr. This returns the size parameter of the * most recent ta_alloc.../ta_realloc... call. * If ptr==NULL, return 0. */ size_t ta_get_size(void *ptr) { struct ta_header *h = get_header(ptr); return h ? h->size : 0; } /* Free all allocations that (recursively) have ptr as parent allocation, but * do not free ptr itself. */ void ta_free_children(void *ptr) { struct ta_header *h = get_header(ptr); struct ta_ext_header *eh = h ? h->ext : NULL; if (!eh) return; while (eh->children.next != &eh->children) ta_free(PTR_FROM_HEADER(eh->children.next)); } /* Free the given allocation, and all of its direct and indirect children. */ void ta_free(void *ptr) { struct ta_header *h = get_header(ptr); if (!h) return; if (h->ext && h->ext->destructor) h->ext->destructor(ptr); ta_free_children(ptr); if (h->next) { // Unlink from sibling list h->next->prev = h->prev; h->prev->next = h->next; } free(h->ext); free(h); } /* Set a destructor that is to be called when the given allocation is freed. * (Whether the allocation is directly freed with ta_free() or indirectly by * freeing its parent does not matter.) There is only one destructor. If an * destructor was already set, it's overwritten. * * The destructor will be called with ptr as argument. The destructor can do * almost anything, but it must not attempt to free or realloc ptr. The * destructor is run before the allocation's children are freed (also, before * their destructors are run). * * Returns false if ptr==NULL, or on OOM. */ bool ta_set_destructor(void *ptr, void (*destructor)(void *)) { struct ta_ext_header *eh = get_or_alloc_ext_header(ptr); if (!eh) return false; eh->destructor = destructor; return true; } /* Return the ptr's parent allocation, or NULL if there isn't any. * * Warning: this has O(N) runtime complexity with N sibling allocations! */ void *ta_find_parent(void *ptr) { struct ta_header *h = get_header(ptr); if (!h || !h->next) return NULL; for (struct ta_header *cur = h->next; cur != h; cur = cur->next) { if (cur->size == CHILDREN_SENTINEL) return PTR_FROM_HEADER(cur->ext->header); } return NULL; } /* Return a copy of str. * Returns NULL on OOM. */ char *ta_strdup(void *ta_parent, const char *str) { if (str) { size_t len = strlen(str) + 1; char *dup = ta_alloc_size(ta_parent, len); if (dup) memcpy(dup, str, len); return dup; } return NULL; } ================================================ FILE: libdcadec/ta.h ================================================ /* Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef TA_H_ #define TA_H_ #include #include #include void *ta_alloc_size(void *ta_parent, size_t size); void *ta_zalloc_size(void *ta_parent, size_t size); void *ta_realloc_size(void *ta_parent, void *ptr, size_t size); size_t ta_get_size(void *ptr); void ta_free(void *ptr); void ta_free_children(void *ptr); bool ta_set_destructor(void *ptr, void (*destructor)(void *)); bool ta_set_parent(void *ptr, void *ta_parent); void *ta_find_parent(void *ptr); char *ta_strdup(void *ta_parent, const char *str); static inline size_t ta_calc_array_size(size_t element_size, size_t count) { if (count > (((size_t)-1) / element_size)) return (size_t)-1; return element_size * count; } static inline int ta_zalloc_fast(void *ta_parent, void *ptr, size_t count, size_t element_size) { void **_ptr = ptr; size_t old_size = ta_get_size(*_ptr); size_t new_size = ta_calc_array_size(element_size, count); if (old_size < new_size) { ta_free(*_ptr); if (!(*_ptr = ta_zalloc_size(ta_parent, new_size))) return -1; return 1; } return 0; } static inline int ta_alloc_fast(void *ta_parent, void *ptr, size_t count, size_t element_size) { void **_ptr = ptr; size_t old_size = ta_get_size(*_ptr); size_t new_size = ta_calc_array_size(element_size, count); if (old_size < new_size) { ta_free(*_ptr); if (!(*_ptr = ta_alloc_size(ta_parent, new_size))) return -1; return 1; } return 0; } #define ta_new(ta_parent, type) (type *)ta_alloc_size(ta_parent, sizeof(type)) #define ta_znew(ta_parent, type) (type *)ta_zalloc_size(ta_parent, sizeof(type)) #define ta_new_array(ta_parent, type, count) \ (type *)ta_alloc_size(ta_parent, ta_calc_array_size(sizeof(type), count)) #define ta_znew_array(ta_parent, type, count) \ (type *)ta_zalloc_size(ta_parent, ta_calc_array_size(sizeof(type), count)) #define ta_new_array_size(ta_parent, element_size, count) \ ta_alloc_size(ta_parent, ta_calc_array_size(element_size, count)) #define ta_znew_array_size(ta_parent, element_size, count) \ ta_zalloc_size(ta_parent, ta_calc_array_size(element_size, count)) #define ta_realloc(ta_parent, ptr, type, count) \ (type *)ta_realloc_size(ta_parent, ptr, ta_calc_array_size(sizeof(type), count)) #endif ================================================ FILE: libdcadec/xll_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 "fixed_math.h" #include "xll_decoder.h" #include "exss_parser.h" #include "dmix_tables.h" #include "xll_tables.h" #define XLL_PBR_SIZE (240 << 10) static int parse_dmix_coeffs(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; int m, n; if (chs->primary_chset) { m = dmix_primary_nch[chs->dmix_type]; n = chs->nchannels; } else { m = chs->hier_m; n = chs->nchannels + 2; // Two extra columns for scales } // Reallocate downmix coefficients buffer if (ta_zalloc_fast(xll->chset, &chs->dmix_coeff, m * n * 2, sizeof(int)) < 0) return -DCADEC_ENOMEM; // Setup buffer pointers for current and previous frame bool valid = (chs->dmix_coeffs_signature == XLL_DMIX_SIGNATURE(chs)); chs->dmix_coeff_cur = chs->dmix_coeff + m * n * chs->dmix_coeffs_parity; chs->dmix_coeff_pre = chs->dmix_coeff + m * n * (chs->dmix_coeffs_parity ^ valid); if (chs->primary_chset) { chs->dmix_scale_cur = chs->dmix_scale_pre = NULL; chs->dmix_scale_inv_cur = chs->dmix_scale_inv_pre = NULL; } else { chs->dmix_scale_cur = chs->dmix_coeff_cur + m * chs->nchannels; chs->dmix_scale_pre = chs->dmix_coeff_pre + m * chs->nchannels; chs->dmix_scale_inv_cur = chs->dmix_coeff_cur + m * (chs->nchannels + 1); chs->dmix_scale_inv_pre = chs->dmix_coeff_pre + m * (chs->nchannels + 1); } int *coeff_ptr = chs->dmix_coeff_cur; for (int i = 0; i < m; i++) { int scale_inv = 0; // Downmix scale // Only for non-primary channel sets if (!chs->primary_chset) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; unsigned int index = (code & 0xff) - 1; if (index < 40 || index >= dca_countof(dmix_table)) { xll_err("Invalid XLL downmix scale index"); return -DCADEC_EBADDATA; } int scale = dmix_table[index]; scale_inv = dmix_table_inv[index - 40]; chs->dmix_scale_cur[i] = (scale ^ sign) - sign; chs->dmix_scale_inv_cur[i] = (scale_inv ^ sign) - sign; } // Downmix coefficients for (int j = 0; j < chs->nchannels; j++) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; if (code &= 0xff) { unsigned int index = code - 1; if (index >= dca_countof(dmix_table)) { xll_err("Invalid XLL downmix coefficient index"); return -DCADEC_EBADDATA; } int coeff = dmix_table[index]; if (!chs->primary_chset) // Multiply by |InvDmixScale| to get |UndoDmixScale| coeff = mul16(scale_inv, coeff); // Convert sign *coeff_ptr++ = (coeff ^ sign) - sign; } else { *coeff_ptr++ = 0; } } } return 0; } static int chs_parse_header(struct xll_chset *chs, struct exss_asset *asset) { struct xll_decoder *xll = chs->decoder; int i, j, k, ret, header_pos = xll->bits.index; // Size of channel set sub-header int header_size = bits_get(&xll->bits, 10) + 1; // Check CRC if ((ret = bits_check_crc(&xll->bits, header_pos, header_pos + header_size * 8)) < 0) { xll_err("Invalid XLL sub-header checksum"); return ret; } // Number of channels in the channel set chs->nchannels = bits_get(&xll->bits, 4) + 1; if (chs->nchannels > XLL_MAX_CHANNELS) { xll_err_once("Unsupported number of XLL channels (%d)", chs->nchannels); return -DCADEC_ENOSUP; } // Residual type chs->residual_encode = bits_get(&xll->bits, chs->nchannels); // PCM bit resolution chs->pcm_bit_res = bits_get(&xll->bits, 5) + 1; // Storage unit width chs->storage_bit_res = bits_get(&xll->bits, 5) + 1; // Original sampling frequency chs->freq = exss_sample_rates[bits_get(&xll->bits, 4)]; if (chs->freq > 192000) { xll_err_once("Unsupported XLL sampling frequency"); return -DCADEC_ENOSUP; } // Sampling frequency modifier chs->interpolate = bits_get(&xll->bits, 2); // Which replacement set this channel set is member of chs->replace_set_index = bits_get(&xll->bits, 2); if (chs->replace_set_index) { xll_err_once("Replacement sets are not supported"); return -DCADEC_ENOSUP; } // Default replacement set flag if (chs->replace_set_index) bits_skip1(&xll->bits); if (asset->one_to_one_map_ch_to_spkr) { // Primary channel set flag chs->primary_chset = bits_get1(&xll->bits); // Downmix coefficients present in stream chs->dmix_coeffs_present = bits_get1(&xll->bits); // Downmix already performed by encoder chs->dmix_embedded = chs->dmix_coeffs_present && bits_get1(&xll->bits); // Downmix type if (chs->dmix_coeffs_present && chs->primary_chset) { chs->dmix_type = bits_get(&xll->bits, 3); if (chs->dmix_type >= DMIX_TYPE_COUNT) { xll_err("Invalid XLL primary channel set downmix type"); return -DCADEC_EBADDATA; } } // Whether the channel set is part of a hierarchy chs->hier_chset = bits_get1(&xll->bits); // Downmix coefficients if (chs->dmix_coeffs_present && (ret = parse_dmix_coeffs(chs)) < 0) return ret; // Channel mask enabled chs->ch_mask_enabled = bits_get1(&xll->bits); if (chs->ch_mask_enabled) { // Channel mask for set chs->ch_mask = bits_get(&xll->bits, xll->ch_mask_nbits); if (dca_popcount(chs->ch_mask) != chs->nchannels) { xll_err("Invalid XLL channel mask"); return -DCADEC_EBADDATA; } } else { chs->ch_mask = 0; // Angular speaker position table for (i = 0; i < chs->nchannels; i++) { bits_skip(&xll->bits, 9); bits_skip(&xll->bits, 9); bits_skip(&xll->bits, 7); } } } else { chs->primary_chset = true; chs->dmix_coeffs_present = false; chs->dmix_embedded = false; chs->hier_chset = true; chs->ch_mask_enabled = false; chs->ch_mask = 0; // Mapping coeffs present flag if (bits_get1(&xll->bits)) { xll_warn_once("Stream with speaker mapping coefficients"); // Number of bits used to pack each // channel-to-speaker mapping coefficient int nchspkrcoefbits = 6 + 2 * bits_get(&xll->bits, 3); // Number of loudspeaker configurations int nspkrconfigs = bits_get(&xll->bits, 2) + 1; for (i = 0; i < nspkrconfigs; i++) { // Active channel mask for current configuration int active_ch_mask = bits_get(&xll->bits, chs->nchannels); // Number of speakers in current configuration int nspeakers = bits_get(&xll->bits, 6) + 1; // Speaker mask or polar coordinates flag if (bits_get1(&xll->bits)) { // Speaker mask for current configuration bits_skip(&xll->bits, xll->ch_mask_nbits); } else { // Angular speaker position table for current configuration for (j = 0; j < nspeakers; j++) { bits_skip(&xll->bits, 9); bits_skip(&xll->bits, 9); bits_skip(&xll->bits, 7); } } // Channel to loudspeaker mapping coefficients for (j = 0; j < chs->nchannels; j++) if (active_ch_mask & (1 << j)) bits_skip(&xll->bits, nchspkrcoefbits); } } } // Mark downmix coefficients invalid until filtering chs->dmix_coeffs_signature = 0; if (chs->freq > 96000) // Extra frequency bands flag chs->nfreqbands = 2 * (1 + bits_get1(&xll->bits)); else chs->nfreqbands = 1; if (chs->nfreqbands > XLL_MAX_BANDS) { xll_err_once("Extra frequency bands are not supported"); return -DCADEC_ENOSUP; } // Set the sampling frequency to that of the first frequency band. // Frequency will be doubled again after bands assembly. chs->freq >>= chs->nfreqbands - 1; // Determine number of bits to read bit allocation coding parameter if (chs->storage_bit_res > 16) chs->nabits = 5; else if (chs->storage_bit_res > 8) chs->nabits = 4; else chs->nabits = 3; // Account for embedded downmix and decimator saturation if ((xll->nchsets > 1 || chs->nfreqbands > 1) && chs->nabits < 5) chs->nabits++; for (int band_i = 0; band_i < chs->nfreqbands; band_i++) { struct xll_band *band = &chs->bands[band_i]; // Pairwise channel decorrelation band->decor_enabled = bits_get1(&xll->bits); if (band->decor_enabled && chs->nchannels > 1) { // Original channel order for (i = 0; i < chs->nchannels; i++) { band->orig_order[i] = bits_get(&xll->bits, ch_nbits[chs->nchannels - 1]); if (band->orig_order[i] >= chs->nchannels) { xll_err("Invalid original channel order"); return -DCADEC_EBADDATA; } } // Pairwise channel coefficients for (i = 0; i < chs->nchannels / 2; i++) { if (bits_get1(&xll->bits)) band->decor_coeff[i] = bits_get_signed_linear(&xll->bits, 7); else band->decor_coeff[i] = 0; } } else { for (i = 0; i < chs->nchannels; i++) band->orig_order[i] = i; for (i = 0; i < chs->nchannels / 2; i++) band->decor_coeff[i] = 0; } // Adaptive predictor order band->highest_pred_order = 0; for (i = 0; i < chs->nchannels; i++) { band->adapt_pred_order[i] = bits_get(&xll->bits, 4); if (band->adapt_pred_order[i] > band->highest_pred_order) band->highest_pred_order = band->adapt_pred_order[i]; } if (band->highest_pred_order > xll->nsegsamples) { xll_err("Invalid adaptive predicition order"); return -DCADEC_EBADDATA; } // Fixed predictor order for (i = 0; i < chs->nchannels; i++) { if (band->adapt_pred_order[i] == 0) band->fixed_pred_order[i] = bits_get(&xll->bits, 2); else band->fixed_pred_order[i] = 0; } // Adaptive predictor quantized reflection coefficients for (i = 0; i < chs->nchannels; i++) { for (j = 0; j < band->adapt_pred_order[i]; j++) { k = bits_get_signed_linear(&xll->bits, 8); if (k == -128) { xll_err("Invalid reflection coefficient index"); return -DCADEC_EBADDATA; } if (k < 0) band->adapt_refl_coeff[i][j] = -(int)refl_coeff_table[-k]; else band->adapt_refl_coeff[i][j] = (int)refl_coeff_table[ k]; } } // Downmix performed by encoder in extension frequency band band->dmix_embedded = chs->dmix_embedded && (band_i == 0 || bits_get1(&xll->bits)); // MSB/LSB split flag in extension frequency band if ((band_i == 0 && xll->scalable_lsbs) || (band_i != 0 && bits_get1(&xll->bits))) { // Size of LSB section in any segment band->lsb_section_size = bits_get(&xll->bits, xll->seg_size_nbits); if (band->lsb_section_size < 0 || band->lsb_section_size > xll->frame_size) { xll_err("Invalid LSB section size"); return -DCADEC_EBADDATA; } // Account for optional CRC bytes after LSB section if (band->lsb_section_size && (xll->band_crc_present > 2 || (band_i == 0 && xll->band_crc_present > 1))) band->lsb_section_size += 2; // Number of bits to represent the samples in LSB part for (i = 0; i < chs->nchannels; i++) { band->nscalablelsbs[i] = bits_get(&xll->bits, 4); if (band->nscalablelsbs[i] && !band->lsb_section_size) { xll_err("LSB section missing with non-zero LSB width"); return -DCADEC_EBADDATA; } } } else { band->lsb_section_size = 0; for (i = 0; i < chs->nchannels; i++) band->nscalablelsbs[i] = 0; } // Scalable resolution flag in extension frequency band if ((band_i == 0 && xll->scalable_lsbs) || (band_i != 0 && bits_get1(&xll->bits))) { // Number of bits discarded by authoring for (i = 0; i < chs->nchannels; i++) band->bit_width_adjust[i] = bits_get(&xll->bits, 4); } else { for (i = 0; i < chs->nchannels; i++) band->bit_width_adjust[i] = 0; } } // Reserved // Byte align // CRC16 of channel set sub-header if ((ret = bits_seek(&xll->bits, header_pos + header_size * 8)) < 0) xll_err("Read past end of XLL sub-header"); return ret; } static int chs_alloc_msb_band_data(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; // Reallocate MSB sample buffer if (ta_zalloc_fast(xll->chset, &chs->sample_buffer1, (xll->nframesamples + XLL_DECI_HISTORY) * chs->nchannels * chs->nfreqbands, sizeof(int)) < 0) return -DCADEC_ENOMEM; int *ptr = chs->sample_buffer1 + XLL_DECI_HISTORY; for (int band = 0; band < chs->nfreqbands; band++) { for (int i = 0; i < chs->nchannels; i++) { chs->bands[band].msb_sample_buffer[i] = ptr; ptr += xll->nframesamples + XLL_DECI_HISTORY; } } return 0; } static int chs_alloc_lsb_band_data(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; // Number of frequency bands that have MSB/LSB split int nfreqbands = 0; for (int band = 0; band < chs->nfreqbands; band++) if (chs->bands[band].lsb_section_size) nfreqbands++; if (!nfreqbands) return 0; // Reallocate LSB sample buffer if (ta_zalloc_fast(xll->chset, &chs->sample_buffer2, xll->nframesamples * chs->nchannels * nfreqbands, sizeof(int)) < 0) return -DCADEC_ENOMEM; int *ptr = chs->sample_buffer2; for (int band = 0; band < chs->nfreqbands; band++) { if (chs->bands[band].lsb_section_size) { for (int i = 0; i < chs->nchannels; i++) { chs->bands[band].lsb_sample_buffer[i] = ptr; ptr += xll->nframesamples; } } else { for (int i = 0; i < chs->nchannels; i++) chs->bands[band].lsb_sample_buffer[i] = NULL; } } return 0; } static int chs_parse_band_data(struct xll_chset *chs, int band_i, int seg, int band_data_end) { struct xll_decoder *xll = chs->decoder; struct xll_band *band = &chs->bands[band_i]; int i, j, ret; // Start unpacking MSB portion of the segment // Unpack flag whether to reuse parameters from previous segment if (!(seg && bits_get1(&xll->bits))) { // Unpack segment type // 0 - distinct coding parameters for each channel // 1 - common coding parameters for all channels chs->seg_common = bits_get1(&xll->bits); // Determine number of coding parameters encoded in segment int nparamsets = chs->seg_common ? 1 : chs->nchannels; // Unpack Rice coding parameters for (i = 0; i < nparamsets; i++) { // Unpack Rice coding flag // 0 - linear code, 1 - Rice code chs->rice_code_flag[i] = bits_get1(&xll->bits); // Unpack Hybrid Rice coding flag // 0 - Rice code, 1 - Hybrid Rice code if (!chs->seg_common && chs->rice_code_flag[i] && bits_get1(&xll->bits)) // Unpack binary code length for isolated samples chs->bitalloc_hybrid_linear[i] = bits_get(&xll->bits, chs->nabits) + 1; else // 0 indicates no Hybrid Rice coding chs->bitalloc_hybrid_linear[i] = 0; } // Unpack coding parameters for (i = 0; i < nparamsets; i++) { if (seg == 0) { // Unpack coding parameter for part A of segment 0 chs->bitalloc_part_a[i] = bits_get(&xll->bits, chs->nabits); // Adjust for the linear code if (!chs->rice_code_flag[i] && chs->bitalloc_part_a[i]) chs->bitalloc_part_a[i]++; if (!chs->seg_common) chs->nsamples_part_a[i] = band->adapt_pred_order[i]; else chs->nsamples_part_a[i] = band->highest_pred_order; } else { chs->bitalloc_part_a[i] = 0; chs->nsamples_part_a[i] = 0; } // Unpack coding parameter for part B of segment chs->bitalloc_part_b[i] = bits_get(&xll->bits, chs->nabits); // Adjust for the linear code if (!chs->rice_code_flag[i] && chs->bitalloc_part_b[i]) chs->bitalloc_part_b[i]++; } } // Unpack entropy codes for (i = 0; i < chs->nchannels; i++) { // Select index of coding parameters int k = chs->seg_common ? 0 : i; // Slice the segment into parts A and B int *part_a = band->msb_sample_buffer[i] + seg * xll->nsegsamples; int *part_b = part_a + chs->nsamples_part_a[k]; int nsamples_part_b = xll->nsegsamples - chs->nsamples_part_a[k]; if (!chs->rice_code_flag[k]) { // Linear codes // Unpack all residuals of part A of segment 0 bits_get_signed_linear_array(&xll->bits, part_a, chs->nsamples_part_a[k], chs->bitalloc_part_a[k]); // Unpack all residuals of part B of segment 0 and others bits_get_signed_linear_array(&xll->bits, part_b, nsamples_part_b, chs->bitalloc_part_b[k]); } else { // Rice codes // Unpack all residuals of part A of segment 0 bits_get_signed_rice_array(&xll->bits, part_a, chs->nsamples_part_a[k], chs->bitalloc_part_a[k]); if (chs->bitalloc_hybrid_linear[k]) { // Hybrid Rice codes // Unpack the number of isolated samples int nisosamples = bits_get(&xll->bits, xll->nsegsamples_log2); // Set all locations to 0 memset(part_b, 0, sizeof(*part_b) * nsamples_part_b); // Extract the locations of isolated samples and flag by -1 for (j = 0; j < nisosamples; j++) { int loc = bits_get(&xll->bits, xll->nsegsamples_log2); if (loc >= nsamples_part_b) { xll_err("Invalid isolated sample location"); return -DCADEC_EBADDATA; } part_b[loc] = -1; } // Unpack all residuals of part B of segment 0 and others for (j = 0; j < nsamples_part_b; j++) { if (part_b[j] == -1) part_b[j] = bits_get_signed_linear(&xll->bits, chs->bitalloc_hybrid_linear[k]); else part_b[j] = bits_get_signed_rice(&xll->bits, chs->bitalloc_part_b[k]); } } else { // Rice codes // Unpack all residuals of part B of segment 0 and others bits_get_signed_rice_array(&xll->bits, part_b, nsamples_part_b, chs->bitalloc_part_b[k]); } } } // Unpack decimator history for frequency band 1 if (seg == 0 && band_i == XLL_BAND_1) { int nbits = bits_get(&xll->bits, 5) + 1; for (i = 0; i < chs->nchannels; i++) for (j = 1; j < XLL_DECI_HISTORY; j++) chs->deci_history[i][j] = bits_get_signed(&xll->bits, nbits); } // Start unpacking LSB portion of the segment if (band->lsb_section_size) { // Skip to the start of LSB portion if ((ret = bits_seek(&xll->bits, band_data_end - band->lsb_section_size * 8)) < 0) { xll_err("Read past end of band data"); return ret; } // Unpack all LSB parts of residuals of this segment for (i = 0; i < chs->nchannels; i++) { if (band->nscalablelsbs[i]) { bits_get_array(&xll->bits, band->lsb_sample_buffer[i] + seg * xll->nsegsamples, xll->nsegsamples, band->nscalablelsbs[i]); } } } // Skip to the end of band data if ((ret = bits_seek(&xll->bits, band_data_end)) < 0) xll_err("Read past end of band data"); return ret; } static void chs_clear_band_data(struct xll_chset *chs, int band_i, int seg) { struct xll_decoder *xll = chs->decoder; struct xll_band *band = &chs->bands[band_i]; for (int i = 0; i < chs->nchannels; i++) memset(band->msb_sample_buffer[i] + seg * xll->nsegsamples, 0, xll->nsegsamples * sizeof(int)); if (seg == 0 && band_i == XLL_BAND_1) memset(chs->deci_history, 0, sizeof(chs->deci_history)); if (band->lsb_section_size) for (int i = 0; i < chs->nchannels; i++) memset(band->lsb_sample_buffer[i] + seg * xll->nsegsamples, 0, xll->nsegsamples * sizeof(int)); } void xll_clear_band_data(struct xll_chset *chs, int band_i) { struct xll_decoder *xll = chs->decoder; struct xll_band *band = &chs->bands[band_i]; for (int i = 0; i < chs->nchannels; i++) memset(band->msb_sample_buffer[i], 0, xll->nframesamples * sizeof(int)); if (band_i == XLL_BAND_1) memset(chs->deci_history, 0, sizeof(chs->deci_history)); if (band->lsb_section_size) for (int i = 0; i < chs->nchannels; i++) memset(band->lsb_sample_buffer[i], 0, xll->nframesamples * sizeof(int)); memset(band->nscalablelsbs, 0, sizeof(band->nscalablelsbs)); memset(band->bit_width_adjust, 0, sizeof(band->bit_width_adjust)); } void xll_filter_band_data(struct xll_chset *chs, int band_i) { struct xll_decoder *xll = chs->decoder; struct xll_band *band = &chs->bands[band_i]; int nsamples = xll->nframesamples; int i, j, k; // Inverse adaptive or fixed prediction for (i = 0; i < chs->nchannels; i++) { int *buf = band->msb_sample_buffer[i]; int order = band->adapt_pred_order[i]; if (order > 0) { int coeff[XLL_MAX_ADAPT_PRED_ORDER]; // Conversion from reflection coefficients to direct form coefficients for (j = 0; j < order; j++) { int rc = band->adapt_refl_coeff[i][j]; for (k = 0; k < (j + 1) / 2; k++) { int tmp1 = coeff[ k ]; int tmp2 = coeff[j - k - 1]; coeff[ k ] = tmp1 + mul16(rc, tmp2); coeff[j - k - 1] = tmp2 + mul16(rc, tmp1); } coeff[j] = rc; } for (j = 0; j < nsamples - order; j++) { int64_t err = INT64_C(0); for (k = 0; k < order; k++) err += (int64_t)buf[j + k] * coeff[order - k - 1]; // Round and scale the prediction // Calculate the original sample buf[j + k] -= clip23(norm16(err)); } } else { // Inverse fixed coefficient prediction for (j = 0; j < band->fixed_pred_order[i]; j++) for (k = 1; k < nsamples; k++) buf[k] += buf[k - 1]; } } // Inverse pairwise channel decorrellation if (band->decor_enabled) { for (i = 0; i < chs->nchannels / 2; i++) { int coeff = band->decor_coeff[i]; if (coeff) { int *src = band->msb_sample_buffer[i * 2 + 0]; int *dst = band->msb_sample_buffer[i * 2 + 1]; for (j = 0; j < nsamples; j++) dst[j] += mul3(src[j], coeff); } } // Reorder channel pointers to the original order int *tmp[XLL_MAX_CHANNELS]; for (i = 0; i < chs->nchannels; i++) tmp[i] = band->msb_sample_buffer[i]; for (i = 0; i < chs->nchannels; i++) band->msb_sample_buffer[band->orig_order[i]] = tmp[i]; } // Map output channel pointers for frequency band 0 if (band_i == XLL_BAND_0) for (i = 0; i < chs->nchannels; i++) chs->out_sample_buffer[i] = band->msb_sample_buffer[i]; } int xll_get_lsb_width(struct xll_chset *chs, int band, int ch) { struct xll_decoder *xll = chs->decoder; int adj = chs->bands[band].bit_width_adjust[ch]; int shift = chs->bands[band].nscalablelsbs[ch]; if (xll->fixed_lsb_width) shift = xll->fixed_lsb_width; else if (shift && adj) shift += adj - 1; else shift += adj; return shift; } void xll_assemble_msbs_lsbs(struct xll_chset *chs, int band_i) { struct xll_decoder *xll = chs->decoder; struct xll_band *band = &chs->bands[band_i]; int nsamples = xll->nframesamples; for (int ch = 0; ch < chs->nchannels; ch++) { int shift = xll_get_lsb_width(chs, band_i, ch); if (shift) { int *msb = band->msb_sample_buffer[ch]; if (band->nscalablelsbs[ch]) { int *lsb = band->lsb_sample_buffer[ch]; int adj = band->bit_width_adjust[ch]; for (int n = 0; n < nsamples; n++) msb[n] = msb[n] * (1 << shift) + (lsb[n] << adj); } else { for (int n = 0; n < nsamples; n++) msb[n] = msb[n] * (1 << shift); } } } } static void filter0(int *dst, const int *src, int nsamples) { for (int n = 0; n < nsamples; n++) dst[n] -= src[n]; } static void filter1(int *dst, const int *src, int nsamples, int32_t coeff) { for (int n = 0; n < nsamples; n++) dst[n] -= mul22(src[n], coeff); } static void filter2(int *dst, const int *src, int nsamples, int32_t coeff) { for (int n = 0; n < nsamples; n++) dst[n] -= mul23(src[n], coeff); } static int chs_assemble_freq_bands(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; int nsamples = xll->nframesamples; assert(chs->nfreqbands > 1); // Reallocate frequency band assembly buffer if (ta_alloc_fast(xll->chset, &chs->sample_buffer3, 2 * nsamples * chs->nchannels, sizeof(int)) < 0) return -DCADEC_ENOMEM; // Assemble frequency bands 0 and 1 int *ptr = chs->sample_buffer3; for (int ch = 0; ch < chs->nchannels; ch++) { // Remap output channel pointer to assembly buffer chs->out_sample_buffer[ch] = ptr; int *band0 = chs->bands[XLL_BAND_0].msb_sample_buffer[ch]; int *band1 = chs->bands[XLL_BAND_1].msb_sample_buffer[ch]; // Copy decimator history for (int i = 1; i < XLL_DECI_HISTORY; i++) band0[i - XLL_DECI_HISTORY] = chs->deci_history[ch][i]; // Filter filter1(band0, band1, nsamples, band_coeff_table0[0]); filter1(band1, band0, nsamples, band_coeff_table0[1]); filter1(band0, band1, nsamples, band_coeff_table0[2]); filter0(band1, band0, nsamples); for (int i = 0; i < XLL_DECI_HISTORY; i++) { filter2(band0, band1, nsamples, band_coeff_table1[i]); filter2(band1, band0, nsamples, band_coeff_table2[i]); filter2(band0, band1, nsamples, band_coeff_table1[i]); band0--; } // Assemble for (int i = 0; i < nsamples; i++) { *ptr++ = *band1++; *ptr++ = *++band0; } } return 0; } int xll_assemble_freq_bands(struct xll_decoder *xll) { int ret; for (int i = 0; i < xll->nactivechsets; i++) if ((ret = chs_assemble_freq_bands(&xll->chset[i])) < 0) return ret; return 0; } int xll_map_ch_to_spkr(struct xll_chset *chs, int ch) { struct xll_decoder *xll = chs->decoder; if (chs->ch_mask_enabled) { for (int spkr = 0, pos = 0; spkr < xll->ch_mask_nbits; spkr++) if (chs->ch_mask & (1U << spkr)) if (pos++ == ch) return spkr; return -1; // Invalid } // Map to LtRt if (chs->nchannels == 2) { if (ch == 0) return SPEAKER_L; if (ch == 1) return SPEAKER_R; } return -1; } static int parse_common_header(struct xll_decoder *xll) { int ret; // XLL extension sync word if (bits_get(&xll->bits, 32) != SYNC_WORD_XLL) { xll_verbose("Invalid XLL sync word"); return -DCADEC_ENOSYNC; } // Version number int stream_ver = bits_get(&xll->bits, 4) + 1; if (stream_ver > 1) { xll_err_once("Unsupported XLL stream version (%d)", stream_ver); return -DCADEC_ENOSUP; } // Lossless frame header length int header_size = bits_get(&xll->bits, 8) + 1; // Check CRC if ((ret = bits_check_crc(&xll->bits, 32, header_size * 8)) < 0) { xll_err("Invalid XLL common header checksum"); return ret; } // Number of bits used to read frame size int frame_size_nbits = bits_get(&xll->bits, 5) + 1; // Number of bytes in a lossless frame xll->frame_size = bits_get(&xll->bits, frame_size_nbits); if (xll->frame_size < 0 || xll->frame_size >= XLL_PBR_SIZE) { xll_err("Invalid XLL frame size"); return -DCADEC_EBADDATA; } xll->frame_size++; // Number of channels sets per frame xll->nchsets = bits_get(&xll->bits, 4) + 1; if (xll->nchsets > 3) xll_warn_once("Stream with %d channel sets", xll->nchsets); // Number of segments per frame int nframesegs_log2 = bits_get(&xll->bits, 4); xll->nframesegs = 1 << nframesegs_log2; if (xll->nframesegs > 1024) { xll_err("Too many segments per frame"); return -DCADEC_EBADDATA; } // Samples in segment per one frequency band for the first channel set // Maximum value is 256 for sampling frequencies <= 48 kHz // Maximum value is 512 for sampling frequencies > 48 kHz xll->nsegsamples_log2 = bits_get(&xll->bits, 4); if (!xll->nsegsamples_log2) { xll_err("Too few samples per segment"); return -DCADEC_EBADDATA; } xll->nsegsamples = 1 << xll->nsegsamples_log2; if (xll->nsegsamples > 512) { xll_err("Too many samples per segment"); return -DCADEC_EBADDATA; } // Samples in frame per one frequency band for the first channel set xll->nframesamples_log2 = xll->nsegsamples_log2 + nframesegs_log2; xll->nframesamples = 1 << xll->nframesamples_log2; if (xll->nframesamples > 65536) { xll_err("Too many samples per frame"); return -DCADEC_EBADDATA; } // Number of bits used to read segment size xll->seg_size_nbits = bits_get(&xll->bits, 5) + 1; // Presence of CRC16 within each frequency band // 0 - No CRC16 within band // 1 - CRC16 placed at the end of MSB0 // 2 - CRC16 placed at the end of MSB0 and LSB0 // 3 - CRC16 placed at the end of MSB0 and LSB0 and other frequency bands xll->band_crc_present = bits_get(&xll->bits, 2); if (xll->band_crc_present) xll_warn_once("Stream with band CRC present (%d)", xll->band_crc_present); // MSB/LSB split flag xll->scalable_lsbs = bits_get1(&xll->bits); // Channel position mask xll->ch_mask_nbits = bits_get(&xll->bits, 5) + 1; // Fixed LSB width if (xll->scalable_lsbs) xll->fixed_lsb_width = bits_get(&xll->bits, 4); else xll->fixed_lsb_width = 0; if (xll->fixed_lsb_width) xll_warn_once("Stream with fixed LSB width (%d)", xll->fixed_lsb_width); // Reserved // Byte align // Header CRC16 protection if ((ret = bits_seek(&xll->bits, header_size * 8)) < 0) xll_err("Read past end of XLL common header"); return ret; } static int parse_sub_headers(struct xll_decoder *xll, struct exss_asset *asset) { struct xll_chset *chs; int i, ret; // Reallocate channel sets if (ta_zalloc_fast(xll, &xll->chset, xll->nchsets, sizeof(struct xll_chset)) < 0) return -DCADEC_ENOMEM; // Parse channel set headers xll->nfreqbands = 0; xll->nchannels = 0; for (i = 0, chs = xll->chset; i < xll->nchsets; i++, chs++) { chs->decoder = xll; chs->hier_m = xll->nchannels; if ((ret = chs_parse_header(chs, asset)) < 0) return ret; if (chs->nfreqbands > xll->nfreqbands) xll->nfreqbands = chs->nfreqbands; if (chs->hier_chset) xll->nchannels += chs->nchannels; } // Number of active channel sets to decode if (xll->flags & DCADEC_FLAG_KEEP_DMIX_2CH) xll->nactivechsets = 1; else if (xll->flags & DCADEC_FLAG_KEEP_DMIX_6CH) xll->nactivechsets = (xll->chset->nchannels < 5 && xll->nchsets > 1) ? 2 : 1; else xll->nactivechsets = xll->nchsets; return 0; } static int parse_navi_table(struct xll_decoder *xll) { struct xll_chset *chs; int i; int navi_nb = xll->nfreqbands * xll->nframesegs * xll->nchsets; if (navi_nb > 1024) { xll_err("Too many NAVI entries"); return -DCADEC_EBADDATA; } // Reallocate NAVI table if (ta_alloc_fast(xll, &xll->navi, navi_nb, sizeof(*xll->navi)) < 0) return -DCADEC_ENOMEM; // Parse NAVI int navi_pos = xll->bits.index; int *navi_ptr = xll->navi; for (int band = 0; band < xll->nfreqbands; band++) { for (int seg = 0; seg < xll->nframesegs; seg++) { for (i = 0, chs = xll->chset; i < xll->nchsets; i++, chs++) { int size = 0; if (chs->nfreqbands > band) { size = bits_get(&xll->bits, xll->seg_size_nbits); if (size < 0 || size >= xll->frame_size) { xll_err("Invalid NAVI size"); return -DCADEC_EBADDATA; } size++; } *navi_ptr++ = size; } } } // Byte align // CRC16 bits_align1(&xll->bits); bits_skip(&xll->bits, 16); // Check CRC int ret; if ((ret = bits_check_crc(&xll->bits, navi_pos, xll->bits.index)) < 0) xll_err("Invalid NAVI checksum"); return ret; } static int parse_band_data(struct xll_decoder *xll) { struct xll_chset *chs; int i, ret; for (i = 0, chs = xll->chset; i < xll->nactivechsets; i++, chs++) { if ((ret = chs_alloc_msb_band_data(chs)) < 0) return ret; if ((ret = chs_alloc_lsb_band_data(chs)) < 0) return ret; } xll->nfailedsegs = 0; int navi_pos = xll->bits.index; int *navi_ptr = xll->navi; for (int band = 0; band < xll->nfreqbands; band++) { for (int seg = 0; seg < xll->nframesegs; seg++) { for (i = 0, chs = xll->chset; i < xll->nchsets; i++, chs++) { if (chs->nfreqbands > band) { navi_pos += *navi_ptr * 8; if (navi_pos > xll->bits.total) { xll_err("Invalid NAVI position"); return -DCADEC_EBADREAD; } if (i < xll->nactivechsets && (ret = chs_parse_band_data(chs, band, seg, navi_pos)) < 0) { if (xll->flags & DCADEC_FLAG_STRICT) return ret; // Zero band data and advance to next segment chs_clear_band_data(chs, band, seg); xll->nfailedsegs++; } xll->bits.index = navi_pos; } navi_ptr++; } } } return 0; } static int parse_frame(struct xll_decoder *xll, uint8_t *data, int size, struct exss_asset *asset) { int ret; bits_init(&xll->bits, data, size); if ((ret = parse_common_header(xll)) < 0) return ret; if ((ret = parse_sub_headers(xll, asset)) < 0) return ret; if ((ret = parse_navi_table(xll)) < 0) return ret; if ((ret = parse_band_data(xll)) < 0) return ret; if ((ret = bits_seek(&xll->bits, xll->frame_size * 8)) < 0) xll_err("Read past end of XLL frame"); return ret; } static void clear_pbr(struct xll_decoder *xll) { xll->pbr_length = 0; xll->pbr_delay = 0; } static int copy_to_pbr(struct xll_decoder *xll, uint8_t *data, int size, int delay) { if (size > XLL_PBR_SIZE) { xll_err("PBR smoothing buffer overflow"); return -DCADEC_EINVAL; } if (!xll->pbr_buffer && !(xll->pbr_buffer = ta_zalloc_size(xll, XLL_PBR_SIZE + DCADEC_BUFFER_PADDING))) return -DCADEC_ENOMEM; memcpy(xll->pbr_buffer, data, size); xll->pbr_length = size; xll->pbr_delay = delay; return 0; } static int parse_frame_no_pbr(struct xll_decoder *xll, uint8_t *data, int size, struct exss_asset *asset) { int ret = parse_frame(xll, data, size, asset); // If XLL packet data didn't start with a sync word, we must have jumped // right into the middle of PBR smoothing period if (ret == -DCADEC_ENOSYNC && asset->xll_sync_present) { if (asset->xll_sync_offset > size) { xll_err("Invalid XLL sync word offset"); return -DCADEC_EINVAL; } if (asset->xll_delay_nframes < 0) { xll_err("Invalid XLL decoding delay"); return -DCADEC_EINVAL; } // Skip to the next sync word in this packet data += asset->xll_sync_offset; size -= asset->xll_sync_offset; // No data to buffer? Should not really happen. if (size == 0) return -DCADEC_ENOSYNC; // If decoding delay is set, put the frame into PBR buffer and return // failure code. Higher level decoder is expected to switch to lossy // core decoding or mute its output until decoding delay expires. if (asset->xll_delay_nframes > 0) { if ((ret = copy_to_pbr(xll, data, size, asset->xll_delay_nframes)) < 0) return ret; return -DCADEC_ENOSYNC; } // Can't parse in place when data is not aligned properly. We could // copy to PBR buffer first, but don't bother for now. if (asset->xll_sync_offset & 3) { xll_warn("Unsupported XLL sync word alignment"); return -DCADEC_ENOSYNC; } // No decoding delay, just parse the frame in place ret = parse_frame(xll, data, size, asset); } if (ret < 0) return ret; if (xll->frame_size > size) return -DCADEC_EINVAL; // If the XLL decoder didn't consume full packet, start PBR smoothing period if (xll->frame_size < size) if ((ret = copy_to_pbr(xll, data + xll->frame_size, size - xll->frame_size, 0)) < 0) return ret; return 0; } static int parse_frame_pbr(struct xll_decoder *xll, uint8_t *data, int size, struct exss_asset *asset) { int ret; if (size > XLL_PBR_SIZE - xll->pbr_length) { xll_err("PBR smoothing buffer overflow"); ret = -DCADEC_EINVAL; goto fail; } memcpy(xll->pbr_buffer + xll->pbr_length, data, size); xll->pbr_length += size; // Respect decoding delay after synchronization error if (xll->pbr_delay > 0 && --xll->pbr_delay) { xll_verbose("Waiting until XLL decoding delay expires (%d)", xll->pbr_delay); return -DCADEC_ENOSYNC; } if ((ret = parse_frame(xll, xll->pbr_buffer, xll->pbr_length, asset)) < 0) goto fail; if (xll->frame_size > xll->pbr_length) { ret = -DCADEC_EINVAL; goto fail; } if (xll->frame_size == xll->pbr_length) { // End of PBR smoothing period clear_pbr(xll); } else { xll->pbr_length -= xll->frame_size; memmove(xll->pbr_buffer, xll->pbr_buffer + xll->frame_size, xll->pbr_length); } return 0; fail: // For now, throw out all PBR state on failure. // Perhaps we can be smarter and try to at least resync. clear_pbr(xll); return ret; } static void clear_chs(struct xll_decoder *xll) { if (xll->chset) { for (int i = 0; i < xll->nchsets; i++) { xll->chset[i].dmix_coeffs_signature = 0; xll->chset[i].dmix_coeffs_parity = false; } } } int xll_parse(struct xll_decoder *xll, uint8_t *data, struct exss_asset *asset) { int ret; if (xll->hd_stream_id != asset->hd_stream_id) { xll_clear(xll); xll->hd_stream_id = asset->hd_stream_id; } if (xll->pbr_length) ret = parse_frame_pbr(xll, data + asset->xll_offset, asset->xll_size, asset); else ret = parse_frame_no_pbr(xll, data + asset->xll_offset, asset->xll_size, asset); if (ret < 0) clear_chs(xll); return ret; } void xll_clear(struct xll_decoder *xll) { if (xll) { clear_pbr(xll); clear_chs(xll); } } ================================================ FILE: libdcadec/xll_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 XLL_DECODER_H #define XLL_DECODER_H #include "bitstream.h" #define XLL_MAX_CHANNELS 8 #define XLL_MAX_BANDS 2 #define XLL_MAX_ADAPT_PRED_ORDER 16 #define XLL_DECI_HISTORY 8 #define XLL_BAND_0 0 #define XLL_BAND_1 1 #define XLL_DMIX_SIGNATURE(chs) \ ((chs)->nchannels | ((chs)->hier_m << 4) | ((chs)->primary_chset << 12) \ | ((chs)->dmix_embedded << 13) | ((chs)->hier_chset << 14) | ((chs)->dmix_type << 15)) #define xll_err(...) dca_log(xll, ERROR, __VA_ARGS__) #define xll_warn(...) dca_log(xll, WARNING, __VA_ARGS__) #define xll_verbose(...) dca_log(xll, VERBOSE, __VA_ARGS__) #define xll_err_once(...) dca_log_once(xll, ERROR, __VA_ARGS__) #define xll_warn_once(...) dca_log_once(xll, WARNING, __VA_ARGS__) struct xll_decoder; struct exss_asset; struct xll_band { bool decor_enabled; ///< Pairwise channel decorrelation flag int orig_order[XLL_MAX_CHANNELS]; ///< Original channel order int decor_coeff[XLL_MAX_CHANNELS / 2]; ///< Pairwise channel coefficients int adapt_pred_order[XLL_MAX_CHANNELS]; ///< Adaptive predictor order int highest_pred_order; ///< Highest adaptive predictor order int fixed_pred_order[XLL_MAX_CHANNELS]; ///< Fixed predictor order int adapt_refl_coeff[XLL_MAX_CHANNELS][XLL_MAX_ADAPT_PRED_ORDER]; ///< Adaptive predictor reflection coefficients bool dmix_embedded; ///< Downmix performed by encoder in frequency band int lsb_section_size; ///< Size of LSB section in any segment int nscalablelsbs[XLL_MAX_CHANNELS]; ///< Number of bits to represent the samples in LSB part int bit_width_adjust[XLL_MAX_CHANNELS]; ///< Number of bits discarded by authoring int *msb_sample_buffer[XLL_MAX_CHANNELS]; ///< MSB sample buffer pointers int *lsb_sample_buffer[XLL_MAX_CHANNELS]; ///< LSB sample buffer pointers or NULL }; struct xll_chset { struct xll_decoder *decoder; ///< Parent context // Channel set header int nchannels; ///< Number of channels in the channel set (N) int residual_encode; ///< Residual encoding mask (0 - residual, 1 - full channel) int pcm_bit_res; ///< PCM bit resolution (variable) int storage_bit_res; ///< Storage bit resolution (16 or 24) int freq; ///< Original sampling frequency (max. 96000 Hz) int interpolate; ///< Sampling frequency modifier int replace_set_index; ///< Which replacement set this channel set is member of bool primary_chset; ///< Primary channel set flag bool dmix_coeffs_present; ///< Downmix coefficients present in stream bool dmix_embedded; ///< Downmix already performed by encoder int dmix_type; ///< Primary channel set downmix type bool hier_chset; ///< Whether the channel set is part of a hierarchy int hier_m; ///< Number of preceding channels in a hierarchy (M) int *dmix_coeff; ///< Downmixing coefficients buffer base int *dmix_coeff_cur; ///< M*N downmixing coefficients for current frame int *dmix_coeff_pre; ///< M*N downmixing coefficients for previous frame int *dmix_scale_cur; ///< M downmixing scales for current frame int *dmix_scale_pre; ///< M downmixing scales for previous frame int *dmix_scale_inv_cur; ///< M inverse downmixing scales for current frame int *dmix_scale_inv_pre; ///< M inverse downmixing scales for previous frame int dmix_coeffs_signature; ///< Signature of downmixing parameters from previous frame bool dmix_coeffs_parity; ///< Index of current downmixing coefficients buffer, flipped each frame bool ch_mask_enabled; ///< Channel mask enabled int ch_mask; ///< Channel mask for set int nfreqbands; ///< Number of frequency bands (1 or 2) int nabits; ///< Number of bits to read bit allocation coding parameter struct xll_band bands[XLL_MAX_BANDS]; ///< Frequency bands // Frequency band coding parameters bool seg_common; ///< Segment type bool rice_code_flag[XLL_MAX_CHANNELS]; ///< Rice coding flag int bitalloc_hybrid_linear[XLL_MAX_CHANNELS]; ///< Binary code length for isolated samples int bitalloc_part_a[XLL_MAX_CHANNELS]; ///< Coding parameter for part A of segment int bitalloc_part_b[XLL_MAX_CHANNELS]; ///< Coding parameter for part B of segment int nsamples_part_a[XLL_MAX_CHANNELS]; ///< Number of samples in part A of segment // Decimator history int deci_history[XLL_MAX_CHANNELS][XLL_DECI_HISTORY]; ///< Decimator history for frequency band 1 // Sample buffers int *out_sample_buffer[XLL_MAX_CHANNELS]; ///< Output sample buffer pointers int *sample_buffer1; ///< MSB sample buffer base int *sample_buffer2; ///< LSB sample buffer base int *sample_buffer3; ///< Frequency band assembly buffer base }; struct xll_decoder { struct dcadec_context *ctx; ///< Parent context struct bitstream bits; ///< Bitstream reader int flags; ///< Context flags int frame_size; ///< Number of bytes in a lossless frame int nchsets; ///< Number of channels sets per frame int nframesegs; ///< Number of segments per frame int nsegsamples_log2; ///< log2(nsegsamples) int nsegsamples; ///< Samples in segment per one frequency band int nframesamples_log2; ///< log2(nframesamples) int nframesamples; ///< Samples in frame per one frequency band int seg_size_nbits; ///< Number of bits used to read segment size int band_crc_present; ///< Presence of CRC16 within each frequency band bool scalable_lsbs; ///< MSB/LSB split flag int ch_mask_nbits; ///< Number of bits used to read channel mask int fixed_lsb_width; ///< Fixed LSB width struct xll_chset *chset; ///< Channel sets int *navi; ///< NAVI table int nfreqbands; ///< Highest number of frequency bands int nchannels; ///< Total number of channels in a hierarchy int nactivechsets; ///< Number of active channel sets to decode int nfailedsegs; ///< Number of frequency band segments that failed to decode int hd_stream_id; ///< Previous DTS-HD stream ID for detecting changes uint8_t *pbr_buffer; ///< Peak bit rate (PBR) smoothing buffer int pbr_length; ///< Length in bytes of data currently buffered int pbr_delay; ///< Delay in frames before decoding buffered data }; void xll_clear_band_data(struct xll_chset *chs, int band) __attribute__((cold)); void xll_filter_band_data(struct xll_chset *chs, int band); int xll_get_lsb_width(struct xll_chset *chs, int band, int ch); void xll_assemble_msbs_lsbs(struct xll_chset *chs, int band); int xll_assemble_freq_bands(struct xll_decoder *xll); int xll_map_ch_to_spkr(struct xll_chset *chs, int ch); int xll_parse(struct xll_decoder *xll, uint8_t *data, struct exss_asset *asset); void xll_clear(struct xll_decoder *xll) __attribute__((cold)); #endif ================================================ FILE: libdcadec/xll_tables.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 */ // Section 8.4.3: Look-up table of quantized reflection coefficients static const uint16_t refl_coeff_table[128] = { 0, 3070, 5110, 7140, 9156, 11154, 13132, 15085, 17010, 18904, 20764, 22588, 24373, 26117, 27818, 29474, 31085, 32648, 34164, 35631, 37049, 38418, 39738, 41008, 42230, 43404, 44530, 45609, 46642, 47630, 48575, 49477, 50337, 51157, 51937, 52681, 53387, 54059, 54697, 55302, 55876, 56421, 56937, 57426, 57888, 58326, 58741, 59132, 59502, 59852, 60182, 60494, 60789, 61066, 61328, 61576, 61809, 62029, 62236, 62431, 62615, 62788, 62951, 63105, 63250, 63386, 63514, 63635, 63749, 63855, 63956, 64051, 64140, 64224, 64302, 64376, 64446, 64512, 64573, 64631, 64686, 64737, 64785, 64830, 64873, 64913, 64950, 64986, 65019, 65050, 65079, 65107, 65133, 65157, 65180, 65202, 65222, 65241, 65259, 65275, 65291, 65306, 65320, 65333, 65345, 65357, 65368, 65378, 65387, 65396, 65405, 65413, 65420, 65427, 65434, 65440, 65446, 65451, 65456, 65461, 65466, 65470, 65474, 65478, 65481, 65485, 65488, 65491 }; static const uint8_t ch_nbits[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; static const int32_t band_coeff_table0[] = { 868669, -5931642, -1228483 }; static const int32_t band_coeff_table1[] = { -20577, 122631, -393647, 904476, -1696305, 2825313, -4430736, 6791313 }; static const int32_t band_coeff_table2[] = { 41153, -245210, 785564, -1788164, 3259333, -5074941, 6928550, -8204883 }; ================================================ FILE: msvc/dcadec/dcadec.vcxproj ================================================ Debug DLL Win32 Debug DLL x64 Debug Win32 Debug x64 Release DLL Win32 Release DLL x64 Release Win32 Release x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8} Win32Proj dcadec Application true v120 Unicode Application true v120 Unicode Application true v120 Unicode Application true v120 Unicode Application false v120 true Unicode Application false v120 true Unicode Application false v120 true Unicode Application false v120 true Unicode true true true true false false false false Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console true $(OutDir)libdcadec.lib;%(AdditionalDependencies) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console true $(OutDir)libdcadec.lib;%(AdditionalDependencies) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;%(PreprocessorDefinitions) Console true $(OutDir)libdcadec.lib;%(AdditionalDependencies) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;%(PreprocessorDefinitions) Console true $(OutDir)libdcadec.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console true true true $(OutDir)libdcadec.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) Console true true true $(OutDir)libdcadec.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;%(PreprocessorDefinitions) Console true true true $(OutDir)libdcadec.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;%(PreprocessorDefinitions) Console true true true $(OutDir)libdcadec.lib;%(AdditionalDependencies) ================================================ FILE: msvc/dcadec/dcadec.vcxproj.filters ================================================ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Header Files ================================================ FILE: msvc/dcadec.sln ================================================ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdcadec", "libdcadec\libdcadec.vcxproj", "{5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcadec", "dcadec\dcadec.vcxproj", "{594F41A5-3F08-4CF9-84F4-237466EC5EE8}" ProjectSection(ProjectDependencies) = postProject {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0} = {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug DLL|Win32 = Debug DLL|Win32 Debug DLL|x64 = Debug DLL|x64 Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release DLL|Win32 = Release DLL|Win32 Release DLL|x64 = Release DLL|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug DLL|x64.ActiveCfg = Debug DLL|x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug DLL|x64.Build.0 = Debug DLL|x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug|Win32.ActiveCfg = Debug|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug|Win32.Build.0 = Debug|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug|x64.ActiveCfg = Debug|x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Debug|x64.Build.0 = Debug|x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release DLL|Win32.Build.0 = Release DLL|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release DLL|x64.ActiveCfg = Release DLL|x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release DLL|x64.Build.0 = Release DLL|x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release|Win32.ActiveCfg = Release|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release|Win32.Build.0 = Release|Win32 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release|x64.ActiveCfg = Release|x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0}.Release|x64.Build.0 = Release|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug DLL|x64.ActiveCfg = Debug DLL|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug DLL|x64.Build.0 = Debug DLL|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug|Win32.ActiveCfg = Debug|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug|Win32.Build.0 = Debug|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug|x64.ActiveCfg = Debug|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Debug|x64.Build.0 = Debug|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release DLL|Win32.Build.0 = Release DLL|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release DLL|x64.ActiveCfg = Release DLL|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release DLL|x64.Build.0 = Release DLL|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release|Win32.ActiveCfg = Release|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release|Win32.Build.0 = Release|Win32 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release|x64.ActiveCfg = Release|x64 {594F41A5-3F08-4CF9-84F4-237466EC5EE8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: msvc/libdcadec/libdcadec.vcxproj ================================================ Debug DLL Win32 Debug DLL x64 Debug Win32 Debug x64 Release DLL Win32 Release DLL x64 Release Win32 Release x64 {5B5AAF6D-79E0-42AE-8B57-2BEFA8C571F0} Win32Proj libdcadec StaticLibrary true v120 Unicode StaticLibrary true v120 Unicode DynamicLibrary true v120 Unicode DynamicLibrary true v120 Unicode StaticLibrary false v120 true Unicode StaticLibrary false v120 true Unicode DynamicLibrary false v120 true Unicode DynamicLibrary false v120 true Unicode .dll .dll .dll .dll Level3 Disabled WIN32;_DEBUG;_LIB;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 4146 Windows true Level3 Disabled WIN32;_DEBUG;_LIB;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 4146 Windows true Level3 Disabled WIN32;_DEBUG;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;DCADEC_INTERNAL;%(PreprocessorDefinitions) 4146 Windows true %(AdditionalDependencies) false Level3 Disabled WIN32;_DEBUG;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;DCADEC_INTERNAL;%(PreprocessorDefinitions) 4146 Windows true %(AdditionalDependencies) false Level3 MaxSpeed true true WIN32;NDEBUG;_LIB;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 4146 Windows true true true Level3 MaxSpeed true true WIN32;NDEBUG;_LIB;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 4146 Windows true true true Level3 MaxSpeed true true WIN32;NDEBUG;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;DCADEC_INTERNAL;%(PreprocessorDefinitions) 4146 Windows true true %(AdditionalDependencies) true Level3 MaxSpeed true true WIN32;NDEBUG;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;DCADEC_SHARED;DCADEC_INTERNAL;%(PreprocessorDefinitions) 4146 Windows true true %(AdditionalDependencies) true ================================================ FILE: msvc/libdcadec/libdcadec.vcxproj.filters ================================================ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files ================================================ FILE: test/checksum.txt ================================================ 9415e0d4c7cd58ee793d7b2bfae34e4de411181c *decoded/dmix_0/core_51_24_48_768_0.wav de10f73b35c2db915f69c46ddc95468c25510bdf *decoded/dmix_0/core_51_24_48_768_1.wav 15a63dd037994c3f4749ae8f6e27bdcae83835d8 *decoded/dmix_0/x96_51_24_96_1509.wav 2ba74e27d61f041d4a2bb124a636182ed0104996 *decoded/dmix_0/x96_xch_61_24_96_3840.wav 1b310b329e1f8df551798fdd104c6af6d5dec904 *decoded/dmix_0/x96_xxch_71_24_96_3840.wav b64efecbd7b2df7b5edb3dbda7f2b3f715c06eef *decoded/dmix_0/xbr_51_24_48_3840.wav 346e21a2f26f798808709e4153ea68b6207e377c *decoded/dmix_0/xbr_xch_61_24_48_3840.wav eabf815257bba4388e46c3330ee8456d793bb44d *decoded/dmix_0/xbr_xxch_71_24_48_3840.wav 05529c0991df6e55811b582b263118a62f2ff1e7 *decoded/dmix_0/xch_61_24_48_768.wav d7f7cf50d55ce32aea4121549973db16cd5d5bd0 *decoded/dmix_0/xll_51_16_192_768_0.wav d7f7cf50d55ce32aea4121549973db16cd5d5bd0 *decoded/dmix_0/xll_51_16_192_768_1.wav 15be906b3c57c90304702eab2cc83650e553da1d *decoded/dmix_0/xll_51_24_48_768.wav 96d31af60dc3e8b5c568737ff697730b7c549ea0 *decoded/dmix_0/xll_51_24_48_none.wav 431446b087a74257d338c290bd31a40e6e54e060 *decoded/dmix_0/xll_71_24_48_768_0.wav 431446b087a74257d338c290bd31a40e6e54e060 *decoded/dmix_0/xll_71_24_48_768_1.wav 045f5972843c5e442678d742fe1e6d3af1d062f9 *decoded/dmix_0/xll_71_24_96_768.wav a3d3eb3ef1d6f96bb95c809d8b2c053133e25f20 *decoded/dmix_0/xll_x96_51_24_96_1509.wav e3cbf8670dd14208c34a66cae90c45c2eb20d6bb *decoded/dmix_0/xll_xch_61_24_48_768.wav 009524ee6202a4f8e8daa6a4033a8e1c4909508d *decoded/dmix_0/xxch_71_24_48_2046.wav 9415e0d4c7cd58ee793d7b2bfae34e4de411181c *decoded/dmix_2/core_51_24_48_768_0.wav ecd0b8b3a6a79691be3ad3da904e7e9c3b1f313d *decoded/dmix_2/core_51_24_48_768_1.wav 15a63dd037994c3f4749ae8f6e27bdcae83835d8 *decoded/dmix_2/x96_51_24_96_1509.wav 40b95e3e5afa4660bf858fff2e96df1ec3326716 *decoded/dmix_2/x96_xch_61_24_96_3840.wav dee2f9f5c98a23431325e194606f9541a0680ee6 *decoded/dmix_2/x96_xxch_71_24_96_3840.wav b64efecbd7b2df7b5edb3dbda7f2b3f715c06eef *decoded/dmix_2/xbr_51_24_48_3840.wav 54fcc9441c3670b43d2df2e4018f5be4d481c9db *decoded/dmix_2/xbr_xch_61_24_48_3840.wav 6e2e95df72687c818164d84ddc20f41a90935cdc *decoded/dmix_2/xbr_xxch_71_24_48_3840.wav 55d2dd0ae8501134963655e149ee7420859d6996 *decoded/dmix_2/xch_61_24_48_768.wav d7f7cf50d55ce32aea4121549973db16cd5d5bd0 *decoded/dmix_2/xll_51_16_192_768_0.wav 9b5e7b8109cadcccec7b98784856cdb87b787ca0 *decoded/dmix_2/xll_51_16_192_768_1.wav 47043676e438e3727f398ff6f0b2b46ec3ab02f6 *decoded/dmix_2/xll_51_24_48_768.wav 96d31af60dc3e8b5c568737ff697730b7c549ea0 *decoded/dmix_2/xll_51_24_48_none.wav 1c0c7ad09c2d335bd3dae9f8b5b6bb803f211abe *decoded/dmix_2/xll_71_24_48_768_0.wav 4b701b2b906a1af079774b23052e96fb8ee1a5fc *decoded/dmix_2/xll_71_24_48_768_1.wav 359ea5c7b8abcbde36c469afa9b364ba4dc59f9f *decoded/dmix_2/xll_71_24_96_768.wav a3d3eb3ef1d6f96bb95c809d8b2c053133e25f20 *decoded/dmix_2/xll_x96_51_24_96_1509.wav bf59eebc557f8240fe9545ecc8fddd4ff52c3fb6 *decoded/dmix_2/xll_xch_61_24_48_768.wav fb4040a45e51de1bde777b1c5e1116462e9d9aba *decoded/dmix_2/xxch_71_24_48_2046.wav 9415e0d4c7cd58ee793d7b2bfae34e4de411181c *decoded/dmix_6/core_51_24_48_768_0.wav de10f73b35c2db915f69c46ddc95468c25510bdf *decoded/dmix_6/core_51_24_48_768_1.wav 15a63dd037994c3f4749ae8f6e27bdcae83835d8 *decoded/dmix_6/x96_51_24_96_1509.wav 40b95e3e5afa4660bf858fff2e96df1ec3326716 *decoded/dmix_6/x96_xch_61_24_96_3840.wav dee2f9f5c98a23431325e194606f9541a0680ee6 *decoded/dmix_6/x96_xxch_71_24_96_3840.wav b64efecbd7b2df7b5edb3dbda7f2b3f715c06eef *decoded/dmix_6/xbr_51_24_48_3840.wav 54fcc9441c3670b43d2df2e4018f5be4d481c9db *decoded/dmix_6/xbr_xch_61_24_48_3840.wav 6e2e95df72687c818164d84ddc20f41a90935cdc *decoded/dmix_6/xbr_xxch_71_24_48_3840.wav 55d2dd0ae8501134963655e149ee7420859d6996 *decoded/dmix_6/xch_61_24_48_768.wav d7f7cf50d55ce32aea4121549973db16cd5d5bd0 *decoded/dmix_6/xll_51_16_192_768_0.wav d7f7cf50d55ce32aea4121549973db16cd5d5bd0 *decoded/dmix_6/xll_51_16_192_768_1.wav 15be906b3c57c90304702eab2cc83650e553da1d *decoded/dmix_6/xll_51_24_48_768.wav 96d31af60dc3e8b5c568737ff697730b7c549ea0 *decoded/dmix_6/xll_51_24_48_none.wav 1c0c7ad09c2d335bd3dae9f8b5b6bb803f211abe *decoded/dmix_6/xll_71_24_48_768_0.wav 179e28454bc831cbba30369357dfe6778b4cb1c5 *decoded/dmix_6/xll_71_24_48_768_1.wav 359ea5c7b8abcbde36c469afa9b364ba4dc59f9f *decoded/dmix_6/xll_71_24_96_768.wav a3d3eb3ef1d6f96bb95c809d8b2c053133e25f20 *decoded/dmix_6/xll_x96_51_24_96_1509.wav bf59eebc557f8240fe9545ecc8fddd4ff52c3fb6 *decoded/dmix_6/xll_xch_61_24_48_768.wav fb4040a45e51de1bde777b1c5e1116462e9d9aba *decoded/dmix_6/xxch_71_24_48_2046.wav f9567e7e8926a0d1247d551dfdee06922953fda2 *decoded/mono/xll_51_16_192_768_0_C.wav b338184ad40c7bfab8811ca465ee333d5da818ff *decoded/mono/xll_51_16_192_768_0_L.wav d5e0325811b8ca44093b33104fa390300068f1ec *decoded/mono/xll_51_16_192_768_0_LFE.wav 63f9cb37032d724d30bfa4224e6dcd5ce76ee926 *decoded/mono/xll_51_16_192_768_0_Ls.wav b338184ad40c7bfab8811ca465ee333d5da818ff *decoded/mono/xll_51_16_192_768_0_R.wav 63f9cb37032d724d30bfa4224e6dcd5ce76ee926 *decoded/mono/xll_51_16_192_768_0_Rs.wav f9567e7e8926a0d1247d551dfdee06922953fda2 *decoded/mono/xll_51_16_192_768_1_C.wav b338184ad40c7bfab8811ca465ee333d5da818ff *decoded/mono/xll_51_16_192_768_1_L.wav d5e0325811b8ca44093b33104fa390300068f1ec *decoded/mono/xll_51_16_192_768_1_LFE.wav 63f9cb37032d724d30bfa4224e6dcd5ce76ee926 *decoded/mono/xll_51_16_192_768_1_Ls.wav b338184ad40c7bfab8811ca465ee333d5da818ff *decoded/mono/xll_51_16_192_768_1_R.wav 63f9cb37032d724d30bfa4224e6dcd5ce76ee926 *decoded/mono/xll_51_16_192_768_1_Rs.wav bbbf7fd9a60805e384c6cc3c95bd48a2b74ed5e3 *decoded/mono/xll_51_24_48_768_C.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_51_24_48_768_L.wav d7fdbd9e826aa3de8aa4ee2156068369a3bbbf9a *decoded/mono/xll_51_24_48_768_LFE.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_51_24_48_768_Ls.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_51_24_48_768_R.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_51_24_48_768_Rs.wav 241d6ed12c09bd02e89d9c2eddb8daac5e4688ba *decoded/mono/xll_51_24_48_none_C.wav 5eeff9f6c2993ed8bbea174659133e8b0fb2eb2d *decoded/mono/xll_51_24_48_none_L.wav 9bb05d6de708d22837128168ec951b8a91cedfa8 *decoded/mono/xll_51_24_48_none_LFE.wav 5a0cb7df9dee257d81d7c08729bc2c5830c7807d *decoded/mono/xll_51_24_48_none_Ls.wav b54ee1a50ddfa843860e7c6e8a4643261e6babea *decoded/mono/xll_51_24_48_none_R.wav 5d89b3afc78c63ca3dec1ea77b2a06be0d8ce4fa *decoded/mono/xll_51_24_48_none_Rs.wav bbbf7fd9a60805e384c6cc3c95bd48a2b74ed5e3 *decoded/mono/xll_71_24_48_768_0_C.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_71_24_48_768_0_L.wav d7fdbd9e826aa3de8aa4ee2156068369a3bbbf9a *decoded/mono/xll_71_24_48_768_0_LFE.wav af2edeaf1bb4b7992d4161615e6bc30be8277407 *decoded/mono/xll_71_24_48_768_0_Lsr.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_71_24_48_768_0_Lss.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_71_24_48_768_0_R.wav af2edeaf1bb4b7992d4161615e6bc30be8277407 *decoded/mono/xll_71_24_48_768_0_Rsr.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_71_24_48_768_0_Rss.wav bbbf7fd9a60805e384c6cc3c95bd48a2b74ed5e3 *decoded/mono/xll_71_24_48_768_1_C.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_71_24_48_768_1_L.wav d7fdbd9e826aa3de8aa4ee2156068369a3bbbf9a *decoded/mono/xll_71_24_48_768_1_LFE.wav af2edeaf1bb4b7992d4161615e6bc30be8277407 *decoded/mono/xll_71_24_48_768_1_Lsr.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_71_24_48_768_1_Lss.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_71_24_48_768_1_R.wav af2edeaf1bb4b7992d4161615e6bc30be8277407 *decoded/mono/xll_71_24_48_768_1_Rsr.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_71_24_48_768_1_Rss.wav 5f6766f79859a43e86d5084fd141280a2da0e2b5 *decoded/mono/xll_71_24_96_768_C.wav e619c5dbb080298e4ec338766fc9082a748ced9e *decoded/mono/xll_71_24_96_768_L.wav 62b25ecaafc86d4ff05cf7830e9ba4cca94c96e1 *decoded/mono/xll_71_24_96_768_LFE.wav 8d538275a2a8cc1d94dd28a13ffbe5ecab01e31d *decoded/mono/xll_71_24_96_768_Lsr.wav e8c1bfdfa4917b45045b8a937e24d6c3851b4f3c *decoded/mono/xll_71_24_96_768_Lss.wav e619c5dbb080298e4ec338766fc9082a748ced9e *decoded/mono/xll_71_24_96_768_R.wav 8d538275a2a8cc1d94dd28a13ffbe5ecab01e31d *decoded/mono/xll_71_24_96_768_Rsr.wav e8c1bfdfa4917b45045b8a937e24d6c3851b4f3c *decoded/mono/xll_71_24_96_768_Rss.wav 5f6766f79859a43e86d5084fd141280a2da0e2b5 *decoded/mono/xll_x96_51_24_96_1509_C.wav e619c5dbb080298e4ec338766fc9082a748ced9e *decoded/mono/xll_x96_51_24_96_1509_L.wav 62b25ecaafc86d4ff05cf7830e9ba4cca94c96e1 *decoded/mono/xll_x96_51_24_96_1509_LFE.wav e8c1bfdfa4917b45045b8a937e24d6c3851b4f3c *decoded/mono/xll_x96_51_24_96_1509_Ls.wav e619c5dbb080298e4ec338766fc9082a748ced9e *decoded/mono/xll_x96_51_24_96_1509_R.wav e8c1bfdfa4917b45045b8a937e24d6c3851b4f3c *decoded/mono/xll_x96_51_24_96_1509_Rs.wav bbbf7fd9a60805e384c6cc3c95bd48a2b74ed5e3 *decoded/mono/xll_xch_61_24_48_768_C.wav af2edeaf1bb4b7992d4161615e6bc30be8277407 *decoded/mono/xll_xch_61_24_48_768_Cs.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_xch_61_24_48_768_L.wav d7fdbd9e826aa3de8aa4ee2156068369a3bbbf9a *decoded/mono/xll_xch_61_24_48_768_LFE.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_xch_61_24_48_768_Ls.wav 1dd4af9b5a3bb56267d73a05a6d6276b9096c672 *decoded/mono/xll_xch_61_24_48_768_R.wav 2555b7da3430f24bc28512596da48dc24be65f95 *decoded/mono/xll_xch_61_24_48_768_Rs.wav ================================================ FILE: test/stddev.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 #include #include #include #include #define BUF 3000 #define HDR 44 int main(int argc, char **argv) { uint8_t buf1[BUF], buf2[BUF], *p1, *p2; int64_t acc = 0, cnt = 0; size_t r1, r2, i; double ref = 0.0; if (argc != 4) goto fail; if (strcmp(argv[3], "?")) { char *p; ref = strtod(argv[3], &p); if (*p || p == argv[3]) goto fail; } FILE *fp1 = fopen(argv[1], "rb"); FILE *fp2 = fopen(argv[2], "rb"); if (!fp1 || !fp2) goto fail; if (fread(buf1, HDR, 1, fp1) != 1 || fread(buf2, HDR, 1, fp2) != 1) goto fail; if (memcmp(buf1, buf2, HDR) || memcmp(buf1, "RIFF", 4)) goto fail; int bps; switch (buf1[34] | (buf1[35] << 8)) { case 16: bps = 2; break; case 24: bps = 3; break; default: goto fail; } do { r1 = fread(buf1, 1, BUF, fp1); r2 = fread(buf2, 1, BUF, fp2); if (r1 != r2 || r1 % bps) goto fail; for (i = 0, p1 = buf1, p2 = buf2; i < r1 / bps; i++, p1 += bps, p2 += bps) { int64_t d; if (bps == 3) { uint32_t u1 = (p1[0] << 8) | (p1[1] << 16) | ((uint32_t)p1[2] << 24); uint32_t u2 = (p2[0] << 8) | (p2[1] << 16) | ((uint32_t)p2[2] << 24); int32_t v1 = (int32_t)u1 >> 8; int32_t v2 = (int32_t)u2 >> 8; d = v1 - v2; } else { int16_t v1 = p1[0] | (p1[1] << 8); int16_t v2 = p2[0] | (p2[1] << 8); d = v1 - v2; } acc += d * d; } cnt += i; } while (r1 == BUF); if (!cnt) goto fail; double var = (double)acc / cnt; double dev = sqrt(var); if (strcmp(argv[3], "?")) { if (fabs(dev - ref) > 0.1) goto fail; printf("%s: OK\n", argv[1]); } else { printf("%s: %f\n", argv[1], dev); } return 0; fail: printf("%s: FAILED\n", argc > 1 ? argv[1] : "???"); return 1; } ================================================ FILE: test/stddev.txt ================================================ decoded/mono/core_51_24_48_768_0_C.wav: 2.282641 decoded/mono/core_51_24_48_768_0_L.wav: 1.783442 decoded/mono/core_51_24_48_768_0_LFE.wav: 0.000000 decoded/mono/core_51_24_48_768_0_Ls.wav: 1.780153 decoded/mono/core_51_24_48_768_0_R.wav: 1.737961 decoded/mono/core_51_24_48_768_0_Rs.wav: 1.761957 decoded/mono/core_51_24_48_768_1_C.wav: 2.258123 decoded/mono/core_51_24_48_768_1_L.wav: 1.828726 decoded/mono/core_51_24_48_768_1_LFE.wav: 0.000000 decoded/mono/core_51_24_48_768_1_Ls.wav: 1.727110 decoded/mono/core_51_24_48_768_1_R.wav: 1.800879 decoded/mono/core_51_24_48_768_1_Rs.wav: 1.710206 decoded/mono/x96_51_24_96_1509_C.wav: 3.372648 decoded/mono/x96_51_24_96_1509_L.wav: 2.959649 decoded/mono/x96_51_24_96_1509_LFE.wav: 0.549103 decoded/mono/x96_51_24_96_1509_Ls.wav: 3.121600 decoded/mono/x96_51_24_96_1509_R.wav: 2.959649 decoded/mono/x96_51_24_96_1509_Rs.wav: 3.053878 decoded/mono/x96_xch_61_24_96_3840_C.wav: 3.550590 decoded/mono/x96_xch_61_24_96_3840_Cs.wav: 2.152851 decoded/mono/x96_xch_61_24_96_3840_L.wav: 3.175529 decoded/mono/x96_xch_61_24_96_3840_LFE.wav: 0.549103 decoded/mono/x96_xch_61_24_96_3840_Ls.wav: 3.565754 decoded/mono/x96_xch_61_24_96_3840_R.wav: 3.175529 decoded/mono/x96_xch_61_24_96_3840_Rs.wav: 3.546978 decoded/mono/x96_xxch_71_24_96_3840_C.wav: 3.431600 decoded/mono/x96_xxch_71_24_96_3840_L.wav: 3.354502 decoded/mono/x96_xxch_71_24_96_3840_LFE.wav: 0.875697 decoded/mono/x96_xxch_71_24_96_3840_Lsr.wav: 2.181241 decoded/mono/x96_xxch_71_24_96_3840_Lss.wav: 4.218345 decoded/mono/x96_xxch_71_24_96_3840_R.wav: 3.485461 decoded/mono/x96_xxch_71_24_96_3840_Rsr.wav: 2.048544 decoded/mono/x96_xxch_71_24_96_3840_Rss.wav: 3.940506 decoded/mono/xbr_51_24_48_3840_C.wav: 2.499609 decoded/mono/xbr_51_24_48_3840_L.wav: 1.944418 decoded/mono/xbr_51_24_48_3840_LFE.wav: 0.000000 decoded/mono/xbr_51_24_48_3840_Ls.wav: 2.080297 decoded/mono/xbr_51_24_48_3840_R.wav: 1.950060 decoded/mono/xbr_51_24_48_3840_Rs.wav: 2.005242 decoded/mono/xbr_xch_61_24_48_3840_C.wav: 2.161339 decoded/mono/xbr_xch_61_24_48_3840_Cs.wav: 1.422133 decoded/mono/xbr_xch_61_24_48_3840_L.wav: 1.758212 decoded/mono/xbr_xch_61_24_48_3840_LFE.wav: 0.000000 decoded/mono/xbr_xch_61_24_48_3840_Ls.wav: 2.442103 decoded/mono/xbr_xch_61_24_48_3840_R.wav: 1.807914 decoded/mono/xbr_xch_61_24_48_3840_Rs.wav: 2.365627 decoded/mono/xbr_xxch_71_24_48_3840_C.wav: 2.798402 decoded/mono/xbr_xxch_71_24_48_3840_L.wav: 2.057641 decoded/mono/xbr_xxch_71_24_48_3840_LFE.wav: 0.000000 decoded/mono/xbr_xxch_71_24_48_3840_Lsr.wav: 1.502439 decoded/mono/xbr_xxch_71_24_48_3840_Lss.wav: 2.729415 decoded/mono/xbr_xxch_71_24_48_3840_R.wav: 2.024387 decoded/mono/xbr_xxch_71_24_48_3840_Rsr.wav: 1.485444 decoded/mono/xbr_xxch_71_24_48_3840_Rss.wav: 2.797617 decoded/mono/xch_61_24_48_768_C.wav: 2.111284 decoded/mono/xch_61_24_48_768_Cs.wav: 1.331705 decoded/mono/xch_61_24_48_768_L.wav: 1.850623 decoded/mono/xch_61_24_48_768_LFE.wav: 0.000000 decoded/mono/xch_61_24_48_768_Ls.wav: 1.999267 decoded/mono/xch_61_24_48_768_R.wav: 1.850623 decoded/mono/xch_61_24_48_768_Rs.wav: 2.159644 decoded/mono/xxch_71_24_48_2046_C.wav: 2.353314 decoded/mono/xxch_71_24_48_2046_L.wav: 1.915577 decoded/mono/xxch_71_24_48_2046_LFE.wav: 0.000000 decoded/mono/xxch_71_24_48_2046_Lsr.wav: 1.260309 decoded/mono/xxch_71_24_48_2046_Lss.wav: 2.389961 decoded/mono/xxch_71_24_48_2046_R.wav: 1.915577 decoded/mono/xxch_71_24_48_2046_Rsr.wav: 1.282964 decoded/mono/xxch_71_24_48_2046_Rss.wav: 2.442203 ================================================ FILE: test/test.sh ================================================ #!/bin/sh set -e if [ ! -f samples/README ] ; then echo "ERROR: Run 'git submodule update --init test/samples' first." exit 1 fi export LD_LIBRARY_PATH=../libdcadec [ -z $SHA1SUM ] && command -v sha1sum > /dev/null && SHA1SUM=sha1sum [ -z $SHA1SUM ] && command -v shasum > /dev/null && SHA1SUM=shasum if [ -z $SHA1SUM ] ; then echo "ERROR: Neither sha1sum nor shasum found" exit 1 fi rm -rf decoded mkdir -p decoded/dmix_0 decoded/dmix_2 decoded/dmix_6 decoded/mono for i in samples/*.dtshd ; do ../dcadec -b -q $i decoded/dmix_0/$(basename $i .dtshd).wav ../dcadec -b -q -2 $i decoded/dmix_2/$(basename $i .dtshd).wav ../dcadec -b -q -6 $i decoded/dmix_6/$(basename $i .dtshd).wav ../dcadec -i -m -q $i decoded/mono/$(basename $i .dtshd)_%s.wav done LOSSY="\ decoded/mono/core_*.wav \ decoded/mono/x96_*.wav \ decoded/mono/xbr_*.wav \ decoded/mono/xch_*.wav \ decoded/mono/xxch_*.wav" if [ "$1" = "--update" ] ; then $SHA1SUM -b decoded/dmix_0/*.wav decoded/dmix_2/*.wav decoded/dmix_6/*.wav > checksum.txt $SHA1SUM -b samples/reference/xll_*.wav | sed 's|samples/reference|decoded/mono|' >> checksum.txt for i in $LOSSY ; do ./stddev $i samples/reference/$(basename $i) ? done > stddev.txt else $SHA1SUM -c checksum.txt for i in $LOSSY ; do ./stddev $i samples/reference/$(basename $i) $(grep -F $i stddev.txt | cut -d ' ' -f 2) done fi