pax_global_header00006660000000000000000000000064151701042240014506gustar00rootroot0000000000000052 comment=79329efee51c9d3545bc4c7179b43a23fe350b6b knik0-faac-79329ef/000077500000000000000000000000001517010422400137645ustar00rootroot00000000000000knik0-faac-79329ef/.github/000077500000000000000000000000001517010422400153245ustar00rootroot00000000000000knik0-faac-79329ef/.github/dependabot.yml000066400000000000000000000002631517010422400201550ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" groups: actions: patterns: - "*" knik0-faac-79329ef/.github/workflows/000077500000000000000000000000001517010422400173615ustar00rootroot00000000000000knik0-faac-79329ef/.github/workflows/master.yml000066400000000000000000000070651517010422400214070ustar00rootroot00000000000000name: Continuous Integration on: push: branches: [ "master" ] tags-ignore: ['*'] paths-ignore: ['**.md'] pull_request: branches: [ "master" ] paths-ignore: ['**.md'] jobs: build: name: ${{ matrix.config.name }} runs-on: ${{ matrix.config.os }} defaults: run: shell: ${{ matrix.config.shell }} strategy: fail-fast: false matrix: config: - { name: Linux GCC, os: ubuntu-latest, compiler: gcc, shell: bash, options: -Dfloating-point=double, } - { name: Linux GCC (Single Precision), os: ubuntu-latest, compiler: gcc, shell: bash, options: -Dfloating-point=single, } - { name: macOS Clang, os: macos-latest, compiler: clang, shell: bash, } - { name: MSYS2 UCRT64, os: windows-latest, compiler: gcc, shell: 'msys2 {0}', msystem: ucrt64, msys-env: mingw-w64-ucrt-x86_64, } - { name: Windows MSVC, os: windows-latest, compiler: cl, shell: pwsh, options: -Dfloating-point=double, } steps: - name: Install dependencies (Ubuntu) if: runner.os == 'Linux' run: sudo apt install meson-1.5 - name: Install dependencies (macOS) if: runner.os == 'macOS' env: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 run: | brew update || true brew install \ meson - name: Install dependencies (MSYS2) if: matrix.config.shell == 'msys2 {0}' uses: msys2/setup-msys2@v2.31.0 with: msystem: ${{ matrix.config.msystem }} update: false install: >- ${{ matrix.config.msys-env }}-meson ${{ matrix.config.msys-env }}-gcc - name: Install dependencies (MSVC) if: matrix.config.compiler == 'cl' run: | pip install meson ninja - name: Set up MSVC if: matrix.config.compiler == 'cl' uses: ilammy/msvc-dev-cmd@v1 with: arch: x64 - uses: actions/checkout@v6 - name: Build (MSYS2) if: matrix.config.shell == 'msys2 {0}' env: CC: ${{ matrix.config.compiler }} run: | mkdir -p build temp cd build meson setup .. -Dprefix=$(realpath ../temp) ${{ matrix.config.options }} meson install - name: Build (General) if: matrix.config.shell != 'msys2 {0}' env: CC: ${{ matrix.config.compiler }} run: | meson setup build -Dprefix="${{ github.workspace }}/temp" ${{ matrix.config.options }} meson install -C build - name: Upload artifacts (Windows) uses: actions/upload-artifact@v7 if: runner.os == 'Windows' with: name: faac-${{ github.sha }}-${{ matrix.config.name }} path: temp/* cppcheck: name: Cppcheck runs-on: ubuntu-latest steps: - name: Install dependencies run: | sudo apt-get update sudo apt-get install cppcheck - uses: actions/checkout@v6 - name: Run cppcheck shell: bash run: | cppcheck --version cppcheck --error-exitcode=1 -j4 -q --check-level=exhaustive -Iinclude/ libfaac/ frontend/ knik0-faac-79329ef/.gitignore000066400000000000000000000006121517010422400157530ustar00rootroot00000000000000*.o *.so *.a *.ncb *.plg *.aps *.opt *.aac *.wav *.mp4 *.m4a *.lo Makefile* *.deps *.libs *.la *~ /frontend/faac /aclocal.m4 /autom4te.cache /compile /config.guess /config.h /config.h.in /config.log /config.status /config.sub /configure /depcomp /install-sh /libtool /ltmain.sh /missing /stamp-h1 .vs/ /project/msvc/bin/ /project/msvc/intermediate/ *.user /libfaac/win32_ver.h /libfaac/faac.pc knik0-faac-79329ef/AUTHORS000066400000000000000000000024211517010422400150330ustar00rootroot00000000000000Currently maintained by knik . The following list contains the user names of all FAAC developers with their first appearance in the ChangeLog: 1999-12-13 lenox (Tony Lenox) 1999-12-13 menno 2000-02-07 oxygene2000/oxygene (?) 2000-02-22 thebard (wmilas@rarcoa.com) 2000-07-22 prkoat (?) 2001-03-18 xfhobbes (?) 2001-04-27 flyingfox (?) 2001-09-21 eraser (?) 2002-08-07 knik (Krzysztof Nikiel) 2003-08-02 stux (Stuart Espey) 2003-09-07 ca5e (Janne Hyvärinen) 2004-03-17 danchr (Dan Christiansen) 2004-07-04 corrados (Volker Fischer) 2012-04-08 arcen (Arcen@github) Furthermore there are other contributors from the SourceForge mailing list and trackers as well as from the web forum or via email whose patches were checked in by members of the FAAC project. Among them are Antonio Foranna (Winamp and CoolEdit plugins), Bill May, Stephen Shultz (sms00), Jordan Breeding, Brandon Forehand, Andrew Voznytsa, Måns Rullgård, RageOMatic and Ivan Dimkovic. You can find their names and/or aliases in the ChangeLog most of the time. Question marks mean that neither the real name nor the email address is known. If you think your name should also be in this list or know who some of the early developers are, please email me: hans-juergen.bardenhagen@arcor.de knik0-faac-79329ef/COPYING000066400000000000000000000613141517010422400150240ustar00rootroot00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] 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 Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the 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 a program 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. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. 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, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library 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 compile 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) 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. c) 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. d) 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 source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. 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 to 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 Library 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 Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA. Also add information on how to contact you by electronic and paper mail. 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! knik0-faac-79329ef/ChangeLog000066400000000000000000000163261517010422400155460ustar00rootroot000000000000001.50 (Apr 16, 2026) [ Fabian Greffrath ] * Build quantize_sse library with hidden symbols * Don't call `exit()` from the library * Define some more `default_options` in Meson build * Fix some warnings in `frontend/maingui.c` * Default to `buildtype=release` in Meson build * Initialize `data` variable in `huffcode()` * Remove the faulty `HAVE_STRCASECMP` check and other pointless header checks * CI: Let Meson build set `CFLAGS` [ Nils Schimmelmann ] * Disallow PNS in MPEG-2 mode to match spec * frontend: Change default to MPEG-4 as MPEG-2 is obsolete * Add `max-channels` option to change `MAX_CHANNELS` from 64 * Fix PNS to stay on in `JOINT_MS` for low-bitrate accuracy * Replace redundant `cpe`, `sce`, and `lfe` boolean flags in `ChannelInfo` with an `enum` * Reduce `MAX_CHANNELS` to 8 for ADTS compliance * tns: Prevent division-by-zero or instability on highly correlated signals * Implement MOS-optimized bandwidth calculation * Fine-tune rate controller to restore bitrate accuracy * Fix channel-specific group metadata in joint-stereo * Enable link-time optimization (LTO) in Meson build * stereo: Fix undefined behaviour in intensity stereo for degenerate bands * Fix scalefactor delta overflows to comply with AAC spec (ISO 14496-3) * quantize: Pre-clamp scalefactor deltas to fix encoder/decoder mismatch 1.40 (Mar 17, 2026) [ tatsuz ] * Fix compilation with Visual Studio [ enWILLYado ] * Fix SIMD calls [ David Fort ] * Add meson as build system [ KokonoeTooru ] * Meson: Install faac executable [ Fabian Greffrath ] * CI: fix artifact path * Remove autoconf/automake build system * Remove plugins stuff, unmaintained for decades * Remove MSVC projects, deprecated in favour of meson * Do not check for unused headers * Generalize OS check in CI rule * Remove redundant defines * Make `faacgui` usable again * Report library version on version mismatch * Maintain library SONAME version 0.0.0 * Build both static and shared library by default * Properly declare symbol visibility as hidden [ Nils Schimmelmann ] * Add options to disable DRM and opt for single floating-point precision * CI: add native MSVC build and fix Windows compatibility * Remove dead code * Optimize FFT reordering by combining real and imaginary passes * Optimize FFT performance * CI: update GitHub Actions and add Dependabot configuration * Refactor quantizer for portable C and extensible SIMD dispatch * Optimize memory allocation and unify MDCT implementation * Optimize MDCT by removing conditional branches and hoisting logic * Rrefactor the hot path for writing bits to the output stream * Remove Digital Radio Mondiale (DRM) support 1.31.1 (Mar 03, 2025) [ Fabian Greffrath ] * Reduce autoconf requirement back down to 2.69 * Reformat configure.ac for the ac2ver.exe hack to work * Upload Windows artifacts 1.31 (Feb 28, 2025) [ Tatsuya Suzuki ] * updated Visual Studio projects to VS 2019 * main.c : progress report keeps alignment when encoding a large file * project/msvc : cleanup, fixes and changes [ Christopher Degawa ] * frontend: fix out-of-root build [ Fabian Greffrath ] * add a pkg-config file * avoid division by zero * Remove #pragma pack from faacEncStruct (thanks Locutus of Borg) * Reduce memory (thanks xnvi) + Remove `BwpInfo bwpInfo` from `struct CoderInfo` + Remove `nextSampleBuff[]` and `next2SampleBuff[]` from `struct faacEncStruct` * tns: Initialize `rArray[]` variable * update autoconf.ac and friends * do not pass add-stdcall-alias option to clang * always build both the regular and the DRM library * fix cppcheck warnings * add some basic CI * fix compilation with clang on Windows * Append INSTALL to README [ Steve Fosdick ] * Add album artist and various sort order MP4 tags [ Aaron Boxer ] * set libfaac library name to "faac" rather than "libfaac" [ Frank ] * Error C2065 (add #define _USE_MATH_DEFINES) [ pine3ree ] * Allow genre-id up to 255 1.30 (Oct 16, 2019) [ Robert Kausch ] * Fix Joint Stereo coding [ Krzysztof Nikiel ] * Code cleanup and compilation fixes * Fix endianness conversion functions [ Takashi Yoshi ] * Fix compilation with GCC < 4.6 * Fix compilation on big endian systems [ Fabian Greffrath ] * Fix division by zero errors * Fix compilation with GCC <= 4.7.3 * Change pointer type for proper arithmetics * Fix logic error in compiler detection * Revert back to some more generic SSE2 code * Fix a memory leak * Fix some cppcheck warnings in the Cfaac code * Check index ranges before dereferencing book arrays (CVE-2018-19886) * Clean up stdint.h header inclusions * Consistently use stdint.h types [ Michael Fink ] * Update Visual Studio 2017 projects * Add stdint.h header inclusions * Port over ac2ver tool from faad2 to generate PACKAGE_VERSION when compiling with Visual Studio [ Eugène Filin ] * Memory allocations redefined 1.29.9.2 (Nov 14, 2017) * fixed max MP4 bitrate calculation 1.29.9 (Nov 2, 2017) * initial version of PNS coding * Intensity Stereo coding * more speed improvements * finer bandwidth/cutoff setting (doesn't work with PNS) * fixed more bugs * rewritten mid/side coding * fixed bug in blockswitch 1.29.8 (Oct 15, 2017) * changed default mode to ABR 64kbps/channel * implemented short windows grouping * new huffman coder * SSE quantizer * modified functioning of ABR mode (-b option) * improved autotools support * allowed even higher bitrates, including ADTS * framebuffer size bug fixed * removed broken object types: Main and LTP * some mp4 atoms fixed for better compalibility * stdin seek bug fixed 1.29.7 (Aug 22, 2017) * quantizer tweaked to better support high bitrates * allow higher quality for mp4 files (-q 5000 max) * removed mid frequency boost (it turned out useless) * cutoff frequency adjusted to fully utilize upper band * --help-long option removed, it was just an alias for -H * -b option bug fixed 1.29.6 (Aug 18, 2017) - quality related bug fixed 1.29.5 (Aug 17, 2017) - updated manpage - check if output file exists; --overwrite option added - help/usage options reorganized - block switching is now tuned to match quality/bitrate - give more quality to lower frequancies (less to highs) - quantizer updated again 1.29.4 (Aug 14, 2017) - rewritten quantizer: faster, diffrerent quality, different bitrates - ftyp atom: set brands like itunes does, shoud be more compatible with picky tools - new option(--tag) to add named tags (iTunes '----') - faster and better short/long window type switch - Don't build DRM(Digital Radio Mondiale) by default. Use ./configure --enable-drm to build DRM version. - fixed bugs * rounding in QuantizeReflectionCoeffs (tns.c) * use +60 value for scalefactor. * use clipped diff instead of original value (huffman.c) 1.29.3 (Jul 21, 2017) - MP4 tag options improved - fixed MP4 'meta' atom bug - new option to set verbosity (-v0 to silence output) 1.29.2 (Jul 17, 2017) - new mp4 output code 1.29 (Jul 4, 2017) - various patches applied and bugs fixed 1.28 (Feb 5, 2009) * Prevent out of range scalefactors * Updated to latest mpeg4ip mp4 file format library * Added -s option to make the encoder output optimized mp4 layout * Improved JPEG detection for album art * Lot's of compilation issues solved knik0-faac-79329ef/NEWS000066400000000000000000000003041517010422400144600ustar00rootroot000000000000002017: FAAC thread on hydrogenaudio: https://hydrogenaud.io/index.php/topic,114363.0.html FAAC mirrored on github: https://github.com/knik0/faac FAAC download page: http://faac.sourceforge.net/ knik0-faac-79329ef/README000066400000000000000000000063001517010422400146430ustar00rootroot00000000000000__________ COPYRIGHTS FAAC is based on the ISO MPEG-4 reference code. For this base code the following license applies: ********************************************************************** This software module was originally developed by FirstName LastName (CompanyName) and edited by FirstName LastName (CompanyName) FirstName LastName (CompanyName) in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-2 NBC/MPEG-4 Audio conforming products. The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1997. ********************************************************************** For the changes made for the FAAC project the GNU Library General Public License (LGPL), version 2 1991 applies. For the changes the following statement applies: ********************************************************************** FAAC - Freeware Advanced Audio Coder Copyright (C) 2001 M. Bakker 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ********************************************************************** Please note that the use of this software may require the payment of patent royalties. You need to consider this issue before you start building derivative works. We are not warranting or indemnifying you in any way for patent royalities! YOU ARE SOLELY RESPONSIBLE FOR YOUR OWN ACTIONS! ___________________________________ General FAAC compiling instructions 1. Make sure you have recent versions of meson and ninja installed. 2. cd to FAAC source dir 3. Run: mkdir -p build cd build meson setup .. meson install knik0-faac-79329ef/TODO000066400000000000000000000005641517010422400144610ustar00rootroot00000000000000- fix scalefactor encoding check (-60 .. 60) - optimize quantization bias - optimize codebook list (section_data) - optimize CPE windows grouping - Add bit reservoir control - Add resampler and downmixer (hans-juergen, Oct 17, 2004) - Add HE AAC (hans-juergen, Oct 17, 2004) - Test TNS(arcen, Apr 8th, 2012) - add PCE (Program Config Element) or 4-bit AudioSpecificConfig knik0-faac-79329ef/docs/000077500000000000000000000000001517010422400147145ustar00rootroot00000000000000knik0-faac-79329ef/docs/faac.1000066400000000000000000000114071517010422400156730ustar00rootroot00000000000000.TH FAAC 1 "2017-08-16" "1.29.5" "Free Advanced Audio Coder" .SH NAME faac \- open source MPEG-4 and MPEG-2 AAC encoder .SH SYNOPSIS .B faac .RI [ options ] .RI [\-o\ outfile ] .I infiles .RI ... .PP .RI < infiles > and/or .RI < outfile > can be "\-", which means stdin/stdout. .SH DESCRIPTION .B FAAC is an open source MPEG-4 and MPEG-2 AAC encoder, it is licensed under the LGPL license. Note that the quality of .B FAAC is not up to par with the currently best AAC encoders available. .SH FEATURES .TP * Portable .TP * Fast .TP * LC, Main, LTP support .SH HELP OPTIONS .TP .BR -h Short help on using FAAC .TP .BR -H Description of all options for FAAC .TP .BR --license License terms for FAAC. .TP .BR --help-qual Quality-related options .TP .BR --help-io Input/output options .TP .BR --help-mp4 MP4 specific options Quality-related options .TP .BR --help-advanced Advanced options, only for testing purposes .SH QUALITY-RELATED OPTIONS .TP .BR -q\ <\fIquality\fP> Set encoding quality. Set default variable bitrate (VBR) quality level in percent. max. 5000, min. 10. default: 100, averages at approx. 120 kbps VBR for a normal stereo input file with 16 bit and 44.1 kHz sample rate .TP .BR -b\ <\fIbitrate\fP> Set average bitrate (ABR) to approximately kbps. max. ~500 (stereo) .TP .BR -c\ <\fIfreq\fP> Set the bandwidth in Hz. The actual frequency is adjusted to maximize upper spectral band usage. .SH INPUT/OUTPUT OPTIONS .TP .BR -o\ <\fIfilename\fP> Set output file to X (only for one input file) only for one input file; you can use *.aac, *.mp4, *.m4a or *.m4b as file extension, and the file format will be set automatically to ADTS or MP4). .TP .BR - Use stdin/stdout. If you simply use a hyphen/minus sign instead of a filename, FAAC can encode directly from stdin, thus enabling piping from other applications and utilities. The same works for stdout as well, so FAAC can pipe its output to other apps such as a server. .TP .BR -v\ <\fIvebose\fP> Verbosity level (-v0 is quiet mode) .TP .BR -r Use RAW AAC output file. Generate raw AAC bitstream (i.e. without any headers). Not advised!!!, RAW AAC files are practically useless!!! .TP .BR -P Raw PCM input mode (default 44100Hz 16bit stereo). Raw PCM input mode (default: off, i.e. expecting a WAV header; necessary for input files or bitstreams without a header; using only -P assumes the default values for -R, -B and -C in the input file). .TP .BR -R\ <\fIsamplerate\fP> Raw PCM input rate. Raw PCM input sample rate in Hz (default: 44100 Hz, max. 96 kHz) .TP .BR -B\ <\fIsamplebits\fP> Raw PCM input sample size (8, 16 (default), 24 or 32bits). Raw PCM input sample size (default: 16, also possible 8, 24, 32 bit fixed or float input). .TP .BR -C\ <\fIchannels\fP> Raw PCM input channels. Raw PCM input channels (default: 2, max. 33 + 1 LFE). .TP .BR -X Raw PCM swap input bytes Raw PCM swap input bytes (default: bigendian). .TP .BR -I\ <\fIC[,LFE]\fP> Input channel config, default is 3,4 (Center third, LF fourth) Input multichannel configuration (default: 3,4 which means Center is third and LFE is fourth like in 5.1 WAV, so you only have to specify a different position of these two mono channels in your multichannel input files if they haven't been reordered already). .TP .BR --ignorelength Ignore wav length from header (useful with files over 4 GB) .TP .BR --overwrite Overwrite existing output file .SH MP4 SPECIFIC OPTIONS .TP .BR -w Wrap AAC data in MP4 container. (default for *.mp4, *.m4a and *.m4b) .TP .BR --tag\ <\fItagname,tagvalue\fP> Add named tag (iTunes '----') .TP .BR --artist\ <\fIname\fP> Set artist name .TP .BR --composer\ <\fIname\fP> Set composer name .TP .BR --title\ <\fIname\fP> Set title/track name .TP .BR --genre\ <\fInumber\fP> Set genre number .TP .BR --album\ <\fIname\fP> Set album/performer .TP .BR --compilation Mark as compilation .TP .BR --track\ <\fInumber/total\fP> Set track number .TP .BR --disc\ <\fInumber/total\fP> Set disc number .TP .BR --year\ <\fInumber\fP> Set year .TP .BR --cover-art\ <\fIfilename\fP> Read cover art from file X Supported image formats are GIF, JPEG, and PNG. .TP .BR --comment\ <\fIstring\fP> Set comment .SH ADVANCED OPTIONS, ONLY FOR TESTING PURPOSES .TP .BR --tns Enable coding of TNS, temporal noise shaping. .TP .BR --no-tns Disable coding of TNS, temporal noise shaping. .TP .BR --no-midside Don't use mid/side coding. .TP .BR --mpeg-vers\ \fIX\fP Force AAC MPEG version, X can be 2 or 4 .TP .BR --shortctl\ \fIX\fP Enforce block type (0 = both (default); 1 = no short; 2 = no long). .SH AUTHORS .B FAAC was written by M. Bakker . .PP .nh 2 Developed and maintained by Krzysztof Nikiel . .PP This manpage was written by Fabian Greffrath for the Debian Unofficial project (but may be used by others, of course). .nh 1 knik0-faac-79329ef/docs/faac.html000066400000000000000000000162321517010422400165000ustar00rootroot00000000000000 FAAC - Freeware Advanced Audio Coder

FAAC 1.18 beta (www.audiocoding.com)


Contents

  • Usage
  • options
  • notes
  • Copyrights
  • Patents
  • People


  • Usage

    (More up to date info can be found at
    FAAC wiki page by Hans-Jürgen Bardenhagen)

    faac [options] <infile> <outfile>

    Options:
  • -a X Set average bitrate to approximately X kbps per channel (i.e. using -a 64 averages at 128 kbps/stereo).
  • -c <bandwidth> Set the bandwidth in Hz (default value depends on sample rate)
  • -q <quality> Set quantizer quality (default: 100, averages at approx. 128 kbps VBR for a normal stereo input file at 16 bit and 44.1 kHz sample rate).
  • --tns Enable TNS coding.
  • --notns Disable TNS coding.
  • -n Disable mid/side coding.
  • -m X AAC MPEG version, X can be 2 or 4 (default: MPEG-2, so for the sake of interoperability with non-standard compliant players like QuickTime 6 you should set it to "4").
  • -o X AAC object type, X can be LC, MAIN or LTP (default: LC, for the same reason as with the MPEG version don't use Main or LTP).
  • -r RAW AAC output file (i.e. without ADTS headers).
  • -P Raw PCM input mode.
  • -R Raw PCM input sample rate in Hz (default: 44100 Hz).
  • -B Raw PCM input bit depth (default: 16 bits, also possible 8 bits).
  • -C Raw PCM input channels (default: 2).
  • - <stdin> If you simply use a hyphen/minus sign instead of an input file name, FAAC can encode directly from stdin, thus enabling piping within other applications like foobar2000 or mp4live.

    Note: VBR output bitrate depends on -q AND -c, so you should only vary the default setting -q 100 -c 16000 if you know what you're doing and/or want to experiment with other cutoff frequencies at a given quality setting.

    The ABR setting with -a is an approximate average bitrate that does not use a bit reservoir, i.e -a 64 and -q 100 at 44.1 kHz will result in exactly the same output file.

    The following list should give some orientation for useful -q and -c settings, based on FAAC v1.17. The resulting VBR bitrates are referring to an average sounding stereo file with 16bit, 44.1 kHz, i.e. ct_reference.wav in this case. Multiplexing these AAC files to MP4 with e.g. mp4creator will result in a ~3 kbps lower bitrate because of the stripped ADTS headers:

    -q 130 -c 22000 -m 4 (~218 kbps)
    -q 120 -c 20000 -m 4 (~194 kbps)
    -q 110 -c 18000 -m 4 (~158 kbps)
    -q 100 -c 16000 -m 4 (~129 kbps)
    -q 90 -c 14000 -m 4 (~103 kbps)
    -q 80 -c 12000 -m 4 (~79 kbps)
    -q 70 -c 10000 -m 4 (~62 kbps)

    The added -m 4 switch does not change the bitrate or sound of course, but is recommended for most AAC/MP4 players that use an updated FAAD2-based plugin from this year (Winamp 2.x, foobar2000 etc.) or can't decode MPEG-2 AAC LC files like QuickTime 6. Philips Expanium users should not use this switch, because their CD portable does not know MPEG-4 AAC files.



    Copyrights

    FAAC - Freeware Advanced Audio Coder (
    www.audiocoding.com)
    	Portions Copyright © 1999,2000,2001 Menno Bakker
    	Portions Copyright © 2002,2003 Krzysztof Nikiel
    
    FAAC is based on the ISO MPEG-4 reference code. For this base code the following license applies:
    This software module was originally developed by
    
    FirstName LastName (CompanyName)
    
    and edited by
    
    FirstName LastName (CompanyName)
    FirstName LastName (CompanyName)
    
    in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
    ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
    implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
    as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
    users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
    software module or modifications thereof for use in hardware or
    software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
    standards. Those intending to use this software module in hardware or
    software products are advised that this use may infringe existing
    patents. The original developer of this software module and his/her
    company, the subsequent editors and their companies, and ISO/IEC have
    no liability for use of this software module or modifications thereof
    in an implementation. Copyright is not released for non MPEG-2
    NBC/MPEG-4 Audio conforming products. The original developer retains
    full right to use the code for his/her own purpose, assign or donate
    the code to a third party and to inhibit third party from using the
    code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
    copyright notice must be included in all copies or derivative works.
    
    Copyright © 1997.
    

    For the changes made for the FAAC project the GNU Library General Public License (LGPL), version 2 1991 applies. For the changes the following statement applies:
    FAAC - Freeware Advanced Audio Coder
    Copyright © 1999,2000,2001,2002,2003 FAAC developers
    
    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    

    Patents

    Please note that the use of this software may require the payment of patent royalties. You need to consider this issue before you start building derivative works. We are not warranting or indemnifying you in any way for patent royalities! YOU ARE SOLELY RESPONSIBLE FOR YOUR OWN ACTIONS!



    People

    Currently maintained by M. Bakker (menno)


    Other contributors:
    Tony Lenox
    RageOMatic
    thebard
    Ivan Dimkovic
    Krzysztof Nikiel (knik)
    Janne Hyvärinen (ca5e)
    Stuart Espey (stux)
    Andrew Voznytsa
    Måns Rullgård
    Bill May


    Copyright © 2003 AudioCoding.com
    knik0-faac-79329ef/docs/libfaac.html000066400000000000000000000114511517010422400171650ustar00rootroot00000000000000 FAAC - ISO/MPEG 2/4 AAC Encoder Library

    FAAC - ISO/MPEG 2/4 AAC Encoder Library version 1.0
    (www.audiocoding.com)

    Contents

  • Scope
  • Interface description
  • Usage
  • Calling sequence
  • Function reference
  • Initialization / De-initialization
  • faacEncOpen()
  • faacEncClose()
  • Encoder configuration
  • faacEncGetCurrentConfiguration()
  • faacEncSetConfiguration()
  • Encoding functions
  • faacEncEncode()
  • Data structures reference
  • faacEncConfiguration
  • Scope

    This document describes the interface and usage of the FAAC - ISO/MPEG 2/4 AAC Encoder Library Developed for the Freeware Advanced Audio Coding project.

    Interface description

    The ISO/MPEG 2/4 AAC Encoder Library provides a high-level interface for encoding MPEG2 and MPEG4 ISO AAC files. The following header file is provided for usage in C/C++ programs:

    faac.h: function prototypes

    The encoder core resides in a statically linkable library called libfaac.lib (Microsoft Windows) or libfaac.a (UNIX). There are various example programs that show how to use the library.

    Usage

    Calling sequence

    For encoding AAC bitstreams the following calling sequence is mandatory:
  • Call faacEncOpen() for every encoder instance you need.
  • To set encoder options, call faacEncGetCurrentConfiguration(), change the parameters in the structure accessible by the returned pointer and then call faacEncSetConfiguration().
  • As long as there are still samples left to encode, call faacEncEncode() to encode the data. The encoder returns the bitstream data in a client-supplied buffer.
  • Once you call faacEncEncode() with zero samples of input the flushing process is initiated; afterwards you may call faacEncEncode() with zero samples input only.
    faacEncEncode() will continue to write out data until all audio samples have been encoded.
  • Once faacEncEncode() has returned with zero bytes written, call faacEncClose() to destroy this encoder instance.
  • Function reference

    Initialization / De-initialization

    faacEncOpen()
    Prototype
    faacEncHandle FAACAPI faacEncOpen
    (
    unsigned long sampleRate,
    unsigned int numChannels,
    unsigned long *inputSamples,
    unsigned long *maxOutputBytes
    );
    Description
    Open and initialize one instance of the encoder.
    Parameters
    
  • sampleRate The samplerate of the encoder input data.
  • numChannels The number of channels of the encoder input data.
  • inputSamples Receives the total number of samples that should be fed to faacEncEncode() in each call.
  • maxOutputBytes Receives the maximum number of bytes that can be in the output buffer after a call to faacEncEncode(). Return value An initialized encoder handle. If anything goes wrong NULL is returned.
  • faacEncClose()
    Prototype
    void FAACAPI faacEncClose
    (
    faacEncHandle hEncoder
    );
    Description
    Closes an encoder instance.
    Parameters
    
  • hEncoder An encoder handle returned by faacEncOpen().
  • Encoder configuration

    faacEncGetCurrentConfiguration()
    Prototype
    faacEncConfigurationPtr FAACAPI
    faacEncGetCurrentConfiguration
    (
    faacEncHandle hEncoder
    );
    Description
    Get a pointer to a structure describing the current encoder
    configuration. You may change this structure and feed it into
    faacEncSetConfiguration().
    
    faacEncSetConfiguration()
    Prototype
    int FAACAPI faacEncSetConfiguration
    (
    faacDecHandle hDecoder,
    faacEncConfigurationPtr config
    );
    Description
    Set a new encoder configuration. See
    faacEncGetCurrentConfiguration().
    


    Copyright © 2001,2003
    AudioCoding.com. All rights reserved.
    knik0-faac-79329ef/docs/libfaac.pdf000066400000000000000000000616711517010422400170030ustar00rootroot00000000000000%PDF-1.2 %âãÏÓ 12 0 obj << /Length 13 0 R /Filter /FlateDecode >> stream H‰•“ÝnÛ0 …ŸÀïÀËt€e’²~¼;7MŠ6`F¯z“Únš¡K 7«±·Ÿ$ˋӤ( †lQG‡ÉË*1(%Œ¨®ÿtkH²%‚EÁì6î¤[ÕnªftÕ¯D VáÏUx»]AVÛ!BOB1©©JB¤¿~IQ0¡ŒZÈLQkY–ó(¨?ªH2XªÃÚègYß÷båÔÁˆ¨w¿³ °¨r áÚ‚CÈøôP\÷Ée•H×ðšét§¾f·ç§ï\zVOÓ{¯¦"â•T1mVŒHÖùÿd”ÐmÖûggü¹í^ÚFÄÙ,Þ÷ä0ü%½ü› endstream endobj 13 0 obj 461 endobj 4 0 obj << /Type /Page /Parent 5 0 R /Resources << /Font << /F0 6 0 R /F1 8 0 R /F2 10 0 R >> /ProcSet 2 0 R >> /Contents 12 0 R >> endobj 17 0 obj << /Length 18 0 R /Filter /FlateDecode >> stream H‰ÕWMoÛ8ýþ<¶ÓäðûØuâ"@] Þ=õ¢UdC‹@NeE÷ׯDÒiÉŽÉÁ6#žJïÍ›yüm9Q ¤V¡åÝ„ ú·\£ÉlAÂÆT_¬&S©ªOiõ5Zþ@à#Zþ3„ýÏý[}‹©–Ú… A¦@EXejCX}¼ ™ ”0_‹P_kñéÓÜ”}+Rf)µŸ•ä¾äÃã×ÙïÜF0ã¨._¤›§¬D_ò¿Ë¤ü‰þ¢˜ØrT‚¯6[PD)– ,‡²ŒCøÒS ¬~JÉÐV™€h—Ò6Õ&i>;u‡Õ”ĘF#Là DBXe¾)vY±ÛÚH¥Ú V›‚©ƒ¦Tt¾"&Ô²"Š)Æ¥6|°lJ· ‘Q€9öÊ¡\2€Å$‰éÇç~lª!Í£V§ér=ð²ùr¶`mš«G7,FŽiæ cø xÇC"Žîyç m‚DÜGQÑ#”p±ç¡ £4PÛRê¹Q­ÝK…mܰƒÙ¸’ ‹zÀpEÃCÓÍKæ„ÒœTÃbt–Û¡½VNÓ]Ÿðnm°÷Ó»…6¨ò{ 3cK•÷Pé£\%i†ž²mZæ/»|S8Ì€tËåµùÒŸ+ªU7êü½4ÀÌ›MÕöiv*fxäþÜ&ë_Y " ¥'XS&ÁñbQëÆK3sƒ½#нû€ž1,õþUœû,®Á›¡yòüœk´Í¾ï³"u,3¦.ÁÞ™LLçzƒ¥qŽ‚¶:Ä-6QB `Ê%.öEZO!Tf«¬²*7°+¯_ò×/ ¾+ ‘.ñ.Ù%h»+÷én_fÛÓ[˜ c‹âì ³áBwo£óJ8Fò·®j±N#ÙáaxØð€ixe.¯ §1~ äu'PT®QÇ%Ò½þýròˆXª endstream endobj 18 0 obj 1044 endobj 14 0 obj << /Type /Page /Parent 5 0 R /Resources << /Font << /F0 6 0 R /F1 8 0 R /F2 10 0 R /F3 15 0 R >> /ProcSet 2 0 R >> /Contents 17 0 R >> endobj 20 0 obj << /Length 21 0 R /Filter /FlateDecode >> stream H‰•”ÝnÛ0 …ŸÀïÀËíŠHY’}™5É0`ÃÔØ½k+©‹Í.”¤ÅÞ~úsc§ºÁ€aˆÔ'òÊŸêLs&AK¦%@½É8øÇ [í8hVUD.°Ï8C¥ÝWëÂP?Ãñê‡L2’aeÞ.ʰTeLB³†„rNÉCŠðÇÇ”œ3B.‹abíÖë›TÿKDJj÷VEB~¹ý¾úöcûhU€Ço‡v쌅¯ýmìø‰Œ*J´Õ‘)’Q– + š7# _¥**&“<0(;¥TrÔŒ.ñIyôÂê2œ襘7I±*ïÝR|.p!þ,Åa8*5Çܶ㣉>â; <ؘ£|K<ÙÀ Qʸµ¾ïÐíù·NÐP¥.Öøm©"ï»*î3ÇÖöwæ§{ýp2vß´š¡ƒó±9÷>§ÊEéox!¨ðgNŧe¯¾`S?tÕ+FO<ý2…—!z.¬X¸“¿º®O-^&Å?`l°à× É+sJz·Ãåܺ«îAàñBGÜÆ<™_n&:Ø6¨¿³Æ<7ÖÀº{j†ÖEÖç®áfìúáv|0í‰EM¤¸þ¼vc[gè°ÿH endstream endobj 21 0 obj 467 endobj 19 0 obj << /Type /Page /Parent 5 0 R /Resources << /Font << /F0 6 0 R /F1 8 0 R /F2 10 0 R >> /ProcSet 2 0 R >> /Contents 20 0 R >> endobj 23 0 obj << /Length 24 0 R /Filter /FlateDecode >> stream H‰•UÉnÛ0üÿÃ;6LsÅÜÒ,E€¦-Pw9äÂÈ”­V‘ I‰›¿/7m­Ó 0¼€zΛ™G¿]/$F¤@R¬/Ü«ÙÂbuA"¥(µòF$‘öWfÃúoø ¬,¢Â¯\úOû‘4IC ø:)A„1EYúæŽ%KŒ(Á,baJIĺ>?¿ˆ€Éÿ"æ)eþ·Lx„¼ùüquûéêÐUeõÆ4ð¾¸otó _ ÂŽ$4¢­® ‚*‚,=,ãtÚô’0f…M¸B^Øa=QŽÙ’HDE¤@œŒ2õˆ+eÓ–XààœšK™I=-ADð4Ö%T†²›ª3M®3ÓfM±ïŠº [í‘ÿ·-qGzIÄ1%–Î-ÕŸHD"Âæõμ.ô¾©Ÿ K 4ìŠí.XHåÌDLeú·Ñ“ú¢G(ŽÙ)Í“)cŒ±¡·ù4„d‘„ Å S^7`Ù¢Ú‚k‚®61‡˜Ì 2®úö9UÊíáNßw^”¦Eà4 t"†Õœˆ"½ǰæuYÖÇbg´“ÎAAÑöÒm<ÕÇVoíj«‹ÓS÷lÛè‡ö,š¨™ÅGRëJzuâžóYYN¹šE5×:CÑ?õÂÈX¡ðè’ì•:ƒü±Ê\ ï®îž÷¦ Ù¤ì5ân@—„÷C5á~lm*6'd0M‘1³&F4«i}<­²ÚNwE¦ËòÊ¢ú©ï­e ²[6›ñ¤ñI† Q‰cÐì6¯˜ý†»7~W‡vWð&û„ñ4Žôm‘5u[ç|+ªM}ˆ’átÌæ’þ†µ×gº;› ž‘îù¤ü8ëP|êý—7ßÃ`¨q(Ýt“«þp?VjÝ ³‘&h:~zÞLÉÈûI7EýØ‚ ÷›þ9`êsâUÇ)‡ýÒ{ëY?Ðítí®>€{wµ#cWQÈ3Æ£¤/ñj½ø k »„ endstream endobj 24 0 obj 747 endobj 22 0 obj << /Type /Page /Parent 5 0 R /Resources << /Font << /F0 6 0 R /F1 8 0 R /F2 10 0 R >> /ProcSet 2 0 R >> /Contents 23 0 R >> endobj 30 0 obj << /Length 31 0 R /Filter /FlateDecode >> stream H‰ÅWÙŽÛ6ýÿ'@Ä!).Rû4uf‚-&@Ü>Í -Ó3*dÑÕÃýúrÕâ%nú @` ÉË{Î=÷\ê—ÕB È€`P0VØÍ+XÜ?! `žb¶ 1æWa–ÁêîØ;°úkÁ aî/ÜÿfâŒg~ p[Èd iji”ÄmIíõ~K‚ Á( ±!8ÄzzxX†€ü[#âÔ¥T¸ß‚Óò×ÏÏ÷¿züÈ=6üc]èjÀo庑Íü‰!rá0'!ÚýCN˜§%†M)™‚NJm–œFjÍI°åKdî¨;”¥ÓÜ©¿Ì–dÎ)JñŒÓéˆ0ͦQþhå«òÕ!7#%"5{"Æ4)À)ÌCš9'³4!öYd#Ë(bzA>)Oƒ„`F¸ß´”UUÖ¯ U÷ª.|Þã[ažƒ HØ¥²ØGȈ¤þè“n€²5¶7Ú‚¯Ë®í%w-èÞØêªÒ»Xœ¤ÊÖߋ̭4Þj1aʧÜìd½‘nŽ?¹í<;m Zñ›l+áÁ°S0¹˜‰ü…pq­ÿPžÎµrEº.y1ô!1+[’ÐiÌêgTŸIßË‚ð Ãy8½•²0}ô¼WõËÝË» aE6‰t^-B"RBÙr}Q¦Uh̲n;iËqÔ=¨•Ú@Ÿ'ð&Ë)sOð¤#¿Ïb͈t+mÔÕ Ðô¾+uݾwÒµ6jâ”|2Ë4ÐþQu˾iTÝ-u½-_û`_bÌßÂLÌ»FÚ[m¡HÎ6Ö0/\Ô˜Þ8e'öáõBqžÒÁ#1áA¡à½‡®ëê#èÔØ£tMmÑÕr¬YºîʺWÖ(MÙ) Mt×F½Y©€…/ûM©Ï­ÃÍøìÕúçÕØ"#¦4$`¼É/¦q•±ßÿáÍ`£·[Å|ËøaöÝ{q$gÑG\³øI2%çM‚ÿ›Fè˜â¹L‚±º\pphCf;ŽâQ2ëcg˜¶eíTý>’gÀÎs6<ÌwXø´…OÒiB§º§$¿jYévÄ”‹¯<`0œ9'ñkÂÈq£Œ©kûÎ0MzúÔ jÉÙíÑý¸Zü i'¦Ò endstream endobj 31 0 obj 1219 endobj 25 0 obj << /Type /Page /Parent 5 0 R /Resources << /Font 34 0 R /ProcSet 2 0 R >> /Contents 30 0 R >> endobj 34 0 obj << /F0 6 0 R /F1 8 0 R /F2 10 0 R /F4 26 0 R /F5 28 0 R /F6 32 0 R >> endobj 38 0 obj << /Length 39 0 R /Filter /FlateDecode >> stream H‰ÝWÛNãF~‚¼Ã\†ª1szÅrh‘hA»i¯¸1É„¸Jlä8lÙ§ïœlÏØN“E+$È?ÿáûþã§ùDÀ„ÁÁ˜_M 0?Õ3˜œß@ )1Ö_¬&0A\èO ý5˜S~æOX‚™ýÏ•ý­¿MPÊS'¬D„ µÌ¬1æÈ &AâuAŒ‘×usqqéòïÕˆˆuia? N½ÊÛ/÷ç¿?\ÿ ð9Fýu±(—ªwùS•Uoà/”@«qìµß €PÂ1s°4j ÅaÐ3 ‰ñ’ÓZýdð©}j¥$ô9c†’SHP„i(¢#‚´Ž¤Ü Þì‹E—¨ÔJUªX( 9ª}†Rª…fXt¾S€H’B*Zß%Ç‘ï rÒú˜ ZÛœ!ïcØSs[äužmòo™ á\yï!O^¡ŒRÒQOC „¹´"ÓpcîüÔ¥9ÚUÓ4N‹Ád÷(˜·„40×ûª¯Ùfï‡Û…é»JЀ´×âÍ„¿(‚Ù¾l{ÛÚnÒ ¸]éñÿV¯s½.=—šß¯•Ùœ\ø.² ÆÒ>ÚŽ·H8÷ÿøóîÎ+°Oÿ£H1£­ÇŒø÷ù®é¤”¦%Ž3 ²Xª¥ã‹í®ƒRÆDŸd¬í='\dø=Y:v‘]nÊ]—Œ=ȨkÇé¡üú¿®1Ô¥U¿CÒ.Ž§Þ¿×2_öï0Ü÷\Tô¦úû¯°è2H1jdÅ2bÀŸk7M*báSÜuR?ÌM0 ŽÓ1¤§ÖÒ¸Óm!X„Ü5 [ôá2sR?Ö`¶,š†Z£ç³µÆî×~±5”yczÛzs± ÇÝ ²Y‹¯s-*ÇÇæåñ¼¸žOþѳ endstream endobj 39 0 obj 1428 endobj 35 0 obj << /Type /Page /Parent 5 0 R /Resources << /Font 42 0 R /ProcSet 2 0 R >> /Contents 38 0 R >> endobj 42 0 obj << /F0 6 0 R /F1 8 0 R /F2 10 0 R /F4 26 0 R /F5 28 0 R /F6 32 0 R /F7 36 0 R /F8 40 0 R >> endobj 45 0 obj << /Length 46 0 R /Filter /FlateDecode >> stream H‰ÕWÙnÛFýýÃ<ÚA9ž}Až/©1`£@¿ÐÒÈf“E"p¿¾ÃY¨á"[vœ…ïÜõÜsï|º^H9JÀõéîSßÅÑ9jMˆ}±^ ˆ…´OKû\ò\ÿ³àp÷Ï©û¶o!VByàDH"1Á<Õ’9Ú™÷"‚#t!BpÐu~||Š×jÄÔ¹´tÏR° òâêËÑŸ—gŸ9b SV.«•©ÁÅm×Oà/ ‘S‡ ÚŽÎ1À Â}Z¢ZÊHtFí¼L…ÔÚ“ ` bÒíiARßm6½9µu¿·€””© ÄÇuL˜ÄÔ ÅX–U¹.îÚ:oŠªôÚWmF}†%á0z/&r,#ß!öõQpŒ ŠM•‹mùØPÍ:Ï—ÖõϦ9iëÚ”ÍIêÿÍÁÍ¡·Ø8ES+Úº’aB@ié|Ìã—uÕTÍÓ£ñØæp’¥q™L†I0 ذðåñ {ÚÆ7ˆê²©¼//|pXŒí’x>ÂËŠdMÉô¨ŒDHOvÓMiªRå8ößd"Î÷“Áų—œ¶C^àöŸàƒRÌË—ýÎpïh(¤Þðåԓ蟙ˆ .á´×â:M Ýq m7˜&/Ê ÈÛUQExvWÏ[·‚a«™Û#¦—ª_€¤N-Žä”žÝY¹‡÷g׋ÿñÞq endstream endobj 46 0 obj 1246 endobj 43 0 obj << /Type /Page /Parent 44 0 R /Resources << /Font 47 0 R /ProcSet 2 0 R >> /Contents 45 0 R >> endobj 47 0 obj << /F0 6 0 R /F1 8 0 R /F4 26 0 R /F5 28 0 R /F6 32 0 R /F7 36 0 R >> endobj 49 0 obj << /Length 50 0 R /Filter /FlateDecode >> stream H‰•UÛnÛ8ýÿÃ<¦‹˜!)Q”“&Y,°EŠÖèS^h™Ž¹P¤@¢’M¿¾Ã›,'v ¶a‘3gΜ9sµYIJHA¤Ø\¯(¸Wÿ«‹[ ’Tçø`¿¢„Õø6/pV~‚Í?+A¸ðÿ\ûO|JXY”áø#|v„0ÎÄ<ÊÚÉ\úpdM g4‹±(ç,ƺ½¼ü¿‘eRíË"!ÿú~wñåëÍŸÀ/rpáoÚºÛéþ6Û^õ¯ðƒêñ‚Çh· #–6Ëù¼è5ce‘WD$”,§LTáÂæ ¡·˜·ÛójÌõøÔèL‹ï§Ñ^û½îÏÁÌá›luHEaÍxìŸ,EéãU‘…$ö˜¤×µ6Ïz炇â2‡1•Wœ”Gh)Oèõp¾xþv™ÌŒ£šQ‘`R#1­CS«¦ÛEº8ÏÚ‰P¸¢«æ0öJÕØ­»'ÝÞŸÝòA*êXXÓÄÅ{@TðX É *B¨sP4AYò(<É<é0¯"ü®}pçíAÙYצ~ SûËY=¾ÝÅÔz!‹L=+Ó¨m£ ܵµ†×n„ƒzä`‡B{Êò¨÷÷ý9mOä%yb†Q± _¼O'`¨ò ^Œ=ÀOÝOý©2 š+-wñjUÆ«Gé¢PÎ}«÷Í8 ÷Ôwµ*^ñ•ˆ·ý­NÙ¸ç…\²)Ze'6Å&Ü…¥’ÏÃv£fÒß•|¦›%ðáКe3CȪ4 ,—Qa_;ÓZ”Ά‚­OgÖQèøÜ;Ø^«GØ)«lœ+Ä“ï-ÁáÏ“ì)/£ì£‹ Œ­ëìÄ ÙüŒ¶Â]ÔMB=ªï%¯VÏFqòßÔ–³!9Y¤wœI‰ÎMkr( ‘¿‘¦ÛAL&ä“v©²¥Âp—œ4zÙe¦‰e¬”¼]CË›÷™<ÁïVï[VÓõ,–óMÛ±oÝÂé2ÿ#$#YþkAƚ¥ý{ ­~P{2:yšvgjœaÔélìu˜÷ù6Ãe¶EU GaN™]¦|f>Ébc‹Ã”%]wøWÿb´ÊK‡cé.7ª]‡YÚΆL›?–åi朖)~„A“Ø×ÿ îf³ú?œ> /ProcSet 2 0 R >> /Contents 49 0 R >> endobj 52 0 obj << /Length 53 0 R /Filter /FlateDecode >> stream H‰ÅW[OãFþü‡y¤1sOûD¹tWbT¢Ý—¾˜d¼ 6²¥lÕÿÞ¹šÛQÒÕŠ L|æ|g¾sÿm~$`Æ€`™`Ì/Ž 0?Í^A 2)1Ö/VG0C\è§…~ æÏàXþæ_ŽX†™ýæÂ~ê·ÊyîD€Á‘H†0b±–™!Þ‰Ì`†$^Äy]Wggç^!ÿ¯±&-ì³àÔ«|wsúáöòw€O)0ê/«E½T ¸.yŸP­:ı×vz…BÇÌÑÔŠãKÏ0$ÆJNµú$Èð%r{ÔÊIl;w`Æ%)§ „ÓXD;†z1L±»(º´]³]tÛFµ Q+Õ¨j¡ƒ¿ò³ c†©eq†Åë(@$Ë!ý$ÇÉ2ä,̇ZæBÄ2r“±šUQ,´7ÎëjU®·MÑ•uåôR8 ¹ Å3™©¦ÃØoÒòB­Êªì\øˆˆ_’ç¥ãÞ1aÃ0µì!ìñy7:´Y8é¾Ô'»—'µT+ï8°“í™!::‚ówð$c}bá$Sþ¶’|Ÿ&nî"Àp-)ïãÍ>jÙmÕ–ëJ-AYuàñI­?©¦Õæþêù"„ ¼Ô²PW$›ÀÒÝÜQ‹n®¹óh¹ÈöƒY¡„y¨;ˆÙÇØfS?(—m¹ì±àDœÁ …øf,$†a>·mÕõ*‘©„9©¢!îšWíwÅ7B(X†û˜î6uµ÷e÷GÑ…;1|HX8©ÔUŠà*ÅÄ•î‹jù¹\vJr+'•Þj5ÿ–5OÄ2d}Îã>œ§²üü<ñµË}‰³¨µA‘XWÝv»1¡û“€`¡MŒ:Ô°FB‰yZ#ÛES>õ…ˆO€ ë •‰"rÐA-/ˆö•IßñçM½]?€î¡l_[x©·`QT`ñPTk¥ß* \ÛöôÈj³—Ь2&T.b‡döœû¯ke’ëŽH¥Å@W¥Ú,[ç´©„"A>œ^±‘ÛÒ¨øs±k\ƒ’¤£Å®IÇH&­>*óŽ6‘b#zب-AŽú†‚$ÞWÀÎf_BεÓïµ³KíòÆÛ*yïAƒ5Ð) F¦ÆD0"ˆ‚ñré­¯=$ŽÆ1$CRÉâcb1Ïݱãl8¼îèúW”¼o½·œ|Ò€íÙœíÏ+“¦G¢—ƹx 3™×˜©„ºÒ¿+SZ¾›­jñN’Ö„WjF~ÆÆÙûî¤ugÑÑ]¾2[E(á'ý8»rÐF®o>Gñ´p§ÿvþZb·„ ·!lQ”›£Q§d\ÏoièG,s̾uÀÚú"’Í5žâ\ámCS… &+³AÈžr̉¯\wJÇi ùpM2 Æ,ú3g$2Èv²m[¬mP?–ËScЭ¬Ö'ZÃJû²ªCSåQ 5Î÷¥ÙΘ·| ÄùJŽF—áM"ƒæøv®b<).nv1Æ©Š|ä$HrÄ¡”dì$ bkÉõÕ¥**µÉB¡qÙ5òPîmE¡,”,=¯¬6Åè¿UÝvûôT7L=¿Nk:¤sÌi|óÕùã‡v ù¿¸Õͺ±WõºáŒžËÇVO,50σ!9aÓ^¼‹2Gÿ—ùš ™Qº!¾]ÐT­ß™ì1 ÷÷V+“tÖSEsoÅ»ZÏœ¶æhõzÆUzk2-xÒÓU«ôô»´!#s9ÞK[­ß|<ÍÚëiÓà³Ù]†{÷8,¯[ „y{,\ó‘ÑúP?`_jþ*·ÀYÓ=šß}sl"ò‹Šs9?ú,oé$ endstream endobj 53 0 obj 1415 endobj 51 0 obj << /Type /Page /Parent 44 0 R /Resources << /Font 54 0 R /ProcSet 2 0 R >> /Contents 52 0 R >> endobj 54 0 obj << /F0 6 0 R /F1 8 0 R /F2 10 0 R /F4 26 0 R /F5 28 0 R /F6 32 0 R >> endobj 6 0 obj << /Type /Font /Subtype /TrueType /Name /F0 /BaseFont /Verdana,Italic /FirstChar 32 /LastChar 255 /Widths [ 352 394 459 818 636 1076 727 269 454 454 636 818 364 454 364 454 636 636 636 636 636 636 636 636 636 636 454 454 818 818 818 545 1000 683 686 698 766 632 575 775 751 421 455 693 557 843 748 787 603 787 695 684 616 732 683 990 685 615 685 454 454 454 818 636 636 601 623 521 623 596 352 622 633 274 344 587 274 973 633 607 623 623 427 521 394 633 591 818 592 591 525 635 454 635 818 1000 636 1000 269 636 459 818 636 636 636 1519 684 454 1070 1000 685 1000 1000 269 269 459 459 545 636 1000 636 977 521 454 980 1000 525 615 352 394 636 636 636 636 454 636 636 1000 545 645 818 454 1000 636 542 818 542 542 636 642 636 364 636 542 545 645 1000 1000 1000 545 683 683 683 683 683 683 989 698 632 632 632 632 421 421 421 421 766 748 787 787 787 787 787 818 787 732 732 732 732 615 605 620 601 601 601 601 601 601 955 521 596 596 596 596 274 274 274 274 612 633 607 607 607 607 607 818 607 633 633 633 633 591 623 591 ] /Encoding /WinAnsiEncoding /FontDescriptor 7 0 R >> endobj 7 0 obj << /Type /FontDescriptor /FontName /Verdana,Italic /Flags 96 /FontBBox [ -250 -210 1830 1005 ] /MissingWidth 456 /StemV 92 /StemH 92 /ItalicAngle -11 /CapHeight 1005 /XHeight 503 /Ascent 1005 /Descent -210 /Leading 215 /MaxWidth 1525 /AvgWidth 508 >> endobj 8 0 obj << /Type /Font /Subtype /TrueType /Name /F1 /BaseFont /Verdana /FirstChar 32 /LastChar 255 /Widths [ 352 394 459 818 636 1076 727 269 454 454 636 818 364 454 364 454 636 636 636 636 636 636 636 636 636 636 454 454 818 818 818 545 1000 684 686 698 771 632 575 775 751 421 455 693 557 843 748 787 603 787 695 684 616 732 684 989 685 615 685 454 454 454 818 636 636 601 623 521 623 596 352 623 633 274 344 592 274 973 633 607 623 623 427 521 394 633 592 818 592 592 525 635 454 635 818 1000 636 1000 269 636 459 818 636 636 636 1521 684 454 1070 1000 685 1000 1000 269 269 459 459 545 636 1000 636 977 521 454 981 1000 525 615 352 394 636 636 636 636 454 636 636 1000 545 645 818 454 1000 636 542 818 542 542 636 642 636 364 636 542 545 645 1000 1000 1000 545 684 684 684 684 684 684 984 698 632 632 632 632 421 421 421 421 775 748 787 787 787 787 787 818 787 732 732 732 732 615 605 620 601 601 601 601 601 601 955 521 596 596 596 596 274 274 274 274 612 633 607 607 607 607 607 818 607 633 633 633 633 592 623 592 ] /Encoding /WinAnsiEncoding /FontDescriptor 9 0 R >> endobj 9 0 obj << /Type /FontDescriptor /FontName /Verdana /Flags 32 /FontBBox [ -250 -210 1822 1005 ] /MissingWidth 453 /StemV 92 /StemH 92 /ItalicAngle 0 /CapHeight 1005 /XHeight 503 /Ascent 1005 /Descent -210 /Leading 215 /MaxWidth 1518 /AvgWidth 508 >> endobj 10 0 obj << /Type /Font /Subtype /TrueType /Name /F2 /BaseFont /Verdana,Bold /FirstChar 32 /LastChar 255 /Widths [ 342 402 587 867 711 1272 862 332 543 543 711 867 361 480 361 689 711 711 711 711 711 711 711 711 711 711 402 402 867 867 867 617 964 776 762 724 830 683 650 811 837 546 555 771 637 948 847 850 733 850 782 710 682 812 764 1128 764 737 692 543 689 543 867 711 711 668 699 588 699 664 422 699 712 342 403 671 342 1058 712 687 699 699 497 593 456 712 650 979 669 651 597 711 543 711 867 1000 711 1000 332 711 587 1049 711 711 711 1777 710 543 1135 1000 692 1000 1000 332 332 587 587 711 711 1000 711 964 593 543 1068 1000 597 737 342 402 711 711 711 711 543 711 711 964 598 850 867 480 964 711 587 867 598 598 711 721 711 361 711 598 598 850 1182 1182 1182 617 776 776 776 776 776 776 1094 724 683 683 683 683 546 546 546 546 830 847 850 850 850 850 850 867 850 812 812 812 812 737 735 713 668 668 668 668 668 668 1018 588 664 664 664 664 342 342 342 342 679 712 687 687 687 687 687 867 687 712 712 712 712 651 699 651 ] /Encoding /WinAnsiEncoding /FontDescriptor 11 0 R >> endobj 11 0 obj << /Type /FontDescriptor /FontName /Verdana,Bold /Flags 16416 /FontBBox [ -250 -210 2129 1005 ] /MissingWidth 542 /StemV 181 /StemH 181 /ItalicAngle 0 /CapHeight 1005 /XHeight 503 /Ascent 1005 /Descent -210 /Leading 215 /MaxWidth 1774 /AvgWidth 568 >> endobj 15 0 obj << /Type /Font /Subtype /TrueType /Name /F3 /BaseFont /TimesNewRoman /FirstChar 32 /LastChar 255 /Widths [ 250 333 408 500 500 833 778 180 333 333 500 564 250 333 250 278 500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 722 667 556 611 722 722 944 722 722 611 333 278 333 469 500 333 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 480 200 480 541 778 500 778 333 500 444 1000 500 500 333 1000 556 333 889 778 611 778 778 333 333 444 444 350 500 1000 333 980 389 333 722 778 444 722 250 333 500 500 500 500 200 500 333 760 276 500 564 333 760 500 400 549 300 300 333 576 453 250 333 300 310 500 750 750 750 444 722 722 722 722 722 722 889 667 611 611 611 611 333 333 333 333 722 722 722 722 722 722 722 564 722 722 722 722 722 722 556 500 444 444 444 444 444 444 667 444 444 444 444 444 278 278 278 278 500 500 500 500 500 500 500 549 500 500 500 500 500 500 500 500 ] /Encoding /WinAnsiEncoding /FontDescriptor 16 0 R >> endobj 16 0 obj << /Type /FontDescriptor /FontName /TimesNewRoman /Flags 34 /FontBBox [ -250 -216 1166 1000 ] /MissingWidth 324 /StemV 73 /StemH 73 /ItalicAngle 0 /CapHeight 891 /XHeight 446 /Ascent 891 /Descent -216 /Leading 149 /MaxWidth 972 /AvgWidth 401 >> endobj 26 0 obj << /Type /Font /Subtype /TrueType /Name /F4 /BaseFont /Arial,BoldItalic /FirstChar 32 /LastChar 255 /Widths [ 278 333 474 556 556 889 722 238 333 333 389 584 278 333 278 278 556 556 556 556 556 556 556 556 556 556 333 333 584 584 584 611 975 722 722 722 722 667 611 778 722 278 556 722 611 833 722 778 667 778 722 667 611 722 667 944 667 667 611 333 278 333 584 556 333 556 611 556 611 556 333 611 611 278 278 556 278 889 611 611 611 611 389 556 333 611 556 778 556 556 500 389 280 389 584 750 556 750 278 556 500 1000 556 556 333 1000 667 333 1000 750 611 750 750 278 278 500 500 350 556 1000 333 1000 556 333 944 750 500 667 278 333 556 556 556 556 280 556 333 737 370 556 584 333 737 552 400 549 333 333 333 576 556 278 333 333 365 556 834 834 834 611 722 722 722 722 722 722 1000 722 667 667 667 667 278 278 278 278 722 722 778 778 778 778 778 584 778 722 722 722 722 667 667 611 556 556 556 556 556 556 889 556 556 556 556 556 278 278 278 278 611 611 611 611 611 611 611 549 611 611 611 611 611 556 611 556 ] /Encoding /WinAnsiEncoding /FontDescriptor 27 0 R >> endobj 27 0 obj << /Type /FontDescriptor /FontName /Arial,BoldItalic /Flags 16480 /FontBBox [ -250 -212 1174 1000 ] /MissingWidth 326 /StemV 153 /StemH 153 /ItalicAngle -11 /CapHeight 905 /XHeight 453 /Ascent 905 /Descent -212 /Leading 150 /MaxWidth 978 /AvgWidth 479 >> endobj 28 0 obj << /Type /Font /Subtype /TrueType /Name /F5 /BaseFont /Symbol /FirstChar 30 /LastChar 255 /Widths [ 600 600 250 333 713 500 549 833 778 439 333 333 500 549 250 549 250 278 500 500 500 500 500 500 500 500 500 500 278 278 549 549 549 444 549 722 667 722 612 611 763 603 722 333 631 722 686 889 722 722 768 741 556 592 611 690 439 768 645 795 611 333 863 333 658 500 500 631 549 549 494 439 521 411 603 329 603 549 549 576 521 549 549 521 549 603 439 576 713 686 493 686 494 480 200 480 549 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 620 247 549 167 713 500 753 753 753 753 1042 987 603 987 603 400 549 411 549 549 713 494 460 549 549 549 549 1000 603 1000 658 823 686 795 987 768 768 823 768 768 713 713 713 713 713 713 713 768 713 790 790 890 823 549 250 713 603 603 1042 987 603 987 603 494 329 790 790 786 713 384 384 384 384 384 384 494 494 494 494 600 329 274 686 686 686 384 384 384 384 384 384 494 494 494 600 ] /FontDescriptor 29 0 R >> endobj 29 0 obj << /Type /FontDescriptor /FontName /Symbol /Flags 6 /FontBBox [ -250 -220 1249 1005 ] /MissingWidth 333 /StemV 109 /StemH 109 /ItalicAngle 0 /CapHeight 1005 /XHeight 503 /Ascent 1005 /Descent -220 /Leading 225 /MaxWidth 1041 /AvgWidth 600 >> endobj 32 0 obj << /Type /Font /Subtype /TrueType /Name /F6 /BaseFont /CourierNew,Bold /FirstChar 32 /LastChar 255 /Widths [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] /Encoding /WinAnsiEncoding /FontDescriptor 33 0 R >> endobj 33 0 obj << /Type /FontDescriptor /FontName /CourierNew,Bold /Flags 16418 /FontBBox [ -250 -300 716 1000 ] /MissingWidth 597 /StemV 191 /StemH 191 /ItalicAngle 0 /CapHeight 833 /XHeight 417 /Ascent 833 /Descent -300 /Leading 133 /MaxWidth 597 /AvgWidth 600 >> endobj 36 0 obj << /Type /Font /Subtype /TrueType /Name /F7 /BaseFont /Arial,Bold /FirstChar 32 /LastChar 255 /Widths [ 278 333 474 556 556 889 722 238 333 333 389 584 278 333 278 278 556 556 556 556 556 556 556 556 556 556 333 333 584 584 584 611 975 722 722 722 722 667 611 778 722 278 556 722 611 833 722 778 667 778 722 667 611 722 667 944 667 667 611 333 278 333 584 556 333 556 611 556 611 556 333 611 611 278 278 556 278 889 611 611 611 611 389 556 333 611 556 778 556 556 500 389 280 389 584 750 556 750 278 556 500 1000 556 556 333 1000 667 333 1000 750 611 750 750 278 278 500 500 350 556 1000 333 1000 556 333 944 750 500 667 278 333 556 556 556 556 280 556 333 737 370 556 584 333 737 552 400 549 333 333 333 576 556 278 333 333 365 556 834 834 834 611 722 722 722 722 722 722 1000 722 667 667 667 667 278 278 278 278 722 722 778 778 778 778 778 584 778 722 722 722 722 667 667 611 556 556 556 556 556 556 889 556 556 556 556 556 278 278 278 278 611 611 611 611 611 611 611 549 611 611 611 611 611 556 611 556 ] /Encoding /WinAnsiEncoding /FontDescriptor 37 0 R >> endobj 37 0 obj << /Type /FontDescriptor /FontName /Arial,Bold /Flags 16416 /FontBBox [ -250 -212 1165 1000 ] /MissingWidth 323 /StemV 153 /StemH 153 /ItalicAngle 0 /CapHeight 905 /XHeight 453 /Ascent 905 /Descent -212 /Leading 150 /MaxWidth 971 /AvgWidth 479 >> endobj 40 0 obj << /Type /Font /Subtype /TrueType /Name /F8 /BaseFont /TrebuchetMS /FirstChar 32 /LastChar 255 /Widths [ 301 367 325 524 524 600 706 160 367 367 367 524 367 367 367 524 524 524 524 524 524 524 524 524 524 524 367 367 524 524 524 367 771 590 566 598 613 536 525 676 654 278 477 576 506 709 638 674 558 676 582 481 581 648 587 852 557 570 550 367 355 367 524 524 524 525 557 495 557 545 370 502 546 285 367 504 295 830 546 537 557 557 389 405 396 546 490 744 501 493 475 367 524 367 524 500 524 500 367 388 524 734 459 459 524 913 481 367 993 500 550 500 500 367 367 524 524 524 367 734 524 635 405 367 924 500 475 570 301 367 524 524 524 570 524 454 524 713 367 524 524 367 713 524 524 524 451 454 524 546 524 367 524 451 367 524 814 814 814 367 590 590 590 590 590 590 867 598 536 536 536 536 278 278 278 278 613 638 674 674 674 674 674 524 657 648 648 648 648 570 556 546 525 525 525 525 525 525 873 495 545 545 545 545 285 285 285 285 549 546 537 537 537 537 537 524 545 546 546 546 546 493 553 493 ] /Encoding /WinAnsiEncoding /FontDescriptor 41 0 R >> endobj 41 0 obj << /Type /FontDescriptor /FontName /TrebuchetMS /Flags 32 /FontBBox [ -250 -222 1104 1000 ] /MissingWidth 340 /StemV 83 /StemH 83 /ItalicAngle 0 /CapHeight 939 /XHeight 470 /Ascent 939 /Descent -222 /Leading 161 /MaxWidth 920 /AvgWidth 454 >> endobj 2 0 obj [ /PDF /Text ] endobj 5 0 obj << /Kids [4 0 R 14 0 R 19 0 R 22 0 R 25 0 R 35 0 R ] /Count 6 /Type /Pages /Parent 55 0 R >> endobj 44 0 obj << /Kids [43 0 R 48 0 R 51 0 R ] /Count 3 /Type /Pages /Parent 55 0 R >> endobj 55 0 obj << /Kids [5 0 R 44 0 R ] /Count 9 /Type /Pages /MediaBox [ 0 0 596 842 ] >> endobj 1 0 obj << /Creator /CreationDate (D:20010518230136) /Title /Author /Producer (Acrobat PDFWriter 5.0 for Windows NT) >> endobj 3 0 obj << /Pages 55 0 R /Type /Catalog >> endobj xref 0 56 0000000000 65535 f 0000023881 00000 n 0000023561 00000 n 0000024205 00000 n 0000000578 00000 n 0000023592 00000 n 0000011365 00000 n 0000012468 00000 n 0000012734 00000 n 0000013830 00000 n 0000014087 00000 n 0000015193 00000 n 0000000019 00000 n 0000000558 00000 n 0000001863 00000 n 0000015461 00000 n 0000016552 00000 n 0000000720 00000 n 0000001842 00000 n 0000002583 00000 n 0000002018 00000 n 0000002563 00000 n 0000003571 00000 n 0000002726 00000 n 0000003551 00000 n 0000005032 00000 n 0000016813 00000 n 0000017910 00000 n 0000018181 00000 n 0000019247 00000 n 0000003714 00000 n 0000005011 00000 n 0000019505 00000 n 0000020595 00000 n 0000005142 00000 n 0000006755 00000 n 0000020862 00000 n 0000021953 00000 n 0000005228 00000 n 0000006734 00000 n 0000022216 00000 n 0000023302 00000 n 0000006865 00000 n 0000008318 00000 n 0000023700 00000 n 0000006973 00000 n 0000008297 00000 n 0000008429 00000 n 0000009498 00000 n 0000008515 00000 n 0000009478 00000 n 0000011168 00000 n 0000009654 00000 n 0000011147 00000 n 0000011279 00000 n 0000023789 00000 n trailer << /Size 56 /Root 3 0 R /Info 1 0 R /ID [<41022e51d44c0d7cc8d6eac38733ab06><41022e51d44c0d7cc8d6eac38733ab06>] >> startxref 24255 %%EOF knik0-faac-79329ef/docs/meson.build000066400000000000000000000000261517010422400170540ustar00rootroot00000000000000install_man('faac.1') knik0-faac-79329ef/frontend/000077500000000000000000000000001517010422400156035ustar00rootroot00000000000000knik0-faac-79329ef/frontend/faac.ico000066400000000000000000000226761517010422400172060ustar00rootroot0000000000000000 ¨%(0` ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿ$ÿÿ,ÿÿ1ÿÿ6ÿÿ8ÿÿ9ÿÿ9ÿÿ8ÿÿ6ÿÿ1ÿÿ,ÿÿ$ÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%ÿÿ1ÿÿ;ÿÿAÿÿGÿÿKÿÿNÿÿPÿÿQÿÿQÿÿPÿÿNÿÿKÿÿGÿÿAÿÿ;ÿÿ1ÿÿ%ÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿþÿ(üÿ7ýÿBÿÿJÿÿQÿÿWÿÿ\ÿÿ_ÿÿbÿÿeÿÿfÿÿfÿÿeÿÿbÿÿ_ÿÿ\ÿÿWÿÿQÿÿJýÿBüÿ7þÿ(ÿÿÿÿøÿÿÿÿÿþÿÿÿ ÿÿ"ôÿ7ØÿKÈÿ[ÎÿcçÿcûÿeÿÿiÿÿmÿÿrÿÿtÿÿvÿÿvÿÿvÿÿvÿÿtÿÿrÿÿmÿÿiûÿeçÿcÎÿcÈÿ[ØÿKôÿ7ÿÿ"ÿÿ þÿÿÿÿÿÿÿÿÿÿÿ,îÿA±ÿ_ƒÿ~rÿ‘yÿ—–ÿÏÿùÿ{ÿÿ~ÿÿÿÿƒÿÿ…ÿÿ†ÿÿ†ÿÿ…ÿÿƒÿÿÿÿ~ùÿ{Ïÿ–ÿyÿ—rÿ‘ƒÿ~±ÿ_îÿAÿÿ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ3÷ÿE¶ÿdwÿŒTÿ«Bÿ¾FÿÂ`ÿ¸ÿ¦Ùÿ’ýÿŒÿÿÿÿ‘ÿÿ“ÿÿ”ÿÿ”ÿÿ“ÿÿ‘ÿÿýÿŒÙÿ’ÿ¦`ÿ¸FÿÂBÿ¾Tÿ«wÿŒ¶ÿd÷ÿEÿÿ3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6ÿÿFÙÿ^ÿ†Yÿ¬5ÿÌ ÿá"ÿã=ÿÔkÿÁ¬ÿ¬òÿœÿÿœÿÿžÿÿ ÿÿ¡ÿÿ¡ÿÿ ÿÿžÿÿœòÿœ¬ÿ¬kÿÁ=ÿÔ"ÿã ÿá5ÿÌYÿ¬ÿ†Ùÿ^ÿÿFÿÿ6ÿÿÿÿÿÿÿÿÿÿÿÿ6ÿÿH÷ÿY¹ÿwtÿ FÿÄ!ÿãÿîÿñ&ÿèSÿÔŽÿÀÛÿ­ýÿ¨ÿÿªÿÿ«ÿÿ¬ÿÿ¬ÿÿ«ÿÿªýÿ¨Ûÿ­ŽÿÀSÿÔ&ÿèÿñÿî!ÿãFÿÄtÿ ¹ÿw÷ÿYÿÿHÿÿ6ÿÿÿÿÿÿÿÿÿÿÿÿ3ÿÿGÿÿWèÿk ÿŽdÿ³5ÿÖÿë,ÿä ÿìÿñ@ÿâyÿÏÁÿ¾úÿ´ÿÿµÿÿ¶ÿÿ·ÿÿ·ÿÿ¶ÿÿµúÿ´Áÿ¾yÿÏ@ÿâÿñ ÿì,ÿäÿë5ÿÖdÿ³ ÿŽèÿkÿÿWÿÿGÿÿ3ÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿ,ÿÿCÿÿUÿÿd×ÿ|ÿ¡WÿÃ)ÿã!ÿëDÿÝ6ÿåÿô2ÿëiÿÛ¬ÿÌòÿ¿ÿÿ¿ÿÿÀÿÿÁÿÿÁÿÿÀÿÿ¿òÿ¿¬ÿÌiÿÛ2ÿëÿô6ÿåDÿÝ!ÿë)ÿãWÿÃÿ¡×ÿ|ÿÿdÿÿUÿÿCÿÿ,ÿÿ ÿÿÿÿÿÿÿÿ"ÿÿ>ÿÿQÿÿaøÿqÃÿŒÿ°KÿÐ"ÿé+ÿéYÿÙJÿáÿõ'ÿò[ÿä›ÿ×äÿÊþÿÈÿÿÉÿÿÊÿÿÊÿÿÉþÿÈäÿÊ›ÿ×[ÿä'ÿòÿõJÿáYÿÙ+ÿé"ÿéKÿÐÿ°ÃÿŒøÿqÿÿaÿÿQÿÿ>ÿÿ"ÿÿÿÿÿÿÿÿÿÿ5ÿÿKÿÿ]ÿÿkðÿ}±ÿœsÿ½?ÿÛ"ÿí:ÿæmÿ×]ÿß$ÿóÿöNÿëÿßÔÿÕýÿÐÿÿÒÿÿÒÿÿÒÿÿÒýÿÐÔÿÕÿßNÿëÿö$ÿó]ÿßmÿ×:ÿæ"ÿí?ÿÛsÿ½±ÿœðÿ}ÿÿkÿÿ]ÿÿKÿÿ5ÿÿÿÿÿÿÿÿÿÿÿÿ(ÿÿBÿÿVÿÿgÿÿuåÿ‰¡ÿ©gÿÈ4ÿã&ÿîLÿãÿ×oÿß3ÿñÿùBÿñ€ÿçÅÿÞûÿØÿÿÙÿÿÚÿÿÚÿÿÙûÿØÅÿÞ€ÿçBÿñÿù3ÿñoÿßÿ×Lÿã&ÿî4ÿãgÿÈ¡ÿ©åÿ‰ÿÿuÿÿgÿÿVÿÿBÿÿ(ÿÿÿÿÿÿÿÿÿÿ7ÿÿMÿÿ_ÿÿoýÿ~Øÿ•”ÿµ]ÿÑ.ÿé-ÿí]ÿá“ÿ×ÿàBÿïÿú7ÿõtÿí¶ÿåõÿàÿÿàÿÿáÿÿáÿÿàõÿà¶ÿåtÿí7ÿõÿúBÿïÿà“ÿ×]ÿá-ÿí.ÿé]ÿÑ”ÿµØÿ•ýÿ~ÿÿoÿÿ_ÿÿMÿÿ7ÿÿÿÿÿÿÿÿÿÿ%ÿÿAÿÿWÿÿhÿÿwøÿ†Èÿ ˆÿ¿RÿÚ+ÿí7ÿìoÿà¥ÿØÿàQÿïÿú.ÿøhÿòªÿìîÿæÿÿæÿÿçÿÿçÿÿæîÿæªÿìhÿò.ÿøÿúQÿïÿà¥ÿØoÿà7ÿì+ÿíRÿÚˆÿ¿Èÿ øÿ†ÿÿwÿÿhÿÿWÿÿAÿÿ%ÿÿÿÿÿÿÿÿ ÿÿ1ÿÿJÿÿ^ÿÿoÿÿ~óÿޏÿª|ÿÈGÿá+ÿïFÿêÿß¶ÿÙŸÿá_ÿï ÿû&ÿú]ÿõžÿðäÿìþÿìÿÿíÿÿíþÿìäÿìžÿð]ÿõ&ÿú ÿû_ÿïŸÿá¶ÿÙÿßFÿê+ÿïGÿá|ÿȸÿªóÿŽÿÿ~ÿÿoÿÿ^ÿÿJÿÿ1ÿÿ ÿÿÿÿÿÿÿÿ;ÿÿMÿÿYÿÿpÿþ„éÿ–ªÿ³rþÎ<ÿæ)ÿîSÿæÿßÇÿÛ­ÿälÿð,ÿúÿüRþø”ÿôÝÿðþÿðÿÿñÿÿðÿÿð×ÿñ“ÿôRÿøÿü,ÿúlþð°ÿãÏÿØ’ÿÞTþè-ÿï=ÿæqÿÍ­ÿ°õÿÿÿ{ÿÿkÿÿ\ÿÿNÿÿ;ÿÿÿÿÿÿ$úõCG¶x‚|‚äE¹|§ÿÿ…Ýÿžÿ¼dÿÔ!JÀíi_9ýEt~ñžúà×ÿܼÿåyÿð9ÿùÿýIÿúTybüp…,ýøóõN¯lúp.ýíãõËÿõˆÿøHÿúÿý9ÿù|ÿï£Æìq‰*øE€}ïfÿå3ÿï5ÿégÍÝQ…fßpˆ,æ{‚ëx…ág–=½1Ì¡qÿÿ=ÿÿ#ëÿÿÿ,üôHP®g‡wÿO¯jµÿÿˆÎÿ¥ÿÂYÿÛ=Þîe]Býo~/ùªÐäçÿÜÉÿæ†ÿðEÿùÿþ Bìü~pÿcŽEý÷úø1Í£ú‹sÿ;¼ûÂÿø}ÿú>ÿûÿþEÿù†üð>—‰ó„zý6™ëvÿã>ÿí=Nö|süƒx ûp…+èf•>Ön0Ö‚{ ó†x÷bœGŽ ÷î.ëÿ“ÿ¾ÿ>ÝöTM¯m“‡xÿN±l¶þÿŒ¾ÿ­„ÿÉOÿá1ÿïAU…÷…wþ0°£éøÿÜÖÿæ“ÿñQÿùÿþ3Gžþˆpÿ*¦®üñýûüøû}€ÿl‹3ÿºÿúrÿû2ÿýÿþRÿù Šæóc‡DúmŒ2÷ ¶åâ€ÿã7c˜ò„qÿhq9ö#‚¼Ô ¶ë² êê—òåˆèÔ|f—>¸r…'½ ¶éB“ÿpÿ‰ÿT¦÷hHwž‡xÿM°n¸ôÿ‘¯ÿ³xÿÎEÿå2ÿï"Z¾ïus#ûh’;öA¹…í@¬ˆò>ŠŠø>gŒü9B”þne0ÿzsÿ ©íýëÿüÿÿýL±oþ†vÿB‘ƒþ¿ŠòÒÿíU‰_ú}uÿáþ4ÿþrÿý´ÿýòÿýòÿý´úýQzdþlÿôþPÚüzxÿX Y÷ÿÿäÿÿÞÿÿÖ1ââ„}ýQjgò@öé;ÿäcÿΓÿ±ˆÿªcÿ­Hÿ°Qý•fÿdpÿwÿuÿW]ù‰9[“LJwÿCvÑzÿ¶QÿÓ6ÿæNÿá€ÿÙ»ÿÓóÿÐûô×f˜?ôe™@ø¿Æðw‡!üRceþñþ*ÿþgÿü¨ÿüëÿüëÿü¨þüoÅý†qÿ:Jþ.Y©ýƒ‚ ý*±ðÿÿâÿÿÜÿÿÔà××i:òxqû&R·ë6ÿåQÿÓ{ÿ¸oÿ³Nÿ¸Hò²&b¶žuúXwÿfÿ „ÿHkù{;b޾‡vÿGjyÚcö EìÛ =íå bìÜ’ñÔÑýÌûÿËÿÿÐDºé{ƒü]˜Nø‚ ý$b»ú$ÿý!ÿþ[ÿüÿûßÿùßÿùÿû_õünf0ÿum%ÿ]fPþnŠ1ûáÿèÿÿßÿÿÚÿÿÒþÿÉ9³“Ý„{ükl5ø%F¹ë GçÜ eéÅ ZæÁHØÇ[gTÝkt4Ê „ìKfÿ ÿ–ÿ6{÷k@l†´‹vÿrn)ó]jQë\bSó\dSô`qLòG‘yã ÜçÉÿÿÆÿÿÎäÎÝs‹(øpÿm3ülã÷/ÿüÿþPÿûÿùÔÿ÷Ôÿ÷ÿùRúû:C‘þ’{ÿ„wÿDœ~õðÿãÿÿÜÿÿ×ÿÿÏÿÿÇåÿÄ?šˆÞzyø‚t ými3÷akHígi>ïrú‚v ÷TzaŸ•ò7ÿÿÿ²ÿ ‘øX7w—wt ísq'ðso'ôsr'ôtx&ów|óZœVáèàÃÿÿÂÿÿËÿÿÑM²oëtŒ%ù7™—òyöó:ÿùÿþDÿú„ÿ÷ÇÿôÇÿô„ÿ÷Dÿúäþnm0þ_}Lú³ÔìöÿßÿÿÙÿÿÒÿÿËÿÿÃøÿ¼Ëÿ¼ŽÏÍKrsãfm?ïpn+ómn2íXnZÒ$t»““ÿS³ÿ ÿûõÿæÿ ·ÿ?ÿipÿˆ[ÿ¦Uÿ·cÿ»…ÿ·¹ÿ±ïÿ®ÿÿµÿÿ¿ÿÿÇÿÿÍÿÿÒÿÿ×Êÿä„ÿïDÿ÷ÿý8ÿúwÿöºÿñºÿñwÿö8ÿúÿý?ÿ÷„ÿîÇÿäûþÚÿÿÓÿÿÍÿÿÇÿÿ¿ÿÿµéÿ±¶ÿµ…ÿ¹dÿ»Uÿ·\ÿ§qÿ‹ÿi·ÿ?æÿ õÿÿÿÿÿîÿ&¿ÿQžÿsŒÿމÿž˜ÿ¥¸ÿ¥ãÿ¤þÿ¨ÿÿ°ÿÿ¹ÿÿÁÿÿÈÿÿÎÿÿÔÐÿÞŽÿêNÿôÿü-ÿúiÿô­ÿî­ÿîiÿô-ÿúÿüNÿôŽÿêÐÿÞÿÿÔÿÿÎÿÿÈÿÿÁÿÿ¹ÿÿ°þÿ¨ãÿ¤¸ÿ¥˜ÿ¥‰ÿžŒÿŽžÿs¿ÿQîÿ&ÿÿÿÿÿÿÿÿùÿ8ÜÿUËÿmÉÿ~Öÿ‰îÿÿÿ–ÿÿ ÿÿªÿÿ³ÿÿºÿÿÁÿÿÈÿÿÍÛÿ×™ÿåYÿñÿû#ÿú\ÿóŸÿëŸÿë\ÿó#ÿúÿûYÿñ™ÿåÛÿ×ÿÿÍÿÿÈÿÿÁÿÿºÿÿ³ÿÿªÿÿ ÿÿ–îÿÖÿ‰Éÿ~ËÿmÜÿUùÿ8ÿÿÿÿýÿÿÿÿÿ(ÿÿAÿÿVþÿhÿÿuÿÿ‚ÿÿŽÿÿ™ÿÿ¢ÿÿ«ÿÿ³ÿÿºÿÿÁÿÿÆåÿФÿßbÿì$ÿøÿûOÿòÿéÿéOÿòÿû$ÿøbÿì¤ÿßåÿÐÿÿÆÿÿÁÿÿºÿÿ³ÿÿ«ÿÿ¢ÿÿ™ÿÿŽÿÿ‚ÿÿuþÿhÿÿVÿÿAÿÿ(ÿÿýÿÿÿÿÿÿÿÿÿ5ÿÿKÿÿ]ÿÿlÿÿyÿÿ†ÿÿÿÿ›ÿÿ£ÿÿ«ÿÿ³ÿÿ¹ÿÿ¾ðÿƯÿÖmÿæ/ÿõÿüAÿò€ÿç€ÿçAÿòÿü/ÿõmÿæ¯ÿÖðÿÆÿÿ¾ÿÿ¹ÿÿ³ÿÿ«ÿÿ£ÿÿ›ÿÿÿÿ†ÿÿyÿÿlÿÿ]ÿÿKÿÿ5ÿÿÿÿÿÿÿÿÿÿ"ÿÿ>ÿÿQÿÿaÿÿpÿÿ|ÿÿ‡ÿÿ‘ÿÿ›ÿÿ¢ÿÿªÿÿ°ÿÿ¶øÿ¼»ÿÍwÿÞ9ÿð ÿû3ÿòoÿåoÿå3ÿò ÿû9ÿðwÿÞ»ÿÍøÿ¼ÿÿ¶ÿÿ°ÿÿªÿÿ¢ÿÿ›ÿÿ‘ÿÿ‡ÿÿ|ÿÿpÿÿaÿÿQÿÿ>ÿÿ"ÿÿÿÿÿÿÿÿ ÿÿ,ÿÿCÿÿUÿÿdÿÿqÿÿ}ÿÿ‡ÿÿÿÿ™ÿÿ ÿÿ§ÿÿ¬ÿÿ±ÈÿÁÿÖDÿéÿú&ÿô^ÿä^ÿä&ÿôÿúDÿéÿÖÈÿÁÿÿ±ÿÿ¬ÿÿ§ÿÿ ÿÿ™ÿÿÿÿ‡ÿÿ}ÿÿqÿÿdÿÿUÿÿCÿÿ,ÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿ3ÿÿGÿÿWÿÿeÿÿqÿÿ|ÿÿ†ÿÿŽÿÿ–ÿÿÿÿ£ÿÿ§Öÿ¶ÿÌOÿáÿöÿöLÿäLÿäÿöÿöOÿáÿÌÖÿ¶ÿÿ§ÿÿ£ÿÿÿÿ–ÿÿŽÿÿ†ÿÿ|ÿÿqÿÿeÿÿWÿÿGÿÿ3ÿÿÿÿÿÿÿÿÿÿÿÿ6ÿÿHÿÿWÿÿdÿÿpÿÿyÿÿ‚ÿÿŠÿÿ’ÿÿ˜ÿÿœæÿ§›ÿ¿Zÿ×$ÿî ÿù9ÿæ9ÿæ ÿù$ÿîZÿ×›ÿ¿æÿ§ÿÿœÿÿ˜ÿÿ’ÿÿŠÿÿ‚ÿÿyÿÿpÿÿdÿÿWÿÿHÿÿ6ÿÿÿÿÿÿÿÿÿÿÿÿ6ÿÿGÿÿUÿÿaÿÿlÿÿuÿÿ~ÿÿ…ÿÿ‹ÿÿõÿ—¬ÿ¯gÿÊ1ÿä ÿú&ÿê&ÿê ÿú1ÿägÿʬÿ¯õÿ—ÿÿÿÿ‹ÿÿ…ÿÿ~ÿÿuÿÿlÿÿaÿÿUÿÿGÿÿ6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ3ÿÿCÿÿQÿÿ]ÿÿgÿÿoÿÿwÿÿ~ÿÿƒÿÿˆÁÿwÿ»?ÿ×ÿòÿôÿôÿò?ÿ×wÿ»Áÿÿÿˆÿÿƒÿÿ~ÿÿwÿÿoÿÿgÿÿ]ÿÿQÿÿCÿÿ3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ÿÿ>ÿÿKÿÿVÿÿ_ÿÿhÿÿoÿÿtÿÿyÝÿ†Œÿ¦PÿÄ$ÿá ÿö ÿö$ÿáPÿÄŒÿ¦Ýÿ†ÿÿyÿÿtÿÿoÿÿhÿÿ_ÿÿVÿÿKÿÿ>ÿÿ,ÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿ"ÿÿ5ÿÿBÿÿMÿÿWÿÿ^ÿÿdÿÿiûÿn¬ÿ‰iÿª>ÿÅ&ÿÙ&ÿÙ>ÿÅiÿª¬ÿ‰ûÿnÿÿiÿÿdÿÿ^ÿÿWÿÿMÿÿBÿÿ5ÿÿ"ÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(ÿÿ7ÿÿAÿÿJÿÿQÿÿWÿÿ[ãÿf”ÿ„dÿžNÿ­Nÿ­dÿž”ÿ„ãÿfÿÿ[ÿÿWÿÿQÿÿJÿÿAÿÿ7ÿÿ(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%ÿÿ1ÿÿ;ÿÿAÿÿGÿÿKäÿT¨ÿh‰ÿv‰ÿv¨ÿhäÿTÿÿKÿÿGÿÿAÿÿ;ÿÿ1ÿÿ%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿ$ÿÿ,ÿÿ1þÿ6úÿ9õÿ;õÿ;úÿ9þÿ6ÿÿ1ÿÿ,ÿÿ$ÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿþÿÿøÿÿàÿÿ€ÿÿÿþü?øððààÀÀ€€€€€€€ÀÀààððøü?þÿÿÿ€ÿÿàÿÿøÿÿþÿÿÿàÿÿknik0-faac-79329ef/frontend/faacgui.rc000066400000000000000000000110261517010422400175300ustar00rootroot00000000000000//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_MAINDIALOG DIALOGEX 0, 0, 264, 190 STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "FAAC GUI" FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON "...",IDC_SELECT_INPUTFILE,225,12,19,14,0, WS_EX_STATICEDGE PUSHBUTTON "...",IDC_SELECT_OUTPUTFILE,225,33,19,14,WS_DISABLED, WS_EX_STATICEDGE CONTROL "Allow Mid/Side",IDC_ALLOWMIDSIDE,"Button", BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,14,81,71,10 LTEXT "Quantizer\nquality", IDC_STATIC, 98, 73, 44, 18 EDITTEXT IDC_QUALITY, 138, 76, 30, 12, ES_AUTOHSCROLL CONTROL "", IDC_STATIC, "static", SS_SUNKEN, 98, 94, 70, 30 CONTROL "Set bandwidth", IDC_BWCTL, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 102, 96, 62, 12 EDITTEXT IDC_BANDWIDTH,102,109,34,12,ES_AUTOHSCROLL | WS_DISABLED | WS_TABSTOP LTEXT "Hz", IDC_STATIC, 140, 111, 10, 8 DEFPUSHBUTTON "Encode",IDOK,200,152,50,14,WS_DISABLED PUSHBUTTON "Quit",IDCANCEL,200,170,50,14 LTEXT "",IDC_TIME,7,151,190,20 LTEXT "", IDC_COMPILEDATE, 20, 176, 150, 8 EDITTEXT IDC_INPUTFILENAME,61,12,158,14,ES_AUTOHSCROLL EDITTEXT IDC_OUTPUTFILENAME,61,33,158,14,ES_AUTOHSCROLL | WS_DISABLED LTEXT "Input File:",IDC_STATIC,18,13,38,8 LTEXT "Output File:",IDC_STATIC,18,34,37,8 CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,7,54, 250,1 LTEXT "-",IDC_INPUTPARAMS,32,66,55,8 LTEXT "In:",IDC_STATIC,14,66,12,8 CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7, 135,250,10 GROUPBOX "Output Format",IDC_STATIC,93,62,164,67 CONTROL "Use RAW output",IDC_USERAW,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,14,103,71,10 CONTROL "Use TNS",IDC_USETNS,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,14,92,71,10 COMBOBOX IDC_MPEGVERSION,183,82,67,63,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_OBJECTTYPE,183,109,67,59,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | WS_DISABLED LTEXT "MPEG Version",IDC_STATIC,183,73,56,8 LTEXT "AAC Object Type",IDC_STATIC,183,100,56,8 CONTROL "Use LFE channel",IDC_USELFE,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_DISABLED | WS_TABSTOP,14,114,71,10 END ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_MAINDIALOG, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 257 TOPMARGIN, 7 BOTTOMMARGIN, 178 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog Info // IDD_MAINDIALOG DLGINIT BEGIN IDC_MPEGVERSION, 0x403, 1, 0, "\000", 0 END #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED knik0-faac-79329ef/frontend/getopt.c000066400000000000000000000542261517010422400172620ustar00rootroot00000000000000/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef __STDC__ # ifndef const # define const # endif #endif /* This tells Alpha OSF/1 not to define a getopt prototype in . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include //#include "tailor.h" /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) || !__MacOSX__ /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #endif /* GNU C library. */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is being phased out. */ /* #define GETOPT_COMPAT */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = 0; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ #define BAD_OPTION '\0' int optopt = BAD_OPTION; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #if defined(__GNU_LIBRARY__) || defined(__APPLE__) /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #define my_strlen strlen #else /* Avoid depending on library functions or files whose names are inconsistent. */ #if __STDC__ || defined(PROTO) extern char *getenv(const char *name); extern int strcmp (const char *s1, const char *s2); extern int strncmp(const char *s1, const char *s2, size_t n); static int my_strlen(const char *s); static char *my_index (const char *str, int chr); #else extern char *getenv (); #endif static int my_strlen (str) const char *str; { int n = 0; while (*str++) n++; return n; } static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } #endif /* GNU C library. */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. To perform the swap, we first reverse the order of all elements. So all options now come before all non options, but they are in the wrong order. So we put back the options and non options in original order by reversing them again. For example: original input: a b c -x -y reverse all: -y -x c b a reverse options: -x -y c b a reverse non options: -x -y a b c */ #if __STDC__ || defined(PROTO) static void exchange (char **argv); #endif static void exchange (argv) char **argv; { char *temp, **first, **last; /* Reverse all the elements [first_nonopt, optind) */ first = &argv[first_nonopt]; last = &argv[optind-1]; while (first < last) { temp = *first; *first = *last; *last = temp; first++; last--; } /* Put back the options in order */ first = &argv[first_nonopt]; first_nonopt += (optind - last_nonopt); last = &argv[first_nonopt - 1]; while (first < last) { temp = *first; *first = *last; *last = temp; first++; last--; } /* Put back the non options in order */ first = &argv[first_nonopt]; last_nonopt = optind; last = &argv[last_nonopt-1]; while (first < last) { temp = *first; *first = *last; *last = temp; first++; last--; } } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return BAD_OPTION after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return BAD_OPTION. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { int option_index; optarg = 0; /* Initialize the internal data when the first call is made. Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ if (optind == 0) { first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv ("POSIXLY_CORRECT") != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; } if (nextchar == NULL || *nextchar == '\0') { if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Now skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) optind++; last_nonopt = optind; } /* Special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Start decoding its characters. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } if (longopts != NULL && ((argv[optind][0] == '-' && (argv[optind][1] == '-' || long_only)) #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ )) { const struct option *p; char *s = nextchar; int exact = 0; int ambig = 0; const struct option *pfound = NULL; int indfound = 0; while (*s && *s != '=') s++; /* Test all options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, s - nextchar)) { if (s - nextchar == my_strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += my_strlen (nextchar); optind++; return BAD_OPTION; } if (pfound != NULL) { option_index = indfound; optind++; if (*s) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = s + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += my_strlen (nextchar); return BAD_OPTION; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += my_strlen (nextchar); return optstring[0] == ':' ? ':' : BAD_OPTION; } } nextchar += my_strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return BAD_OPTION; } } /* Look at and handle the next option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { #if 0 if (c < 040 || c >= 0177) fprintf (stderr, "%s: unrecognized option, character code 0%o\n", argv[0], c); else fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); #endif } optopt = c; return BAD_OPTION; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = 0; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { #if 0 fprintf (stderr, "%s: option `-%c' requires an argument\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); #endif } optopt = c; if (optstring[0] == ':') c = ':'; else c = BAD_OPTION; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case BAD_OPTION: break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ knik0-faac-79329ef/frontend/getopt.h000066400000000000000000000106601517010422400172610ustar00rootroot00000000000000/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif #ifndef __MacOSX__ /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; #endif /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 //#if __STDC__ || defined(PROTO) #if defined(__GNU_LIBRARY__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); //#else /* not __STDC__ */ extern int getopt (int argc, char *const *argv, const char *shortopts); //extern int getopt_long (); //extern int getopt_long_only (); //extern int _getopt_internal (); //#endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ knik0-faac-79329ef/frontend/icon.rc000066400000000000000000000000601517010422400170550ustar00rootroot00000000000000#include "resource.h" ID_ICON1 ICON "faac.ico" knik0-faac-79329ef/frontend/input.c000066400000000000000000000244251517010422400171150ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2002 Krzysztof Nikiel * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: input.c,v 1.21 2017/07/02 14:35:23 knik Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef _WIN32 #include #include #endif #include "input.h" #define SWAP32(x) (((x & 0xff) << 24) | ((x & 0xff00) << 8) \ | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24)) #define SWAP16(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8)) #ifdef WORDS_BIGENDIAN # define UINT32(x) SWAP32(x) # define UINT16(x) SWAP16(x) #else # define UINT32(x) (x) # define UINT16(x) (x) #endif typedef struct { uint32_t label; /* 'RIFF' */ uint32_t length; /* Length of rest of file */ uint32_t chunk_type; /* 'WAVE' */ } riff_t; typedef struct { uint32_t label; uint32_t len; } riffsub_t; #ifdef _MSC_VER #pragma pack(push, 1) #endif #define WAVE_FORMAT_PCM 1 #define WAVE_FORMAT_FLOAT 3 #define WAVE_FORMAT_EXTENSIBLE 0xfffe struct WAVEFORMATEX { uint16_t wFormatTag; uint16_t nChannels; uint32_t nSamplesPerSec; uint32_t nAvgBytesPerSec; uint16_t nBlockAlign; uint16_t wBitsPerSample; uint16_t cbSize; } #ifdef __GNUC__ __attribute__((packed)) #endif ; struct WAVEFORMATEXTENSIBLE { struct WAVEFORMATEX Format; union { uint16_t wValidBitsPerSample; // bits of precision uint16_t wSamplesPerBlock; // valid if wBitsPerSample==0 uint16_t wReserved; // If neither applies, set to zero. } Samples; uint32_t dwChannelMask; // which channels are present in stream unsigned char SubFormat[16]; // guid } #ifdef __GNUC__ __attribute__((packed)) #endif ; #ifdef _MSC_VER #pragma pack(pop) #endif static unsigned char waveformat_pcm_guid[16] = { WAVE_FORMAT_PCM,0,0,0, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; static void unsuperr(const char *name) { fprintf(stderr, "%s: file format not supported\n", name); } static void seekcur(FILE *f, int ofs) { int cnt; for (cnt = 0; cnt < ofs; cnt++) fgetc(f); } static int seekchunk(FILE *f, riffsub_t *riffsub, char *name) { int skipped; for(skipped = 0; skipped < 10; skipped++) { if (fread(riffsub, 1, sizeof(*riffsub), f) != sizeof(*riffsub)) return 0; riffsub->len = UINT32(riffsub->len); if (riffsub->len & 1) riffsub->len++; if (!memcmp(&(riffsub->label), name, 4)) return 1; seekcur(f, riffsub->len); } return 0; } pcmfile_t *wav_open_read(const char *name, int rawinput) { FILE *wave_f; riff_t riff; riffsub_t riffsub = {0}; struct WAVEFORMATEXTENSIBLE wave; char *riffl = "RIFF"; char *wavel = "WAVE"; char *fmtl = "fmt "; char *datal = "data"; int fmtsize; pcmfile_t *sndf; int dostdin = 0; if (!strcmp(name, "-")) { #ifdef _WIN32 _setmode(_fileno(stdin), O_BINARY); #endif wave_f = stdin; dostdin = 1; } else if (!(wave_f = fopen(name, "rb"))) { perror(name); return NULL; } if (!rawinput) // header input { if (fread(&riff, 1, sizeof(riff), wave_f) != sizeof(riff)) return NULL; if (memcmp(&(riff.label), riffl, 4)) return NULL; if (memcmp(&(riff.chunk_type), wavel, 4)) return NULL; if (!seekchunk(wave_f, &riffsub, fmtl)) return NULL; if (memcmp(&(riffsub.label), fmtl, 4)) return NULL; memset(&wave, 0, sizeof(wave)); fmtsize = (riffsub.len < sizeof(wave)) ? riffsub.len : sizeof(wave); // check if format is at least 16 bytes long if (fmtsize < 16) return NULL; if (fread(&wave, 1, fmtsize, wave_f) != fmtsize) return NULL; seekcur(wave_f, riffsub.len - fmtsize); if (!seekchunk(wave_f, &riffsub, datal)) return NULL; if (UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_PCM && UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_FLOAT) { if (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_EXTENSIBLE) { if (UINT16(wave.Format.cbSize) < 22) // struct too small return NULL; if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16)) { waveformat_pcm_guid[0] = WAVE_FORMAT_FLOAT; if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16)) { unsuperr(name); return NULL; } } } else { unsuperr(name); return NULL; } } } sndf = (pcmfile_t*)malloc(sizeof(*sndf)); memset(sndf, 0, sizeof(*sndf)); sndf->f = wave_f; if (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_FLOAT) { sndf->isfloat = 1; } else { sndf->isfloat = (wave.SubFormat[0] == WAVE_FORMAT_FLOAT); } if (rawinput) { sndf->bigendian = 1; if (dostdin) sndf->samples = 0; else { fseek(sndf->f, 0 , SEEK_END); sndf->samples = ftell(sndf->f); rewind(sndf->f); } } else { sndf->bigendian = 0; sndf->channels = UINT16(wave.Format.nChannels); sndf->samplebytes = UINT16(wave.Format.wBitsPerSample) / 8; sndf->samplerate = UINT32(wave.Format.nSamplesPerSec); if (!sndf->samplebytes || !sndf->channels) { free(sndf); return NULL; } sndf->samples = riffsub.len / (sndf->samplebytes * sndf->channels); } return sndf; } static void chan_remap(int32_t *buf, int channels, int blocks, int *map) { int i; int32_t *tmp = (int32_t*)malloc(channels * sizeof(int32_t)); for (i = 0; i < blocks; i++) { int chn; memcpy(tmp, buf + i * channels, sizeof(int32_t) * channels); for (chn = 0; chn < channels; chn++) buf[i * channels + chn] = tmp[map[chn]]; } free(tmp); } size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map) { size_t cnt; size_t isize; char *bufi; if ((sndf->samplebytes > 4) || (sndf->samplebytes < 1)) return 0; isize = num * sndf->samplebytes; bufi = (char*)(buf + num); bufi -= isize; isize = fread(bufi, 1, isize, sndf->f); isize /= sndf->samplebytes; // perform in-place conversion for (cnt = 0; cnt < num; cnt++) { if (cnt >= isize) break; if (sndf->isfloat) { switch (sndf->samplebytes) { case 4: buf[cnt] *= 32768.0; break; default: return 0; } continue; } switch (sndf->samplebytes) { case 1: { uint8_t *in = (uint8_t*)bufi; uint8_t s = in[cnt]; buf[cnt] = ((float)s - 128.0) * (float)256; } break; case 2: { int16_t *in = (int16_t*)bufi; int16_t s = in[cnt]; #ifdef WORDS_BIGENDIAN if (!sndf->bigendian) #else if (sndf->bigendian) #endif buf[cnt] = (float)SWAP16(s); else buf[cnt] = (float)s; } break; case 3: { int s; uint8_t *in = (uint8_t*)bufi; in += 3 * cnt; if (!sndf->bigendian) s = in[0] | (in[1] << 8) | (in[2] << 16); else s = (in[0] << 16) | (in[1] << 8) | in[2]; // fix sign if (s & 0x800000) s |= 0xff000000; buf[cnt] = (float)s / 256; } break; case 4: { int32_t *in = (int32_t*)bufi; int s = in[cnt]; #ifdef WORDS_BIGENDIAN if (!sndf->bigendian) #else if (sndf->bigendian) #endif buf[cnt] = (float)SWAP32(s) / 65536; else buf[cnt] = (float)s / 65536; } break; default: return 0; } } if (map) chan_remap((int32_t *)buf, sndf->channels, cnt / sndf->channels, map); return cnt; } size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map) { int size; int i; uint8_t *bufi; if ((sndf->samplebytes > 4) || (sndf->samplebytes < 1)) return 0; bufi = (uint8_t *)buf + sizeof(*buf) * num - sndf->samplebytes * (num - 1) - sizeof(*buf); size = fread(bufi, sndf->samplebytes, num, sndf->f); // convert to 24 bit // fix endianness switch (sndf->samplebytes) { case 1: /* this is endian clean */ for (i = 0; i < size; i++) buf[i] = (bufi[i] - 128) * 65536; break; case 2: #ifdef WORDS_BIGENDIAN if (!sndf->bigendian) #else if (sndf->bigendian) #endif { // swap bytes for (i = 0; i < size; i++) { int16_t s = ((int16_t *)bufi)[i]; s = SWAP16(s); buf[i] = ((uint32_t)s) << 8; } } else { // no swap for (i = 0; i < size; i++) { int s = ((int16_t *)bufi)[i]; buf[i] = s << 8; } } break; case 3: if (!sndf->bigendian) { for (i = 0; i < size; i++) { int s = bufi[3 * i] | (bufi[3 * i + 1] << 8) | (bufi[3 * i + 2] << 16); // fix sign if (s & 0x800000) s |= 0xff000000; buf[i] = s; } } else // big endian input { for (i = 0; i < size; i++) { int s = (bufi[3 * i] << 16) | (bufi[3 * i + 1] << 8) | bufi[3 * i + 2]; // fix sign if (s & 0x800000) s |= 0xff000000; buf[i] = s; } } break; case 4: #ifdef WORDS_BIGENDIAN if (!sndf->bigendian) #else if (sndf->bigendian) #endif { // swap bytes for (i = 0; i < size; i++) { int s = buf[i]; buf[i] = SWAP32(s); } } break; } if (map) chan_remap(buf, sndf->channels, size / sndf->channels, map); return size; } int wav_close(pcmfile_t *sndf) { int i = fclose(sndf->f); free(sndf); return i; } knik0-faac-79329ef/frontend/input.h000066400000000000000000000027341517010422400171210ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2002 Krzysztof Nikiel * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: input.h,v 1.7 2008/11/24 22:00:11 menno Exp $ */ #ifndef _INPUT_H #define _INPUT_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef __cplusplus extern "C" { #endif typedef struct { FILE *f; int channels; int samplebytes; int samplerate; int samples; int bigendian; int isfloat; } pcmfile_t; pcmfile_t *wav_open_read(const char *path, int rawchans); size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map); size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map); int wav_close(pcmfile_t *file); #ifdef __cplusplus } #endif #endif /* _INPUT_H */ knik0-faac-79329ef/frontend/main.c000066400000000000000000001131071517010422400166760ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * Copyright (C) 2002-2017 Krzysztof Nikiel * Copyright (C) 2004 Dan Villiom P. Christiansen * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef _WIN32 #include #include #else #include #endif /* the BSD derivatives don't define __unix__ */ #if defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) #define __unix__ #endif #ifdef __unix__ #include #include #endif #include #include #include #include #include #ifdef HAVE_GETOPT_H # include #else # include "getopt.h" # include "getopt.c" #endif #include "mp4write.h" #ifdef _WIN32 # undef stderr # define stderr stdout #endif #include "input.h" #include #define FALSE 0 #define TRUE 1 enum flags { SHORTCTL_FLAG = 300, MPEGVERS_FLAG, ARTIST_FLAG, ARTIST_SORT_FLAG, TITLE_FLAG, GENRE_FLAG, ALBUM_FLAG, ALBUM_SORT_FLAG, ALBUM_ARTIST_FLAG, ALBUM_ARTIST_SORT_FLAG, TRACK_FLAG, DISC_FLAG, YEAR_FLAG, COVER_ART_FLAG, COMMENT_FLAG, WRITER_FLAG, WRITER_SORT_FLAG, TAG_FLAG, HELP_QUAL, HELP_IO, HELP_MP4, HELP_ADVANCED, OPT_JOINT, OPT_PNS }; typedef struct { char *shorthelp; char *longhelp; } help_t; const char *usage = "Usage: %s [options] infile\n\n"; static help_t help_qual[] = { {"-q \tSet encoding quality.\n", "\t\tSet default variable bitrate (VBR) quantizer quality in percent.\n" "\t\tmax. 5000, min. 10.\n" "\t\tdefault: 100, averages at approx. 120 kbps VBR for a normal\n" "\t\tstereo input file with 16 bit and 44.1 kHz sample rate\n" }, {"-b \tSet average bitrate to x kbps. (ABR)\n", "\t\tSet average bitrate (ABR) to approximately kbps.\n" "\t\tmax. ~500 (stereo)\n"}, {"-c \tSet the bandwidth in Hz.\n", "\t\tThe actual frequency is adjusted to maximize upper spectral band\n" "\t\tusage.\n"}, {0} }; static help_t help_io[] = { {"-o \tSet output file to X (only for one input file)\n", "\t\tonly for one input file; you can use *.aac, *.mp4, *.m4a or\n" "\t\t*.m4b as file extension, and the file format will be set\n" "\t\tautomatically to ADTS or MP4).\n"}, {"-\t\tUse stdin/stdout\n", "\t\tIf you simply use a hyphen/minus sign instead\n" "\t\tof a filename, FAAC can encode directly from stdin,\n" "\t\tthus enabling piping from other applications and utilities. The\n" "\t\tsame works for stdout as well, so FAAC can pipe its output to\n" "\t\tother apps such as a server.\n"}, {"-v \t\tverbosity level (-v0 is quiet mode)\n"}, {"-r\t\tUse RAW AAC output file.\n", "\t\tGenerate raw AAC bitstream (i.e. without any headers).\n" "\t\tNot advised!!!, RAW AAC files are practically useless!!!\n"}, {"-P\t\tRaw PCM input mode (default 44100Hz 16bit stereo).\n", "\t\tRaw PCM input mode (default: off, i.e. expecting a WAV header;\n" "\t\tnecessary for input files or bitstreams without a header; using\n" "\t\tonly -P assumes the default values for -R, -B and -C in the\n" "\t\tinput file).\n"}, {"-R \tRaw PCM input rate.\n", "\t\tRaw PCM input sample rate in Hz (default: 44100 Hz, max. 96 kHz)\n"}, {"-B \tRaw PCM input sample size (8, 16 (default), 24 or 32bits).\n", "\t\tRaw PCM input sample size (default: 16, also possible 8, 24, 32\n" "\t\tbit fixed or float input).\n"}, {"-C \tRaw PCM input channels.\n", "\t\tRaw PCM input channels (default: 2, max. 33 + 1 LFE).\n"}, {"-X\t\tRaw PCM swap input bytes\n", "\t\tRaw PCM swap input bytes (default: bigendian).\n"}, {"-I \tInput channel config, default is 3,4 (Center third, LF fourth)\n", "\t\tInput multichannel configuration (default: 3,4 which means\n" "\t\tCenter is third and LFE is fourth like in 5.1 WAV, so you only\n" "\t\thave to specify a different position of these two mono channels\n" "\t\tin your multichannel input files if they haven't been reordered\n" "\t\talready).\n"}, {"--ignorelength\tIgnore wav length from header (useful with files over 4 GB)\n"}, {"--overwrite\t\tOverwrite existing output file"}, {0} }; static help_t help_mp4[] = { {"-w\tWrap AAC data in MP4 container (default for *.mp4, *.m4a and *.m4b)\n"}, {"--tag Add named tag (iTunes '----')\n"}, {"--artist \tSet artist name\n"}, {"--artistsort \tSet artist sort order\n"}, {"--composer \tSet composer name\n"}, {"--composersort \tSet composer sort order\n"}, {"--title \tSet title/track name\n"}, {"--genre \tSet genre number\n"}, {"--album \tSet album/performer\n"}, {"--albumartist \tSet album artist\n"}, {"--albumartistsort \tSet album artist sort order\n"}, {"--albumsort \tSet album sort order\n"}, {"--compilation\tMark as compilation\n"}, {"--track \tSet track number\n"}, {"--disc \tSet disc number\n"}, {"--year \tSet year\n"}, {"--cover-art \tRead cover art from file X\n", "\t\tSupported image formats are GIF, JPEG, and PNG.\n"}, {"--comment \tSet comment\n"}, {0} }; static help_t help_advanced[] = { {"--tns \tEnable coding of TNS, temporal noise shaping.\n"}, {"--no-tns\tDisable coding of TNS, temporal noise shaping.\n"}, {"--joint 0\tDisable joint stereo coding.\n"}, {"--joint 1\tUse Mid/Side coding.\n"}, {"--joint 2\tUse Intensity Stereo coding.\n"}, {"--pns <0 .. 10>\tPNS level; 0=disabled.\n"}, {"--mpeg-vers X\tForce AAC MPEG version, X can be 2 or 4\n"}, {"--shortctl X\tEnforce block type (0 = both (default); 1 = no short; 2 = no\n" "\t\tlong).\n"}, {0} }; static struct { int id; char *name; char *option; help_t *help; } g_help[] = { {HELP_QUAL, "Quality-related options", "--help-qual", help_qual}, {HELP_IO, "Input/output options", "--help-io", help_io}, {HELP_MP4, "MP4 specific options", "--help-mp4", help_mp4}, {HELP_ADVANCED, "Advanced options, only for testing purposes", "--help-advanced", help_advanced}, {0} }; char *license = "\nPlease note that the use of this software may require the payment of patent\n" "royalties. You need to consider this issue before you start building derivative\n" "works. We are not warranting or indemnifying you in any way for patent\n" "royalities! YOU ARE SOLELY RESPONSIBLE FOR YOUR OWN ACTIONS!\n" "\n" "FAAC is based on the ISO MPEG-4 reference code. For this code base the\n" "following license applies:\n" "\n" "This software module was originally developed by\n" "\n" "FirstName LastName (CompanyName)\n" "\n" "and edited by\n" "\n" "FirstName LastName (CompanyName)\n" "FirstName LastName (CompanyName)\n" "\n" "in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard\n" "ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an\n" "implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools\n" "as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives\n" "users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this\n" "software module or modifications thereof for use in hardware or\n" "software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio\n" "standards. Those intending to use this software module in hardware or\n" "software products are advised that this use may infringe existing\n" "patents. The original developer of this software module and his/her\n" "company, the subsequent editors and their companies, and ISO/IEC have\n" "no liability for use of this software module or modifications thereof\n" "in an implementation. Copyright is not released for non MPEG-2\n" "NBC/MPEG-4 Audio conforming products. The original developer retains\n" "full right to use the code for his/her own purpose, assign or donate\n" "the code to a third party and to inhibit third party from using the\n" "code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This\n" "copyright notice must be included in all copies or derivative works.\n" "\n" "Copyright (c) 1997.\n" "\n" "For the changes made for the FAAC project the GNU Lesser General Public\n" "License (LGPL), version 2 1991 applies:\n" "\n" "FAAC - Freeware Advanced Audio Coder\n" "Copyright (C) 2001-2004 The individual contributors\n" "\n" "This library is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU Lesser General Public\n" "License as published by the Free Software Foundation; either\n" "version 2.1 of the License, or (at your option) any later version.\n" "\n" "This library is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" "Lesser General Public License for more details.\n" "\n" "You should have received a copy of the GNU Lesser General Public\n" "License along with this library; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" "\n"; #ifndef min #define min(a,b) ( (a) < (b) ? (a) : (b) ) #endif /* globals */ char *progName; #ifndef _WIN32 volatile int running = 1; #endif enum container_format { NO_CONTAINER, MP4_CONTAINER, }; #ifndef _WIN32 void signal_handler(int signal) { running = 0; } #endif static void help0(help_t *h, int l) { int cnt; for (cnt = 0; h[cnt].shorthelp; cnt++) { printf(" %s", h[cnt].shorthelp); if (l && h[cnt].longhelp) printf("%s", h[cnt].longhelp); } printf("\n\n"); } static void help(int mode) { int cnt; static const char *name = "faac"; printf(usage, name); switch (mode) { case '?': case 'h': case 'H': printf("Help options:\n" "\t-h\t\tShort help on using FAAC\n" "\t-H\t\tDescription of all options for FAAC.\n" "\t--license\tLicense terms for FAAC.\n"); for (cnt = 0; g_help[cnt].id; cnt++) printf("\t%s\t%s\n", g_help[cnt].option, g_help[cnt].name); if (mode == 'h') { for (cnt = 0; cnt < 2; cnt++) { printf("%s:\n", g_help[cnt].name); help0(g_help[cnt].help, 0); } } if (mode == 'H') { for (cnt = 0; cnt < g_help[cnt].id; cnt++) { printf("%s:\n", g_help[cnt].name); help0(g_help[cnt].help, 1); } } break; default: for (cnt = 0; g_help[cnt].id; cnt++) if (g_help[cnt].id == mode) { printf("%s:\n", g_help[cnt].name); help0(g_help[cnt].help, 1); break; } break; } } static int check_image_header(const char *buf) { if (!strncmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8)) return 1; /* PNG */ else if (!strncmp(buf, "\xFF\xD8\xFF\xE0", 4) || !strncmp(buf, "\xFF\xD8\xFF\xE1", 4)) return 1; /* JPEG */ else if (!strncmp(buf, "GIF87a", 6) || !strncmp(buf, "GIF89a", 6)) return 1; /* GIF */ else return 0; } static int *mkChanMap(int channels, int center, int lf) { int *map; int inpos; int outpos; if (!center && !lf) return NULL; if (channels < 3) return NULL; if (lf > 0) lf--; else lf = channels - 1; // default AAC position if (center > 0) center--; else center = 0; // default AAC position map = malloc(channels * sizeof(map[0])); memset(map, 0, channels * sizeof(map[0])); outpos = 0; if ((center >= 0) && (center < channels)) map[outpos++] = center; inpos = 0; for (; outpos < (channels - 1); inpos++) { if (inpos == center) continue; if (inpos == lf) continue; map[outpos++] = inpos; } if (outpos < channels) { if ((lf >= 0) && (lf < channels)) map[outpos] = lf; else map[outpos] = inpos; } return map; } #define fprintf if(verbose)fprintf int main(int argc, char *argv[]) { int frames, currentFrame; faacEncHandle hEncoder; pcmfile_t *infile = NULL; unsigned long samplesInput, maxBytesOutput, totalBytesWritten = 0; faacEncConfigurationPtr myFormat; unsigned int mpegVersion = MPEG4; unsigned int objectType = LOW; int jointmode = -1; int pnslevel = -1; static int useTns = 0; enum container_format container = NO_CONTAINER; enum stream_format stream = ADTS_STREAM; int cutOff = -1; int bitRate = 0; unsigned long quantqual = 0; int chanC = 3; int chanLF = 4; char *audioFileName = NULL; char *aacFileName = NULL; char *aacFileExt = NULL; int aacFileNameGiven = 0; float *pcmbuf; int *chanmap = NULL; unsigned char *bitbuf; int samplesRead = 0; const char *dieMessage = NULL; int rawChans = 0; // disabled by default int rawBits = 16; int rawRate = 44100; int rawEndian = 1; int shortctl = SHORTCTL_NORMAL; FILE *outfile = NULL; unsigned int ntracks = 0, trackno = 0; unsigned int ndiscs = 0, discno = 0; static int compilation = 0; const char *artist = NULL, *artistsort = NULL, *title = NULL, *album = NULL, *albumartist = NULL, *albumartistsort = NULL, *albumsort = NULL, *year = NULL, *comment = NULL, *composer = NULL, *composersort = NULL, *tagname = 0, *tagval = 0; int genre = 0; uint8_t *artData = NULL; uint64_t artSize = 0; uint64_t encoded_samples = 0; unsigned int delay_samples; unsigned int frameSize; uint64_t input_samples = 0; char *faac_id_string; char *faac_copyright_string; static int ignorelen = 0; int verbose = 1; static int overwrite = 0; #ifndef _WIN32 // install signal handler signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); #endif // get faac version if (faacEncGetVersion(&faac_id_string, &faac_copyright_string) == FAAC_CFG_VERSION) { fprintf(stderr, "Freeware Advanced Audio Coder\nFAAC %s\n\n", faac_id_string); } else { fprintf(stderr, __FILE__ "(%d): wrong libfaac version " "(expected %s, found %s)\n", __LINE__, PACKAGE_VERSION, faac_id_string); return 1; } /* begin process command line */ progName = argv[0]; if (argc < 2) { help('?'); return 1; } while (1) { static struct option long_options[] = { {"help", 0, 0, 'h'}, {"help-qual", 0, 0, HELP_QUAL}, {"help-io", 0, 0, HELP_IO}, {"help-mp4", 0, 0, HELP_MP4}, {"help-advanced", 0, 0, HELP_ADVANCED}, {"raw", 0, 0, 'r'}, {"joint", required_argument, 0, OPT_JOINT}, {"pns", required_argument, 0, OPT_PNS}, {"cutoff", 1, 0, 'c'}, {"quality", 1, 0, 'q'}, {"pcmraw", 0, 0, 'P'}, {"pcmsamplerate", 1, 0, 'R'}, {"pcmsamplebits", 1, 0, 'B'}, {"pcmchannels", 1, 0, 'C'}, {"shortctl", 1, 0, SHORTCTL_FLAG}, {"tns", 0, &useTns, 1}, {"no-tns", 0, &useTns, 0}, {"mpeg-version", 1, 0, MPEGVERS_FLAG}, {"license", 0, 0, 'L'}, {"createmp4", 0, 0, 'w'}, {"artist", 1, 0, ARTIST_FLAG}, {"artistsort", 1, 0, ARTIST_SORT_FLAG}, {"title", 1, 0, TITLE_FLAG}, {"album", 1, 0, ALBUM_FLAG}, {"albumartist", 1, 0, ALBUM_ARTIST_FLAG}, {"albumartistsort", 1, 0, ALBUM_ARTIST_SORT_FLAG}, {"albumsort", 1, 0, ALBUM_SORT_FLAG}, {"track", 1, 0, TRACK_FLAG}, {"disc", 1, 0, DISC_FLAG}, {"genre", 1, 0, GENRE_FLAG}, {"year", 1, 0, YEAR_FLAG}, {"cover-art", 1, 0, COVER_ART_FLAG}, {"comment", 1, 0, COMMENT_FLAG}, {"composer", 1, 0, WRITER_FLAG}, {"composersort", 1, 0, WRITER_SORT_FLAG}, {"compilation", 0, &compilation, 1}, {"pcmswapbytes", 0, 0, 'X'}, {"ignorelength", 0, &ignorelen, 1}, {"tag", 1, 0, TAG_FLAG}, {"overwrite", 0, &overwrite, 1}, {0, 0, 0, 0} }; int c = -1; int option_index = 0; c = getopt_long(argc, argv, "Hhb:m:o:rnc:q:PR:B:C:I:Xwv:", long_options, &option_index); if (c == -1) break; if (!c) continue; switch (c) { case 'o': { int l = strlen(optarg); aacFileName = malloc(l + 1); memcpy(aacFileName, optarg, l); aacFileName[l] = '\0'; aacFileNameGiven = 1; } break; case 'r': { stream = RAW_STREAM; break; } case 'c': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { cutOff = i; } break; } case 'b': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { bitRate = 1000 * i; } break; } case 'q': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { if (i > 0) quantqual = i; } break; } case 'I': sscanf(optarg, "%d,%d", &chanC, &chanLF); break; case 'P': rawChans = 2; // enable raw input break; case 'R': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { rawRate = i; rawChans = (rawChans > 0) ? rawChans : 2; } break; } case 'B': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { if (i > 32) i = 32; if (i < 8) i = 8; rawBits = i; rawChans = (rawChans > 0) ? rawChans : 2; } break; } case 'C': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) rawChans = i; break; } case 'w': container = MP4_CONTAINER; break; case ARTIST_FLAG: artist = optarg; break; case ARTIST_SORT_FLAG: artistsort = optarg; break; case WRITER_FLAG: composer = optarg; break; case WRITER_SORT_FLAG: composersort = optarg; break; case TITLE_FLAG: title = optarg; break; case ALBUM_FLAG: album = optarg; break; case ALBUM_ARTIST_FLAG: albumartist = optarg; break; case ALBUM_ARTIST_SORT_FLAG: albumartistsort = optarg; break; case ALBUM_SORT_FLAG: albumsort = optarg; break; case TRACK_FLAG: if (sscanf(optarg, "%d/%d", &trackno, &ntracks) < 1) dieMessage = "Wrong track number.\n"; break; case DISC_FLAG: if (sscanf(optarg, "%d/%d", &discno, &ndiscs) < 1) dieMessage = "Wrong disc number.\n"; break; case GENRE_FLAG: genre = atoi(optarg); if ((genre < 0) || (genre > 255)) dieMessage = "Genre number out of range.\n"; genre++; break; case YEAR_FLAG: year = optarg; break; case COMMENT_FLAG: comment = optarg; break; case TAG_FLAG: tagname = optarg; if (!(tagval = strchr(optarg, ','))) dieMessage = "Missing tag value.\n"; else *(char *)tagval++ = 0; mp4tag_add(tagname, tagval); break; case COVER_ART_FLAG: { FILE *artFile = fopen(optarg, "rb"); if (artFile) { uint64_t r; fseek(artFile, 0, SEEK_END); artSize = ftell(artFile); artData = malloc(artSize); fseek(artFile, 0, SEEK_SET); clearerr(artFile); r = fread(artData, artSize, 1, artFile); if (r != 1) { dieMessage = "Error reading cover art file!\n"; free(artData); artData = NULL; } else if (artSize < 12 || !check_image_header((const char *) artData)) { /* the above expression checks the image signature */ dieMessage = "Unsupported cover image file format!\n"; free(artData); artData = NULL; } fclose(artFile); } else { dieMessage = "Error opening cover art file!\n"; } break; } case SHORTCTL_FLAG: shortctl = atoi(optarg); break; case MPEGVERS_FLAG: mpegVersion = atoi(optarg); switch (mpegVersion) { case 2: mpegVersion = MPEG2; break; case 4: mpegVersion = MPEG4; break; default: dieMessage = "Unrecognised MPEG version!\n"; } break; case 'L': fprintf(stderr, "%s", faac_copyright_string); dieMessage = license; break; case 'X': rawEndian = 0; break; case 'v': verbose = atoi(optarg); break; case HELP_QUAL: case HELP_IO: case HELP_MP4: case HELP_ADVANCED: case 'H': case 'h': help(c); return 1; break; case OPT_JOINT: jointmode = atoi(optarg); break; case OPT_PNS: pnslevel = atoi(optarg); break; case '?': default: help('?'); return 1; break; } } /* check that we have at least one non-option arguments */ if (!dieMessage && (argc - optind) > 1 && aacFileNameGiven) dieMessage = "Cannot encode several input files to one output file.\n"; if (argc - optind < 1 || dieMessage) { fprintf(stderr, dieMessage, progName, progName, progName, progName); return 1; } while (argc - optind > 0) { /* get the input file name */ audioFileName = argv[optind++]; } /* generate the output file name, if necessary */ if (!aacFileNameGiven) { char *t = strrchr(audioFileName, '.'); int l = t ? strlen(audioFileName) - strlen(t) : strlen(audioFileName); aacFileExt = container == MP4_CONTAINER ? ".m4a" : ".aac"; aacFileName = malloc(l + 1 + 4); memcpy(aacFileName, audioFileName, l); memcpy(aacFileName + l, aacFileExt, 4); aacFileName[l + 4] = '\0'; } else { aacFileExt = strrchr(aacFileName, '.'); if (aacFileExt && (!strcmp(".m4a", aacFileExt) || !strcmp(".m4b", aacFileExt) || !strcmp(".mp4", aacFileExt))) container = MP4_CONTAINER; } /* open the audio input file */ if (rawChans > 0) // use raw input { infile = wav_open_read(audioFileName, 1); if (infile) { infile->bigendian = rawEndian; infile->channels = rawChans; infile->samplebytes = rawBits / 8; infile->samplerate = rawRate; infile->samples /= (infile->channels * infile->samplebytes); } } else // header input infile = wav_open_read(audioFileName, 0); if (infile == NULL) { fprintf(stderr, "Couldn't open input file %s\n", audioFileName); return 1; } /* open the encoder library */ hEncoder = faacEncOpen(infile->samplerate, infile->channels, &samplesInput, &maxBytesOutput); if (hEncoder == NULL) { fprintf(stderr, "Couldn't open encoder instance for input file %s\n", audioFileName); wav_close(infile); return 1; } if (container != MP4_CONTAINER && (ntracks || trackno || artist || artistsort || title || album || albumartist || albumartistsort || albumsort || year || artData || genre || comment || discno || ndiscs || composer || composersort || compilation)) { fprintf(stderr, "Metadata requires MP4 output!\n"); return 1; } if (container == MP4_CONTAINER) { mpegVersion = MPEG4; stream = RAW_STREAM; } frameSize = samplesInput / infile->channels; delay_samples = frameSize; // encoder delay 1024 samples pcmbuf = (float *) malloc(samplesInput * sizeof(float)); bitbuf = (unsigned char *) malloc(maxBytesOutput * sizeof(unsigned char)); chanmap = mkChanMap(infile->channels, chanC, chanLF); if (chanmap) { fprintf(stderr, "Remapping input channels: Center=%d, LFE=%d\n", chanC, chanLF); } if (cutOff <= 0) { if (cutOff < 0) // default cutOff = 0; else // disabled cutOff = infile->samplerate / 2; } if (cutOff > (infile->samplerate / 2)) cutOff = infile->samplerate / 2; /* put the options in the configuration struct */ myFormat = faacEncGetCurrentConfiguration(hEncoder); myFormat->aacObjectType = objectType; myFormat->mpegVersion = mpegVersion; myFormat->useTns = useTns; switch (shortctl) { case SHORTCTL_NOSHORT: fprintf(stderr, "disabling short blocks\n"); myFormat->shortctl = shortctl; break; case SHORTCTL_NOLONG: fprintf(stderr, "disabling long blocks\n"); myFormat->shortctl = shortctl; break; } if (infile->channels >= 6) myFormat->useLfe = 1; if (jointmode >= 0) myFormat->jointmode = jointmode; if (pnslevel > 0 && mpegVersion == MPEG2) { fprintf(stderr, "PNS not allowed in MPEG-2 mode, disabling PNS\n"); pnslevel = 0; } if (pnslevel >= 0) myFormat->pnslevel = pnslevel; if (quantqual > 0) { myFormat->quantqual = quantqual; myFormat->bitRate = 0; } if (bitRate) myFormat->bitRate = bitRate / infile->channels; myFormat->bandWidth = cutOff; myFormat->outputFormat = stream; myFormat->inputFormat = FAAC_INPUT_FLOAT; if (!faacEncSetConfiguration(hEncoder, myFormat)) { fprintf(stderr, "Unsupported output format!\n"); return 1; } /* initialize MP4 creation */ if (container == MP4_CONTAINER) { if (!strcmp(aacFileName, "-")) { fprintf(stderr, "cannot encode MP4 to stdout\n"); return 1; } if (mp4atom_open(aacFileName, overwrite)) { fprintf(stderr, "Couldn't create output file %s\n", aacFileName); return 1; } mp4atom_head(); mp4config.samplerate = infile->samplerate; mp4config.channels = infile->channels; mp4config.bits = infile->samplebytes * 8; } else { /* open the aac output file */ if (!strcmp(aacFileName, "-")) { outfile = stdout; } else { outfile = fopen(aacFileName, "wb"); } if (!outfile) { fprintf(stderr, "Couldn't create output file %s\n", aacFileName); return 1; } } cutOff = myFormat->bandWidth; quantqual = myFormat->quantqual; bitRate = myFormat->bitRate; if (bitRate) { fprintf(stderr, "Initial quantization quality: %ld\n", quantqual); fprintf(stderr, "Average bitrate: %d kbps/channel\n", (bitRate + 500) / 1000); } else fprintf(stderr, "Quantization quality: %ld\n", quantqual); fprintf(stderr, "Bandwidth: %d Hz\n", cutOff); if (myFormat->pnslevel > 0) fprintf(stderr, "PNS level: %d\n", myFormat->pnslevel); fprintf(stderr, "Object type: "); switch (objectType) { case LOW: fprintf(stderr, "Low Complexity"); break; case MAIN: fprintf(stderr, "Main"); break; case LTP: fprintf(stderr, "LTP"); break; } fprintf(stderr, " (MPEG-%d)", (mpegVersion == MPEG4) ? 4 : 2); if (myFormat->useTns) fprintf(stderr, " + TNS"); switch(myFormat->jointmode) { case JOINT_MS: fprintf(stderr, " + M/S"); break; case JOINT_IS: fprintf(stderr, " + IS"); break; } if (myFormat->pnslevel > 0) fprintf(stderr, " + PNS"); fprintf(stderr, "\n"); fprintf(stderr, "Container format: "); switch (container) { case NO_CONTAINER: switch (stream) { case RAW_STREAM: fprintf(stderr, "Headerless AAC (RAW)\n"); break; case ADTS_STREAM: fprintf(stderr, "Transport Stream (ADTS)\n"); break; } break; case MP4_CONTAINER: fprintf(stderr, "MPEG-4 File Format (MP4)\n"); break; } int showcnt = 0; #ifdef _WIN32 long begin = GetTickCount(); #endif if (infile->samples) frames = ((infile->samples + 1023) / 1024) + 1; else frames = 0; currentFrame = 0; fprintf(stderr, "Encoding %s to %s\n", audioFileName, aacFileName); if (frames != 0) { fprintf(stderr, " frame | bitrate | elapsed/estim | " "play/CPU | ETA\n"); } else { fprintf(stderr, " frame | elapsed | play/CPU\n"); } /* encoding loop */ #ifdef _WIN32 for (;;) #else while (running) #endif { int bytesWritten; if (!ignorelen) { if (input_samples < infile->samples || infile->samples == 0) samplesRead = wav_read_float32(infile, pcmbuf, samplesInput, chanmap); else samplesRead = 0; if (input_samples + (samplesRead / infile->channels) > infile->samples && infile->samples != 0) samplesRead = (infile->samples - input_samples) * infile->channels; } else samplesRead = wav_read_float32(infile, pcmbuf, samplesInput, chanmap); input_samples += samplesRead / infile->channels; /* call the actual encoding routine */ bytesWritten = faacEncEncode(hEncoder, (int32_t *) pcmbuf, samplesRead, bitbuf, maxBytesOutput); if (bytesWritten) { currentFrame++; showcnt--; totalBytesWritten += bytesWritten; } if ((showcnt <= 0) || !bytesWritten) { double timeused; #ifdef __unix__ struct rusage usage; #endif #ifdef _WIN32 char percent[MAX_PATH + 20]; timeused = (GetTickCount() - begin) * 1e-3; #else #ifdef __unix__ if (getrusage(RUSAGE_SELF, &usage) == 0) { timeused = (double) usage.ru_utime.tv_sec + (double) usage.ru_utime.tv_usec * 1e-6; } else timeused = 0; #else timeused = (double) clock() * (1.0 / CLOCKS_PER_SEC); #endif #endif if (currentFrame && (timeused > 0.1)) { showcnt += 50; if (frames != 0) { fprintf(stderr, "\r%7d/%-7d (%3d%%) | %5.1f | %6.1f/%-6.1f | %7.2fx | %.1f ", currentFrame, frames, currentFrame * 100 / frames, ((double) totalBytesWritten * 8.0 / 1000.0) / ((double) infile->samples / infile->samplerate * currentFrame / frames), timeused, timeused * frames / currentFrame, (1024.0 * currentFrame / infile->samplerate) / timeused, timeused * (frames - currentFrame) / currentFrame); } else { fprintf(stderr, "\r %7d | %7.1f | %7.2fx ", currentFrame, timeused, (1024.0 * currentFrame / infile->samplerate) / timeused); } fflush(stderr); #ifdef _WIN32 if (frames != 0) { sprintf(percent, "%.2f%% encoding %s", 100.0 * currentFrame / frames, audioFileName); SetConsoleTitle(percent); } #endif } } /* all done, bail out */ if (!samplesRead && !bytesWritten) break; if (bytesWritten < 0) { fprintf(stderr, "faacEncEncode() failed\n"); break; } if (bytesWritten > 0) { uint64_t frame_samples = input_samples - encoded_samples; if (frame_samples > delay_samples) frame_samples = delay_samples; if (container == MP4_CONTAINER) mp4atom_frame(bitbuf, bytesWritten, frame_samples); else fwrite(bitbuf, 1, bytesWritten, outfile); encoded_samples += frame_samples; } } fprintf(stderr, "\n"); if (container == MP4_CONTAINER) { char *version_string = malloc(strlen(faac_id_string) + 6); faacEncGetDecoderSpecificInfo(hEncoder, &mp4config.asc.data, &mp4config.asc.size); strcpy(version_string, "FAAC "); strcpy(version_string + 5, faac_id_string); mp4config.tag.encoder = version_string; #define SETTAG(x) if(x)mp4config.tag.x=x SETTAG(artist); SETTAG(artistsort); SETTAG(composer); SETTAG(composersort); SETTAG(title); SETTAG(album); SETTAG(albumartist); SETTAG(albumartistsort); SETTAG(albumsort); SETTAG(trackno); SETTAG(ntracks); SETTAG(discno); SETTAG(ndiscs); SETTAG(compilation); SETTAG(year); SETTAG(genre); SETTAG(comment); if (artData && artSize) { mp4config.tag.cover.data = artData; mp4config.tag.cover.size = artSize; } mp4atom_tail(); mp4atom_close(); free(version_string); if (verbose >= 2) { fprintf(stderr, "%u frames\n", mp4config.frame.ents); fprintf(stderr, "%u output samples\n", mp4config.samples); fprintf(stderr, "max bitrate: %u\n", mp4config.bitrate.max); fprintf(stderr, "avg bitrate: %u\n", mp4config.bitrate.avg); fprintf(stderr, "max frame size: %u\n", mp4config.buffersize); } } else { fclose(outfile); } faacEncClose(hEncoder); wav_close(infile); if (artData) free(artData); if (pcmbuf) free(pcmbuf); if (bitbuf) free(bitbuf); if (aacFileNameGiven) free(aacFileName); return 0; } knik0-faac-79329ef/frontend/maingui.c000066400000000000000000000326211517010422400174040ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: maingui.c,v 1.21 2007/03/19 19:57:40 menno Exp $ */ #include #include #include #include #include "input.h" #include #include "resource.h" static HINSTANCE hInstance; static char inputFilename[_MAX_PATH], outputFilename[_MAX_PATH]; static BOOL Encoding = FALSE; static BOOL SelectFileName(HWND hParent, char *filename, BOOL forReading) { OPENFILENAME ofn; ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hParent; ofn.hInstance = hInstance; ofn.nFilterIndex = 0; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 31; filename [0] = 0x00; ofn.lpstrFile = (LPSTR)filename; ofn.nMaxFile = _MAX_PATH; ofn.lpstrInitialDir = NULL; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lCustData = 0; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL; if (forReading) { char filters[] = { "Wave Files (*.wav)\0*.wav\0" \ "AIFF Files (*.aif;*.aiff;*.aifc)\0*.aif;*.aiff;*.aifc\0" \ "AU Files (*.au)\0*.au\0" \ "All Files (*.*)\0*.*\0\0" }; ofn.lpstrFilter = filters; ofn.lpstrDefExt = "wav"; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrTitle = "Select Source File"; return GetOpenFileName (&ofn); } else { char filters [] = { "AAC Files (*.aac)\0*.aac\0" \ "All Files (*.*)\0*.*\0\0" }; ofn.lpstrFilter = filters; ofn.lpstrDefExt = "aac"; ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; ofn.lpstrTitle = "Select Output File"; return GetSaveFileName(&ofn); } } static void AwakeDialogControls(HWND hWnd) { char szTemp[64]; pcmfile_t *infile = NULL; unsigned int sampleRate, numChannels; char *pExt; if ((infile = wav_open_read(inputFilename, 0)) == NULL) return; /* determine input file parameters */ sampleRate = infile->samplerate; numChannels = infile->channels; wav_close(infile); SetDlgItemText (hWnd, IDC_INPUTFILENAME, inputFilename); strncpy(outputFilename, inputFilename, sizeof(outputFilename) - 5); outputFilename[sizeof(outputFilename) - 5] = '\0'; pExt = strrchr(outputFilename, '.'); if (pExt == NULL) lstrcat(outputFilename, ".aac"); else lstrcpy(pExt, ".aac"); EnableWindow(GetDlgItem(hWnd, IDC_OUTPUTFILENAME), TRUE); EnableWindow(GetDlgItem(hWnd, IDC_SELECT_OUTPUTFILE), TRUE); SetDlgItemText(hWnd, IDC_OUTPUTFILENAME, outputFilename); wsprintf(szTemp, "%iHz %ich", sampleRate, numChannels); SetDlgItemText(hWnd, IDC_INPUTPARAMS, szTemp); EnableWindow(GetDlgItem(hWnd, IDOK), TRUE); } static DWORD WINAPI EncodeFile(LPVOID pParam) { HWND hWnd = (HWND) pParam; pcmfile_t *infile = NULL; GetDlgItemText(hWnd, IDC_INPUTFILENAME, inputFilename, sizeof(inputFilename)); GetDlgItemText(hWnd, IDC_OUTPUTFILENAME, outputFilename, sizeof(outputFilename)); /* open the input file */ if ((infile = wav_open_read(inputFilename, 0)) != NULL) { /* determine input file parameters */ unsigned int sampleRate = infile->samplerate; unsigned int numChannels = infile->channels; unsigned long inputSamples; unsigned long maxOutputBytes; /* open and setup the encoder */ faacEncHandle hEncoder = faacEncOpen(sampleRate, numChannels, &inputSamples, &maxOutputBytes); if (hEncoder) { HANDLE hOutfile; char szTemp[256]; /* set encoder configuration */ faacEncConfigurationPtr config = faacEncGetCurrentConfiguration(hEncoder); config->jointmode = IsDlgButtonChecked(hWnd, IDC_ALLOWMIDSIDE) == BST_CHECKED ? 1 : 0; config->useTns = IsDlgButtonChecked(hWnd, IDC_USETNS) == BST_CHECKED ? 1 : 0; config->useLfe = IsDlgButtonChecked(hWnd, IDC_USELFE) == BST_CHECKED ? 1 : 0; config->outputFormat = IsDlgButtonChecked(hWnd, IDC_USERAW) == BST_CHECKED ? 0 : 1; config->mpegVersion = SendMessage(GetDlgItem(hWnd, IDC_MPEGVERSION), CB_GETCURSEL, 0, 0); config->aacObjectType = SendMessage(GetDlgItem(hWnd, IDC_OBJECTTYPE), CB_GETCURSEL, 0, 0); config->aacObjectType = LOW; GetDlgItemText(hWnd, IDC_QUALITY, szTemp, sizeof(szTemp)); config->quantqual = atoi(szTemp); if (IsDlgButtonChecked(hWnd, IDC_BWCTL) == BST_CHECKED) { GetDlgItemText(hWnd, IDC_BANDWIDTH, szTemp, sizeof(szTemp)); config->bandWidth = atoi(szTemp); } else config->bandWidth = 0; if (!faacEncSetConfiguration(hEncoder, config)) { faacEncClose(hEncoder); wav_close(infile); MessageBox (hWnd, "faacEncSetConfiguration failed!", "Error", MB_OK | MB_ICONSTOP); SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)"FAAC GUI"); Encoding = FALSE; SetDlgItemText(hWnd, IDOK, "Encode"); return 0; } sprintf(szTemp, "%ld", config->quantqual); SetDlgItemText(hWnd, IDC_QUALITY, szTemp); sprintf(szTemp, "%d", config->bandWidth); SetDlgItemText(hWnd, IDC_BANDWIDTH, szTemp); /* open the output file */ hOutfile = CreateFile(outputFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hOutfile != INVALID_HANDLE_VALUE) { UINT startTime = GetTickCount(), lastUpdated = 50; DWORD totalBytesRead = 0; unsigned int bytesInput = 0; DWORD numberOfBytesWritten = 0; int *pcmbuf; unsigned char *bitbuf; char HeaderText[50]; char Percentage[5]; pcmbuf = (int*)LocalAlloc(0, inputSamples*sizeof(int)); bitbuf = (unsigned char*)LocalAlloc(0, maxOutputBytes*sizeof(unsigned char)); SendDlgItemMessage(hWnd, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, 1024)); SendDlgItemMessage(hWnd, IDC_PROGRESS, PBM_SETPOS, 0, 0); for ( ;; ) { int bytesWritten; UINT timeElapsed, timeEncoded; bytesInput = wav_read_int24(infile, pcmbuf, inputSamples, NULL) * sizeof(int); SendDlgItemMessage (hWnd, IDC_PROGRESS, PBM_SETPOS, (unsigned long)((float)totalBytesRead * 1024.0f / (infile->samples*sizeof(int)*numChannels)), 0); /* Percentage for Dialog Output */ _itoa((int)((float)totalBytesRead * 100.0f / (infile->samples*sizeof(int)*numChannels)),Percentage,10); lstrcpy(HeaderText,"FAAC GUI: "); lstrcat(HeaderText,Percentage); lstrcat(HeaderText,"%"); SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)HeaderText); totalBytesRead += bytesInput; timeElapsed = (GetTickCount () - startTime) / 10; timeEncoded = 100.0 * totalBytesRead / (sampleRate * numChannels * sizeof (int)); if (timeElapsed > (lastUpdated + 20)) { float factor; unsigned timeLeft; lastUpdated = timeElapsed; factor = (float) timeEncoded / (float) (timeElapsed ? timeElapsed : 1); timeLeft = 10.0 * infile->samples / sampleRate / factor - 0.1 * timeElapsed; sprintf(szTemp, "Playing time: %2.2i:%04.1f\tEncoding time: %2.2i:%04.1f\n" "Play/enc factor: %.2f\tEstimated time left: %2.2i:%04.1f", timeEncoded / 6000, 0.01 * (timeEncoded % 6000), timeElapsed / 6000, 0.01 * (timeElapsed % 6000), factor, timeLeft / 600, 0.1 * (timeLeft % 600) ); SetDlgItemText(hWnd, IDC_TIME, szTemp); } /* call the actual encoding routine */ bytesWritten = faacEncEncode(hEncoder, pcmbuf, bytesInput/sizeof(int), bitbuf, maxOutputBytes); /* Stop Pressed */ if ( !Encoding ) break; /* all done, bail out */ if (!bytesInput && !bytesWritten) break; if (bytesWritten < 0) { MessageBox (hWnd, "faacEncEncodeFrame failed!", "Error", MB_OK | MB_ICONSTOP); break; } WriteFile(hOutfile, bitbuf, bytesWritten, &numberOfBytesWritten, NULL); } CloseHandle(hOutfile); if (pcmbuf) LocalFree(pcmbuf); if (bitbuf) LocalFree(bitbuf); } faacEncClose(hEncoder); } wav_close(infile); MessageBeep(1); SendDlgItemMessage(hWnd, IDC_PROGRESS, PBM_SETPOS, 0, 0); } else { MessageBox(hWnd, "Couldn't open input file!", "Error", MB_OK | MB_ICONSTOP); } SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)"FAAC GUI"); Encoding = FALSE; SetDlgItemText(hWnd, IDOK, "Encode"); return 0; } static BOOL WINAPI DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { unsigned long samplesInput, maxBytesOutput; faacEncHandle hEncoder = faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput); faacEncConfigurationPtr myFormat = faacEncGetCurrentConfiguration(hEncoder); if (myFormat->version == FAAC_CFG_VERSION) { char txt[100]; sprintf(txt, "libfaac version %s", myFormat->name); SetDlgItemText(hWnd, IDC_COMPILEDATE, txt); } else { MessageBox(hWnd, "wrong libfaac version", "FAAC", MB_OK | MB_ICONERROR); PostMessage(hWnd, WM_CLOSE, 0, 0); } faacEncClose(hEncoder); } inputFilename[0] = 0x00; SendMessage(GetDlgItem(hWnd, IDC_MPEGVERSION), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"MPEG4"); SendMessage(GetDlgItem(hWnd, IDC_MPEGVERSION), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"MPEG2"); SendMessage(GetDlgItem(hWnd, IDC_MPEGVERSION), CB_SETCURSEL, 0, 0); SendMessage(GetDlgItem(hWnd, IDC_OBJECTTYPE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Low Complexity"); SendMessage(GetDlgItem(hWnd, IDC_OBJECTTYPE), CB_SETCURSEL, 0, 0); CheckDlgButton(hWnd, IDC_ALLOWMIDSIDE, TRUE); CheckDlgButton(hWnd, IDC_USELFE, FALSE); CheckDlgButton(hWnd, IDC_USERAW, FALSE); CheckDlgButton(hWnd, IDC_USETNS, TRUE); SetDlgItemText(hWnd, IDC_QUALITY, "100"); SetDlgItemText(hWnd, IDC_BANDWIDTH, "0"); DragAcceptFiles(hWnd, TRUE); return TRUE; case WM_DROPFILES: if (DragQueryFile((HDROP) wParam, 0, (LPSTR) inputFilename, _MAX_PATH - 1)) AwakeDialogControls(hWnd); DragFinish((HDROP) wParam); return FALSE; case WM_COMMAND: switch (wParam) { case IDOK: if ( !Encoding ) { DWORD retval; CreateThread(NULL,0,EncodeFile,hWnd,0,&retval); Encoding = TRUE; SetDlgItemText(hWnd, IDOK, "Stop"); } else { Encoding = FALSE; SetDlgItemText(hWnd, IDOK, "Encode"); } return TRUE; case IDCANCEL: EndDialog(hWnd, TRUE); return TRUE; case IDC_SELECT_INPUTFILE: if (SelectFileName(hWnd, inputFilename, TRUE)) AwakeDialogControls(hWnd); break; case IDC_SELECT_OUTPUTFILE: if (SelectFileName(hWnd, outputFilename, FALSE)) { SetDlgItemText(hWnd, IDC_OUTPUTFILENAME, outputFilename); } break; case IDC_BWCTL: switch (IsDlgButtonChecked(hWnd, IDC_BWCTL)) { case BST_CHECKED: EnableWindow(GetDlgItem(hWnd, IDC_BANDWIDTH), TRUE); //SetDlgItemText(hWnd, IDC_BANDWIDTH, "0"); break; case BST_UNCHECKED: EnableWindow(GetDlgItem(hWnd, IDC_BANDWIDTH), FALSE); //SetDlgItemText(hWnd, IDC_BANDWIDTH, ""); break; } break; } break; } return FALSE; } int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { hInstance = hInst; return DialogBox(hInstance, MAKEINTRESOURCE (IDD_MAINDIALOG), NULL, (DLGPROC) DialogProc); } knik0-faac-79329ef/frontend/meson.build000066400000000000000000000011071517010422400177440ustar00rootroot00000000000000faac = executable('faac', ['main.c', 'input.c', 'mp4write.c', 'input.h', 'mp4write.h'], include_directories: ['..', '../include'], link_with: libfaac, install: true ) if target_machine.system() == 'windows' windows = import('windows') resource_src = windows.compile_resources('faacgui.rc', 'icon.rc') faacgui = executable('faacgui', ['input.c', 'input.h', 'maingui.c', 'resource.h'] + resource_src, include_directories: ['..', '../include'], link_with: libfaac, win_subsystem: 'windows', install: true ) endif knik0-faac-79329ef/frontend/mp4write.c000066400000000000000000000503741517010422400175330ustar00rootroot00000000000000/**************************************************************************** MP4 output module Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef _WIN32 #include #define access _access #define W_OK 2 #else #include #endif #include "mp4write.h" enum ATOM_TYPE { ATOM_STOP = 0 /* end of atoms */ , ATOM_NAME /* plain atom */ , ATOM_DESCENT, /* starts group of children */ ATOM_ASCENT, /* ends group */ ATOM_DATA, }; typedef struct { uint16_t opcode; void *data; } creator_t; mp4config_t mp4config = { 0 }; static FILE *g_fout = NULL; static inline uint32_t be32(uint32_t u32) { #ifndef WORDS_BIGENDIAN #if defined (__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) return __builtin_bswap32(u32); #elif defined (_MSC_VER) return _byteswap_ulong(u32); #else return (u32 << 24) | ((u32 << 8) & 0xFF0000) | ((u32 >> 8) & 0xFF00) | (u32 >> 24); #endif #else return u32; #endif } static inline uint16_t be16(uint16_t u16) { #ifndef WORDS_BIGENDIAN #if defined (__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))) return __builtin_bswap16(u16); #elif defined (_MSC_VER) return _byteswap_ushort(u16); #else return (u16 << 8) | (u16 >> 8); #endif #else return u16; #endif } static int dataout(const void *data, int size) { if (fwrite(data, 1, size, g_fout) != size) { perror("mp4out"); return -1; } return size; } static int stringout(const char *txt) { return dataout(txt, strlen(txt)); } static int u32out(uint32_t u32) { u32 = be32(u32); return dataout(&u32, 4); } static int u16out(uint16_t u16) { u16 = be16(u16); return dataout(&u16, 2); } static int u8out(uint8_t u8) { if (fwrite(&u8, 1, 1, g_fout) != 1) { perror("mp4 out"); return 0; } return 1; } static int ftypout(void) { int size = 0; size += stringout("M4A "); size += u32out(0); size += stringout("M4A "); size += stringout("mp42"); size += stringout("isom"); size += u32out(0); return size; } enum { SECSINDAY = 24 * 60 * 60 }; static time_t mp4time(void) { int y; time_t t; time(&t); // add some time from the start of 1904 to the start of 1970 for (y = 1904; y < 1970; y++) { t += 365 * SECSINDAY; if (!(y & 3)) t += SECSINDAY; } return t; } static int mvhdout(void) { int size = 0; int cnt; // version size += u8out(0); // flags size += u8out(0); size += u16out(0); // Creation time size += u32out(mp4time()); // Modification time size += u32out(mp4time()); // Time scale (samplerate) size += u32out(mp4config.samplerate); // Duration size += u32out(mp4config.samples); // rate size += u32out(0x00010000); // volume size += u16out(0x0100); // reserved size += u16out(0); size += u32out(0); size += u32out(0); // matrix size += u32out(0x00010000); size += u32out(0); size += u32out(0); size += u32out(0); size += u32out(0x00010000); size += u32out(0); size += u32out(0); size += u32out(0); size += u32out(0x40000000); for (cnt = 0; cnt < 6; cnt++) size += u32out(0); // Next track ID size += u32out(2); return size; }; static int tkhdout(void) { int size = 0; // version size += u8out(0); // flags // bits 8-23 size += u16out(0); // bits 0-7 size += u8out(1 /*track enabled */ ); // Creation time size += u32out(mp4time()); // Modification time size += u32out(mp4time()); // Track ID size += u32out(1); // Reserved size += u32out(0); // Duration size += u32out(mp4config.samples); // Reserved size += u32out(0); size += u32out(0); // Layer size += u16out(0); // Alternate group size += u16out(0); // Volume size += u16out(0x0100); // Reserved size += u16out(0); // matrix size += u32out(0x00010000); size += u32out(0); size += u32out(0); size += u32out(0); size += u32out(0x00010000); size += u32out(0); size += u32out(0); size += u32out(0); size += u32out(0x40000000); // Track width size += u32out(0); // Track height size += u32out(0); return size; }; static int mdhdout(void) { int size = 0; // version/flags size += u32out(0); // Creation time size += u32out(mp4time()); // Modification time size += u32out(mp4time()); // Time scale size += u32out(mp4config.samplerate); // Duration size += u32out(mp4config.samples); // Language size += u16out(0 /*0=English */ ); // pre_defined size += u16out(0); return size; }; static int hdlr1out(void) { int size = 0; // version/flags size += u32out(0); // pre_defined size += u32out(0); // Component subtype size += stringout("soun"); // reserved size += u32out(0); size += u32out(0); size += u32out(0); // name // null terminate size += u8out(0); return size; }; static int smhdout(void) { int size = 0; // version/flags size += u32out(0); // Balance size += u16out(0 /*center */ ); // Reserved size += u16out(0); return size; }; static int drefout(void) { int size = 0; // version/flags size += u32out(0); // Number of entries size += u32out(1 /*url reference */ ); return size; }; static int urlout(void) { int size = 0; size += u32out(1); return size; }; static int stsdout(void) { int size = 0; // version/flags size += u32out(0); // Number of entries(one 'mp4a') size += u32out(1); return size; }; static int mp4aout(void) { int size = 0; // Reserved (6 bytes) size += u32out(0); size += u16out(0); // Data reference index size += u16out(1); // Version size += u16out(0); // Revision level size += u16out(0); // Vendor size += u32out(0); // Number of channels size += u16out(mp4config.channels); // Sample size (bits) size += u16out(mp4config.bits); // Compression ID size += u16out(0); // Packet size size += u16out(0); // Sample rate (16.16) // rate integer part size += u16out(mp4config.samplerate); // rate reminder part size += u16out(0); return size; } static int esdsout(void) { int size = 0; // descriptor definitions: // systems/mp4_file_format/libisomediafile/src/MP4Descriptors.h // systems/mp4_file_format/libisomediafile/src/MP4Descriptors.c // // descriptor tree: // MP4ES_Descriptor // MP4DecoderConfigDescriptor // MP4DecSpecificInfoDescriptor // MP4SLConfigDescriptor struct { int es; int dc; // DecoderConfig int dsi; // DecSpecificInfo int sl; // SLConfig } dsize; enum { TAG_ES = 3, TAG_DC = 4, TAG_DSI = 5, TAG_SLC = 6 }; // calc sizes #define DESCSIZE(x) (x + 5/*.tag+.size*/) dsize.sl = 1; dsize.dsi = mp4config.asc.size; dsize.dc = 13 + DESCSIZE(dsize.dsi); dsize.es = 3 + DESCSIZE(dsize.dc) + DESCSIZE(dsize.sl); // output esds atom data // version/flags ? size += u32out(0); // mp4es size += u8out(TAG_ES); size += u8out(0x80); size += u8out(0x80); size += u8out(0x80); size += u8out(dsize.es); // ESID size += u16out(0); // flags(url(bit 6); ocr(5); streamPriority (0-4)): size += u8out(0); size += u8out(TAG_DC); size += u8out(0x80); size += u8out(0x80); size += u8out(0x80); size += u8out(dsize.dc); size += u8out(0x40 /*MPEG-4 audio */ ); size += u8out((5 << 2) /* AudioStream */ | 1 /* reserved = 1 */); // decode buffer size bytes #if 0 size += u16out(mp4config.buffersize >> 8); size += u8out(mp4config.buffersize && 0xff); #else size += u8out(0); size += u8out(0x18); size += u8out(0); #endif // bitrate size += u32out(mp4config.bitrate.max); size += u32out(mp4config.bitrate.avg); size += u8out(TAG_DSI); size += u8out(0x80); size += u8out(0x80); size += u8out(0x80); size += u8out(dsize.dsi); // AudioSpecificConfig size += dataout(mp4config.asc.data, mp4config.asc.size); size += u8out(TAG_SLC); size += u8out(0x80); size += u8out(0x80); size += u8out(0x80); size += u8out(dsize.sl); // "predefined" (no idea) size += u8out(2); return size; } static int sttsout(void) { int size = 0; // version/flags size += u32out(0); // Number of entries size += u32out(1); // only one entry // Sample count (number of frames) size += u32out(mp4config.frame.ents); // Sample duration (samples per frame) size += u32out(mp4config.framesamples); return size; } static int stszout(void) { int size = 0; int cnt; // version/flags size += u32out(0); // Sample size size += u32out(0 /*i.e. variable size */ ); // Number of entries if (!mp4config.frame.ents) return size; if (!mp4config.frame.data) return size; size += u32out(mp4config.frame.ents); for (cnt = 0; cnt < mp4config.frame.ents; cnt++) size += u32out(mp4config.frame.data[cnt]); return size; } static int stscout(void) { int size = 0; // version/flags size += u32out(0); // Number of entries size += u32out(1); // first chunk size += u32out(1); // frames in chunk size += u32out(mp4config.frame.ents); // sample id size += u32out(1); return size; } static int stcoout(void) { int size = 0; // version/flags size += u32out(0); // Number of entries size += u32out(1); // Chunk offset table size += u32out(mp4config.mdatofs); return size; } static int tagtxt(char *tagname, const char *tagtxt) { int txtsize = strlen(tagtxt); int size = 0; int datasize = txtsize + 16; size += u32out(datasize + 8); size += dataout(tagname, 4); size += u32out(datasize); size += dataout("data", 4); size += u32out(1); // data type text size += u32out(0); size += dataout(tagtxt, txtsize); return size; } static int tagu16(char *tagname, int n /*number of stored fields*/) { int numsize = n * 2; int size = 0; int datasize = numsize + 16; size += u32out(datasize + 8); size += dataout(tagname, 4); size += u32out(datasize); size += dataout("data", 4); size += u32out(0); // data type uint16 size += u32out(0); return size; } static int tagu8(char *tagname, int n /*number of stored fields*/) { int numsize = n * 1; int size = 0; int datasize = numsize + 16; size += u32out(datasize + 8); size += dataout(tagname, 4); size += u32out(datasize); size += dataout("data", 4); size += u32out(0x15); // data type uint8 size += u32out(0); return size; } static int tagimage(char *tagname, int n /*image size*/) { int numsize = n; int size = 0; int datasize = numsize + 16; size += u32out(datasize + 8); size += dataout(tagname, 4); size += u32out(datasize); size += dataout("data", 4); size += u32out(0x0d); // data type: image size += u32out(0); return size; } static int metaout(void) { int size = 0; // version/flags size += u32out(0); return size; } static int hdlr2out(void) { int size = 0; // version/flags size += u32out(0); // Predefined size += u32out(0); // Handler type size += stringout("mdir"); size += stringout("appl"); // Reserved size += u32out(0); size += u32out(0); // null terminator size += u8out(0); return size; }; static int ilstout(void) { int size = 0; int cnt; size += tagtxt("\xa9" "too", mp4config.tag.encoder); if (mp4config.tag.artist) size += tagtxt("\xa9" "ART", mp4config.tag.artist); if (mp4config.tag.artistsort) size += tagtxt("soar", mp4config.tag.artistsort); if (mp4config.tag.composer) size += tagtxt("\xa9" "wrt", mp4config.tag.composer); if (mp4config.tag.composersort) size += tagtxt("soco", mp4config.tag.composersort); if (mp4config.tag.title) size += tagtxt("\xa9" "nam", mp4config.tag.title); if (mp4config.tag.genre) { size += tagu16("gnre", 1); size += u16out(mp4config.tag.genre); } if (mp4config.tag.album) size += tagtxt("\xa9" "alb", mp4config.tag.album); if (mp4config.tag.albumartist) size += tagtxt("aART", mp4config.tag.albumartist); if (mp4config.tag.albumartistsort) size += tagtxt("soaa", mp4config.tag.albumartistsort); if (mp4config.tag.albumsort) size += tagtxt("soal", mp4config.tag.albumsort); if (mp4config.tag.compilation) { size += tagu8("cpil", 1); size += u8out(mp4config.tag.compilation); } if (mp4config.tag.trackno) { size += tagu16("trkn", 4); size += u16out(0); size += u16out(mp4config.tag.trackno); size += u16out(mp4config.tag.ntracks); size += u16out(0); } if (mp4config.tag.discno) { size += tagu16("disk", 4); size += u16out(0); size += u16out(mp4config.tag.discno); size += u16out(mp4config.tag.ndiscs); size += u16out(0); } if (mp4config.tag.year) size += tagtxt("\xa9" "day", mp4config.tag.year); if (mp4config.tag.cover.data) { size += tagimage("covr", mp4config.tag.cover.size); size += dataout(mp4config.tag.cover.data, mp4config.tag.cover.size); } if (mp4config.tag.comment) size += tagtxt("\xa9" "cmt", mp4config.tag.comment); // ----(mean(com.apple.iTunes),name(name),data(data)) for (cnt = 0; cnt < mp4config.tag.extnum; cnt++) { static const char *mean = "faac";//"com.apple.iTunes"; const char *name = mp4config.tag.ext[cnt].name; const char *data = mp4config.tag.ext[cnt].data; uint32_t len1 = 8 + strlen(mean) + 4; uint32_t len2 = 8 + strlen(name) + 4; uint32_t len3 = 8 + strlen(data) + 4 + 4; u32out(8 + len1 + len2 + len3); size += 8 + len1 + len2 + len3; stringout("----"); u32out(len1); stringout("mean"); u32out(0); stringout(mean); u32out(len2); stringout("name"); u32out(0); stringout(name); u32out(len3); stringout("data"); u32out(1); u32out(0); stringout(data); } return size; }; static creator_t g_head[] = { {ATOM_NAME, "ftyp"}, {ATOM_DATA, ftypout}, {ATOM_NAME, "free"}, {ATOM_NAME, "mdat"}, {0} }; static creator_t g_tail[] = { {ATOM_NAME, "moov"}, {ATOM_DESCENT}, {ATOM_NAME, "mvhd"}, {ATOM_DATA, mvhdout}, {ATOM_NAME, "trak"}, {ATOM_DESCENT}, {ATOM_NAME, "tkhd"}, {ATOM_DATA, tkhdout}, {ATOM_NAME, "mdia"}, {ATOM_DESCENT}, {ATOM_NAME, "mdhd"}, {ATOM_DATA, mdhdout}, {ATOM_NAME, "hdlr"}, {ATOM_DATA, hdlr1out}, {ATOM_NAME, "minf"}, {ATOM_DESCENT}, {ATOM_NAME, "smhd"}, {ATOM_DATA, smhdout}, {ATOM_NAME, "dinf"}, {ATOM_DESCENT}, {ATOM_NAME, "dref"}, {ATOM_DATA, drefout}, {ATOM_DESCENT}, {ATOM_NAME, "url "}, {ATOM_DATA, urlout}, {ATOM_ASCENT}, {ATOM_ASCENT}, {ATOM_NAME, "stbl"}, {ATOM_DESCENT}, {ATOM_NAME, "stsd"}, {ATOM_DATA, stsdout}, {ATOM_DESCENT}, {ATOM_NAME, "mp4a"}, {ATOM_DATA, mp4aout}, {ATOM_DESCENT}, {ATOM_NAME, "esds"}, {ATOM_DATA, esdsout}, {ATOM_ASCENT}, {ATOM_ASCENT}, {ATOM_NAME, "stts"}, {ATOM_DATA, sttsout}, {ATOM_NAME, "stsc"}, {ATOM_DATA, stscout}, {ATOM_NAME, "stsz"}, {ATOM_DATA, stszout}, {ATOM_NAME, "stco"}, {ATOM_DATA, stcoout}, {ATOM_ASCENT}, {ATOM_ASCENT}, {ATOM_ASCENT}, {ATOM_ASCENT}, {ATOM_NAME, "udta"}, {ATOM_DESCENT}, {ATOM_NAME, "meta"}, {ATOM_DATA, metaout}, {ATOM_DESCENT}, {ATOM_NAME, "hdlr"}, {ATOM_DATA, hdlr2out}, {ATOM_NAME, "ilst"}, {ATOM_DATA, ilstout}, {0} }; static creator_t *g_atom = 0; static int create(void) { long apos = ftell(g_fout);; int size; size = u32out(8); size += dataout(g_atom->data, 4); g_atom++; if (g_atom->opcode == ATOM_DATA) { size += ((int (*)(void)) g_atom->data) (); g_atom++; } if (g_atom->opcode == ATOM_DESCENT) { g_atom++; while (g_atom->opcode != ATOM_STOP) { if (g_atom->opcode == ATOM_ASCENT) { g_atom++; break; } size += create(); } } fseek(g_fout, apos, SEEK_SET); u32out(size); fseek(g_fout, apos + size, SEEK_SET); return size; } enum {BUFSTEP = 0x4000}; int mp4atom_frame(uint8_t * buf, int size, int samples) { if (mp4config.framesamples <= samples) { int bitrate; mp4config.bitrate.samples += samples; mp4config.bitrate.size += size; if (mp4config.bitrate.samples >= mp4config.samplerate) { bitrate = 8.0 * mp4config.bitrate.size * mp4config.samplerate / mp4config.bitrate.samples; mp4config.bitrate.size = 0; mp4config.bitrate.samples = 0; if (mp4config.bitrate.max < bitrate) mp4config.bitrate.max = bitrate; } mp4config.framesamples = samples; } if (mp4config.buffersize < size) mp4config.buffersize = size; mp4config.samples += samples; mp4config.mdatsize += dataout(buf, size); if (((mp4config.frame.ents + 1) * sizeof(*(mp4config.frame.data))) > mp4config.frame.bufsize) { mp4config.frame.bufsize += BUFSTEP; mp4config.frame.data = realloc(mp4config.frame.data, mp4config.frame.bufsize); } mp4config.frame.data[mp4config.frame.ents++] = size; return 0; } int mp4atom_close(void) { if (g_fout) { fseek(g_fout, mp4config.mdatofs - 8, SEEK_SET); u32out(mp4config.mdatsize + 8); fclose(g_fout); g_fout = 0; } if (mp4config.frame.data) { free(mp4config.frame.data); mp4config.frame.data = 0; } return 0; } int mp4atom_open(char *name, int over) { mp4atom_close(); if (!access(name, W_OK) && !over) { fprintf(stderr, "output file exists, use --overwrite option\n"); return 1; } if (!(g_fout = fopen(name, "wb"))) { perror(name); return 1; } mp4config.mdatsize = 0; mp4config.frame.bufsize = BUFSTEP; mp4config.frame.data = malloc(mp4config.frame.bufsize); return 0; } int mp4atom_head(void) { g_atom = g_head; while (g_atom->opcode != ATOM_STOP) create(); mp4config.mdatofs = ftell(g_fout); return 0; } int mp4atom_tail(void) { mp4config.bitrate.avg = 8.0 * mp4config.mdatsize * mp4config.samplerate / mp4config.samples; if (!mp4config.bitrate.max) mp4config.bitrate.max = mp4config.bitrate.avg; g_atom = g_tail; while (g_atom->opcode != ATOM_STOP) create(); return 0; } int mp4tag_add(const char *name, const char *data) { int idx = mp4config.tag.extnum; if (idx >= TAGMAX) { fprintf(stderr, "To many tags\n"); return -1; } mp4config.tag.ext[idx].name = name; mp4config.tag.ext[idx].data = data; mp4config.tag.extnum++; return 0; } knik0-faac-79329ef/frontend/mp4write.h000066400000000000000000000050071517010422400175310ustar00rootroot00000000000000/**************************************************************************** MP4 output module Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #include enum {TAGMAX = 100}; typedef struct { uint32_t samplerate; // total sound samples uint32_t samples; uint32_t channels; // sample depth uint32_t bits; // buffer config uint16_t buffersize; struct { uint32_t max; uint32_t avg; int size; int samples; } bitrate; uint32_t framesamples; struct { uint16_t *data; uint32_t ents; uint32_t bufsize; } frame; // AudioSpecificConfig data: struct { uint8_t *data; unsigned long size; } asc; uint32_t mdatofs; uint32_t mdatsize; struct { // meta fields const char *encoder; const char *artist; const char *artistsort; const char *composer; const char *composersort; const char *title; const char *album; const char *albumartist; const char *albumartistsort; const char *albumsort; uint8_t compilation; uint32_t trackno; uint32_t ntracks; uint32_t discno; uint32_t ndiscs; int genre; const char *year; struct { uint8_t *data; int size; } cover; const char *comment; struct { const char *name; const char *data; } ext[TAGMAX]; int extnum; } tag; } mp4config_t; extern mp4config_t mp4config; int mp4atom_open(char *name, int over); int mp4atom_head(void); int mp4atom_tail(void); int mp4atom_frame(uint8_t * bitbuf, int bytesWritten, int frame_samples); int mp4atom_close(void); int mp4tag_add(const char *name, const char *data); knik0-faac-79329ef/frontend/resource.h000066400000000000000000000023701517010422400176050ustar00rootroot00000000000000//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by faacgui.rc // #define ID_ICON1 200 #define IDD_MAINDIALOG 102 #define IDC_INPUTFILENAME 1000 #define IDC_SELECT_INPUTFILE 1001 #define IDC_OUTPUTFILENAME 1002 #define IDC_SELECT_OUTPUTFILE 1003 #define IDC_INPUTPARAMS 1004 #define IDC_PROGRESS 1006 #define IDC_ALLOWMIDSIDE 1007 #define IDC_TIME 1008 #define IDC_BANDWIDTH 1009 #define IDC_QUALITY 1010 #define IDC_USERAW 1011 #define IDC_USETNS 1012 #define IDC_USELFE2 1013 #define IDC_USELFE 1013 #define IDC_BWCTL 1014 #define IDC_COMPILEDATE 1018 #define IDC_MPEGVERSION 1020 #define IDC_OBJECTTYPE 1021 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1022 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif knik0-faac-79329ef/include/000077500000000000000000000000001517010422400154075ustar00rootroot00000000000000knik0-faac-79329ef/include/faac.h000066400000000000000000000046661517010422400164660ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: faac.h,v 1.38 2012/03/01 18:34:17 knik Exp $ */ #ifndef _FAAC_H_ #define _FAAC_H_ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if !defined(FAACAPI) && defined(__GNUC__) && (__GNUC__ >= 4) # if defined(_WIN32) # define FAACAPI __stdcall __declspec(dllexport) # else # define FAACAPI __attribute__((visibility("default"))) # endif #endif #ifndef FAACAPI # define FAACAPI #endif #pragma pack(push, 1) typedef struct { void *ptr; char *name; } psymodellist_t; #include #include "faaccfg.h" typedef void *faacEncHandle; /* Allows an application to get FAAC version info. This is intended purely for informative purposes. Returns FAAC_CFG_VERSION. */ int FAACAPI faacEncGetVersion(char **faac_id_string, char **faac_copyright_string); faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder); int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder, faacEncConfigurationPtr config); faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate, unsigned int numChannels, unsigned long *inputSamples, unsigned long *maxOutputBytes ); int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder, unsigned char **ppBuffer, unsigned long *pSizeOfDecoderSpecificInfo); int FAACAPI faacEncEncode(faacEncHandle hEncoder, int32_t * inputBuffer, unsigned int samplesInput, unsigned char *outputBuffer, unsigned int bufferSize); int FAACAPI faacEncClose(faacEncHandle hEncoder); #pragma pack(pop) #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _FAAC_H_ */ knik0-faac-79329ef/include/faaccfg.h000066400000000000000000000063151517010422400171370ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: faaccfg.h,v 1.3 2004/07/04 12:12:05 corrados Exp $ */ #ifndef _FAACCFG_H_ #define _FAACCFG_H_ #define FAAC_CFG_VERSION 105 /* MPEG ID's */ #define MPEG2 1 #define MPEG4 0 /* AAC object types */ #define MAIN 1 #define LOW 2 #define SSR 3 #define LTP 4 /* Input Formats */ #define FAAC_INPUT_NULL 0 #define FAAC_INPUT_16BIT 1 #define FAAC_INPUT_24BIT 2 #define FAAC_INPUT_32BIT 3 #define FAAC_INPUT_FLOAT 4 #define SHORTCTL_NORMAL 0 #define SHORTCTL_NOSHORT 1 #define SHORTCTL_NOLONG 2 enum stream_format { RAW_STREAM = 0, ADTS_STREAM = 1, }; enum {JOINT_NONE = 0, JOINT_MS, JOINT_IS}; #pragma pack(push, 1) typedef struct faacEncConfiguration { /* config version */ int version; /* library version */ char *name; /* copyright string */ char *copyright; /* MPEG version, 2 or 4 */ unsigned int mpegVersion; /* AAC object type */ unsigned int aacObjectType; union { /* Joint coding mode */ unsigned int jointmode; /* compatibility alias */ unsigned int allowMidside; }; /* Use one of the channels as LFE channel */ unsigned int useLfe; /* Use Temporal Noise Shaping */ unsigned int useTns; /* bitrate / channel of AAC file */ unsigned long bitRate; /* AAC file frequency bandwidth */ unsigned int bandWidth; /* Quantizer quality */ unsigned long quantqual; /* Bitstream output format (0 = Raw; 1 = ADTS) */ unsigned int outputFormat; /* psychoacoustic model list */ psymodellist_t *psymodellist; /* selected index in psymodellist */ unsigned int psymodelidx; /* PCM Sample Input Format 0 FAAC_INPUT_NULL invalid, signifies a misconfigured config 1 FAAC_INPUT_16BIT native endian 16bit 2 FAAC_INPUT_24BIT native endian 24bit in 24 bits (not implemented) 3 FAAC_INPUT_32BIT native endian 24bit in 32 bits (DEFAULT) 4 FAAC_INPUT_FLOAT 32bit floating point */ unsigned int inputFormat; /* block type enforcing (SHORTCTL_NORMAL/SHORTCTL_NOSHORT/SHORTCTL_NOLONG) */ int shortctl; /* Channel Remapping Default 0, 1, 2, 3 ... 63 (64 is MAX_CHANNELS in coder.h) WAVE 4.0 2, 0, 1, 3 WAVE 5.0 2, 0, 1, 3, 4 WAVE 5.1 2, 0, 1, 4, 5, 3 AIFF 5.1 2, 0, 3, 1, 4, 5 */ int channel_map[64]; int pnslevel; } faacEncConfiguration, *faacEncConfigurationPtr; #pragma pack(pop) #endif /* _FAACCFG_H_ */ knik0-faac-79329ef/include/meson.build000066400000000000000000000000511517010422400175450ustar00rootroot00000000000000install_headers(['faac.h', 'faaccfg.h']) knik0-faac-79329ef/libfaac/000077500000000000000000000000001517010422400153455ustar00rootroot00000000000000knik0-faac-79329ef/libfaac/bitstream.c000066400000000000000000000661421517010422400175140ustar00rootroot00000000000000/********************************************************************** This software module was originally developed by and edited by Texas Instruments in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-2 NBC/MPEG-4 Audio conforming products. The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1997. **********************************************************************/ #include #include #include #include "coder.h" #include "channels.h" #include "huff2.h" #include "bitstream.h" #include "util.h" static int CountBitstream(faacEncStruct* hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannels); static int WriteADTSHeader(faacEncStruct* hEncoder, BitStream *bitStream, int writeFlag); static int WriteCPE(CoderInfo *coderInfoL, CoderInfo *coderInfoR, ChannelInfo *channelInfo, BitStream* bitStream, int objectType, int writeFlag); static int WriteSCE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag); static int WriteLFE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag); static int WriteICSInfo(CoderInfo *coderInfo, BitStream *bitStream, int objectType, int common_window, int writeFlag); static int WriteICS(CoderInfo *coderInfo, BitStream *bitStream, int commonWindow, int objectType, int writeFlag); static int WritePulseData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteTNSData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteGainControlData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteSpectralData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag); static int WriteAACFillBits(BitStream* bitStream, int numBits, int writeFlag); static int FindGroupingBits(CoderInfo *coderInfo); static long BufferNumBit(BitStream *bitStream); static int ByteAlign(BitStream* bitStream, int writeFlag, int bitsSoFar); static int WriteFAACStr(BitStream *bitStream, char *version, int write) { int i; char str[200]; int len, padbits, count; int bitcnt; sprintf(str, "libfaac %s", version); len = strlen(str) + 1; padbits = (8 - ((bitStream->numBit + 7) % 8)) % 8; count = len + 3; bitcnt = LEN_SE_ID + 4 + ((count < 15) ? 0 : 8) + count * 8; if (!write) return bitcnt; PutBit(bitStream, ID_FIL, LEN_SE_ID); if (count < 15) { PutBit(bitStream, count, 4); } else { PutBit(bitStream, 15, 4); PutBit(bitStream, count - 14, 8); } PutBit(bitStream, 0, padbits); PutBit(bitStream, 0, 8); PutBit(bitStream, 0, 8); // just in case for (i = 0; i < len; i++) PutBit(bitStream, str[i], 8); PutBit(bitStream, 0, 8 - padbits); return bitcnt; } int WriteBitstream(faacEncStruct* hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannel) { int channel; int bits = 0; int bitsLeftAfterFill, numFillBits; if (CountBitstream(hEncoder, coderInfo, channelInfo, bitStream, numChannel) < 0) return -1; if(hEncoder->config.outputFormat == 1){ bits += WriteADTSHeader(hEncoder, bitStream, 1); }else{ bits = 0; // compilier will remove it, byt anyone will see that current size of bitstream is 0 } /* sur: faad2 complains about scalefactor error if we are writing FAAC String */ if (hEncoder->frameNum == 4) WriteFAACStr(bitStream, hEncoder->config.name, 1); for (channel = 0; channel < numChannel; channel++) { if (channelInfo[channel].present) { /* Write out a single_channel_element */ if (channelInfo[channel].type != ELEMENT_CPE) { if (channelInfo[channel].type == ELEMENT_LFE) { /* Write out lfe */ bits += WriteLFE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } else { /* Write out sce */ bits += WriteSCE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } } else { if (channelInfo[channel].ch_is_left) { /* Write out cpe */ bits += WriteCPE(&coderInfo[channel], &coderInfo[channelInfo[channel].paired_ch], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 1); } } } } /* Compute how many fill bits are needed to avoid overflowing bit reservoir */ /* Save room for ID_END terminator */ if (bits < (8 - LEN_SE_ID) ) { numFillBits = 8 - LEN_SE_ID - bits; } else { numFillBits = 0; } /* Write AAC fill_elements, smallest fill element is 7 bits. */ /* Function may leave up to 6 bits left after fill, so tell it to fill a few extra */ numFillBits += 6; bitsLeftAfterFill = WriteAACFillBits(bitStream, numFillBits, 1); bits += (numFillBits - bitsLeftAfterFill); /* Write ID_END terminator */ bits += LEN_SE_ID; PutBit(bitStream, ID_END, LEN_SE_ID); /* Now byte align the bitstream */ /* * This byte_alignment() is correct for both MPEG2 and MPEG4, although * in MPEG4 the byte_alignment() is officially done before the new frame * instead of at the end. But this is basically the same. */ bits += ByteAlign(bitStream, 1, bits); return bits; } static int CountBitstream(faacEncStruct* hEncoder, CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int numChannel) { int channel; int bits = 0; int bitsLeftAfterFill, numFillBits; if(hEncoder->config.outputFormat == 1){ bits += WriteADTSHeader(hEncoder, bitStream, 0); }else{ bits = 0; // compilier will remove it, byt anyone will see that current size of bitstream is 0 } /* sur: faad2 complains about scalefactor error if we are writing FAAC String */ if (hEncoder->frameNum == 4) bits += WriteFAACStr(bitStream, hEncoder->config.name, 0); for (channel = 0; channel < numChannel; channel++) { if (channelInfo[channel].present) { /* Write out a single_channel_element */ if (channelInfo[channel].type != ELEMENT_CPE) { if (channelInfo[channel].type == ELEMENT_LFE) { /* Write out lfe */ bits += WriteLFE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 0); } else { /* Write out sce */ bits += WriteSCE(&coderInfo[channel], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 0); } } else { if (channelInfo[channel].ch_is_left) { /* Write out cpe */ bits += WriteCPE(&coderInfo[channel], &coderInfo[channelInfo[channel].paired_ch], &channelInfo[channel], bitStream, hEncoder->config.aacObjectType, 0); } } } } /* Compute how many fill bits are needed to avoid overflowing bit reservoir */ /* Save room for ID_END terminator */ if (bits < (8 - LEN_SE_ID) ) { numFillBits = 8 - LEN_SE_ID - bits; } else { numFillBits = 0; } /* Write AAC fill_elements, smallest fill element is 7 bits. */ /* Function may leave up to 6 bits left after fill, so tell it to fill a few extra */ numFillBits += 6; bitsLeftAfterFill = WriteAACFillBits(bitStream, numFillBits, 0); bits += (numFillBits - bitsLeftAfterFill); /* Write ID_END terminator */ bits += LEN_SE_ID; /* Now byte align the bitstream */ bits += ByteAlign(bitStream, 0, bits); hEncoder->usedBytes = bit2byte(bits); if (hEncoder->usedBytes > bitStream->size) { fprintf(stderr, "frame buffer overrun\n"); return -1; } if (hEncoder->usedBytes >= ADTS_FRAMESIZE) { fprintf(stderr, "frame size limit exceeded\n"); return -1; } return bits; } static int WriteADTSHeader(faacEncStruct* hEncoder, BitStream *bitStream, int writeFlag) { int bits = 56; if (writeFlag) { /* Fixed ADTS header */ PutBit(bitStream, 0xFFFF, 12); /* 12 bit Syncword */ PutBit(bitStream, hEncoder->config.mpegVersion, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */ PutBit(bitStream, 0, 2); /* layer == 0 */ PutBit(bitStream, 1, 1); /* protection absent */ PutBit(bitStream, hEncoder->config.aacObjectType - 1, 2); /* profile */ PutBit(bitStream, hEncoder->sampleRateIdx, 4); /* sampling rate */ PutBit(bitStream, 0, 1); /* private bit */ PutBit(bitStream, hEncoder->numChannels, 3); /* ch. config (must be > 0) */ /* simply using numChannels only works for 6 channels or less, else a channel configuration should be written */ PutBit(bitStream, 0, 1); /* original/copy */ PutBit(bitStream, 0, 1); /* home */ #if 0 // Removed in corrigendum 14496-3:2002 if (hEncoder->config.mpegVersion == 0) PutBit(bitStream, 0, 2); /* emphasis */ #endif /* Variable ADTS header */ PutBit(bitStream, 0, 1); /* copyr. id. bit */ PutBit(bitStream, 0, 1); /* copyr. id. start */ PutBit(bitStream, hEncoder->usedBytes, 13); PutBit(bitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */ PutBit(bitStream, 0, 2); /* raw data blocks (0+1=1) */ } /* * MPEG2 says byte_aligment() here, but ADTS always is multiple of 8 bits * MPEG4 has no byte_alignment() here */ /* if (hEncoder->config.mpegVersion == 1) bits += ByteAlign(bitStream, writeFlag); */ #if 0 // Removed in corrigendum 14496-3:2002 if (hEncoder->config.mpegVersion == 0) bits += 2; /* emphasis */ #endif return bits; } static int WriteCPE(CoderInfo *coderInfoL, CoderInfo *coderInfoR, ChannelInfo *channelInfo, BitStream* bitStream, int objectType, int writeFlag) { int bits = 0; if (writeFlag) { /* write ID_CPE, single_element_channel() identifier */ PutBit(bitStream, ID_CPE, LEN_SE_ID); /* write the element_identifier_tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); /* common_window? */ PutBit(bitStream, channelInfo->common_window, LEN_COM_WIN); } bits += LEN_SE_ID; bits += LEN_TAG; bits += LEN_COM_WIN; /* if common_window, write ics_info */ if (channelInfo->common_window) { int numWindows, maxSfb; bits += WriteICSInfo(coderInfoL, bitStream, objectType, channelInfo->common_window, writeFlag); numWindows = coderInfoL->groups.n; maxSfb = coderInfoL->sfbn; if (writeFlag) { PutBit(bitStream, channelInfo->msInfo.is_present, LEN_MASK_PRES); if (channelInfo->msInfo.is_present == 1) { int g; int b; for (g=0;gmsInfo.ms_used[g*maxSfb+b], LEN_MASK); } } } } bits += LEN_MASK_PRES; if (channelInfo->msInfo.is_present == 1) bits += (numWindows*maxSfb*LEN_MASK); } /* Write individual_channel_stream elements */ bits += WriteICS(coderInfoL, bitStream, channelInfo->common_window, objectType, writeFlag); bits += WriteICS(coderInfoR, bitStream, channelInfo->common_window, objectType, writeFlag); return bits; } static int WriteSCE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag) { int bits = 0; if (writeFlag) { /* write Single Element Channel (SCE) identifier */ PutBit(bitStream, ID_SCE, LEN_SE_ID); /* write the element identifier tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); } bits += LEN_SE_ID; bits += LEN_TAG; /* Write an Individual Channel Stream element */ bits += WriteICS(coderInfo, bitStream, 0, objectType, writeFlag); return bits; } static int WriteLFE(CoderInfo *coderInfo, ChannelInfo *channelInfo, BitStream *bitStream, int objectType, int writeFlag) { int bits = 0; if (writeFlag) { /* write ID_LFE, lfe_element_channel() identifier */ PutBit(bitStream, ID_LFE, LEN_SE_ID); /* write the element_identifier_tag */ PutBit(bitStream, channelInfo->tag, LEN_TAG); } bits += LEN_SE_ID; bits += LEN_TAG; /* Write an individual_channel_stream element */ bits += WriteICS(coderInfo, bitStream, 0, objectType, writeFlag); return bits; } static int WriteICSInfo(CoderInfo *coderInfo, BitStream *bitStream, int objectType, int common_window, int writeFlag) { int grouping_bits; int bits = 0; if (writeFlag) { /* write out ics_info() information */ PutBit(bitStream, 0, LEN_ICS_RESERV); /* reserved Bit*/ /* Write out window sequence */ PutBit(bitStream, coderInfo->block_type, LEN_WIN_SEQ); /* block type */ /* Write out window shape */ PutBit(bitStream, coderInfo->window_shape, LEN_WIN_SH); /* window shape */ } bits += LEN_ICS_RESERV; bits += LEN_WIN_SEQ; bits += LEN_WIN_SH; /* For short windows, write out max_sfb and scale_factor_grouping */ if (coderInfo->block_type == ONLY_SHORT_WINDOW){ if (writeFlag) { PutBit(bitStream, coderInfo->sfbn, LEN_MAX_SFBS); grouping_bits = FindGroupingBits(coderInfo); PutBit(bitStream, grouping_bits, MAX_SHORT_WINDOWS - 1); /* the grouping bits */ } bits += LEN_MAX_SFBS; bits += MAX_SHORT_WINDOWS - 1; } else { /* Otherwise, write out max_sfb and predictor data */ if (writeFlag) { PutBit(bitStream, coderInfo->sfbn, LEN_MAX_SFBL); } bits += LEN_MAX_SFBL; bits++; if (writeFlag) PutBit(bitStream, 0, LEN_PRED_PRES); /* predictor_data_present */ } return bits; } static int WriteICS(CoderInfo *coderInfo, BitStream *bitStream, int commonWindow, int objectType, int writeFlag) { /* this function writes out an individual_channel_stream to the bitstream and */ /* returns the number of bits written to the bitstream */ int bits = 0; /* Write the 8-bit global_gain */ if (writeFlag) PutBit(bitStream, coderInfo->global_gain, LEN_GLOB_GAIN); bits += LEN_GLOB_GAIN; /* Write ics information */ if (!commonWindow) { bits += WriteICSInfo(coderInfo, bitStream, objectType, commonWindow, writeFlag); } bits += writebooks(coderInfo, bitStream, writeFlag); bits += writesf(coderInfo, bitStream, writeFlag); bits += WritePulseData(coderInfo, bitStream, writeFlag); bits += WriteTNSData(coderInfo, bitStream, writeFlag); bits += WriteGainControlData(coderInfo, bitStream, writeFlag); bits += WriteSpectralData(coderInfo, bitStream, writeFlag); /* Return number of bits */ return bits; } static int WritePulseData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag) { int bits = 0; if (writeFlag) { PutBit(bitStream, 0, LEN_PULSE_PRES); /* no pulse_data_present */ } bits += LEN_PULSE_PRES; return bits; } static int WriteTNSData(CoderInfo *coderInfo, BitStream *bitStream, int writeFlag) { int bits = 0; int numWindows; int len_tns_nfilt; int len_tns_length; int len_tns_order; int filtNumber; int resInBits; int bitsToTransmit; unsigned long unsignedIndex; int w; TnsInfo* tnsInfoPtr = &coderInfo->tnsInfo; if (writeFlag) { PutBit(bitStream,tnsInfoPtr->tnsDataPresent,LEN_TNS_PRES); } bits += LEN_TNS_PRES; /* If TNS is not present, bail */ if (!tnsInfoPtr->tnsDataPresent) { return bits; } /* Set window-dependent TNS parameters */ if (coderInfo->block_type == ONLY_SHORT_WINDOW) { numWindows = MAX_SHORT_WINDOWS; len_tns_nfilt = LEN_TNS_NFILTS; len_tns_length = LEN_TNS_LENGTHS; len_tns_order = LEN_TNS_ORDERS; } else { numWindows = 1; len_tns_nfilt = LEN_TNS_NFILTL; len_tns_length = LEN_TNS_LENGTHL; len_tns_order = LEN_TNS_ORDERL; } /* Write TNS data */ bits += (numWindows * len_tns_nfilt); for (w=0;wwindowData[w]; int numFilters = windowDataPtr->numFilters; if (writeFlag) { PutBit(bitStream,numFilters,len_tns_nfilt); /* n_filt[] = 0 */ } if (numFilters) { bits += LEN_TNS_COEFF_RES; resInBits = windowDataPtr->coefResolution; if (writeFlag) { PutBit(bitStream,resInBits-DEF_TNS_RES_OFFSET,LEN_TNS_COEFF_RES); } bits += numFilters * (len_tns_length+len_tns_order); for (filtNumber=0;filtNumbertnsFilter[filtNumber]; int order = tnsFilterPtr->order; if (writeFlag) { PutBit(bitStream,tnsFilterPtr->length,len_tns_length); PutBit(bitStream,order,len_tns_order); } if (order) { bits += (LEN_TNS_DIRECTION + LEN_TNS_COMPRESS); if (writeFlag) { PutBit(bitStream,tnsFilterPtr->direction,LEN_TNS_DIRECTION); PutBit(bitStream,tnsFilterPtr->coefCompress,LEN_TNS_COMPRESS); } bitsToTransmit = resInBits - tnsFilterPtr->coefCompress; bits += order * bitsToTransmit; if (writeFlag) { int i; for (i=1;i<=order;i++) { unsignedIndex = (unsigned long) (tnsFilterPtr->index[i])&(~(~0<datacnt; i++) { int data = coderInfo->s[i].data; int len = coderInfo->s[i].len; if (len > 0) { PutBit(bitStream, data, len); bits += len; } } } else { for(i = 0; i < coderInfo->datacnt; i++) { bits += coderInfo->s[i].len; } } return bits; } static int WriteAACFillBits(BitStream* bitStream, int numBits, int writeFlag) { int numberOfBitsLeft = numBits; /* Need at least (LEN_SE_ID + LEN_F_CNT) bits for a fill_element */ int minNumberOfBits = LEN_SE_ID + LEN_F_CNT; while (numberOfBitsLeft >= minNumberOfBits) { int numberOfBytes; int maxCount; if (writeFlag) { PutBit(bitStream, ID_FIL, LEN_SE_ID); /* Write fill_element ID */ } numberOfBitsLeft -= minNumberOfBits; /* Subtract for ID,count */ numberOfBytes = (int)(numberOfBitsLeft/LEN_BYTE); maxCount = (1< maxNumberOfBytes ) ? (maxNumberOfBytes) : (numberOfBytes); escCount = numberOfBytes - maxCount; if (writeFlag) { PutBit(bitStream, escCount, LEN_BYTE); for (i = 0; i < numberOfBytes-1; i++) { PutBit(bitStream, 0, LEN_BYTE); } } } numberOfBitsLeft -= LEN_BYTE*numberOfBytes; } return numberOfBitsLeft; } static int FindGroupingBits(CoderInfo *coderInfo) { /* This function inputs the grouping information and outputs the seven bit 'grouping_bits' field that the AAC decoder expects. */ int grouping_bits = 0; int tmp[8]; int i, j; int index = 0; for(i = 0; i < coderInfo->groups.n; i++){ for (j = 0; j < coderInfo->groups.len[i]; j++){ tmp[index++] = i; } } for(i = 1; i < 8; i++){ grouping_bits = grouping_bits << 1; if(tmp[i] == tmp[i-1]) { grouping_bits++; } } return grouping_bits; } /* size in bytes! */ BitStream *OpenBitStream(int size, unsigned char *buffer) { BitStream *bitStream; bitStream = AllocMemory(sizeof(BitStream)); bitStream->size = size; bitStream->numBit = 0; bitStream->currentBit = 0; bitStream->data = buffer; SetMemory(bitStream->data, 0, size); return bitStream; } int CloseBitStream(BitStream *bitStream) { int bytes = bit2byte(bitStream->numBit); FreeMemory(bitStream); return bytes; } static long BufferNumBit(BitStream *bitStream) { return bitStream->numBit; } int PutBit(BitStream *bitStream, unsigned long data, int numBit) { /* write bits in packets according to buffer byte boundaries */ if (numBit == 0) return 0; /* Hoist bitstream state for faster access */ unsigned int currentBit = (unsigned int)bitStream->currentBit; unsigned int bitOffset = currentBit & 7; unsigned char *ptr = bitStream->data + (currentBit >> 3); /* Update bitstream state immediately */ bitStream->currentBit += numBit; bitStream->numBit = bitStream->currentBit; /* Mask input data to ensure no extra bits are set */ data &= (1UL << numBit) - 1; /* Fast path: bit write fits within the current byte */ if (bitOffset + numBit <= 8) { if (bitOffset == 0) *ptr = 0; *ptr |= (unsigned char)(data << (8 - bitOffset - numBit)); } else { /* General case: multi-byte write */ /* Handle first partial byte */ int firstBits = 8 - bitOffset; if (bitOffset == 0) *ptr = 0; *ptr++ |= (unsigned char)(data >> (numBit - firstBits)); numBit -= firstBits; /* Handle full bytes */ while (numBit >= 8) { *ptr++ = (unsigned char)((data >> (numBit - 8)) & 0xFF); numBit -= 8; } /* Handle remaining bits in last byte */ if (numBit > 0) { *ptr = (unsigned char)((data & ((1UL << numBit) - 1)) << (8 - numBit)); } } return 0; } static int ByteAlign(BitStream *bitStream, int writeFlag, int bitsSoFar) { int len, i,j; if (writeFlag) { len = BufferNumBit(bitStream); } else { len = bitsSoFar; } j = (8 - (len%8))%8; if ((len % 8) == 0) j = 0; if (writeFlag) { for( i=0; i #include #include #include #include "blockswitch.h" #include "coder.h" #include "fft.h" #include "util.h" #include "filtbank.h" #include typedef float psyfloat; typedef struct { /* bandwidth */ int bandS; int lastband; /* band volumes */ psyfloat *engPrev[8]; psyfloat *eng[8]; psyfloat *engNext[8]; psyfloat *engNext2[8]; } psydata_t; static void Hann(GlobalPsyInfo * gpsyInfo, faac_real *inSamples, int size) { int i; /* Applying Hann window */ if (size == BLOCK_LEN_LONG * 2) { for (i = 0; i < size; i++) inSamples[i] *= gpsyInfo->hannWindow[i]; } else { for (i = 0; i < size; i++) inSamples[i] *= gpsyInfo->hannWindowS[i]; } } #define PRINTSTAT 0 #if PRINTSTAT static struct { int tot; int s; } frames; #endif static void PsyCheckShort(PsyInfo * psyInfo, faac_real quality) { enum {PREVS = 2, NEXTS = 2}; psydata_t *psydata = psyInfo->data; int lastband = psydata->lastband; int firstband = 2; int sfb, win; psyfloat *lasteng; psyInfo->block_type = ONLY_LONG_WINDOW; lasteng = NULL; for (win = 0; win < PREVS + 8 + NEXTS; win++) { psyfloat *eng; if (win < PREVS) eng = psydata->engPrev[win + 8 - PREVS]; else if (win < (PREVS + 8)) eng = psydata->eng[win - PREVS]; else eng = psydata->engNext[win - PREVS - 8]; if (lasteng) { faac_real toteng = 0.0; faac_real volchg = 0.0; for (sfb = firstband; sfb < lastband; sfb++) { toteng += (eng[sfb] < lasteng[sfb]) ? eng[sfb] : lasteng[sfb]; volchg += FAAC_FABS(eng[sfb] - lasteng[sfb]); } if ((volchg / toteng * quality) > 3.0) { psyInfo->block_type = ONLY_SHORT_WINDOW; break; } } lasteng = eng; } #if PRINTSTAT frames.tot++; if (psyInfo->block_type == ONLY_SHORT_WINDOW) frames.s++; #endif } static void PsyInit(GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, unsigned int numChannels, unsigned int sampleRate, int *cb_width_long, int num_cb_long, int *cb_width_short, int num_cb_short) { unsigned int channel; int i, j, size; gpsyInfo->hannWindow = (faac_real *) AllocMemory(2 * BLOCK_LEN_LONG * sizeof(faac_real)); gpsyInfo->hannWindowS = (faac_real *) AllocMemory(2 * BLOCK_LEN_SHORT * sizeof(faac_real)); for (i = 0; i < BLOCK_LEN_LONG * 2; i++) gpsyInfo->hannWindow[i] = 0.5 * (1 - FAAC_COS(2.0 * M_PI * (i + 0.5) / (BLOCK_LEN_LONG * 2))); for (i = 0; i < BLOCK_LEN_SHORT * 2; i++) gpsyInfo->hannWindowS[i] = 0.5 * (1 - FAAC_COS(2.0 * M_PI * (i + 0.5) / (BLOCK_LEN_SHORT * 2))); gpsyInfo->sampleRate = (faac_real) sampleRate; for (channel = 0; channel < numChannels; channel++) { psydata_t *psydata = AllocMemory(sizeof(psydata_t)); psyInfo[channel].data = psydata; } size = BLOCK_LEN_LONG; for (channel = 0; channel < numChannels; channel++) { psyInfo[channel].size = size; psyInfo[channel].prevSamples = (faac_real *) AllocMemory(size * sizeof(faac_real)); memset(psyInfo[channel].prevSamples, 0, size * sizeof(faac_real)); } size = BLOCK_LEN_SHORT; for (channel = 0; channel < numChannels; channel++) { psydata_t *psydata = psyInfo[channel].data; psyInfo[channel].sizeS = size; for (j = 0; j < 8; j++) { psydata->engPrev[j] = (psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat)); memset(psydata->engPrev[j], 0, NSFB_SHORT * sizeof(psyfloat)); psydata->eng[j] = (psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat)); memset(psydata->eng[j], 0, NSFB_SHORT * sizeof(psyfloat)); psydata->engNext[j] = (psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat)); memset(psydata->engNext[j], 0, NSFB_SHORT * sizeof(psyfloat)); psydata->engNext2[j] = (psyfloat *) AllocMemory(NSFB_SHORT * sizeof(psyfloat)); memset(psydata->engNext2[j], 0, NSFB_SHORT * sizeof(psyfloat)); } } } static void PsyEnd(GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, unsigned int numChannels) { unsigned int channel; int j; if (gpsyInfo->hannWindow) FreeMemory(gpsyInfo->hannWindow); if (gpsyInfo->hannWindowS) FreeMemory(gpsyInfo->hannWindowS); for (channel = 0; channel < numChannels; channel++) { if (psyInfo[channel].prevSamples) FreeMemory(psyInfo[channel].prevSamples); } for (channel = 0; channel < numChannels; channel++) { psydata_t *psydata = psyInfo[channel].data; for (j = 0; j < 8; j++) { if (psydata->engPrev[j]) FreeMemory(psydata->engPrev[j]); if (psydata->eng[j]) FreeMemory(psydata->eng[j]); if (psydata->engNext[j]) FreeMemory(psydata->engNext[j]); if (psydata->engNext2[j]) FreeMemory(psydata->engNext2[j]); } } for (channel = 0; channel < numChannels; channel++) { if (psyInfo[channel].data) FreeMemory(psyInfo[channel].data); } #if PRINTSTAT printf("short frames: %d/%d (%.2f %%)\n", frames.s, frames.tot, 100.0*frames.s/frames.tot); #endif } /* Do psychoacoustical analysis */ static void PsyCalculate(ChannelInfo * channelInfo, GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, int *cb_width_long, int num_cb_long, int *cb_width_short, int num_cb_short, unsigned int numChannels, faac_real quality ) { unsigned int channel; // limit switching threshold if (quality < 0.4) quality = 0.4; for (channel = 0; channel < numChannels; channel++) { if (channelInfo[channel].present) { if (channelInfo[channel].type == ELEMENT_CPE && channelInfo[channel].ch_is_left) { /* CPE */ int leftChan = channel; int rightChan = channelInfo[channel].paired_ch; PsyCheckShort(&psyInfo[leftChan], quality); PsyCheckShort(&psyInfo[rightChan], quality); } else if (channelInfo[channel].type == ELEMENT_LFE) { /* LFE */ // Only set block type and it should be OK psyInfo[channel].block_type = ONLY_LONG_WINDOW; } else if (channelInfo[channel].type == ELEMENT_SCE) { /* SCE */ PsyCheckShort(&psyInfo[channel], quality); } } } } static void PsyBufferUpdate( FFT_Tables *fft_tables, GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, faac_real *newSamples, unsigned int bandwidth, int *cb_width_short, int num_cb_short) { int win; faac_real *transBuff = gpsyInfo->sharedWorkBuffLong; faac_real *transBuffS = gpsyInfo->sharedWorkBuffShort; psydata_t *psydata = psyInfo->data; psyfloat *tmp; int sfb; psydata->bandS = psyInfo->sizeS * bandwidth * 2 / gpsyInfo->sampleRate; memcpy(transBuff, psyInfo->prevSamples, psyInfo->size * sizeof(faac_real)); memcpy(transBuff + psyInfo->size, newSamples, psyInfo->size * sizeof(faac_real)); for (win = 0; win < 8; win++) { int first = 0; int last = 0; memcpy(transBuffS, transBuff + (win * BLOCK_LEN_SHORT) + (BLOCK_LEN_LONG - BLOCK_LEN_SHORT) / 2, 2 * psyInfo->sizeS * sizeof(faac_real)); Hann(gpsyInfo, transBuffS, 2 * psyInfo->sizeS); MDCT( fft_tables, transBuffS, 2 * psyInfo->sizeS, gpsyInfo->mdctXr, gpsyInfo->mdctXi); // shift bufs tmp = psydata->engPrev[win]; psydata->engPrev[win] = psydata->eng[win]; psydata->eng[win] = psydata->engNext[win]; psydata->engNext[win] = psydata->engNext2[win]; psydata->engNext2[win] = tmp; for (sfb = 0; sfb < num_cb_short; sfb++) { faac_real e; int l; first = last; last = first + cb_width_short[sfb]; if (first < 1) first = 1; if (first >= psydata->bandS) // band out of range break; e = 0.0; for (l = first; l < last; l++) e += transBuffS[l] * transBuffS[l]; psydata->engNext2[win][sfb] = e; } psydata->lastband = sfb; for (; sfb < num_cb_short; sfb++) { psydata->engNext2[win][sfb] = 0; } } memcpy(psyInfo->prevSamples, newSamples, psyInfo->size * sizeof(faac_real)); } static void BlockSwitch(CoderInfo * coderInfo, PsyInfo * psyInfo, unsigned int numChannels) { unsigned int channel; int desire = ONLY_LONG_WINDOW; /* Use the same block type for all channels If there is 1 channel that wants a short block, use a short block on all channels. */ for (channel = 0; channel < numChannels; channel++) { if (psyInfo[channel].block_type == ONLY_SHORT_WINDOW) desire = ONLY_SHORT_WINDOW; } for (channel = 0; channel < numChannels; channel++) { int lasttype = coderInfo[channel].block_type; if (desire == ONLY_SHORT_WINDOW || coderInfo[channel].desired_block_type == ONLY_SHORT_WINDOW) { if (lasttype == ONLY_LONG_WINDOW || lasttype == SHORT_LONG_WINDOW) coderInfo[channel].block_type = LONG_SHORT_WINDOW; else coderInfo[channel].block_type = ONLY_SHORT_WINDOW; } else { if (lasttype == ONLY_SHORT_WINDOW || lasttype == LONG_SHORT_WINDOW) coderInfo[channel].block_type = SHORT_LONG_WINDOW; else coderInfo[channel].block_type = ONLY_LONG_WINDOW; } coderInfo[channel].desired_block_type = desire; } } psymodel_t psymodel2 = { PsyInit, PsyEnd, PsyCalculate, PsyBufferUpdate, BlockSwitch }; knik0-faac-79329ef/libfaac/blockswitch.h000066400000000000000000000051361517010422400200370ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: psych.h,v 1.15 2009/06/05 16:32:15 menno Exp $ */ #ifndef PSYCH_H #define PSYCH_H #include "faac_real.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #include "coder.h" #include "channels.h" #include "fft.h" typedef struct { int size; int sizeS; /* Previous input samples */ faac_real *prevSamples; int block_type; void *data; } PsyInfo; typedef struct { faac_real sampleRate; /* Hann window */ faac_real *hannWindow; faac_real *hannWindowS; /* shared work buffers */ faac_real *sharedWorkBuffLong; /* Used for 2048-sample windows (filtbank, psy, tns) */ faac_real *sharedWorkBuffShort; /* Used for 256-sample windows (psy) */ faac_real *mdctXr; /* MDCT pre-twiddle work buffer (xr) */ faac_real *mdctXi; /* MDCT pre-twiddle work buffer (xi) */ void *data; } GlobalPsyInfo; typedef struct { void (*PsyInit) (GlobalPsyInfo *gpsyInfo, PsyInfo *psyInfo, unsigned int numChannels, unsigned int sampleRate, int *cb_width_long, int num_cb_long, int *cb_width_short, int num_cb_short); void (*PsyEnd) (GlobalPsyInfo *gpsyInfo, PsyInfo *psyInfo, unsigned int numChannels); void (*PsyCalculate) (ChannelInfo *channelInfo, GlobalPsyInfo *gpsyInfo, PsyInfo *psyInfo, int *cb_width_long, int num_cb_long, int *cb_width_short, int num_cb_short, unsigned int numChannels, faac_real quality); void (*PsyBufferUpdate) ( FFT_Tables *fft_tables, GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, faac_real *newSamples, unsigned int bandwidth, int *cb_width_short, int num_cb_short); void (*BlockSwitch) (CoderInfo *coderInfo, PsyInfo *psyInfo, unsigned int numChannels); } psymodel_t; extern psymodel_t psymodel2; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PSYCH_H */knik0-faac-79329ef/libfaac/channels.c000066400000000000000000000126741517010422400173160ustar00rootroot00000000000000/************************* MPEG-2 NBC Audio Decoder ************************** * * "This software module was originally developed in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must be included in all copies or derivative works." Copyright(c)1996. * * ****************************************************************************/ /* * $Id: channels.c,v 1.5 2001/09/04 18:39:35 menno Exp $ */ #include "channels.h" #include "coder.h" #include "util.h" /* If LFE present */ /* Num channels # of SCE's # of CPE's #of LFE's */ /* ============ ========== ========== ========= */ /* 1 1 0 0 */ /* 2 0 1 0 */ /* 3 1 1 0 */ /* 4 1 1 1 */ /* 5 1 2 0 */ /* For more than 5 channels, use the following elements: */ /* 2*N 1 2*(N-1) 1 */ /* 2*N+1 1 2*N 0 */ /* */ /* Else: */ /* */ /* Num channels # of SCE's # of CPE's #of LFE's */ /* ============ ========== ========== ========= */ /* 1 1 0 0 */ /* 2 0 1 0 */ /* 3 1 1 0 */ /* 4 2 1 0 */ /* 5 1 2 0 */ /* For more than 5 channels, use the following elements: */ /* 2*N 2 2*(N-1) 0 */ /* 2*N+1 1 2*N 0 */ void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe) { int sceTag = 0; int lfeTag = 0; int cpeTag = 0; int numChannelsLeft = numChannels; /* First element is sce, except for 2 channel case */ if (numChannelsLeft != 2) { channelInfo[numChannels-numChannelsLeft].present = 1; channelInfo[numChannels-numChannelsLeft].tag = sceTag++; channelInfo[numChannels-numChannelsLeft].type = ELEMENT_SCE; numChannelsLeft--; } /* Next elements are cpe's */ while (numChannelsLeft > 1) { /* Left channel info */ channelInfo[numChannels-numChannelsLeft].present = 1; channelInfo[numChannels-numChannelsLeft].tag = cpeTag++; channelInfo[numChannels-numChannelsLeft].common_window = 0; channelInfo[numChannels-numChannelsLeft].ch_is_left = 1; channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft+1; channelInfo[numChannels-numChannelsLeft].type = ELEMENT_CPE; numChannelsLeft--; /* Right channel info */ channelInfo[numChannels-numChannelsLeft].present = 1; channelInfo[numChannels-numChannelsLeft].common_window = 0; channelInfo[numChannels-numChannelsLeft].ch_is_left = 0; channelInfo[numChannels-numChannelsLeft].paired_ch = numChannels-numChannelsLeft-1; channelInfo[numChannels-numChannelsLeft].type = ELEMENT_CPE; numChannelsLeft--; } /* Is there another channel left ? */ if (numChannelsLeft) { if (useLfe) { channelInfo[numChannels-numChannelsLeft].present = 1; channelInfo[numChannels-numChannelsLeft].tag = lfeTag++; channelInfo[numChannels-numChannelsLeft].type = ELEMENT_LFE; } else { channelInfo[numChannels-numChannelsLeft].present = 1; channelInfo[numChannels-numChannelsLeft].tag = sceTag++; channelInfo[numChannels-numChannelsLeft].type = ELEMENT_SCE; } numChannelsLeft--; } } knik0-faac-79329ef/libfaac/channels.h000066400000000000000000000026761517010422400173240ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: channels.h,v 1.7 2003/06/26 19:19:41 knik Exp $ */ #ifndef CHANNEL_H #define CHANNEL_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "coder.h" typedef struct { int is_present; int ms_used[MAX_SCFAC_BANDS]; } MSInfo; typedef enum { ELEMENT_SCE, ELEMENT_CPE, ELEMENT_LFE } ElementType; typedef struct { int tag; int present; int ch_is_left; int paired_ch; int common_window; ElementType type; MSInfo msInfo; } ChannelInfo; void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* CHANNEL_H */ knik0-faac-79329ef/libfaac/coder.h000066400000000000000000000065331517010422400166210ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: coder.h,v 1.13 2005/02/02 07:49:10 sur Exp $ */ #ifndef CODER_H #define CODER_H #include "faac_real.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define FRAME_LEN 1024 #define BLOCK_LEN_LONG 1024 #define BLOCK_LEN_SHORT 128 #define NSFB_LONG 51 #define NSFB_SHORT 15 #define MAX_SHORT_WINDOWS 8 #define MAX_SCFAC_BANDS ((NSFB_SHORT+1)*MAX_SHORT_WINDOWS) enum WINDOW_TYPE { ONLY_LONG_WINDOW, LONG_SHORT_WINDOW, ONLY_SHORT_WINDOW, SHORT_LONG_WINDOW }; #define TNS_MAX_ORDER 20 #define DEF_TNS_GAIN_THRESH 1.4 #define DEF_TNS_COEFF_THRESH 0.1 #define DEF_TNS_COEFF_RES 4 #define DEF_TNS_RES_OFFSET 3 #define LEN_TNS_NFILTL 2 #define LEN_TNS_NFILTS 1 typedef struct { int order; /* Filter order */ int direction; /* Filtering direction */ int coefCompress; /* Are coeffs compressed? */ int length; /* Length, in bands */ faac_real aCoeffs[TNS_MAX_ORDER+1]; /* AR Coefficients */ faac_real kCoeffs[TNS_MAX_ORDER+1]; /* Reflection Coefficients */ int index[TNS_MAX_ORDER+1]; /* Coefficient indices */ } TnsFilterData; typedef struct { int numFilters; /* Number of filters */ int coefResolution; /* Coefficient resolution */ TnsFilterData tnsFilter[1< # elif defined(__GNUC__) || defined(__clang__) # include # endif #endif CPUCaps get_cpu_caps(void) { CPUCaps caps = CPU_CAP_NONE; #if defined(SSE2_ARCH) unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; unsigned int max_leaf = 0; # ifdef _MSC_VER int cpu_info[4] = {0}; __cpuid(cpu_info, 0); max_leaf = (unsigned int)cpu_info[0]; # elif defined(__GNUC__) || defined(__clang__) __cpuid(0, max_leaf, ebx, ecx, edx); # endif if (max_leaf >= 1) { # ifdef _MSC_VER __cpuid(cpu_info, 1); eax = (unsigned int)cpu_info[0]; ebx = (unsigned int)cpu_info[1]; ecx = (unsigned int)cpu_info[2]; edx = (unsigned int)cpu_info[3]; # elif defined(__GNUC__) || defined(__clang__) __get_cpuid(1, &eax, &ebx, &ecx, &edx); # endif if (edx & (1 << 26)) // SSE2 caps |= CPU_CAP_SSE2; } #endif return caps; } knik0-faac-79329ef/libfaac/cpu_compute.h000066400000000000000000000021061517010422400200400ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2026 Nils Schimmelmann * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef CPU_COMPUTE_H #define CPU_COMPUTE_H #if defined(_M_X64) || defined(__x86_64__) || defined(_M_IX86) || defined(__i386__) # define SSE2_ARCH #endif typedef enum { CPU_CAP_NONE = 0, CPU_CAP_SSE2 = (1 << 0) } CPUCaps; CPUCaps get_cpu_caps(void); #endif knik0-faac-79329ef/libfaac/faac.pc.in000066400000000000000000000003371517010422400171730ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: FAAC Description: Freeware Advanced Audio Coder Version: @VERSION@ Libs: -L${libdir} -lfaac Libs.private: -lm Cflags: -I${includedir} knik0-faac-79329ef/libfaac/faac_real.h000066400000000000000000000027041517010422400174160ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2026 Nils Schimmelmann * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FAAC_REAL_H #define FAAC_REAL_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef FAAC_PRECISION_SINGLE typedef float faac_real; #define FAAC_SIN sinf #define FAAC_COS cosf #define FAAC_SQRT sqrtf #define FAAC_FABS fabsf #define FAAC_LOG10 log10f #define FAAC_POW powf #define FAAC_ASIN asinf #define FAAC_LRINT lrintf #define FAAC_FLOOR floorf #else typedef double faac_real; #define FAAC_SIN sin #define FAAC_COS cos #define FAAC_SQRT sqrt #define FAAC_FABS fabs #define FAAC_LOG10 log10 #define FAAC_POW pow #define FAAC_ASIN asin #define FAAC_LRINT lrint #define FAAC_FLOOR floor #endif #endif /* FAAC_REAL_H */ knik0-faac-79329ef/libfaac/fft.c000066400000000000000000000136151517010422400162760ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * $Id: fft.c,v 1.12 2005/02/02 07:49:55 sur Exp $ * Copyright (C) 2002 Krzysztof Nikiel * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include "fft.h" #include "util.h" #define MAXLOGM 9 #define MAXLOGR 8 void fft_initialize( FFT_Tables *fft_tables ) { int i; fft_tables->costbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->costbl[0] ) ); fft_tables->negsintbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->negsintbl[0] ) ); fft_tables->reordertbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->reordertbl[0] ) ); for( i = 0; i< MAXLOGM+1; i++ ) { fft_tables->costbl[i] = NULL; fft_tables->negsintbl[i] = NULL; fft_tables->reordertbl[i] = NULL; } } void fft_terminate( FFT_Tables *fft_tables ) { int i; for( i = 0; i< MAXLOGM+1; i++ ) { if( fft_tables->costbl[i] != NULL ) FreeMemory( fft_tables->costbl[i] ); if( fft_tables->negsintbl[i] != NULL ) FreeMemory( fft_tables->negsintbl[i] ); if( fft_tables->reordertbl[i] != NULL ) FreeMemory( fft_tables->reordertbl[i] ); } FreeMemory( fft_tables->costbl ); FreeMemory( fft_tables->negsintbl ); FreeMemory( fft_tables->reordertbl ); fft_tables->costbl = NULL; fft_tables->negsintbl = NULL; fft_tables->reordertbl = NULL; } static void reorder2( FFT_Tables *fft_tables, faac_real *xr, faac_real *xi, int logm) { int i; int size = 1 << logm; const unsigned short *r; if ( fft_tables->reordertbl[logm] == NULL ) // create bit reversing table { fft_tables->reordertbl[logm] = AllocMemory(size * sizeof(*(fft_tables->reordertbl[0]))); for (i = 0; i < size; i++) { int reversed = 0; int b0; int tmp = i; for (b0 = 0; b0 < logm; b0++) { reversed = (reversed << 1) | (tmp & 1); tmp >>= 1; } fft_tables->reordertbl[logm][i] = reversed; } } r = fft_tables->reordertbl[logm]; for (i = 0; i < size; i++) { int j = r[i]; faac_real tmp; if (j <= i) continue; tmp = xr[i]; xr[i] = xr[j]; xr[j] = tmp; tmp = xi[i]; xi[i] = xi[j]; xi[j] = tmp; } } static void fft_proc( faac_real *xr, faac_real *xi, fftfloat *refac, fftfloat *imfac, int size) { int step, shift, pos; int exp, estep; estep = size >> 1; /* First stage: step = 1 Twiddle factor W_N^0 is always (1, 0). Eliminate all multiplications and table lookups. */ for (pos = 0; pos < size; pos += 2) { faac_real v2r, v2i; int x1 = pos; int x2 = pos + 1; v2r = xr[x2]; v2i = xi[x2]; xr[x2] = xr[x1] - v2r; xr[x1] += v2r; xi[x2] = xi[x1] - v2i; xi[x1] += v2i; } /* Second stage: step = 2 shift = 0: Twiddle is (1, 0). shift = 1: Twiddle is (0, -1). Eliminate multiplications and avoid trig/table calls entirely. */ if (size >= 4) { for (pos = 0; pos < size; pos += 4) { faac_real v2r, v2i; int x1 = pos; int x2 = pos + 2; /* shift = 0: Rotation by 0 degrees */ v2r = xr[x2]; v2i = xi[x2]; xr[x2] = xr[x1] - v2r; xr[x1] += v2r; xi[x2] = xi[x1] - v2i; xi[x1] += v2i; /* shift = 1: Rotation by -90 degrees */ x1++; x2++; v2r = xi[x2]; v2i = -xr[x2]; xr[x2] = xr[x1] - v2r; xr[x1] += v2r; xi[x2] = xi[x1] - v2i; xi[x1] += v2i; } } /* Resume standard Radix-2 loop from stage 3 (step = 4) */ estep = size >> 2; for (step = 4; step < size; step *= 2) { int x1; int x2 = 0; estep >>= 1; for (pos = 0; pos < size; pos += (2 * step)) { x1 = x2; x2 += step; exp = 0; for (shift = 0; shift < step; shift++) { faac_real v2r, v2i; v2r = xr[x2] * refac[exp] - xi[x2] * imfac[exp]; v2i = xr[x2] * imfac[exp] + xi[x2] * refac[exp]; xr[x2] = xr[x1] - v2r; xr[x1] += v2r; xi[x2] = xi[x1] - v2i; xi[x1] += v2i; exp += estep; x1++; x2++; } } } } static void check_tables( FFT_Tables *fft_tables, int logm) { if( fft_tables->costbl[logm] == NULL ) { int i; int size = 1 << logm; if( fft_tables->negsintbl[logm] != NULL ) FreeMemory( fft_tables->negsintbl[logm] ); fft_tables->costbl[logm] = AllocMemory((size / 2) * sizeof(*(fft_tables->costbl[0]))); fft_tables->negsintbl[logm] = AllocMemory((size / 2) * sizeof(*(fft_tables->negsintbl[0]))); for (i = 0; i < (size >> 1); i++) { faac_real theta = 2.0 * M_PI * ((faac_real) i) / (faac_real) size; fft_tables->costbl[logm][i] = FAAC_COS(theta); fft_tables->negsintbl[logm][i] = -FAAC_SIN(theta); } } } void fft( FFT_Tables *fft_tables, faac_real *xr, faac_real *xi, int logm) { if (logm > MAXLOGM) { fprintf(stderr, "%s:%d: fft size too big (%d)\n", __FILE__, __LINE__, logm); return; } if (logm < 1) { //printf("logm < 1\n"); return; } check_tables( fft_tables, logm); reorder2( fft_tables, xr, xi, logm); fft_proc( xr, xi, fft_tables->costbl[logm], fft_tables->negsintbl[logm], 1 << logm ); } void rfft( FFT_Tables *fft_tables, faac_real *x, int logm) { faac_real xi[1 << MAXLOGR]; if (logm > MAXLOGR) { fprintf(stderr, "%s:%d: rfft size too big (%d)\n", __FILE__, __LINE__, logm); return; } memset(xi, 0, (1 << logm) * sizeof(xi[0])); fft( fft_tables, x, xi, logm); memcpy(x + (1 << (logm - 1)), xi, (1 << (logm - 1)) * sizeof(*x)); } knik0-faac-79329ef/libfaac/fft.h000066400000000000000000000024551517010422400163030ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * $Id: fft.h,v 1.6 2005/02/02 07:50:35 sur Exp $ * Copyright (C) 2002 Krzysztof Nikiel * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _FFT_H_ #define _FFT_H_ #include "faac_real.h" typedef faac_real fftfloat; typedef struct { fftfloat **costbl; fftfloat **negsintbl; unsigned short **reordertbl; } FFT_Tables; void fft_initialize ( FFT_Tables *fft_tables ); void fft_terminate ( FFT_Tables *fft_tables ); void rfft ( FFT_Tables *fft_tables, faac_real *x, int logm ); void fft ( FFT_Tables *fft_tables, faac_real *xr, faac_real *xi, int logm ); #endif knik0-faac-79329ef/libfaac/filtbank.c000066400000000000000000000330531517010422400173070ustar00rootroot00000000000000/************************* MPEG-2 NBC Audio Decoder ************************** * * "This software module was originally developed by AT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must be included in all copies or derivative works." Copyright(c)1996. * * ****************************************************************************/ /* * $Id: filtbank.c,v 1.14 2012/03/01 18:34:17 knik Exp $ */ /* * CHANGES: * 2001/01/17: menno: Added frequency cut off filter. * */ #include #include #include #include #include "coder.h" #include "filtbank.h" #include "frame.h" #include "fft.h" #include "util.h" #define TWOPI 2*M_PI static void CalculateKBDWindow ( faac_real* win, faac_real alpha, int length ); static faac_real Izero ( faac_real x); void FilterBankInit(faacEncStruct* hEncoder) { unsigned int i, channel; for (channel = 0; channel < hEncoder->numChannels; channel++) { hEncoder->freqBuff[channel] = (faac_real*)AllocMemory(2*FRAME_LEN*sizeof(faac_real)); hEncoder->overlapBuff[channel] = (faac_real*)AllocMemory(FRAME_LEN*sizeof(faac_real)); SetMemory(hEncoder->overlapBuff[channel], 0, FRAME_LEN*sizeof(faac_real)); } hEncoder->sin_window_long = (faac_real*)AllocMemory(BLOCK_LEN_LONG*sizeof(faac_real)); hEncoder->sin_window_short = (faac_real*)AllocMemory(BLOCK_LEN_SHORT*sizeof(faac_real)); hEncoder->kbd_window_long = (faac_real*)AllocMemory(BLOCK_LEN_LONG*sizeof(faac_real)); hEncoder->kbd_window_short = (faac_real*)AllocMemory(BLOCK_LEN_SHORT*sizeof(faac_real)); for( i=0; isin_window_long[i] = FAAC_SIN((M_PI/(2*BLOCK_LEN_LONG)) * (i + 0.5)); for( i=0; isin_window_short[i] = FAAC_SIN((M_PI/(2*BLOCK_LEN_SHORT)) * (i + 0.5)); CalculateKBDWindow(hEncoder->kbd_window_long, 4, BLOCK_LEN_LONG*2); CalculateKBDWindow(hEncoder->kbd_window_short, 6, BLOCK_LEN_SHORT*2); hEncoder->gpsyInfo.sharedWorkBuffLong = (faac_real*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(faac_real)); hEncoder->gpsyInfo.sharedWorkBuffShort = (faac_real*)AllocMemory(2*BLOCK_LEN_SHORT*sizeof(faac_real)); hEncoder->gpsyInfo.mdctXr = (faac_real*)AllocMemory((BLOCK_LEN_LONG / 2)*sizeof(faac_real)); hEncoder->gpsyInfo.mdctXi = (faac_real*)AllocMemory((BLOCK_LEN_LONG / 2)*sizeof(faac_real)); } void FilterBankEnd(faacEncStruct* hEncoder) { unsigned int channel; for (channel = 0; channel < hEncoder->numChannels; channel++) { if (hEncoder->freqBuff[channel]) FreeMemory(hEncoder->freqBuff[channel]); if (hEncoder->overlapBuff[channel]) FreeMemory(hEncoder->overlapBuff[channel]); } if (hEncoder->sin_window_long) FreeMemory(hEncoder->sin_window_long); if (hEncoder->sin_window_short) FreeMemory(hEncoder->sin_window_short); if (hEncoder->kbd_window_long) FreeMemory(hEncoder->kbd_window_long); if (hEncoder->kbd_window_short) FreeMemory(hEncoder->kbd_window_short); if (hEncoder->gpsyInfo.sharedWorkBuffLong) FreeMemory(hEncoder->gpsyInfo.sharedWorkBuffLong); if (hEncoder->gpsyInfo.sharedWorkBuffShort) FreeMemory(hEncoder->gpsyInfo.sharedWorkBuffShort); if (hEncoder->gpsyInfo.mdctXr) FreeMemory(hEncoder->gpsyInfo.mdctXr); if (hEncoder->gpsyInfo.mdctXi) FreeMemory(hEncoder->gpsyInfo.mdctXi); } void FilterBank(faacEncStruct* hEncoder, CoderInfo *coderInfo, faac_real *p_in_data, faac_real *p_out_mdct, faac_real *p_overlap, int overlap_select) { faac_real *p_o_buf, *first_window, *second_window; faac_real *transf_buf; int k, i; int block_type = coderInfo->block_type; transf_buf = hEncoder->gpsyInfo.sharedWorkBuffLong; /* create / shift old values */ /* We use p_overlap here as buffer holding the last frame time signal*/ if(overlap_select != MNON_OVERLAPPED) { memcpy(transf_buf, p_overlap, FRAME_LEN*sizeof(faac_real)); memcpy(transf_buf+BLOCK_LEN_LONG, p_in_data, FRAME_LEN*sizeof(faac_real)); memcpy(p_overlap, p_in_data, FRAME_LEN*sizeof(faac_real)); } else { memcpy(transf_buf, p_in_data, 2*FRAME_LEN*sizeof(faac_real)); } /* Window shape processing */ if(overlap_select != MNON_OVERLAPPED) { switch (coderInfo->prev_window_shape) { case SINE_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW)) first_window = hEncoder->sin_window_long; else first_window = hEncoder->sin_window_short; break; default: case KBD_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW)) first_window = hEncoder->kbd_window_long; else first_window = hEncoder->kbd_window_short; break; } switch (coderInfo->window_shape){ case SINE_WINDOW: default: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW)) second_window = hEncoder->sin_window_long; else second_window = hEncoder->sin_window_short; break; case KBD_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW)) second_window = hEncoder->kbd_window_long; else second_window = hEncoder->kbd_window_short; break; } } else { /* Always long block and sine window for LTP */ first_window = hEncoder->sin_window_long; second_window = hEncoder->sin_window_long; } /* Set ptr to transf-Buffer */ p_o_buf = transf_buf; /* Separate action for each Block Type */ switch (block_type) { case ONLY_LONG_WINDOW : for ( i = 0 ; i < BLOCK_LEN_LONG ; i++){ p_out_mdct[i] = p_o_buf[i] * first_window[i]; p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1]; } MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi ); break; case LONG_SHORT_WINDOW : for ( i = 0 ; i < BLOCK_LEN_LONG ; i++) p_out_mdct[i] = p_o_buf[i] * first_window[i]; memcpy(p_out_mdct+BLOCK_LEN_LONG,p_o_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(faac_real)); for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++) p_out_mdct[i+BLOCK_LEN_LONG+NFLAT_LS] = p_o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1]; SetMemory(p_out_mdct+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(faac_real)); MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi ); break; case SHORT_LONG_WINDOW : SetMemory(p_out_mdct,0,NFLAT_LS*sizeof(faac_real)); for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++) p_out_mdct[i+NFLAT_LS] = p_o_buf[i+NFLAT_LS] * first_window[i]; memcpy(p_out_mdct+NFLAT_LS+BLOCK_LEN_SHORT,p_o_buf+NFLAT_LS+BLOCK_LEN_SHORT,NFLAT_LS*sizeof(faac_real)); for ( i = 0 ; i < BLOCK_LEN_LONG ; i++) p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1]; MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi ); break; case ONLY_SHORT_WINDOW : p_o_buf += NFLAT_LS; for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) { for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++ ){ p_out_mdct[i] = p_o_buf[i] * first_window[i]; p_out_mdct[i+BLOCK_LEN_SHORT] = p_o_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1]; } MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_SHORT, hEncoder->gpsyInfo.mdctXr, hEncoder->gpsyInfo.mdctXi ); p_out_mdct += BLOCK_LEN_SHORT; p_o_buf += BLOCK_LEN_SHORT; first_window = second_window; } break; } } static faac_real Izero(faac_real x) { const faac_real IzeroEPSILON = 1E-41; /* Max error acceptable in Izero */ faac_real sum, u, halfx, temp; int n; sum = u = n = 1; halfx = x/2.0; do { temp = halfx/(faac_real)n; n += 1; temp *= temp; u *= temp; sum += u; } while (u >= IzeroEPSILON*sum); return(sum); } static void CalculateKBDWindow(faac_real* win, faac_real alpha, int length) { int i; faac_real IBeta; faac_real tmp; faac_real sum = 0.0; alpha *= M_PI; IBeta = 1.0/Izero(alpha); /* calculate lower half of Kaiser Bessel window */ for(i=0; i<(length>>1); i++) { tmp = 4.0*(faac_real)i/(faac_real)length - 1.0; win[i] = Izero(alpha*FAAC_SQRT(1.0-tmp*tmp))*IBeta; sum += win[i]; } sum = 1.0/sum; tmp = 0.0; /* calculate lower half of window */ for(i=0; i<(length>>1); i++) { tmp += win[i]; win[i] = FAAC_SQRT(tmp*sum); } } void MDCT( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *xr, faac_real *xi ) { faac_real tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */ faac_real freq = TWOPI / N; int i; /* Hoisted constants */ const int N2 = N >> 1; const int N4 = N >> 2; const int N8 = N >> 3; /* Base pointers for address simplification */ faac_real *base0 = data + N4; faac_real *base1 = data + (N4 - 1); faac_real *base2 = data + (N + N4 - 1); /* prepare for recurrence relation in pre-twiddle */ cfreq = FAAC_COS(freq); sfreq = FAAC_SIN(freq); c = FAAC_COS(freq * 0.125); s = FAAC_SIN(freq * 0.125); /* Induction variables */ int n1 = N2 - 1; /* descending: N/2 - 1 - 2i */ int n2 = 0; /* ascending: 2i */ /* Phase 1: i < N/8 */ for (i = 0; i < N8; i++) { /* calculate real and imaginary parts of g(n) or G(p) */ /* use second form of e(n) for n = N / 2 - 1 - 2i */ tempr = base0[n1] + base2[-n1]; /* use first form of e(n) for n = 2i */ tempi = base0[n2] - base1[-n2]; /* calculate pre-twiddled FFT input */ xr[i] = tempr * c + tempi * s; xi[i] = tempi * c - tempr * s; /* use recurrence to prepare cosine and sine for next value of i */ cold = c; c = c * cfreq - s * sfreq; s = s * cfreq + cold * sfreq; n1 -= 2; n2 += 2; } /* Phase 2: i >= N/8 */ for (; i < N4; i++) { /* calculate real and imaginary parts of g(n) or G(p) */ /* use first form of e(n) for n = N / 2 - 1 - 2i */ tempr = base0[n1] - base1[-n1]; /* use second form of e(n) for n = 2i */ tempi = base0[n2] + base2[-n2]; /* calculate pre-twiddled FFT input */ xr[i] = tempr * c + tempi * s; xi[i] = tempi * c - tempr * s; /* use recurrence to prepare cosine and sine for next value of i */ cold = c; c = c * cfreq - s * sfreq; s = s * cfreq + cold * sfreq; n1 -= 2; n2 += 2; } /* Perform in-place complex FFT of length N/4 */ switch (N) { case BLOCK_LEN_SHORT * 2: fft( fft_tables, xr, xi, 6); break; case BLOCK_LEN_LONG * 2: fft( fft_tables, xr, xi, 9); break; } /* prepare for recurrence relations in post-twiddle */ c = FAAC_COS(freq * 0.125); s = FAAC_SIN(freq * 0.125); /* Base pointers for output mapping */ faac_real *base_even0 = data; faac_real *base_odd0 = data + (N2 - 1); faac_real *base_even1 = data + N2; faac_real *base_odd1 = data + (N - 1); n2 = 0; /* post-twiddle FFT output and then get output data */ for (i = 0; i < N4; i++) { /* get post-twiddled FFT output */ tempr = 2. * (xr[i] * c + xi[i] * s); tempi = 2. * (xi[i] * c - xr[i] * s); /* fill in output values */ base_even0[n2] = -tempr; /* first half even */ base_odd0[-n2] = tempi; /* first half odd */ base_even1[n2] = -tempi; /* second half even */ base_odd1[-n2] = tempr; /* second half odd */ /* use recurrence to prepare cosine and sine for next value of i */ cold = c; c = c * cfreq - s * sfreq; s = s * cfreq + cold * sfreq; n2 += 2; } } knik0-faac-79329ef/libfaac/filtbank.h000066400000000000000000000030531517010422400173110ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: filtbank.h,v 1.12 2012/03/01 18:34:17 knik Exp $ */ #ifndef FILTBANK_H #define FILTBANK_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "frame.h" #define NFLAT_LS 448 #define MOVERLAPPED 0 #define MNON_OVERLAPPED 1 #define SINE_WINDOW 0 #define KBD_WINDOW 1 void FilterBankInit ( faacEncStruct* hEncoder ); void FilterBankEnd ( faacEncStruct* hEncoder ); void MDCT ( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *xr, faac_real *xi ); void FilterBank( faacEncStruct* hEncoder, CoderInfo *coderInfo, faac_real *p_in_data, faac_real *p_out_mdct, faac_real *p_overlap, int overlap_select ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* FILTBANK_H */ knik0-faac-79329ef/libfaac/frame.c000066400000000000000000000611741517010422400166140ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include "frame.h" #include "coder.h" #include "channels.h" #include "bitstream.h" #include "filtbank.h" #include "quantize.h" #include "util.h" #include "tns.h" #include "stereo.h" #if (defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined(PACKAGE_VERSION) #include "win32_ver.h" #endif /* Rate control tuning constants */ #define RC_DEADBAND_THRESHOLD 0.05 /* +/- 5% deadband */ #define RC_DAMPING_FACTOR 0.6 /* Control loop damping */ static char *libfaacName = PACKAGE_VERSION; static char *libCopyright = "FAAC - Freeware Advanced Audio Coder (http://faac.sourceforge.net/)\n" " Copyright (C) 1999,2000,2001 Menno Bakker\n" " Copyright (C) 2002,2003,2017 Krzysztof Nikiel\n" "This software is based on the ISO MPEG-4 reference source code.\n"; static const psymodellist_t psymodellist[] = { {&psymodel2, "knipsycho psychoacoustic"}, {NULL} }; static SR_INFO srInfo[12+1]; static unsigned int CalcBandwidth(unsigned long bitRate, unsigned long sampleRate) { const unsigned int nyquist = sampleRate / 2; unsigned int bw; if (!bitRate) return nyquist; if (bitRate <= 16000) { /* Segment 1: Telephony (4kHz to 6kHz) */ bw = 4000 + (bitRate / 8); } else if (bitRate <= 32000) { /* Segment 2: Low-tier (6kHz to 11kHz) */ bw = 6000 + ((bitRate - 16000) * 5 / 16); } else if (bitRate <= 64000) { /* Segment 3: Mid-tier expansion (11kHz to 18.5kHz) */ bw = 11000 + ((bitRate - 32000) * 15 / 64); } else if (bitRate <= 128000) { /* Segment 4: High-fidelity catch-up (18.5kHz to 20kHz) */ bw = 18500 + ((bitRate - 64000) * 3 / 128); } else { /* Segment 5: Transparency plateau (20kHz+) */ bw = 20000 + ((bitRate - 128000) / 16); if (bw > 20000) bw = 20000; } /* Safety clamp to Shannon-Nyquist limit */ return (bw > nyquist) ? nyquist : bw; } int FAACAPI faacEncGetVersion( char **faac_id_string, char **faac_copyright_string) { if (faac_id_string) *faac_id_string = libfaacName; if (faac_copyright_string) *faac_copyright_string = libCopyright; return FAAC_CFG_VERSION; } int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hpEncoder,unsigned char** ppBuffer,unsigned long* pSizeOfDecoderSpecificInfo) { faacEncStruct* hEncoder = (faacEncStruct*)hpEncoder; BitStream* pBitStream = NULL; if((hEncoder == NULL) || (ppBuffer == NULL) || (pSizeOfDecoderSpecificInfo == NULL)) { return -1; } if(hEncoder->config.mpegVersion == MPEG2){ return -2; /* not supported */ } *pSizeOfDecoderSpecificInfo = 2; *ppBuffer = malloc(2); if(*ppBuffer != NULL){ memset(*ppBuffer,0,*pSizeOfDecoderSpecificInfo); pBitStream = OpenBitStream(*pSizeOfDecoderSpecificInfo, *ppBuffer); PutBit(pBitStream, hEncoder->config.aacObjectType, 5); PutBit(pBitStream, hEncoder->sampleRateIdx, 4); PutBit(pBitStream, hEncoder->numChannels, 4); CloseBitStream(pBitStream); return 0; } else { return -3; } } faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hpEncoder) { faacEncStruct* hEncoder = (faacEncStruct*)hpEncoder; faacEncConfigurationPtr config = &(hEncoder->config); return config; } int FAACAPI faacEncSetConfiguration(faacEncHandle hpEncoder, faacEncConfigurationPtr config) { faacEncStruct* hEncoder = (faacEncStruct*)hpEncoder; int i; int maxqual = hEncoder->config.outputFormat ? MAXQUALADTS : MAXQUAL; hEncoder->config.jointmode = config->jointmode; hEncoder->config.useLfe = config->useLfe; hEncoder->config.useTns = config->useTns; hEncoder->config.aacObjectType = config->aacObjectType; hEncoder->config.mpegVersion = config->mpegVersion; hEncoder->config.outputFormat = config->outputFormat; hEncoder->config.inputFormat = config->inputFormat; hEncoder->config.shortctl = config->shortctl; assert((hEncoder->config.outputFormat == 0) || (hEncoder->config.outputFormat == 1)); switch( hEncoder->config.inputFormat ) { case FAAC_INPUT_16BIT: //case FAAC_INPUT_24BIT: case FAAC_INPUT_32BIT: case FAAC_INPUT_FLOAT: break; default: return 0; break; } if (hEncoder->config.aacObjectType != LOW) return 0; /* Re-init TNS for new profile */ TnsInit(hEncoder); /* Check for correct bitrate */ if (!hEncoder->sampleRate || !hEncoder->numChannels) return 0; if (config->bitRate > (MaxBitrate(hEncoder->sampleRate) / hEncoder->numChannels)) config->bitRate = MaxBitrate(hEncoder->sampleRate) / hEncoder->numChannels; #if 0 if (config->bitRate < MinBitrate()) return 0; #endif if (config->bitRate && !config->bandWidth) { config->bandWidth = CalcBandwidth(config->bitRate, hEncoder->sampleRate); if (!config->quantqual) { config->quantqual = (faac_real)config->bitRate * hEncoder->numChannels / 1280; if (config->quantqual > DEFQUAL) config->quantqual = (config->quantqual - DEFQUAL) * 3.0 + DEFQUAL; } } if (!config->quantqual) config->quantqual = DEFQUAL; hEncoder->config.bitRate = config->bitRate; if (!config->bandWidth) { config->bandWidth = CalcBandwidth(config->bitRate, hEncoder->sampleRate); } hEncoder->config.bandWidth = config->bandWidth; // check bandwidth if (hEncoder->config.bandWidth < 100) hEncoder->config.bandWidth = 100; if (hEncoder->config.bandWidth > (hEncoder->sampleRate / 2)) hEncoder->config.bandWidth = hEncoder->sampleRate / 2; if (config->quantqual > maxqual) config->quantqual = maxqual; if (config->quantqual < MINQUAL) config->quantqual = MINQUAL; hEncoder->config.quantqual = config->quantqual; if (config->mpegVersion == MPEG2) config->pnslevel = 0; if (config->pnslevel < 0) config->pnslevel = 0; if (config->pnslevel > 10) config->pnslevel = 10; hEncoder->aacquantCfg.pnslevel = config->pnslevel; /* set quantization quality */ hEncoder->aacquantCfg.quality = config->quantqual; CalcBW(&hEncoder->config.bandWidth, hEncoder->sampleRate, hEncoder->srInfo, &hEncoder->aacquantCfg); // reset psymodel hEncoder->psymodel->PsyEnd(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels); if (config->psymodelidx >= (sizeof(psymodellist) / sizeof(psymodellist[0]) - 1)) config->psymodelidx = (sizeof(psymodellist) / sizeof(psymodellist[0])) - 2; hEncoder->config.psymodelidx = config->psymodelidx; hEncoder->psymodel = (psymodel_t *)psymodellist[hEncoder->config.psymodelidx].ptr; hEncoder->psymodel->PsyInit(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels, hEncoder->sampleRate, hEncoder->srInfo->cb_width_long, hEncoder->srInfo->num_cb_long, hEncoder->srInfo->cb_width_short, hEncoder->srInfo->num_cb_short); /* load channel_map */ for( i = 0; i < MAX_CHANNELS; i++ ) hEncoder->config.channel_map[i] = config->channel_map[i]; /* OK */ return 1; } faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate, unsigned int numChannels, unsigned long *inputSamples, unsigned long *maxOutputBytes) { unsigned int channel; faacEncStruct* hEncoder; if (numChannels > MAX_CHANNELS) return NULL; *inputSamples = FRAME_LEN*numChannels; *maxOutputBytes = ADTS_FRAMESIZE; hEncoder = (faacEncStruct*)AllocMemory(sizeof(faacEncStruct)); SetMemory(hEncoder, 0, sizeof(faacEncStruct)); hEncoder->numChannels = numChannels; hEncoder->sampleRate = sampleRate; hEncoder->sampleRateIdx = GetSRIndex(sampleRate); /* Initialize variables to default values */ hEncoder->frameNum = 0; hEncoder->flushFrame = 0; /* Default configuration */ hEncoder->config.version = FAAC_CFG_VERSION; hEncoder->config.name = libfaacName; hEncoder->config.copyright = libCopyright; hEncoder->config.mpegVersion = MPEG4; hEncoder->config.aacObjectType = LOW; hEncoder->config.jointmode = JOINT_IS; hEncoder->config.pnslevel = 4; hEncoder->config.useLfe = 1; hEncoder->config.useTns = 0; hEncoder->config.bitRate = 64000; hEncoder->config.bandWidth = CalcBandwidth(hEncoder->config.bitRate, sampleRate); hEncoder->config.quantqual = 0; hEncoder->config.psymodellist = (psymodellist_t *)psymodellist; hEncoder->config.psymodelidx = 0; hEncoder->psymodel = (psymodel_t *)hEncoder->config.psymodellist[hEncoder->config.psymodelidx].ptr; hEncoder->config.shortctl = SHORTCTL_NORMAL; /* default channel map is straight-through */ for( channel = 0; channel < MAX_CHANNELS; channel++ ) hEncoder->config.channel_map[channel] = channel; hEncoder->config.outputFormat = ADTS_STREAM; /* be compatible with software which assumes 24bit in 32bit PCM */ hEncoder->config.inputFormat = FAAC_INPUT_32BIT; /* find correct sampling rate depending parameters */ hEncoder->srInfo = &srInfo[hEncoder->sampleRateIdx]; for (channel = 0; channel < numChannels; channel++) { hEncoder->coderInfo[channel].prev_window_shape = SINE_WINDOW; hEncoder->coderInfo[channel].window_shape = SINE_WINDOW; hEncoder->coderInfo[channel].block_type = ONLY_LONG_WINDOW; hEncoder->coderInfo[channel].groups.n = 1; hEncoder->coderInfo[channel].groups.len[0] = 1; hEncoder->sampleBuff[channel] = NULL; } /* Initialize coder functions */ fft_initialize( &hEncoder->fft_tables ); hEncoder->psymodel->PsyInit(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels, hEncoder->sampleRate, hEncoder->srInfo->cb_width_long, hEncoder->srInfo->num_cb_long, hEncoder->srInfo->cb_width_short, hEncoder->srInfo->num_cb_short); FilterBankInit(hEncoder); TnsInit(hEncoder); QuantizeInit(); /* Return handle */ return hEncoder; } int FAACAPI faacEncClose(faacEncHandle hpEncoder) { faacEncStruct* hEncoder = (faacEncStruct*)hpEncoder; unsigned int channel; /* Deinitialize coder functions */ hEncoder->psymodel->PsyEnd(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels); FilterBankEnd(hEncoder); fft_terminate(&hEncoder->fft_tables); /* Free remaining buffer memory */ for (channel = 0; channel < hEncoder->numChannels; channel++) { if (hEncoder->sampleBuff[channel]) FreeMemory(hEncoder->sampleBuff[channel]); if (hEncoder->next3SampleBuff[channel]) FreeMemory (hEncoder->next3SampleBuff[channel]); } /* Free handle */ if (hEncoder) FreeMemory(hEncoder); BlocStat(); return 0; } int FAACAPI faacEncEncode(faacEncHandle hpEncoder, int32_t *inputBuffer, unsigned int samplesInput, unsigned char *outputBuffer, unsigned int bufferSize ) { faacEncStruct* hEncoder = (faacEncStruct*)hpEncoder; unsigned int channel, i; int sb, frameBytes; unsigned int offset; BitStream *bitStream; /* bitstream used for writing the frame to */ /* local copy's of parameters */ ChannelInfo *channelInfo = hEncoder->channelInfo; CoderInfo *coderInfo = hEncoder->coderInfo; unsigned int numChannels = hEncoder->numChannels; unsigned int useLfe = hEncoder->config.useLfe; unsigned int useTns = hEncoder->config.useTns; unsigned int jointmode = hEncoder->config.jointmode; unsigned int bandWidth = hEncoder->config.bandWidth; unsigned int shortctl = hEncoder->config.shortctl; int maxqual = hEncoder->config.outputFormat ? MAXQUALADTS : MAXQUAL; /* Increase frame number */ hEncoder->frameNum++; if (samplesInput == 0) hEncoder->flushFrame++; /* After 4 flush frames all samples have been encoded, return 0 bytes written */ if (hEncoder->flushFrame > 4) return 0; /* Determine the channel configuration */ GetChannelInfo(channelInfo, numChannels, useLfe); /* Update current sample buffers */ for (channel = 0; channel < numChannels; channel++) { faac_real *tmp; if (!hEncoder->sampleBuff[channel]) hEncoder->sampleBuff[channel] = (faac_real*)AllocMemory(FRAME_LEN*sizeof(faac_real)); tmp = hEncoder->sampleBuff[channel]; hEncoder->sampleBuff[channel] = hEncoder->next3SampleBuff[channel]; hEncoder->next3SampleBuff[channel] = tmp; if (samplesInput == 0) { /* start flushing*/ for (i = 0; i < FRAME_LEN; i++) hEncoder->next3SampleBuff[channel][i] = 0.0; } else { int samples_per_channel = samplesInput/numChannels; /* handle the various input formats and channel remapping */ switch( hEncoder->config.inputFormat ) { case FAAC_INPUT_16BIT: { short *input_channel = (short*)inputBuffer + hEncoder->config.channel_map[channel]; for (i = 0; i < samples_per_channel; i++) { hEncoder->next3SampleBuff[channel][i] = (faac_real)*input_channel; input_channel += numChannels; } } break; case FAAC_INPUT_32BIT: { int32_t *input_channel = (int32_t*)inputBuffer + hEncoder->config.channel_map[channel]; for (i = 0; i < samples_per_channel; i++) { hEncoder->next3SampleBuff[channel][i] = (1.0/256) * (faac_real)*input_channel; input_channel += numChannels; } } break; case FAAC_INPUT_FLOAT: { float *input_channel = (float*)inputBuffer + hEncoder->config.channel_map[channel]; for (i = 0; i < samples_per_channel; i++) { hEncoder->next3SampleBuff[channel][i] = (faac_real)*input_channel; input_channel += numChannels; } } break; default: return -1; /* invalid input format */ break; } for (i = (int)(samplesInput/numChannels); i < FRAME_LEN; i++) hEncoder->next3SampleBuff[channel][i] = 0.0; } /* Psychoacoustics */ /* Update buffers and run FFT on new samples */ /* LFE psychoacoustic can run without it */ if (channelInfo[channel].type != ELEMENT_LFE) { hEncoder->psymodel->PsyBufferUpdate( &hEncoder->fft_tables, &hEncoder->gpsyInfo, &hEncoder->psyInfo[channel], hEncoder->next3SampleBuff[channel], bandWidth, hEncoder->srInfo->cb_width_short, hEncoder->srInfo->num_cb_short); } } if (hEncoder->frameNum <= 3) /* Still filling up the buffers */ return 0; /* Psychoacoustics */ hEncoder->psymodel->PsyCalculate(channelInfo, &hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->srInfo->cb_width_long, hEncoder->srInfo->num_cb_long, hEncoder->srInfo->cb_width_short, hEncoder->srInfo->num_cb_short, numChannels, (faac_real)hEncoder->aacquantCfg.quality / DEFQUAL); hEncoder->psymodel->BlockSwitch(coderInfo, hEncoder->psyInfo, numChannels); /* force block type */ if (shortctl == SHORTCTL_NOSHORT) { for (channel = 0; channel < numChannels; channel++) { coderInfo[channel].block_type = ONLY_LONG_WINDOW; } } else if ((hEncoder->frameNum <= 4) || (shortctl == SHORTCTL_NOLONG)) { for (channel = 0; channel < numChannels; channel++) { coderInfo[channel].block_type = ONLY_SHORT_WINDOW; } } /* AAC Filterbank, MDCT with overlap and add */ for (channel = 0; channel < numChannels; channel++) { FilterBank(hEncoder, &coderInfo[channel], hEncoder->sampleBuff[channel], hEncoder->freqBuff[channel], hEncoder->overlapBuff[channel], MOVERLAPPED); } for (channel = 0; channel < numChannels; channel++) { channelInfo[channel].msInfo.is_present = 0; if (coderInfo[channel].block_type == ONLY_SHORT_WINDOW) { coderInfo[channel].sfbn = hEncoder->aacquantCfg.max_cbs; offset = 0; for (sb = 0; sb < coderInfo[channel].sfbn; sb++) { coderInfo[channel].sfb_offset[sb] = offset; offset += hEncoder->srInfo->cb_width_short[sb]; } coderInfo[channel].sfb_offset[sb] = offset; BlocGroup(hEncoder->freqBuff[channel], coderInfo + channel, &hEncoder->aacquantCfg); } else { coderInfo[channel].sfbn = hEncoder->aacquantCfg.max_cbl; coderInfo[channel].groups.n = 1; coderInfo[channel].groups.len[0] = 1; offset = 0; for (sb = 0; sb < coderInfo[channel].sfbn; sb++) { coderInfo[channel].sfb_offset[sb] = offset; offset += hEncoder->srInfo->cb_width_long[sb]; } coderInfo[channel].sfb_offset[sb] = offset; } } /* Perform TNS analysis and filtering */ for (channel = 0; channel < numChannels; channel++) { if ((channelInfo[channel].type != ELEMENT_LFE) && (useTns)) { TnsEncode(&(coderInfo[channel].tnsInfo), coderInfo[channel].sfbn, coderInfo[channel].sfbn, coderInfo[channel].block_type, coderInfo[channel].sfb_offset, hEncoder->freqBuff[channel], hEncoder->gpsyInfo.sharedWorkBuffLong); } else { coderInfo[channel].tnsInfo.tnsDataPresent = 0; /* TNS not used for LFE */ } } for (channel = 0; channel < numChannels; channel++) { // reduce LFE bandwidth if (channelInfo[channel].type == ELEMENT_LFE) { coderInfo[channel].sfbn = 3; } } AACstereo(coderInfo, channelInfo, hEncoder->freqBuff, numChannels, (faac_real)hEncoder->aacquantCfg.quality/DEFQUAL, jointmode); for (channel = 0; channel < numChannels; channel++) { BlocQuant(&coderInfo[channel], hEncoder->freqBuff[channel], &(hEncoder->aacquantCfg)); } // fix max_sfb in CPE mode for (channel = 0; channel < numChannels; channel++) { if (channelInfo[channel].present && (channelInfo[channel].type == ELEMENT_CPE) && (channelInfo[channel].ch_is_left)) { CoderInfo *cil, *cir; cil = &coderInfo[channel]; cir = &coderInfo[channelInfo[channel].paired_ch]; cil->sfbn = cir->sfbn = max(cil->sfbn, cir->sfbn); } } /* Write the AAC bitstream */ bitStream = OpenBitStream(bufferSize, outputBuffer); if (WriteBitstream(hEncoder, coderInfo, channelInfo, bitStream, numChannels) < 0) return -1; /* Close the bitstream and return the number of bytes written */ frameBytes = CloseBitStream(bitStream); /* Adjust quality to get correct average bitrate */ if (hEncoder->config.bitRate) { int desbits = numChannels * (hEncoder->config.bitRate * FRAME_LEN) / hEncoder->sampleRate; faac_real fix = (faac_real)desbits / (faac_real)(frameBytes * 8); if (fix < (1.0 - RC_DEADBAND_THRESHOLD)) { fix += RC_DEADBAND_THRESHOLD; } else if (fix > (1.0 + RC_DEADBAND_THRESHOLD)) { fix -= RC_DEADBAND_THRESHOLD; } else { fix = 1.0; } /* Apply damping to the quality adjustment */ fix = (fix - 1.0) * RC_DAMPING_FACTOR + 1.0; // printf("q: %.1f(f:%.4f)\n", hEncoder->aacquantCfg.quality, fix); hEncoder->aacquantCfg.quality *= fix; if (hEncoder->aacquantCfg.quality > maxqual) hEncoder->aacquantCfg.quality = maxqual; if (hEncoder->aacquantCfg.quality < MINQUAL) hEncoder->aacquantCfg.quality = MINQUAL; } return frameBytes; } /* Scalefactorband data table for 1024 transform length */ static SR_INFO srInfo[12+1] = { { 96000, 41, 12, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },{ 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } }, { 88200, 41, 12, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },{ 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } }, { 64000, 47, 12, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 },{ 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 32 } }, { 48000, 49, 14, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96 }, { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } }, { 44100, 49, 14, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96 }, { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } }, { 32000, 51, 14, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 },{ 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } }, { 24000, 47, 15, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64 }, { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 } }, { 22050, 47, 15, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64 }, { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 } }, { 16000, 43, 15, { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64 }, { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } }, { 12000, 43, 15, { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64 }, { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } }, { 11025, 43, 15, { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64 }, { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } }, { 8000, 40, 15, { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80 }, { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20 } }, { -1 } }; knik0-faac-79329ef/libfaac/frame.h000066400000000000000000000044741517010422400166210ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef FRAME_H #define FRAME_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "coder.h" #include "channels.h" #include "blockswitch.h" #include "fft.h" #include "quantize.h" #include typedef struct { /* number of channels in AAC file */ unsigned int numChannels; /* samplerate of AAC file */ unsigned long sampleRate; unsigned int sampleRateIdx; unsigned int usedBytes; /* frame number */ unsigned int frameNum; unsigned int flushFrame; /* Scalefactorband data */ SR_INFO *srInfo; /* sample buffers of current next and next next frame*/ faac_real *sampleBuff[MAX_CHANNELS]; faac_real *next3SampleBuff[MAX_CHANNELS]; /* Filterbank buffers */ faac_real *sin_window_long; faac_real *sin_window_short; faac_real *kbd_window_long; faac_real *kbd_window_short; faac_real *freqBuff[MAX_CHANNELS]; faac_real *overlapBuff[MAX_CHANNELS]; /* Channel and Coder data for all channels */ CoderInfo coderInfo[MAX_CHANNELS]; ChannelInfo channelInfo[MAX_CHANNELS]; /* Psychoacoustics data */ PsyInfo psyInfo[MAX_CHANNELS]; GlobalPsyInfo gpsyInfo; /* Configuration data */ faacEncConfiguration config; psymodel_t *psymodel; /* quantizer specific config */ AACQuantCfg aacquantCfg; /* FFT Tables */ FFT_Tables fft_tables; } faacEncStruct; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* FRAME_H */ knik0-faac-79329ef/libfaac/huff2.c000066400000000000000000000276401517010422400165340ustar00rootroot00000000000000/**************************************************************************** Huffman coding Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #include #include #include "coder.h" #include "huffdata.h" #include "huff2.h" #include "bitstream.h" static int escape(int x, int *code) { int preflen = 0; int base = 32; if (x > MAX_HUFF_ESC_VAL) { fprintf(stderr, "%s(%d): x_quant > %d\n", __FILE__, __LINE__, MAX_HUFF_ESC_VAL); return 0; } *code = 0; while (base <= x) { base <<= 1; *code <<= 1; *code |= 1; preflen++; } base >>= 1; // separator *code <<= 1; *code <<= (preflen + 4); *code |= (x - base); return (preflen << 1) + 5; } #define arrlen(array) (sizeof(array) / sizeof(*array)) static int huffcode(int *qs /* quantized spectrum */, int len, int bnum, CoderInfo *coder) { static hcode16_t * const hmap[12] = {0, book01, book02, book03, book04, book05, book06, book07, book08, book09, book10, book11}; hcode16_t *book; int cnt; int bits = 0, blen; int ofs, *qp; int data = 0; int idx; int datacnt; if (coder) datacnt = coder->datacnt; else datacnt = 0; book = hmap[bnum]; switch (bnum) { case 1: case 2: for(ofs = 0; ofs < len; ofs += 4) { qp = qs+ofs; idx = 27 * qp[0] + 9 * qp[1] + 3 * qp[2] + qp[3] + 40; if (idx < 0 || idx >= arrlen(book01)) { return -1; } blen = book[idx].len; if (coder) { data = book[idx].data; coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; } break; case 3: case 4: for(ofs = 0; ofs < len; ofs += 4) { qp = qs+ofs; idx = 27 * abs(qp[0]) + 9 * abs(qp[1]) + 3 * abs(qp[2]) + abs(qp[3]); if (idx < 0 || idx >= arrlen(book03)) { return -1; } blen = book[idx].len; if (!coder) { // add sign bits for(cnt = 0; cnt < 4; cnt++) if(qp[cnt]) blen++; } else { data = book[idx].data; // add sign bits for(cnt = 0; cnt < 4; cnt++) { if(qp[cnt]) { blen++; data <<= 1; if (qp[cnt] < 0) data |= 1; } } coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; } break; case 5: case 6: for(ofs = 0; ofs < len; ofs += 2) { qp = qs+ofs; idx = 9 * qp[0] + qp[1] + 40; if (idx < 0 || idx >= arrlen(book05)) { return -1; } blen = book[idx].len; if (coder) { data = book[idx].data; coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; } break; case 7: case 8: for(ofs = 0; ofs < len; ofs += 2) { qp = qs+ofs; idx = 8 * abs(qp[0]) + abs(qp[1]); if (idx < 0 || idx >= arrlen(book07)) { return -1; } blen = book[idx].len; if (!coder) { for(cnt = 0; cnt < 2; cnt++) if(qp[cnt]) blen++; } else { data = book[idx].data; for(cnt = 0; cnt < 2; cnt++) { if(qp[cnt]) { blen++; data <<= 1; if (qp[cnt] < 0) data |= 1; } } coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; } break; case 9: case 10: for(ofs = 0; ofs < len; ofs += 2) { qp = qs+ofs; idx = 13 * abs(qp[0]) + abs(qp[1]); if (idx < 0 || idx >= arrlen(book09)) { return -1; } blen = book[idx].len; if (!coder) { for(cnt = 0; cnt < 2; cnt++) if(qp[cnt]) blen++; } else { data = book[idx].data; for(cnt = 0; cnt < 2; cnt++) { if(qp[cnt]) { blen++; data <<= 1; if (qp[cnt] < 0) data |= 1; } } coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; } break; case HCB_ESC: for(ofs = 0; ofs < len; ofs += 2) { int x0, x1; qp = qs+ofs; x0 = abs(qp[0]); x1 = abs(qp[1]); if (x0 > 16) x0 = 16; if (x1 > 16) x1 = 16; idx = 17 * x0 + x1; if (idx < 0 || idx >= arrlen(book11)) { return -1; } blen = book[idx].len; if (!coder) { for(cnt = 0; cnt < 2; cnt++) if(qp[cnt]) blen++; } else { data = book[idx].data; for(cnt = 0; cnt < 2; cnt++) { if(qp[cnt]) { blen++; data <<= 1; if (qp[cnt] < 0) data |= 1; } } coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; if (x0 >= 16) { blen = escape(abs(qp[0]), &data); if (coder) { coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; } if (x1 >= 16) { blen = escape(abs(qp[1]), &data); if (coder) { coder->s[datacnt].data = data; coder->s[datacnt++].len = blen; } bits += blen; } } break; default: fprintf(stderr, "%s(%d) book %d out of range\n", __FILE__, __LINE__, bnum); return -1; } if (coder) coder->datacnt = datacnt; return bits; } int huffbook(CoderInfo *coder, int *qs /* quantized spectrum */, int len) { int cnt; int maxq = 0; int bookmin, lenmin; for (cnt = 0; cnt < len; cnt++) { int q = abs(qs[cnt]); if (maxq < q) maxq = q; } #define BOOKMIN(n)bookmin=n;lenmin=huffcode(qs,len,bookmin,0);if(huffcode(qs,len,bookmin+1,0) HCB_ZERO) huffcode(qs, len, bookmin, coder); coder->book[coder->bandcnt] = bookmin; return 0; } int writebooks(CoderInfo *coder, BitStream *stream, int write) { int bits = 0; int maxcnt, cntbits; int group; int bookbits = 4; if (coder->block_type == ONLY_SHORT_WINDOW){ maxcnt = 7; cntbits = 3; } else { maxcnt = 31; cntbits = 5; } for (group = 0; group < coder->groups.n; group++) { int band = group * coder->sfbn; int maxband = band + coder->sfbn; while (band < maxband) { int book = coder->book[band++]; int bookcnt = 1; if (write) { PutBit(stream, book, bookbits); } bits += bookbits; if (band < maxband) { while (book == coder->book[band]) { band++; bookcnt++; if (band >= maxband) break; } } while (bookcnt >= maxcnt) { if (write) PutBit(stream, maxcnt, cntbits); bits += cntbits; bookcnt -= maxcnt; } if (write) PutBit(stream, bookcnt, cntbits); bits += cntbits; } } return bits; } int writesf(CoderInfo *coder, BitStream *stream, int write) { int cnt; int bits = 0; int diff, length; int lastsf; int lastis; int lastpns; int initpns = 1; lastsf = coder->global_gain; lastis = 0; lastpns = coder->global_gain - SF_PNS_OFFSET; // fixme: move range check to quantizer for (cnt = 0; cnt < coder->bandcnt; cnt++) { int book = coder->book[cnt]; if ((book == HCB_INTENSITY) || (book== HCB_INTENSITY2)) { diff = coder->sf[cnt] - lastis; diff = clamp_sf_diff(diff); length = book12[SF_DELTA + diff].len; bits += length; lastis += diff; if (write) PutBit(stream, book12[SF_DELTA + diff].data, length); } else if (book == HCB_PNS) { diff = coder->sf[cnt] - lastpns; if (initpns) { initpns = 0; length = 9; bits += length; lastpns += diff; if (write) PutBit(stream, diff + 256, length); continue; } diff = clamp_sf_diff(diff); length = book12[SF_DELTA + diff].len; bits += length; lastpns += diff; if (write) PutBit(stream, book12[SF_DELTA + diff].data, length); } else if ((book != HCB_ZERO) && (book != HCB_NONE)) { diff = coder->sf[cnt] - lastsf; diff = clamp_sf_diff(diff); length = book12[SF_DELTA + diff].len; bits += length; lastsf += diff; if (write) PutBit(stream, book12[SF_DELTA + diff].data, length); } } return bits; } knik0-faac-79329ef/libfaac/huff2.h000066400000000000000000000042421517010422400165320ustar00rootroot00000000000000/**************************************************************************** Huffman coding Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #ifndef HUFF2_H #define HUFF2_H #include "bitstream.h" /* Huffman Codebooks */ enum { HCB_ZERO = 0, HCB_ESC = 11, HCB_PNS = 13, HCB_INTENSITY2 = 14, HCB_INTENSITY = 15, HCB_NONE }; /* Maximum value representable by Huffman Book 11 escape sequences. * Values >= 8192 would cause bitstream overflow/sync loss. */ #define MAX_HUFF_ESC_VAL 8191 /* Scalefactor Management */ enum { /* Baseline scalefactor value used in bitstream */ SF_OFFSET = 100, /* Minimum allowable scalefactor to prevent underflow */ SF_MIN = 10, /* PNS predictor initialization offset (starts at floor) */ SF_PNS_OFFSET = SF_OFFSET - SF_MIN, /* Max allowed difference between successive scalefactors (AAC spec) */ SF_DELTA = 60, }; /** * Restrict scalefactor delta to the spec-defined +/- SF_DELTA range. * This ensures the delta remains valid for Book 12 Huffman encoding. */ static inline int clamp_sf_diff(int diff) { if (diff > SF_DELTA) return SF_DELTA; if (diff < -SF_DELTA) return -SF_DELTA; return diff; } int huffbook(CoderInfo *coderInfo, int *qs /* quantized spectrum */, int len); int writebooks(CoderInfo *coder, BitStream *stream, int writeFlag); int writesf(CoderInfo *coder, BitStream *bitStream, int writeFlag); #endif /* HUFF2_H */ knik0-faac-79329ef/libfaac/huffdata.c000066400000000000000000000322551517010422400173020ustar00rootroot00000000000000/**************************************************************************** Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #include "huffdata.h" hcode16_t book01[81] = { {11,2040},{9,497},{11,2045},{10,1013},{7,104},{10,1008},{11,2039},{9,492}, {11,2037},{10,1009},{7,114},{10,1012},{7,116},{5,17},{7,118},{9,491}, {7,108},{10,1014},{11,2044},{9,481},{11,2033},{9,496},{7,97},{9,502}, {11,2034},{9,490},{11,2043},{9,498},{7,105},{9,493},{7,119},{5,23}, {7,111},{9,486},{7,100},{9,485},{7,103},{5,21},{7,98},{5,18}, {1,0},{5,20},{7,101},{5,22},{7,109},{9,489},{7,99},{9,484}, {7,107},{5,19},{7,113},{9,483},{7,112},{9,499},{11,2046},{9,487}, {11,2035},{9,495},{7,96},{9,494},{11,2032},{9,482},{11,2042},{10,1011}, {7,106},{9,488},{7,117},{5,16},{7,115},{9,500},{7,110},{10,1015}, {11,2038},{9,480},{11,2041},{10,1010},{7,102},{9,501},{11,2047},{9,503}, {11,2036}, }; hcode16_t book02[81] = { {9,499},{7,111},{9,509},{8,235},{6,35},{8,234},{9,503},{8,232}, {9,506},{8,242},{6,45},{7,112},{6,32},{5,6},{6,43},{7,110}, {6,40},{8,233},{9,505},{7,102},{8,248},{8,231},{6,27},{8,241}, {9,500},{7,107},{9,501},{8,236},{6,42},{7,108},{6,44},{5,10}, {6,39},{7,103},{6,26},{8,245},{6,36},{5,8},{6,31},{5,9}, {3,0},{5,7},{6,29},{5,11},{6,48},{8,239},{6,28},{7,100}, {6,30},{5,12},{6,41},{8,243},{6,47},{8,240},{9,508},{7,113}, {9,498},{8,244},{6,33},{8,230},{8,247},{7,104},{9,504},{8,238}, {6,34},{7,101},{6,49},{4,2},{6,38},{8,237},{6,37},{7,106}, {9,507},{7,114},{9,510},{7,105},{6,46},{8,246},{9,511},{7,109}, {9,502}, }; hcode16_t book03[81] = { {1,0},{4,9},{8,239},{4,11},{5,25},{8,240},{9,491},{9,486}, {10,1010},{4,10},{6,53},{9,495},{6,52},{6,55},{9,489},{9,493}, {9,487},{10,1011},{9,494},{10,1005},{13,8186},{9,492},{9,498},{11,2041}, {11,2040},{10,1016},{12,4088},{4,8},{6,56},{10,1014},{6,54},{7,117}, {10,1009},{10,1003},{10,1004},{12,4084},{5,24},{7,118},{11,2036},{6,57}, {7,116},{10,1007},{9,499},{9,500},{11,2038},{9,488},{10,1002},{13,8188}, {8,242},{9,497},{12,4091},{10,1013},{11,2035},{12,4092},{8,238},{10,1015}, {15,32766},{9,496},{11,2037},{15,32765},{13,8187},{14,16378},{16,65535},{8,241}, {10,1008},{14,16380},{9,490},{10,1006},{14,16379},{12,4086},{12,4090},{15,32764}, {11,2034},{12,4085},{16,65534},{10,1012},{11,2039},{15,32763},{12,4087},{12,4089}, {15,32762}, }; hcode16_t book04[81] = { {4,7},{5,22},{8,246},{5,24},{4,8},{8,239},{9,495},{8,243}, {11,2040},{5,25},{5,23},{8,237},{5,21},{4,1},{8,226},{8,240}, {7,112},{10,1008},{9,494},{8,241},{11,2042},{8,238},{8,228},{10,1010}, {11,2038},{10,1007},{11,2045},{4,5},{5,20},{8,242},{4,9},{4,4}, {8,229},{8,244},{8,232},{10,1012},{4,6},{4,2},{8,231},{4,3}, {4,0},{7,107},{8,227},{7,105},{9,499},{8,235},{8,230},{10,1014}, {7,110},{7,106},{9,500},{10,1004},{9,496},{10,1017},{8,245},{8,236}, {11,2043},{8,234},{7,111},{10,1015},{11,2041},{10,1011},{12,4095},{8,233}, {7,109},{10,1016},{7,108},{7,104},{9,501},{10,1006},{9,498},{11,2036}, {11,2039},{10,1009},{12,4094},{10,1005},{9,497},{11,2037},{11,2046},{10,1013}, {11,2044}, }; hcode16_t book05[81] = { {13,8191},{12,4087},{11,2036},{11,2024},{10,1009},{11,2030},{11,2041},{12,4088}, {13,8189},{12,4093},{11,2033},{10,1000},{9,488},{8,240},{9,492},{10,1006}, {11,2034},{12,4090},{12,4084},{10,1007},{9,498},{8,232},{7,112},{8,236}, {9,496},{10,1002},{11,2035},{11,2027},{9,491},{8,234},{5,26},{4,8}, {5,25},{8,238},{9,495},{11,2029},{10,1008},{8,242},{7,115},{4,11}, {1,0},{4,10},{7,113},{8,243},{11,2025},{11,2031},{9,494},{8,239}, {5,24},{4,9},{5,27},{8,235},{9,489},{11,2028},{11,2038},{10,1003}, {9,499},{8,237},{7,114},{8,233},{9,497},{10,1005},{11,2039},{12,4086}, {11,2032},{10,1001},{9,493},{8,241},{9,490},{10,1004},{11,2040},{12,4089}, {13,8188},{12,4092},{12,4085},{11,2026},{10,1011},{10,1010},{11,2037},{12,4091}, {13,8190}, }; hcode16_t book06[81] = { {11,2046},{10,1021},{9,497},{9,491},{9,500},{9,490},{9,496},{10,1020}, {11,2045},{10,1014},{9,485},{8,234},{7,108},{7,113},{7,104},{8,240}, {9,486},{10,1015},{9,499},{8,239},{6,50},{6,39},{6,40},{6,38}, {6,49},{8,235},{9,503},{9,488},{7,111},{6,46},{4,8},{4,4}, {4,6},{6,41},{7,107},{9,494},{9,495},{7,114},{6,45},{4,2}, {4,0},{4,3},{6,47},{7,115},{9,506},{9,487},{7,110},{6,43}, {4,7},{4,1},{4,5},{6,44},{7,109},{9,492},{9,505},{8,238}, {6,48},{6,36},{6,42},{6,37},{6,51},{8,236},{9,498},{10,1016}, {9,484},{8,237},{7,106},{7,112},{7,105},{7,116},{8,241},{10,1018}, {11,2047},{10,1017},{9,502},{9,493},{9,504},{9,489},{9,501},{10,1019}, {11,2044}, }; hcode16_t book07[64] = { {1,0},{3,5},{6,55},{7,116},{8,242},{9,491},{10,1005},{11,2039}, {3,4},{4,12},{6,53},{7,113},{8,236},{8,238},{9,494},{9,501}, {6,54},{6,52},{7,114},{8,234},{8,241},{9,489},{9,499},{10,1013}, {7,115},{7,112},{8,235},{8,240},{9,497},{9,496},{10,1004},{10,1018}, {8,243},{8,237},{9,488},{9,495},{10,1007},{10,1009},{10,1017},{11,2043}, {9,493},{8,239},{9,490},{9,498},{10,1011},{10,1016},{11,2041},{11,2044}, {10,1006},{9,492},{9,500},{10,1012},{10,1015},{11,2040},{12,4093},{12,4094}, {11,2038},{10,1008},{10,1010},{10,1014},{11,2042},{11,2045},{12,4092},{12,4095}, }; hcode16_t book08[64] = { {5,14},{4,5},{5,16},{6,48},{7,111},{8,241},{9,506},{10,1022}, {4,3},{3,0},{4,4},{5,18},{6,44},{7,106},{7,117},{8,248}, {5,15},{4,2},{4,6},{5,20},{6,46},{7,105},{7,114},{8,245}, {6,47},{5,17},{5,19},{6,42},{6,50},{7,108},{8,236},{8,250}, {7,113},{6,43},{6,45},{6,49},{7,109},{7,112},{8,242},{9,505}, {8,239},{7,104},{6,51},{7,107},{7,110},{8,238},{8,249},{10,1020}, {9,504},{7,116},{7,115},{8,237},{8,240},{8,246},{9,502},{9,509}, {10,1021},{8,243},{8,244},{8,247},{9,503},{9,507},{9,508},{10,1023}, }; hcode16_t book09[169] = { {1,0},{3,5},{6,55},{8,231},{9,478},{10,974},{10,985},{11,1992}, {11,1997},{12,4040},{12,4061},{13,8164},{13,8172},{3,4},{4,12},{6,53}, {7,114},{8,234},{8,237},{9,482},{10,977},{10,979},{10,992},{11,2008}, {12,4047},{12,4053},{6,54},{6,52},{7,113},{8,232},{8,236},{9,481}, {10,975},{10,989},{10,987},{11,2000},{12,4039},{12,4052},{12,4068},{8,230}, {7,112},{8,233},{9,477},{9,483},{10,978},{10,988},{11,1996},{11,1994}, {11,2014},{12,4056},{12,4074},{13,8155},{9,479},{8,235},{9,476},{9,486}, {10,981},{10,990},{11,1995},{11,2013},{11,2012},{12,4045},{12,4066},{12,4071}, {13,8161},{10,976},{9,480},{9,484},{10,982},{11,1989},{11,2001},{11,2011}, {12,4050},{11,2016},{12,4057},{12,4075},{13,8163},{13,8169},{11,1988},{9,485}, {10,983},{11,1990},{11,1999},{11,2010},{12,4043},{12,4058},{12,4067},{12,4073}, {13,8166},{13,8179},{13,8183},{11,2003},{10,984},{10,993},{11,2004},{11,2009}, {12,4051},{12,4062},{13,8157},{13,8153},{13,8162},{13,8170},{13,8177},{13,8182}, {11,2002},{10,980},{10,986},{11,1991},{11,2007},{11,2018},{12,4046},{12,4059}, {13,8152},{13,8174},{14,16368},{13,8180},{14,16370},{11,2017},{10,991},{11,1993}, {11,2006},{12,4042},{12,4048},{12,4069},{12,4070},{13,8171},{13,8175},{14,16371}, {14,16372},{14,16373},{12,4064},{11,1998},{11,2005},{12,4038},{12,4049},{12,4065}, {13,8160},{13,8168},{13,8176},{14,16369},{14,16376},{14,16374},{15,32764},{12,4072}, {11,2015},{12,4041},{12,4055},{12,4060},{13,8156},{13,8159},{13,8173},{13,8181}, {14,16377},{14,16379},{15,32765},{15,32766},{13,8167},{12,4044},{12,4054},{12,4063}, {13,8158},{13,8154},{13,8165},{13,8178},{14,16378},{14,16375},{14,16380},{14,16381}, {15,32767}, }; hcode16_t book10[169] = { {6,34},{5,8},{6,29},{6,38},{7,95},{8,211},{9,463},{10,976}, {10,983},{10,1005},{11,2032},{11,2038},{12,4093},{5,7},{4,0},{4,1}, {5,9},{6,32},{7,84},{7,96},{8,213},{8,220},{9,468},{10,973}, {10,990},{11,2023},{6,28},{4,2},{5,6},{5,12},{6,30},{6,40}, {7,91},{8,205},{8,217},{9,462},{9,476},{10,985},{10,1009},{6,37}, {5,11},{5,10},{5,13},{6,36},{7,87},{7,97},{8,204},{8,221}, {9,460},{9,478},{10,979},{10,999},{7,93},{6,33},{6,31},{6,35}, {6,39},{7,89},{7,100},{8,216},{8,223},{9,466},{9,482},{10,989}, {10,1006},{8,209},{7,85},{6,41},{7,86},{7,88},{7,98},{8,206}, {8,224},{8,226},{9,474},{10,980},{10,995},{11,2027},{9,457},{7,94}, {7,90},{7,92},{7,99},{8,202},{8,218},{9,455},{9,458},{9,480}, {10,987},{10,1000},{11,2028},{9,483},{8,210},{8,203},{8,208},{8,215}, {8,219},{9,454},{9,469},{9,472},{10,970},{10,986},{11,2026},{11,2033}, {9,481},{8,212},{8,207},{8,214},{8,222},{8,225},{9,464},{9,470}, {10,977},{10,981},{10,1010},{11,2030},{11,2043},{10,1001},{9,461},{9,456}, {9,459},{9,465},{9,471},{9,479},{10,975},{10,992},{10,1007},{11,2022}, {11,2040},{12,4090},{10,1003},{9,477},{9,467},{9,473},{9,475},{10,978}, {10,972},{10,988},{10,1002},{11,2029},{11,2035},{11,2041},{12,4089},{11,2034}, {10,974},{9,484},{10,971},{10,984},{10,982},{10,994},{10,997},{11,2024}, {11,2036},{11,2037},{11,2039},{12,4091},{11,2042},{10,1004},{10,991},{10,993}, {10,996},{10,998},{10,1008},{11,2025},{11,2031},{12,4088},{12,4094},{12,4092}, {12,4095}, }; hcode16_t book11[289] = { {4,0},{5,6},{6,25},{7,61},{8,156},{8,198},{9,423},{10,912}, {10,962},{10,991},{11,2022},{11,2035},{12,4091},{11,2028},{12,4090},{12,4094}, {10,910},{5,5},{4,1},{5,8},{6,20},{7,55},{7,66},{8,146}, {8,175},{9,401},{9,421},{9,437},{10,926},{10,960},{10,930},{10,973}, {11,2006},{8,174},{6,23},{5,7},{5,9},{6,24},{7,57},{7,64}, {8,142},{8,163},{8,184},{9,409},{9,428},{9,449},{10,945},{10,918}, {10,958},{10,970},{8,157},{7,60},{6,21},{6,22},{6,26},{7,59}, {7,68},{8,145},{8,165},{8,190},{9,406},{9,430},{9,441},{10,929}, {10,913},{10,933},{10,981},{8,148},{8,154},{7,54},{7,56},{7,58}, {7,65},{8,140},{8,155},{8,176},{8,195},{9,414},{9,427},{9,444}, {10,927},{10,911},{10,937},{10,975},{8,147},{8,191},{7,62},{7,63}, {7,67},{7,69},{8,158},{8,167},{8,185},{9,404},{9,418},{9,442}, {9,451},{10,934},{10,935},{10,955},{10,980},{8,159},{9,416},{8,143}, {8,141},{8,144},{8,152},{8,166},{8,182},{8,196},{9,415},{9,431}, {9,447},{10,921},{10,959},{10,948},{10,969},{10,999},{8,168},{9,438}, {8,171},{8,164},{8,170},{8,178},{8,194},{8,197},{9,408},{9,420}, {9,440},{10,908},{10,932},{10,964},{10,966},{10,989},{10,1000},{8,173}, {10,943},{9,402},{8,189},{8,188},{9,398},{9,407},{9,410},{9,419}, {9,433},{10,909},{10,920},{10,951},{10,979},{10,977},{10,987},{11,2013}, {8,180},{10,990},{9,425},{9,411},{9,412},{9,417},{9,426},{9,429}, {9,435},{10,907},{10,946},{10,952},{10,974},{10,993},{10,992},{11,2002}, {11,2021},{8,183},{11,2019},{9,443},{9,424},{9,422},{9,432},{9,434}, {9,439},{10,923},{10,922},{10,954},{10,949},{10,982},{11,2007},{10,996}, {11,2008},{11,2026},{8,186},{11,2024},{10,928},{9,445},{9,436},{10,906}, {9,452},{10,914},{10,938},{10,944},{10,956},{10,983},{11,2004},{11,2012}, {11,2011},{11,2005},{11,2032},{8,193},{11,2043},{10,968},{10,931},{10,917}, {10,925},{10,940},{10,942},{10,965},{10,984},{10,994},{10,998},{11,2020}, {11,2023},{11,2016},{11,2025},{11,2039},{9,400},{11,2034},{10,915},{9,446}, {9,448},{10,916},{10,919},{10,941},{10,963},{10,961},{10,978},{11,2010}, {11,2009},{11,2015},{11,2027},{11,2036},{11,2042},{9,405},{11,2040},{10,957}, {10,924},{10,939},{10,936},{10,947},{10,953},{10,976},{10,995},{10,997}, {11,2018},{11,2014},{11,2029},{11,2033},{11,2041},{11,2044},{9,403},{12,4093}, {10,988},{10,950},{10,967},{10,972},{10,971},{10,985},{10,986},{11,2003}, {11,2017},{11,2030},{11,2031},{11,2037},{11,2038},{12,4092},{12,4095},{9,413}, {9,450},{8,181},{8,161},{8,150},{8,151},{8,149},{8,153},{8,160}, {8,162},{8,172},{8,169},{8,177},{8,179},{8,187},{8,192},{9,399}, {5,4}, }; hcode32_t book12[2 * SF_DELTA + 1] = { {18,262120},{18,262118},{18,262119},{18,262117},{19,524277},{19,524273},{19,524269},{19,524278}, {19,524270},{19,524271},{19,524272},{19,524284},{19,524285},{19,524287},{19,524286},{19,524279}, {19,524280},{19,524283},{19,524281},{18,262116},{19,524282},{18,262115},{17,131055},{17,131056}, {16,65525},{17,131054},{16,65522},{16,65523},{16,65524},{16,65521},{15,32758},{15,32759}, {14,16377},{14,16373},{14,16375},{14,16371},{14,16374},{14,16370},{13,8183},{13,8181}, {12,4089},{12,4087},{12,4086},{11,2041},{12,4084},{11,2040},{10,1017},{10,1015}, {10,1013},{9,504},{9,503},{8,250},{8,248},{8,246},{7,121},{6,58}, {6,56},{5,26},{4,11},{3,4},{1,0},{4,10},{4,12},{5,27}, {6,57},{6,59},{7,120},{7,122},{8,247},{8,249},{9,502},{9,505}, {10,1012},{10,1014},{10,1016},{11,2037},{11,2036},{11,2038},{11,2039},{12,4085}, {12,4088},{13,8180},{13,8182},{13,8184},{14,16376},{14,16372},{16,65520},{15,32756}, {16,65526},{15,32757},{18,262114},{19,524249},{19,524250},{19,524251},{19,524252},{19,524253}, {19,524254},{19,524248},{19,524242},{19,524243},{19,524244},{19,524245},{19,524246},{19,524274}, {19,524255},{19,524263},{19,524264},{19,524265},{19,524266},{19,524267},{19,524262},{19,524256}, {19,524257},{19,524258},{19,524259},{19,524260},{19,524261},{19,524247},{19,524268},{19,524276}, {19,524275}, }; knik0-faac-79329ef/libfaac/huffdata.h000066400000000000000000000027101517010422400173000ustar00rootroot00000000000000/**************************************************************************** Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #ifndef HUFFDATA_H #define HUFFDATA_H #include "huff2.h" #include typedef struct { const uint16_t len; const uint16_t data; } hcode16_t; typedef struct { const uint32_t len; const uint32_t data; } hcode32_t; extern hcode16_t book01[81]; extern hcode16_t book02[81]; extern hcode16_t book03[81]; extern hcode16_t book04[81]; extern hcode16_t book05[81]; extern hcode16_t book06[81]; extern hcode16_t book07[64]; extern hcode16_t book08[64]; extern hcode16_t book09[169]; extern hcode16_t book10[169]; extern hcode16_t book11[289]; extern hcode32_t book12[2 * SF_DELTA + 1]; #endif /* HUFFDATA_H */ knik0-faac-79329ef/libfaac/libfaac.def000066400000000000000000000004151517010422400174060ustar00rootroot00000000000000EXPORTS ; ; libfaac exports ; faacEncOpen @1 faacEncGetCurrentConfiguration @2 faacEncSetConfiguration @3 faacEncEncode @4 faacEncClose @5 faacEncGetDecoderSpecificInfo @6 faacEncGetVersion @7 knik0-faac-79329ef/libfaac/meson.build000066400000000000000000000027741517010422400175210ustar00rootroot00000000000000link_args = [] if host_machine.system() == 'windows' and meson.get_compiler('c').get_id() == 'gcc' # identifies mingw link_args += '-Wl,--add-stdcall-alias' endif quantize_simd_libs = [] if config_h.get('HAVE_SSE2') sse2_flag = (cc.get_argument_syntax() == 'msvc') ? ['/arch:SSE2'] : ['-msse2'] quantize_sse = static_library('quantize_sse', 'quantize_sse.c', include_directories: ['..', '../include'], c_args: c_args + sse2_flag, gnu_symbol_visibility: 'hidden' ) quantize_simd_libs += quantize_sse endif common_src = [ 'bitstream.c', 'bitstream.h', 'blockswitch.c', 'blockswitch.h', 'channels.c', 'channels.h', 'coder.h', 'cpu_compute.c', 'cpu_compute.h', 'filtbank.c', 'filtbank.h', 'fft.c', 'fft.h', 'frame.c', 'frame.h', 'huff2.c', 'huff2.h', 'huffdata.c', 'huffdata.h', 'quantize.c', 'quantize.h', 'stereo.c', 'stereo.h', 'tns.c', 'tns.h', 'util.c', 'util.h', ] libfaac = library('faac', common_src, include_directories: ['..', '../include'], c_args: c_args, link_args: link_args, dependencies: [ libm ], link_with: quantize_simd_libs, vs_module_defs: 'libfaac.def', install: true, version: '0.0.0', gnu_symbol_visibility: 'hidden' ) pkgconfig = import('pkgconfig') pkgconfig.generate( libfaac, name: 'FAAC', description: 'Freeware Advanced Audio Coder', version: meson.project_version(), filebase: 'faac' ) knik0-faac-79329ef/libfaac/quantize.c000066400000000000000000000347111517010422400173570ustar00rootroot00000000000000/**************************************************************************** Quantizer core functions quality setting, error distribution, etc. Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #include #include #include #include #include #include "quantize.h" #include "huff2.h" #include "cpu_compute.h" #ifdef __GNUC__ #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #endif typedef void (*QuantizeFunc)(const faac_real * __restrict xr, int * __restrict xi, int n, faac_real sfacfix); #if defined(HAVE_SSE2) extern void quantize_sse2(const faac_real * __restrict xr, int * __restrict xi, int n, faac_real sfacfix); #endif static void quantize_scalar(const faac_real * __restrict xr, int * __restrict xi, int n, faac_real sfacfix) { const faac_real magic = MAGIC_NUMBER; int cnt; for (cnt = 0; cnt < n; cnt++) { faac_real val = xr[cnt]; faac_real tmp = FAAC_FABS(val); tmp *= sfacfix; tmp = FAAC_SQRT(tmp * FAAC_SQRT(tmp)); int q = (int)(tmp + magic); xi[cnt] = (val < 0) ? -q : q; } } static QuantizeFunc qfunc = quantize_scalar; static faac_real sfstep; static faac_real max_quant_limit; /* Sentinel: delta chain has no previous band yet (first active regular band). */ #define SF_CHAIN_UNSET INT_MIN void QuantizeInit(void) { #if defined(HAVE_SSE2) CPUCaps caps = get_cpu_caps(); if (caps & CPU_CAP_SSE2) qfunc = quantize_sse2; else #endif qfunc = quantize_scalar; /* 2^0.25 (1.50515 dB) step from AAC specs */ sfstep = 1.0 / FAAC_LOG10(FAAC_SQRT(FAAC_SQRT(2.0))); /* Inverse-quantizer headroom: ensures (x * gain)^0.75 + 0.4054 <= 8191. * Pre-calculated to avoid redundant runtime power functions. */ max_quant_limit = FAAC_POW((faac_real)MAX_HUFF_ESC_VAL + 1.0 - MAGIC_NUMBER, 4.0/3.0); } /* Compute gain from integer sfac, clamping against Huffman overflow. * Updates *sfac if clamping was applied. Returns the usable gain. */ static faac_real gain_with_overflow_clamp(int *sfac, faac_real band_peak) { faac_real gain = FAAC_POW(10, *sfac / sfstep); if (band_peak > 0.0 && gain * band_peak > max_quant_limit) { gain = max_quant_limit / band_peak; *sfac = (int)FAAC_FLOOR(FAAC_LOG10(gain) * sfstep); gain = FAAC_POW(10, *sfac / sfstep); } return gain; } #define NOISEFLOOR 0.4 // band sound masking static void bmask(CoderInfo * __restrict coderInfo, faac_real * __restrict xr0, faac_real * __restrict bandqual, faac_real * __restrict bandenrg, faac_real * __restrict bandmaxe, int gnum, faac_real quality) { int sfb, start, end, cnt; int *cb_offset = coderInfo->sfb_offset; int last; faac_real avgenrg; faac_real powm = 0.4; faac_real totenrg = 0.0; int gsize = coderInfo->groups.len[gnum]; const faac_real *xr; int win; int enrgcnt = 0; int total_len = coderInfo->sfb_offset[coderInfo->sfbn]; for (win = 0; win < gsize; win++) { xr = xr0 + win * BLOCK_LEN_SHORT; for (cnt = 0; cnt < total_len; cnt++) { totenrg += xr[cnt] * xr[cnt]; } } enrgcnt = gsize * total_len; if (totenrg < ((NOISEFLOOR * NOISEFLOOR) * (faac_real)enrgcnt)) { for (sfb = 0; sfb < coderInfo->sfbn; sfb++) { bandqual[sfb] = 0.0; bandenrg[sfb] = 0.0; } return; } for (sfb = 0; sfb < coderInfo->sfbn; sfb++) { faac_real avge, maxe; faac_real target; start = cb_offset[sfb]; end = cb_offset[sfb + 1]; avge = 0.0; maxe = 0.0; for (win = 0; win < gsize; win++) { xr = xr0 + win * BLOCK_LEN_SHORT + start; int n = end - start; for (cnt = 0; cnt < n; cnt++) { faac_real val = xr[cnt]; faac_real e = val * val; avge += e; if (maxe < e) maxe = e; } } bandenrg[sfb] = avge; /* Track peak magnitude to identify potential Huffman overflows. */ bandmaxe[sfb] = FAAC_SQRT(maxe); maxe *= gsize; #define NOISETONE 0.2 if (coderInfo->block_type == ONLY_SHORT_WINDOW) { last = BLOCK_LEN_SHORT; avgenrg = totenrg / last; avgenrg *= end - start; target = NOISETONE * FAAC_POW(avge/avgenrg, powm); target += (1.0 - NOISETONE) * 0.45 * FAAC_POW(maxe/avgenrg, powm); target *= 1.5; } else { last = BLOCK_LEN_LONG; avgenrg = totenrg / last; avgenrg *= end - start; target = NOISETONE * FAAC_POW(avge/avgenrg, powm); target += (1.0 - NOISETONE) * 0.45 * FAAC_POW(maxe/avgenrg, powm); } target *= 10.0 / (1.0 + ((faac_real)(start+end)/last)); bandqual[sfb] = target * quality; } } enum {MAXSHORTBAND = 36}; // use band quality levels to quantize a group of windows static void qlevel(CoderInfo * __restrict coderInfo, const faac_real * __restrict xr0, const faac_real * __restrict bandqual, const faac_real * __restrict bandenrg, const faac_real * __restrict bandmaxe, int gnum, int pnslevel, int *p_last_abs /* previous active band's absolute stored scalefactor */ ) { int sb; int gsize = coderInfo->groups.len[gnum]; faac_real pnsthr = 0.1 * pnslevel; for (sb = 0; sb < coderInfo->sfbn && coderInfo->bandcnt < MAX_SCFAC_BANDS; sb++) { faac_real sfacfix; int sfac; int sf_rel; /* relative scalefactor index: SF_OFFSET - sfac */ faac_real rmsx; faac_real etot; int xitab[8 * MAXSHORTBAND]; int *xi; int start, end; const faac_real *xr; int win; if (coderInfo->book[coderInfo->bandcnt] != HCB_NONE) { coderInfo->bandcnt++; continue; } start = coderInfo->sfb_offset[sb]; end = coderInfo->sfb_offset[sb+1]; etot = bandenrg[sb] / (faac_real)gsize; rmsx = FAAC_SQRT(etot / (end - start)); if ((rmsx < NOISEFLOOR) || (!bandqual[sb])) { coderInfo->book[coderInfo->bandcnt++] = HCB_ZERO; continue; } if (bandqual[sb] < pnsthr) { coderInfo->book[coderInfo->bandcnt] = HCB_PNS; coderInfo->sf[coderInfo->bandcnt] += FAAC_LRINT(FAAC_LOG10(etot) * (0.5 * sfstep)); coderInfo->bandcnt++; continue; } sfac = FAAC_LRINT(FAAC_LOG10(bandqual[sb] / rmsx) * sfstep); sf_rel = SF_OFFSET - sfac; /* sf_bias: IS intensity stereo energy offset pre-loaded into sf[] by * AACstereo() before qlevel() runs; zero for regular bands. * sf_abs = sf_bias + sf_rel is the value written to the bitstream. * Delta chain comparisons must use sf_abs, not sf_rel alone. */ int sf_bias = coderInfo->sf[coderInfo->bandcnt]; int sf_abs = sf_bias + sf_rel; if (sf_rel < SF_MIN) { sfacfix = 0.0; } else { /* Compute gain and clamp against Huffman overflow. */ sfacfix = gain_with_overflow_clamp(&sfac, bandmaxe[sb]); sf_rel = SF_OFFSET - sfac; sf_abs = sf_bias + sf_rel; /* Pre-clamp: enforce delta limits against the previous band's stored * value so encoder and decoder use the same gain (sf_abs). */ if (*p_last_abs != SF_CHAIN_UNSET) { int diff = sf_abs - *p_last_abs; int clamped_diff = clamp_sf_diff(diff); if (clamped_diff != diff) { sf_abs = *p_last_abs + clamped_diff; sf_rel = sf_abs - sf_bias; sfac = SF_OFFSET - sf_rel; if (clamped_diff > 0) { /* Upward clamp raised gain; re-check Huffman overflow. */ sfacfix = gain_with_overflow_clamp(&sfac, bandmaxe[sb]); sf_rel = SF_OFFSET - sfac; sf_abs = sf_bias + sf_rel; } else { /* Downward clamp lowered gain; overflow impossible. */ sfacfix = FAAC_POW(10, sfac / sfstep); } } } } end -= start; xi = xitab; if (sfacfix <= 0.0) { memset(xi, 0, gsize * end * sizeof(int)); } else { for (win = 0; win < gsize; win++) { xr = xr0 + win * BLOCK_LEN_SHORT + start; qfunc(xr, xi, end, sfacfix); xi += end; } } huffbook(coderInfo, xitab, gsize * end); /* Track sf_abs (full bitstream value) for the next band's delta check. * HCB_ZERO bands don't participate in the regular-band delta chain. */ if (coderInfo->book[coderInfo->bandcnt] != HCB_ZERO) *p_last_abs = sf_abs; coderInfo->sf[coderInfo->bandcnt++] += sf_rel; } } int BlocQuant(CoderInfo * __restrict coder, faac_real * __restrict xr, AACQuantCfg *aacquantCfg) { faac_real bandlvl[MAX_SCFAC_BANDS]; faac_real bandenrg[MAX_SCFAC_BANDS]; faac_real bandmaxe[MAX_SCFAC_BANDS]; int cnt; faac_real *gxr; coder->global_gain = 0; coder->bandcnt = 0; coder->datacnt = 0; int lastsf = SF_CHAIN_UNSET; /* no previous band yet; first active band skips delta clamp */ gxr = xr; for (cnt = 0; cnt < coder->groups.n; cnt++) { bmask(coder, gxr, bandlvl, bandenrg, bandmaxe, cnt, (faac_real)aacquantCfg->quality/DEFQUAL); qlevel(coder, gxr, bandlvl, bandenrg, bandmaxe, cnt, aacquantCfg->pnslevel, &lastsf); gxr += coder->groups.len[cnt] * BLOCK_LEN_SHORT; } coder->global_gain = 0; for (cnt = 0; cnt < coder->bandcnt; cnt++) { int book = coder->book[cnt]; if (!book) continue; if ((book != HCB_INTENSITY) && (book != HCB_INTENSITY2)) { coder->global_gain = coder->sf[cnt]; break; } } int lastis = 0; int lastpns = coder->global_gain - SF_PNS_OFFSET; for (cnt = 0; cnt < coder->bandcnt; cnt++) { int book = coder->book[cnt]; if ((book == HCB_INTENSITY) || (book == HCB_INTENSITY2)) { int diff = coder->sf[cnt] - lastis; diff = clamp_sf_diff(diff); lastis += diff; coder->sf[cnt] = lastis; } else if (book == HCB_PNS) { int diff = coder->sf[cnt] - lastpns; diff = clamp_sf_diff(diff); lastpns += diff; coder->sf[cnt] = lastpns; } } return 1; } void CalcBW(unsigned *bw, int rate, SR_INFO *sr, AACQuantCfg *aacquantCfg) { // find max short frame band int max = *bw * (BLOCK_LEN_SHORT << 1) / rate; int cnt; int l; l = 0; for (cnt = 0; cnt < sr->num_cb_short; cnt++) { if (l >= max) break; l += sr->cb_width_short[cnt]; } aacquantCfg->max_cbs = cnt; if (aacquantCfg->pnslevel) *bw = (faac_real)l * rate / (BLOCK_LEN_SHORT << 1); // find max long frame band max = *bw * (BLOCK_LEN_LONG << 1) / rate; l = 0; for (cnt = 0; cnt < sr->num_cb_long; cnt++) { if (l >= max) break; l += sr->cb_width_long[cnt]; } aacquantCfg->max_cbl = cnt; aacquantCfg->max_l = l; *bw = (faac_real)l * rate / (BLOCK_LEN_LONG << 1); } enum {MINSFB = 2}; static void calce(faac_real * __restrict xr, const int * __restrict bands, faac_real e[NSFB_SHORT], int maxsfb, int maxl) { int sfb; int l; // mute lines above cutoff freq for (l = maxl; l < bands[maxsfb]; l++) xr[l] = 0.0; for (sfb = MINSFB; sfb < maxsfb; sfb++) { e[sfb] = 0; for (l = bands[sfb]; l < bands[sfb + 1]; l++) e[sfb] += xr[l] * xr[l]; } } static void resete(faac_real min[NSFB_SHORT], faac_real max[NSFB_SHORT], faac_real e[NSFB_SHORT], int maxsfb) { int sfb; for (sfb = MINSFB; sfb < maxsfb; sfb++) min[sfb] = max[sfb] = e[sfb]; } #define PRINTSTAT 0 #if PRINTSTAT static int groups = 0; static int frames = 0; #endif void BlocGroup(faac_real *xr, CoderInfo *coderInfo, AACQuantCfg *cfg) { int win, sfb; faac_real e[NSFB_SHORT]; faac_real min[NSFB_SHORT]; faac_real max[NSFB_SHORT]; const faac_real thr = 3.0; int win0; int fastmin; int maxsfb, maxl; if (coderInfo->block_type != ONLY_SHORT_WINDOW) { coderInfo->groups.n = 1; coderInfo->groups.len[0] = 1; return; } maxl = cfg->max_l / 8; maxsfb = cfg->max_cbs; fastmin = ((maxsfb - MINSFB) * 3) >> 2; #if PRINTSTAT frames++; #endif calce(xr, coderInfo->sfb_offset, e, maxsfb, maxl); resete(min, max, e, maxsfb); win0 = 0; coderInfo->groups.n = 0; for (win = 1; win < MAX_SHORT_WINDOWS; win++) { int fast = 0; calce(xr + win * BLOCK_LEN_SHORT, coderInfo->sfb_offset, e, maxsfb, maxl); for (sfb = MINSFB; sfb < maxsfb; sfb++) { if (min[sfb] > e[sfb]) min[sfb] = e[sfb]; if (max[sfb] < e[sfb]) max[sfb] = e[sfb]; if (max[sfb] > thr * min[sfb]) fast++; } if (fast > fastmin) { coderInfo->groups.len[coderInfo->groups.n++] = win - win0; win0 = win; resete(min, max, e, maxsfb); } } coderInfo->groups.len[coderInfo->groups.n++] = win - win0; #if PRINTSTAT groups += coderInfo->groups.n; #endif } void BlocStat(void) { #if PRINTSTAT printf("frames:%d; groups:%d; g/f:%f\n", frames, groups, (faac_real)groups/frames); #endif } knik0-faac-79329ef/libfaac/quantize.h000066400000000000000000000031151517010422400173560ustar00rootroot00000000000000/**************************************************************************** Quantizer core functions quality setting, error distribution, etc. Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #ifndef QUANTIZE_H #define QUANTIZE_H #include "coder.h" #include "faac_real.h" typedef struct { faac_real quality; int max_cbl; int max_cbs; int max_l; int pnslevel; } AACQuantCfg; #ifdef FAAC_PRECISION_SINGLE #define MAGIC_NUMBER 0.4054f #else #define MAGIC_NUMBER 0.4054 #endif enum { DEFQUAL = 100, MAXQUAL = 5000, MAXQUALADTS = MAXQUAL, MINQUAL = 10, }; int BlocQuant(CoderInfo *coderInfo, faac_real *xr, AACQuantCfg *aacquantCfg); void CalcBW(unsigned *bw, int rate, SR_INFO *sr, AACQuantCfg *aacquantCfg); void BlocGroup(faac_real *xr, CoderInfo *coderInfo, AACQuantCfg *aacquantCfg); void BlocStat(void); void QuantizeInit(void); #endif knik0-faac-79329ef/libfaac/quantize_sse.c000066400000000000000000000053161517010422400202300ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2026 Nils Schimmelmann * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "faac_real.h" #include "quantize.h" void quantize_sse2(const faac_real * __restrict xr, int * __restrict xi, int n, faac_real sfacfix) { const __m128 zero = _mm_setzero_ps(); const __m128 sfac = _mm_set1_ps(sfacfix); const __m128 magic = _mm_set1_ps(MAGIC_NUMBER); // Mask to strip the sign bit (0x7FFFFFFF) const __m128 abs_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF)); int cnt = 0; // Process 4 elements per iteration for (; cnt <= n - 4; cnt += 4) { #ifdef FAAC_PRECISION_SINGLE __m128 x_orig = _mm_loadu_ps((const float*)&xr[cnt]); #else // Convert 4 doubles to 4 floats via two 128-bit loads __m128 low = _mm_cvtpd_ps(_mm_loadu_pd(&xr[cnt])); __m128 high = _mm_cvtpd_ps(_mm_loadu_pd(&xr[cnt + 2])); __m128 x_orig = _mm_movelh_ps(low, high); #endif // Capture sign and Absolute value __m128 sign_mask = _mm_cmplt_ps(x_orig, zero); __m128 x = _mm_and_ps(x_orig, abs_mask); // Math: (x * sfac)^0.75 + magic // Logic: sqrt( (x*sfac) * sqrt(x*sfac) ) x = _mm_mul_ps(x, sfac); x = _mm_mul_ps(x, _mm_sqrt_ps(x)); x = _mm_sqrt_ps(x); x = _mm_add_ps(x, magic); // Convert to integer __m128i xi_vec = _mm_cvttps_epi32(x); // Bitwise Sign Fix: (val ^ mask) - mask __m128i m_int = _mm_castps_si128(sign_mask); xi_vec = _mm_sub_epi32(_mm_xor_si128(xi_vec, m_int), m_int); _mm_storeu_si128((__m128i*)&xi[cnt], xi_vec); } // Safe scalar remainder loop for widths not multiple of 4 for (; cnt < n; cnt++) { faac_real val = xr[cnt]; faac_real tmp = FAAC_FABS(val); tmp *= sfacfix; tmp = FAAC_SQRT(tmp * FAAC_SQRT(tmp)); int q = (int)(tmp + (faac_real)MAGIC_NUMBER); xi[cnt] = (val < 0) ? -q : q; } } knik0-faac-79329ef/libfaac/stereo.c000066400000000000000000000250521517010422400170160ustar00rootroot00000000000000/**************************************************************************** Intensity Stereo Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #define _USE_MATH_DEFINES #include #include "stereo.h" #include "huff2.h" static void stereo(CoderInfo *cl, CoderInfo *cr, faac_real *sl0, faac_real *sr0, int *sfcnt, int wstart, int wend, faac_real phthr ) { int sfb; int win; int sfmin; if (!phthr) return; phthr = 1.0 / phthr; if (cl->block_type == ONLY_SHORT_WINDOW) sfmin = 1; else sfmin = 8; (*sfcnt) += sfmin; for (sfb = sfmin; sfb < cl->sfbn; sfb++) { int l, start, end; faac_real sum, diff; faac_real enrgs, enrgd, enrgl, enrgr; int hcb = HCB_NONE; const faac_real step = 10/1.50515; faac_real ethr; faac_real vfix, efix; start = cl->sfb_offset[sfb]; end = cl->sfb_offset[sfb + 1]; enrgs = enrgd = enrgl = enrgr = 0.0; for (win = wstart; win < wend; win++) { faac_real *sl = sl0 + win * BLOCK_LEN_SHORT; faac_real *sr = sr0 + win * BLOCK_LEN_SHORT; for (l = start; l < end; l++) { faac_real lx = sl[l]; faac_real rx = sr[l]; sum = lx + rx; diff = lx - rx; enrgs += sum * sum; enrgd += diff * diff; enrgl += lx * lx; enrgr += rx * rx; } } ethr = FAAC_SQRT(enrgl) + FAAC_SQRT(enrgr); ethr *= ethr; ethr *= phthr; efix = enrgl + enrgr; /* Skip completely silent bands: efix==0 makes ethr==0 so IS would * trigger spuriously, and vfix=sqrt(0/0) would be NaN. */ if (efix <= 0.0) { (*sfcnt)++; continue; } if (enrgs >= ethr) { hcb = HCB_INTENSITY; vfix = FAAC_SQRT(efix / enrgs); } else if (enrgd >= ethr) { hcb = HCB_INTENSITY2; vfix = FAAC_SQRT(efix / enrgd); } if (hcb != HCB_NONE) { /* If either channel is zero its log10 ratio is -inf; FAAC_LRINT * on -inf is undefined behaviour. Skip to L/R coding instead. */ if (enrgl == 0.0 || enrgr == 0.0) { (*sfcnt)++; continue; } int sf = FAAC_LRINT(FAAC_LOG10(enrgl / efix) * step); int pan = FAAC_LRINT(FAAC_LOG10(enrgr/efix) * step) - sf; if (pan > 30) { cl->book[*sfcnt] = HCB_ZERO; (*sfcnt)++; continue; } if (pan < -30) { cr->book[*sfcnt] = HCB_ZERO; (*sfcnt)++; continue; } cl->sf[*sfcnt] = sf; cr->sf[*sfcnt] = -pan; cr->book[*sfcnt] = hcb; for (win = wstart; win < wend; win++) { faac_real *sl = sl0 + win * BLOCK_LEN_SHORT; faac_real *sr = sr0 + win * BLOCK_LEN_SHORT; for (l = start; l < end; l++) { if (hcb == HCB_INTENSITY) sum = sl[l] + sr[l]; else sum = sl[l] - sr[l]; sl[l] = sum * vfix; } } } (*sfcnt)++; } } static void midside(CoderInfo *coder, ChannelInfo *channel, faac_real *sl0, faac_real *sr0, int *sfcnt, int wstart, int wend, faac_real thrmid, faac_real thrside ) { int sfb; int win; int sfmin; if (coder->block_type == ONLY_SHORT_WINDOW) sfmin = 1; else sfmin = 8; for (sfb = 0; sfb < sfmin; sfb++) { channel->msInfo.ms_used[*sfcnt] = 0; (*sfcnt)++; } for (sfb = sfmin; sfb < coder->sfbn; sfb++) { int ms = 0; int l, start, end; faac_real sum, diff; faac_real enrgs, enrgd, enrgl, enrgr; start = coder->sfb_offset[sfb]; end = coder->sfb_offset[sfb + 1]; enrgs = enrgd = enrgl = enrgr = 0.0; for (win = wstart; win < wend; win++) { faac_real *sl = sl0 + win * BLOCK_LEN_SHORT; faac_real *sr = sr0 + win * BLOCK_LEN_SHORT; for (l = start; l < end; l++) { faac_real lx = sl[l]; faac_real rx = sr[l]; sum = 0.5 * (lx + rx); diff = 0.5 * (lx - rx); enrgs += sum * sum; enrgd += diff * diff; enrgl += lx * lx; enrgr += rx * rx; } } if ((min(enrgl, enrgr) * thrmid) >= max(enrgs, enrgd)) { enum {PH_NONE, PH_IN, PH_OUT}; int phase = PH_NONE; if ((enrgs * thrmid * 2.0) >= (enrgl + enrgr)) { ms = 1; phase = PH_IN; } else if ((enrgd * thrmid * 2.0) >= (enrgl + enrgr)) { ms = 1; phase = PH_OUT; } if (ms) { for (win = wstart; win < wend; win++) { faac_real *sl = sl0 + win * BLOCK_LEN_SHORT; faac_real *sr = sr0 + win * BLOCK_LEN_SHORT; for (l = start; l < end; l++) { if (phase == PH_IN) { sum = sl[l] + sr[l]; diff = 0; } else { sum = 0; diff = sl[l] - sr[l]; } sl[l] = 0.5 * sum; sr[l] = 0.5 * diff; } } } } if (min(enrgl, enrgr) <= (thrside * max(enrgl, enrgr))) { for (win = wstart; win < wend; win++) { faac_real *sl = sl0 + win * BLOCK_LEN_SHORT; faac_real *sr = sr0 + win * BLOCK_LEN_SHORT; for (l = start; l < end; l++) { if (enrgl < enrgr) sl[l] = 0.0; else sr[l] = 0.0; } } } channel->msInfo.ms_used[*sfcnt] = ms; (*sfcnt)++; } } void AACstereo(CoderInfo *coder, ChannelInfo *channel, faac_real *s[MAX_CHANNELS], int maxchan, faac_real quality, int mode ) { int chn; static const faac_real thr075 = 1.09 /* ~0.75dB */ - 1.0; static const faac_real thrmax = 1.25 /* ~2dB */ - 1.0; static const faac_real sidemin = 0.1; /* -20dB */ static const faac_real sidemax = 0.3; /* ~-10.5dB */ static const faac_real isthrmax = M_SQRT2 - 1.0; faac_real thrmid, thrside; faac_real isthr; thrmid = 1.0; thrside = 0.0; isthr = 1.0; switch (mode) { case JOINT_MS: thrmid = thr075 / quality; if (thrmid > thrmax) thrmid = thrmax; thrside = sidemin / quality; if (thrside > sidemax) thrside = sidemax; thrmid += 1.0; break; case JOINT_IS: isthr = 0.18 / (quality * quality); if (isthr > isthrmax) isthr = isthrmax; isthr += 1.0; break; } // convert into energy thrmid *= thrmid; thrside *= thrside; isthr *= isthr; for (chn = 0; chn < maxchan; chn++) { int group; int bookcnt = 0; CoderInfo *cp = coder + chn; if (!channel[chn].present) continue; for (group = 0; group < cp->groups.n; group++) { int band; for (band = 0; band < cp->sfbn; band++) { cp->book[bookcnt] = HCB_NONE; cp->sf[bookcnt] = 0; bookcnt++; } } } for (chn = 0; chn < maxchan; chn++) { int rch; int cnt; int group; int sfcnt = 0; int start = 0; if (!channel[chn].present) continue; if (!((channel[chn].type == ELEMENT_CPE) && (channel[chn].ch_is_left))) continue; rch = channel[chn].paired_ch; channel[chn].common_window = 0; channel[chn].msInfo.is_present = 0; channel[rch].msInfo.is_present = 0; if (coder[chn].block_type != coder[rch].block_type) continue; if (coder[chn].groups.n != coder[rch].groups.n) continue; channel[chn].common_window = 1; for (cnt = 0; cnt < coder[chn].groups.n; cnt++) if (coder[chn].groups.len[cnt] != coder[rch].groups.len[cnt]) { channel[chn].common_window = 0; goto skip; } if (mode == JOINT_MS) { channel[chn].common_window = 1; channel[chn].msInfo.is_present = 1; channel[rch].msInfo.is_present = 1; } for (group = 0; group < coder[chn].groups.n; group++) { int end = start + coder[chn].groups.len[group]; switch(mode) { case JOINT_MS: midside(coder + chn, channel + chn, s[chn], s[rch], &sfcnt, start, end, thrmid, thrside); break; case JOINT_IS: stereo(coder + chn, coder + rch, s[chn], s[rch], &sfcnt, start, end, isthr); break; } start = end; } skip:; } } knik0-faac-79329ef/libfaac/stereo.h000066400000000000000000000021511517010422400170160ustar00rootroot00000000000000/**************************************************************************** Intensity Stereo Copyright (C) 2017 Krzysztof Nikiel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ****************************************************************************/ #include "channels.h" #include "util.h" void AACstereo(CoderInfo *coder, ChannelInfo *channel, faac_real *s[MAX_CHANNELS], int maxchan, faac_real quality, int mode ); knik0-faac-79329ef/libfaac/tns.c000066400000000000000000000444401517010422400163230ustar00rootroot00000000000000/********************************************************************** This software module was originally developed by Texas Instruments and edited by in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-2 NBC/MPEG-4 Audio conforming products. The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1997. **********************************************************************/ /* * $Id: tns.c,v 1.11 2012/03/01 18:34:17 knik Exp $ */ #include #include "frame.h" #include "coder.h" #include "bitstream.h" #include "tns.h" #include "util.h" /***********************************************/ /* TNS Profile/Frequency Dependent Parameters */ /***********************************************/ /* Limit bands to > 2.0 kHz */ static unsigned short tnsMinBandNumberLong[12] = { 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 }; static unsigned short tnsMinBandNumberShort[12] = { 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 }; /**************************************/ /* Main/Low Profile TNS Parameters */ /**************************************/ static unsigned short tnsMaxBandsLongMainLow[12] = { 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 }; static unsigned short tnsMaxBandsShortMainLow[12] = { 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14 }; static unsigned short tnsMaxOrderLongMain = 20; static unsigned short tnsMaxOrderLongLow = 12; static unsigned short tnsMaxOrderShortMainLow = 7; /*************************/ /* Function prototypes */ /*************************/ static void Autocorrelation(int maxOrder, /* Maximum autocorr order */ int dataSize, /* Size of the data array */ faac_real* data, /* Data array */ faac_real* rArray); /* Autocorrelation array */ static faac_real LevinsonDurbin(int maxOrder, /* Maximum filter order */ int dataSize, /* Size of the data array */ faac_real* data, /* Data array */ faac_real* kArray); /* Reflection coeff array */ static void StepUp(int fOrder, faac_real* kArray, faac_real* aArray); static void QuantizeReflectionCoeffs(int fOrder,int coeffRes,faac_real* rArray,int* indexArray); static int TruncateCoeffs(int fOrder,faac_real threshold,faac_real* kArray); static void TnsInvFilter(int length,faac_real* spec,TnsFilterData* filter, faac_real *temp); /*****************************************************/ /* InitTns: */ /*****************************************************/ void TnsInit(faacEncStruct* hEncoder) { unsigned int channel; int fsIndex = hEncoder->sampleRateIdx; int profile = hEncoder->config.aacObjectType; for (channel = 0; channel < hEncoder->numChannels; channel++) { TnsInfo *tnsInfo = &hEncoder->coderInfo[channel].tnsInfo; switch( profile ) { case MAIN: case LTP: tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex]; tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex]; if (hEncoder->config.mpegVersion == 1) { /* MPEG2 */ tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongMain; } else { /* MPEG4 */ if (fsIndex <= 5) /* fs > 32000Hz */ tnsInfo->tnsMaxOrderLong = 12; else tnsInfo->tnsMaxOrderLong = 20; } tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow; break; case LOW : tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex]; tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex]; if (hEncoder->config.mpegVersion == 1) { /* MPEG2 */ tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongLow; } else { /* MPEG4 */ if (fsIndex <= 5) /* fs > 32000Hz */ tnsInfo->tnsMaxOrderLong = 12; else tnsInfo->tnsMaxOrderLong = 20; } tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow; break; } tnsInfo->tnsMinBandNumberLong = tnsMinBandNumberLong[fsIndex]; tnsInfo->tnsMinBandNumberShort = tnsMinBandNumberShort[fsIndex]; } } /*****************************************************/ /* TnsEncode: */ /*****************************************************/ void TnsEncode(TnsInfo* tnsInfo, /* TNS info */ int numberOfBands, /* Number of bands per window */ int maxSfb, /* max_sfb */ enum WINDOW_TYPE blockType, /* block type */ int* sfbOffsetTable, /* Scalefactor band offset table */ faac_real* spec, /* Spectral data array */ faac_real* temp) { int numberOfWindows,windowSize; int startBand,stopBand,order; /* Bands over which to apply TNS */ int lengthInBands; /* Length to filter, in bands */ int w; int startIndex,length; faac_real gain; switch( blockType ) { case ONLY_SHORT_WINDOW : /* TNS not used for short blocks currently */ tnsInfo->tnsDataPresent = 0; return; numberOfWindows = MAX_SHORT_WINDOWS; windowSize = BLOCK_LEN_SHORT; startBand = tnsInfo->tnsMinBandNumberShort; stopBand = numberOfBands; lengthInBands = stopBand-startBand; order = tnsInfo->tnsMaxOrderShort; startBand = min(startBand,tnsInfo->tnsMaxBandsShort); stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort); break; default: numberOfWindows = 1; windowSize = BLOCK_LEN_SHORT; startBand = tnsInfo->tnsMinBandNumberLong; stopBand = numberOfBands; lengthInBands = stopBand - startBand; order = tnsInfo->tnsMaxOrderLong; startBand = min(startBand,tnsInfo->tnsMaxBandsLong); stopBand = min(stopBand,tnsInfo->tnsMaxBandsLong); break; } /* Make sure that start and stop bands < maxSfb */ /* Make sure that start and stop bands >= 0 */ startBand = min(startBand,maxSfb); stopBand = min(stopBand,maxSfb); startBand = max(startBand,0); stopBand = max(stopBand,0); tnsInfo->tnsDataPresent = 0; /* default TNS not used */ /* Perform analysis and filtering for each window */ for (w=0;wwindowData[w]; TnsFilterData* tnsFilter = windowData->tnsFilter; faac_real* k = tnsFilter->kCoeffs; /* reflection coeffs */ faac_real* a = tnsFilter->aCoeffs; /* prediction coeffs */ windowData->numFilters=0; windowData->coefResolution = DEF_TNS_COEFF_RES; startIndex = w * windowSize + sfbOffsetTable[startBand]; length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand]; gain = LevinsonDurbin(order,length,&spec[startIndex],k); if (gain>DEF_TNS_GAIN_THRESH) { /* Use TNS */ int truncatedOrder; windowData->numFilters++; tnsInfo->tnsDataPresent=1; tnsFilter->direction = 0; tnsFilter->coefCompress = 0; tnsFilter->length = lengthInBands; QuantizeReflectionCoeffs(order,DEF_TNS_COEFF_RES,k,tnsFilter->index); truncatedOrder = TruncateCoeffs(order,DEF_TNS_COEFF_THRESH,k); tnsFilter->order = truncatedOrder; StepUp(truncatedOrder,k,a); /* Compute predictor coefficients */ TnsInvFilter(length,&spec[startIndex],tnsFilter,temp); /* Filter */ } } } /*****************************************************/ /* TnsEncodeFilterOnly: */ /* This is a stripped-down version of TnsEncode() */ /* which performs TNS analysis filtering only */ /*****************************************************/ void TnsEncodeFilterOnly(TnsInfo* tnsInfo, /* TNS info */ int numberOfBands, /* Number of bands per window */ int maxSfb, /* max_sfb */ enum WINDOW_TYPE blockType, /* block type */ int* sfbOffsetTable, /* Scalefactor band offset table */ faac_real* spec, /* Spectral data array */ faac_real* temp) { int numberOfWindows,windowSize; int startBand,stopBand; /* Bands over which to apply TNS */ int w; int startIndex,length; switch( blockType ) { case ONLY_SHORT_WINDOW : numberOfWindows = MAX_SHORT_WINDOWS; windowSize = BLOCK_LEN_SHORT; startBand = tnsInfo->tnsMinBandNumberShort; stopBand = numberOfBands; startBand = min(startBand,tnsInfo->tnsMaxBandsShort); stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort); break; default: numberOfWindows = 1; windowSize = BLOCK_LEN_LONG; startBand = tnsInfo->tnsMinBandNumberLong; stopBand = numberOfBands; startBand = min(startBand,tnsInfo->tnsMaxBandsLong); stopBand = min(stopBand,tnsInfo->tnsMaxBandsLong); break; } /* Make sure that start and stop bands < maxSfb */ /* Make sure that start and stop bands >= 0 */ startBand = min(startBand,maxSfb); stopBand = min(stopBand,maxSfb); startBand = max(startBand,0); stopBand = max(stopBand,0); /* Perform filtering for each window */ for(w=0;wwindowData[w]; TnsFilterData* tnsFilter = windowData->tnsFilter; startIndex = w * windowSize + sfbOffsetTable[startBand]; length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand]; if (tnsInfo->tnsDataPresent && windowData->numFilters) { /* Use TNS */ TnsInvFilter(length,&spec[startIndex],tnsFilter,temp); } } } /********************************************************/ /* TnsInvFilter: */ /* Inverse filter the given spec with specified */ /* length using the coefficients specified in filter. */ /* Not that the order and direction are specified */ /* withing the TNS_FILTER_DATA structure. */ /********************************************************/ static void TnsInvFilter(int length,faac_real* spec,TnsFilterData* filter, faac_real *temp) { int i,j,k=0; int order=filter->order; faac_real* a=filter->aCoeffs; /* Determine loop parameters for given direction */ if (filter->direction) { /* Startup, initial state is zero */ temp[length-1]=spec[length-1]; for (i=length-2;i>(length-1-order);i--) { temp[i]=spec[i]; k++; for (j=1;j<=k;j++) { spec[i]+=temp[i+j]*a[j]; } } /* Now filter the rest */ for (i=length-1-order;i>=0;i--) { temp[i]=spec[i]; for (j=1;j<=order;j++) { spec[i]+=temp[i+j]*a[j]; } } } else { /* Startup, initial state is zero */ temp[0]=spec[0]; for (i=1;i= 0; i--) { kArray[i] = (FAAC_FABS(kArray[i])>threshold) ? kArray[i] : 0.0; if (kArray[i]!=0.0) return i; } return 0; } /*****************************************************/ /* QuantizeReflectionCoeffs: */ /* Quantize the given array of reflection coeffs */ /* to the specified resolution in bits. */ /*****************************************************/ static void QuantizeReflectionCoeffs(int fOrder, int coeffRes, faac_real* kArray, int* indexArray) { faac_real iqfac,iqfac_m; int i; iqfac = ((1<<(coeffRes-1))-0.5)/(M_PI/2); iqfac_m = ((1<<(coeffRes-1))+0.5)/(M_PI/2); /* Quantize and inverse quantize */ for (i=1;i<=fOrder;i++) { indexArray[i] = (kArray[i]>=0)?(int)(0.5+(FAAC_ASIN(kArray[i])*iqfac)):(int)(-0.5+(FAAC_ASIN(kArray[i])*iqfac_m)); kArray[i] = FAAC_SIN((faac_real)indexArray[i]/((indexArray[i]>=0)?iqfac:iqfac_m)); } } /*****************************************************/ /* Autocorrelation, */ /* Compute the autocorrelation function */ /* estimate for the given data. */ /*****************************************************/ static void Autocorrelation(int maxOrder, /* Maximum autocorr order */ int dataSize, /* Size of the data array */ faac_real* data, /* Data array */ faac_real* rArray) /* Autocorrelation array */ { int order,index; for (order=0;order<=maxOrder;order++) { rArray[order]=0.0; for (index=0;index= error) { error = 0.0; break; } kTemp = -kTemp/error; kArray[order]=kTemp; aPtr[order]=kTemp; for (i=1;i #include "util.h" #include "coder.h" // FRAME_LEN /* Returns the sample rate index */ int GetSRIndex(unsigned int sampleRate) { if (92017 <= sampleRate) return 0; if (75132 <= sampleRate) return 1; if (55426 <= sampleRate) return 2; if (46009 <= sampleRate) return 3; if (37566 <= sampleRate) return 4; if (27713 <= sampleRate) return 5; if (23004 <= sampleRate) return 6; if (18783 <= sampleRate) return 7; if (13856 <= sampleRate) return 8; if (11502 <= sampleRate) return 9; if (9391 <= sampleRate) return 10; return 11; } /* Returns the maximum bitrate for that sampling frequency */ unsigned int MaxBitrate(unsigned long sampleRate) { /* max ADTS frame size 8k */ return 0x2000 * 8 * (faac_real)sampleRate/(faac_real)FRAME_LEN; } /* Returns the minimum bitrate per channel for that sampling frequency */ unsigned int MinBitrate() { return 8000; } knik0-faac-79329ef/libfaac/util.h000066400000000000000000000030451517010422400164750ustar00rootroot00000000000000/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: util.h,v 1.8 2003/12/20 04:32:48 stux Exp $ */ #ifndef UTIL_H #define UTIL_H #include "faac_real.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include #include #ifndef max #define max(a, b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* Memory functions */ #define AllocMemory(size) malloc(size) #define FreeMemory(block) free(block) #define SetMemory(block, value, size) memset(block, value, size) int GetSRIndex(unsigned int sampleRate); unsigned int MaxBitrate(unsigned long sampleRate); unsigned int MinBitrate(); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* UTIL_H */ knik0-faac-79329ef/meson.build000066400000000000000000000024111517010422400161240ustar00rootroot00000000000000project('faac', 'c', version: '1.50.0', default_options: [ 'default_library=both', 'buildtype=release', 'warning_level=1', 'c_std=gnu99,c99', 'b_lto=true' ]) add_global_arguments('-DHAVE_CONFIG_H', language: 'c') config_h = configuration_data() config_h.set_quoted('PACKAGE', meson.project_name()) config_h.set_quoted('PACKAGE_VERSION', meson.project_version()) cc = meson.get_compiler('c') foreach h: ['getopt.h', 'immintrin.h'] config_h.set('HAVE_' + h.underscorify().to_upper(), cc.has_header(h)) endforeach libm = cc.find_library('m', required: false) cpu_family = target_machine.cpu_family() config_h.set('HAVE_SSE2', (cpu_family in ['x86', 'x86_64']) and config_h.get('HAVE_IMMINTRIN_H')) if get_option('floating-point') == 'double' config_h.set('FAAC_PRECISION_DOUBLE', 1) else config_h.set('FAAC_PRECISION_SINGLE', 1) endif config_h.set('MAX_CHANNELS', get_option('max-channels')) c_args = [] if cc.get_argument_syntax() == 'msvc' c_args += ['-DWIN32', '-DNDEBUG', '-D_WINDOWS', '-D_USRDLL', '-DLIBFAAC_DLL_EXPORTS'] endif configure_file( output: 'config.h', configuration: config_h ) subdir('docs') subdir('include') subdir('libfaac') if get_option('frontend') subdir('frontend') endif knik0-faac-79329ef/meson_options.txt000066400000000000000000000005641517010422400174260ustar00rootroot00000000000000option('frontend', description: 'Build the frontend', type: 'boolean', value: true) option('floating-point', description: 'Floating point precision', type: 'combo', choices: ['single', 'double'], value: 'double') option('max-channels', description: 'Maximum number of channels', type: 'integer', min: 1, max: 8, value: 8)