Projects
Essentials
faac
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 19
View file
faac.changes
Changed
@@ -1,7 +1,7 @@ ------------------------------------------------------------------- -Thu Apr 16 12:34:56 UTC 2026 - olaf@aepfle.de +Tue Jul 7 07:07:07 UTC 2026 - olaf@aepfle.de -- Update version to 1.50 +- Update version to 2.0 See included ChangeLog for details -------------------------------------------------------------------
View file
faac.spec
Changed
@@ -16,14 +16,13 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # -%define so_name libfaac0 +%define so_name libfaac1 Name: faac -Version: 1.50 +Version: 2.0 Release: 0 Summary: Frontend for encoding MPEG2/4 AAC -# Original Code was free to use but restricted. Modifications are LGPL-2.1+ -License: SUSE-Freeware and LGPL-2.1+ +License: LGPL-2.1+ Url: https://github.com/knik0/faac Source0: %name-%version.tar Source99: baselibs.conf @@ -60,7 +59,6 @@ %meson \ -Ddefault_library=shared \ -Dfrontend=true \ - -Dfloating-point="double" \ %nil %meson_build @@ -70,7 +68,7 @@ %ldconfig_scriptlets -n %so_name %files -%doc AUTHORS ChangeLog README +%doc AUTHORS ChangeLog README.md %license COPYING %_bindir/* %_mandir/man1/faac.1%{ext_man}
View file
_service
Changed
@@ -1,7 +1,7 @@ <services> <service name="obs_scm"> <param name="filename">faac</param> - <param name="revision">79329efee51c9d3545bc4c7179b43a23fe350b6b</param> + <param name="revision">19504462aef3d444aa09b9cfcad0e2146889fb3b</param> <param name="scm">git</param> <param name="submodules">disable</param> <param name="url">https://github.com/knik0/faac.git</param>
View file
_service:obs_scm:faac-1.50.obscpio/README
Deleted
@@ -1,81 +0,0 @@ -__________ -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
View file
_service:obs_scm:faac-1.50.obscpio/include/faaccfg.h
Deleted
@@ -1,134 +0,0 @@ -/* - * 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_map64; - int pnslevel; -} faacEncConfiguration, *faacEncConfigurationPtr; - -#pragma pack(pop) - -#endif /* _FAACCFG_H_ */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/faac.pc.in
Deleted
@@ -1,11 +0,0 @@ -prefix=@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}
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/faac_real.h
Deleted
@@ -1,53 +0,0 @@ -/* - * 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 <math.h> - -#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 */
View file
_service:obs_scm:faac-1.50.obscpio/.github/workflows/master.yml -> _service:obs_scm:faac-2.0.obscpio/.github/workflows/master.yml
Changed
@@ -25,14 +25,13 @@ os: ubuntu-latest, compiler: gcc, shell: bash, - options: -Dfloating-point=double, } - { - name: Linux GCC (Single Precision), + name: Linux GCC (SBR Decimation), os: ubuntu-latest, compiler: gcc, shell: bash, - options: -Dfloating-point=single, + options: -Dsbr-decimation=4, } - { name: macOS Clang, @@ -53,13 +52,12 @@ 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 + run: sudo apt install meson - name: Install dependencies (macOS) if: runner.os == 'macOS' @@ -72,7 +70,7 @@ - name: Install dependencies (MSYS2) if: matrix.config.shell == 'msys2 {0}' - uses: msys2/setup-msys2@v2.31.0 + uses: msys2/setup-msys2@v2.32.0 with: msystem: ${{ matrix.config.msystem }} update: false @@ -91,7 +89,7 @@ with: arch: x64 - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Build (MSYS2) if: matrix.config.shell == 'msys2 {0}' @@ -128,7 +126,7 @@ sudo apt-get update sudo apt-get install cppcheck - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Run cppcheck shell: bash
View file
_service:obs_scm:faac-1.50.obscpio/COPYING -> _service:obs_scm:faac-2.0.obscpio/COPYING
Changed
@@ -1,112 +1,125 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + <https://fsf.org/> 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. +This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1. - Preamble + 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. + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. To protect your rights, we need to make restrictions that forbid -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. +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source -code. If you link 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 +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. - 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. + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others.  - Finally, 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. + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The -former contains code derived from the library, 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. +former contains code derived from the library, whereas the latter must +be combined with the library in order to run.  - GNU LIBRARY GENERAL PUBLIC LICENSE + GNU LESSER 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". + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or
View file
_service:obs_scm:faac-1.50.obscpio/ChangeLog -> _service:obs_scm:faac-2.0.obscpio/ChangeLog
Changed
@@ -1,3 +1,76 @@ +2.0 (Jul 20, 2026) + + Fabian Greffrath + * Remove obsolete pkg-config template + * Restrict LTO to the shared library only + + Orbis Security AI + * filtbank: Fix an out-of-bounds `memcpy` in `FilterBank()` that used + `FRAME_LEN` instead of `BLOCK_LEN_LONG` for the overlap buffer copies + + Nils Schimmelmann + * Harden input parsing and guard against allocation failures. + * Replace the classic `faacEnc*` C API with a new `faac_*` API in + `faac.h`: parameters supplied once to `faac_encoder_open()`, uniform + `faac_status` error reporting, resolved-property queries, and + library-owned AudioSpecificConfig. The legacy `faacEnc*` surface and + `faaccfg.h` are removed; the encoder core they exposed is now internal. + SONAME bumped to 1 (libfaac.so.1). `faac.h` now defines + `FAAC_VERSION_MAJOR`/`MINOR`/`PATCH`, tracking the SONAME, so callers + can detect the new API at compile time (`FAAC_VERSION_MAJOR >= 1`). + * frontend: Port `faac` and the Win32 GUI to the new API; this fixes the + AudioSpecificConfig memory leak on the MP4 output path. + * Add HE-AAC v1 (AAC-LC core + Spectral Band Replication) encoding via + `FAAC_OBJ_HE_AAC_V1`, or `FAAC_OBJ_AUTO`, which picks LC or HE-AAC from + the bitrate. The SBR core runs dual-rate (half-rate core, 2048-sample + frame); `faac_encoder_get_info()` reports the full output rate and frame + size so callers need no SBR-specific handling. CLI: + `--object-type lc|he-aac-v1|auto`. + * stereo: Add Mixed Mode joint stereo (`--joint 3`) as the new default: + per scale-factor band, picks IS above 5.5 kHz, M/S where channels are + correlated, or L/R otherwise. Fix a midside band-silencing bug that + produced L=R=0 on decode, guard against negative rounding before + sqrt, and keep IS available at low sample rates. + * quantize: Restore short-window masking penalty, floor masking + targets in quiet bands, drop stale tonal scaling in bmask, and keep + `global_gain` a valid regular scalefactor -- fixing energy drops, + quiet-band artifacts, and a decoder out-of-range error. + * tns: Cap TNS filter order to 12 to fix AAC-LC decoder rejections and + audio dropouts in FFmpeg/FAAD. + * Retire the never-implemented MAIN/SSR/LTP object types across + filtbank, frame, and the frontend, and collapse the single-model + psychoacoustic vtable into direct calls. + * Fix a lookahead regression that had truncated the encoder's + lookahead to an effective 1-frame delay, causing pre-echo artifacts + and broken stereo coherence; then simplify the lookahead into a + unified per-channel FIFO and energy timeline, replacing the ad hoc + sampleBuff/next*SampleBuff/overlapBuff/prevSamples buffers. + * Relicense: rewrite stereo, quantize, channels, bitstream, filtbank, + tns, huffdata, huff2, and the MP4 output code as original work under + LGPL-2.1-or-later, and drop the matching MPEG reference-code preamble + from README.md, --license, and docs/. Every source file is now free + software. Update the license header itself from GNU Library GPL to + Lesser GPL wording. + * fft: Replace the radix-2 FFT with radix-4 decimation-in-frequency as + the sole implementation and precompute MDCT twiddles, for ~18% + faster encode versus the radix-2 baseline. + * Standardize libfaac on single-precision floating point: drop the + `floating-point` Meson build option and `faac_real.h`, and use + `float`/`sinf`/`cosf`/`sqrtf` directly throughout the per-sample hot + path. One-time init-time table generators (FFT/MDCT/SBR twiddles, + window shapes, quantizer limits) keep `double` precision, where it's + free. Benchmarked MOS-neutral versus the prior double-precision path. + * blockswitch: Move short-window detection to the time domain. + * Performance passes: reuse a shared work buffer for filtbank's MDCT + scratch, and optimize TNS and stereo IS-gate hot paths. + * frame: Buffer encoder input so any input chunk size works. + * bitstream: Stop embedding the libfaac version string. + * build: Fix compiler warnings and transition to C11. + * frontend: Add a `--creation-time` flag for configurable MP4 + timestamps, vendor mingw-w64 wingetopt as a minimal-diff getopt + fallback for MSVC builds, and keep TNS off by default in the GUI to + match the CLI. + 1.50 (Apr 16, 2026) Fabian Greffrath
View file
_service:obs_scm:faac-2.0.obscpio/README.md
Added
@@ -0,0 +1,49 @@ +# <img src="frontend/faac.ico" alt="FAAC" width="48" height="48" align="top" /> Freeware Advanced Audio Coder + +FAAC is an open-source, dependency-free AAC encoder aimed at embedded and pipeline use cases where footprint and throughput matter as much as quality. + +### Key features: + +- MPEG-4 AAC-LC and HE-AAC v1 (SBR) profiles +- Sample rates from 8 kHz to 96 kHz, supporting mono up to 5.1 multichannel +- VBR and ABR rate control with a bit reservoir +- Advanced encoding tools: Dynamic block-switching, PNS, and TNS +- Flexible output options: Raw ADTS, ADIF bitstream + +## Copyrights + +FAAC is free software, licensed under the GNU Lesser General Public License (LGPL), version 2.1 or later: + +``` +FAAC - Freeware Advanced Audio Coder +Copyright (C) 1999-2001, Menno Bakker +Copyright (C) 2002-2017, Krzysztof Nikiel +Copyright (C) 2004, Dan Villiom P. Christiansen +Copyright (C) 2005-2026, Fabian Greffrath +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. +``` + +> **Important:** 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!** + +## Compiling Instructions + +1. Make sure you have recent versions of meson and ninja installed. +2. cd to FAAC source dir +3. Run: + ```bash + mkdir -p build + cd build + meson setup .. + meson install + ``` +
View file
_service:obs_scm:faac-1.50.obscpio/TODO -> _service:obs_scm:faac-2.0.obscpio/TODO
Changed
@@ -1,9 +1,7 @@ -- 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) +- optimize codebook list (section_data) via joint/DP optimization +- optimize CPE windows grouping jointly across channel pairs +- Add adaptive bit reservoir control - add PCE (Program Config Element) or 4-bit AudioSpecificConfig +- HE-AAC v1: SBR noise floor / invf mode from within-band tonality +- HE-AAC v1: Move numEnvelopes/eff_amp_res/tEnv to SBRChannel for independent borders +- HE-AAC v1: Use dedicated noise Huffman tables in write_sbr_noise
View file
_service:obs_scm:faac-1.50.obscpio/docs/faac.1 -> _service:obs_scm:faac-2.0.obscpio/docs/faac.1
Changed
@@ -1,4 +1,4 @@ -.TH FAAC 1 "2017-08-16" "1.29.5" "Free Advanced Audio Coder" +.TH FAAC 1 "2026-06-25" "1.50.0" "Free Advanced Audio Coder" .SH NAME faac \- open source MPEG-4 and MPEG-2 AAC encoder @@ -28,7 +28,7 @@ .TP * Fast .TP -* LC, Main, LTP support +* AAC-LC and HE-AAC v1 (SBR) support .SH HELP OPTIONS .TP @@ -56,6 +56,34 @@ .SH QUALITY-RELATED OPTIONS .TP +.BR --object-type\ <\fItype\fP> +Force the AAC object type: +.B lc +(Low Complexity), +.B he-aac-v1 +(High-Efficiency AAC v1, i.e. AAC-LC plus Spectral Band Replication), or +.B auto +(default), which selects LC or HE-AAC v1 from the bitrate and sample rate. +HE-AAC v1 targets low bitrates; its core is coded at half the input sample +rate and reconstructed to full rate by SBR in the decoder. +.TP +.BR --joint\ <\fImode\fP> +Joint stereo coding mode: +.B 0 +(off, independent left/right), +.B 1 +(Mid/Side), +.B 2 +(Intensity Stereo), or +.B 3 +(Mixed Mode, dynamic per-band Mid/Side and Intensity Stereo). Default is +.BR 3 . +.TP +.BR --pns\ <\fIlevel\fP> +Perceptual Noise Substitution level, 0 to 10; +.B 0 +disables PNS. +.TP .BR -q\ <\fIquality\fP> Set encoding quality. Set default variable bitrate (VBR) quality level in percent. max. 5000, min. 10. @@ -180,9 +208,6 @@ .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 @@ -190,7 +215,7 @@ Enforce block type (0 = both (default); 1 = no short; 2 = no long). .SH AUTHORS .B FAAC -was written by M. Bakker <menno@audiocoding.com>. +was written by M. Bakker. .PP .nh 2 Developed and maintained by Krzysztof Nikiel <knik@users.sourceforge.net>.
View file
_service:obs_scm:faac-1.50.obscpio/docs/faac.html -> _service:obs_scm:faac-2.0.obscpio/docs/faac.html
Changed
@@ -1,6 +1,7 @@ <html> <head> +<meta charset="utf-8"> <title> FAAC - Freeware Advanced Audio Coder </title> @@ -10,7 +11,7 @@ <h3> <center> -FAAC 1.18 beta (<a href="http://www.audiocoding.com/">www.audiocoding.com</a>) +FAAC - Freeware Advanced Audio Coder </center> </h3> <br> @@ -35,9 +36,6 @@ <h3> Usage </h3> -(More up to date info can be found at -<a href="http://www.audiocoding.com/wiki/index.php?page=FAAC"> -FAAC wiki page</a> by Hans-Jürgen Bardenhagen)<br><br> <kbd>faac options <infile> <outfile></kbd> <br><br> @@ -133,55 +131,18 @@ Copyrights </h3> FAAC - Freeware Advanced Audio Coder -(<a href="http://www.audiocoding.com/">www.audiocoding.com</a>) -<pre> - Portions Copyright © 1999,2000,2001 Menno Bakker - Portions Copyright © 2002,2003 Krzysztof Nikiel -</pre> -FAAC is based on the ISO MPEG-4 reference code. For this base code the -following license applies: -<br> -<pre> -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. -</pre> - <br> -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 is free software, licensed under the GNU Lesser General Public +License (LGPL), version 2.1 or later: <br> <pre> FAAC - Freeware Advanced Audio Coder -Copyright © 1999,2000,2001,2002,2003 <a href="#people">FAAC developers</a> +Copyright © 1999-2001, Menno Bakker +Copyright © 2002-2017, Krzysztof Nikiel +Copyright © 2004, Dan Villiom P. Christiansen +Copyright © 2005-2026, Fabian Greffrath +Copyright © 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 @@ -192,10 +153,6 @@ 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 </pre> <br> @@ -225,17 +182,17 @@ thebard<br> Ivan Dimkovic<br> Krzysztof Nikiel (knik)<br> -Janne Hyvärinen (ca5e)<br> +Janne Hyvärinen (ca5e)<br> Stuart Espey (stux)<br> Andrew Voznytsa<br> -Måns Rullgård<br> +Måns Rullgård<br> Bill May<br> <br><br> <h6> <center><i> -Copyright © 2003 <a href="http://www.audiocoding.com/">AudioCoding.com</a> +FAAC is free software, licensed under the GNU Lesser General Public License (LGPL), version 2.1 or later. <br></i></center> </h6>
View file
_service:obs_scm:faac-1.50.obscpio/docs/libfaac.html -> _service:obs_scm:faac-2.0.obscpio/docs/libfaac.html
Changed
@@ -1,6 +1,7 @@ <html> <head> +<meta charset="utf-8"> <title>FAAC - ISO/MPEG 2/4 AAC Encoder Library</title> </head> @@ -8,8 +9,7 @@ <h3> <center> -FAAC - ISO/MPEG 2/4 AAC Encoder Library version 1.0<br> -(<a href="http://www.audiocoding.com/">www.audiocoding.com</a>) +FAAC - ISO/MPEG 2/4 AAC Encoder Library </center> </h3> @@ -19,31 +19,13 @@ <menu> <li><a href="#scope">Scope</a> <li><a href="#interface">Interface description</a> - <li><a href="#usage">Usage</a> - <menu> - <li><a href="#callseq">Calling sequence</a> - </menu> - <li><a href="#funcref">Function reference</a> + <li><a href="#api">API (faac.h)</a> <menu> - <li><a href="#init">Initialization / De-initialization</a> - <menu> - <li><a href="#encopen">faacEncOpen()</a> - <li><a href="#encclose">faacEncClose()</a> - </menu> - <li><a href="#encconf">Encoder configuration</a> - <menu> - <li><a href="#getconf">faacEncGetCurrentConfiguration()</a> - <li><a href="#setconfig">faacEncSetConfiguration()</a> - </menu> - <li><a href="#encfunc">Encoding functions</a> - <menu> - <li><a href="#encenc">faacEncEncode()</a> - </menu> + <li><a href="#api-callseq">Calling sequence</a> + <li><a href="#api-errors">Error handling</a> + <li><a href="#api-funcref">Function reference</a> </menu> - <li><a href="#datastruct">Data structures reference</a> - <menu> - <li><a href="#encconfig">faacEncConfiguration</a> - </menu> + <li><a href="#porting">Porting from the legacy faacEnc* API</a> </menu> @@ -56,149 +38,183 @@ <a name="interface"> <h4>Interface description</h4> 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:<br><br> +interface for encoding MPEG2 and MPEG4 ISO AAC files. A single header file is +provided for usage in C/C++ programs:<br><br> -<b>faac.h</b>: function prototypes<br><br> +<b>faac.h</b>: the <b>faac_*</b> API — function prototypes and types.<br><br> The encoder core resides in a statically linkable library called libfaac.lib <i>(Microsoft Window</i>s) or libfaac.a <i>(UNI</i>X). There -are various example programs that show how to use the library. +are various example programs that show how to use the library.<br><br> -<a name="usage"> -<h4>Usage</h4> +<a name="api"> +<h4>API (faac.h)</h4> -<a name="callseq"> -<h4>Calling sequence</h4> - -For encoding AAC bitstreams the following calling sequence is -mandatory:<br> +The API supplies all encoder parameters once, up front, to +<i>faac_encoder_open()</i>. The encoder therefore never exists in a +half-configured state, and every derived quantity (frame size, output-buffer +bound, effective sample rate, resolved object type) is known and queryable the +instant open returns. Every fallible call returns a <i>faac_status</i> code; +fixed-width integer types and width-pinned enums keep the ABI identical across +platforms. +<a name="api-callseq"> +<h5>Calling sequence</h5> <menu> -<li>Call <i>faacEncOpen()</i> - for every encoder instance you need. -<li>To set encoder options, call <i>faacEncGetCurrentConfiguration()</i>, - change the parameters in the structure accessible by the returned pointer - and then call <i>faacEncSetConfiguration()</i>. -<li>As long as there are still samples left to encode, call - <i>faacEncEncode()</i> - to encode the data. - The encoder returns - the bitstream data in a client-supplied buffer. -<li> - Once you call - <i>faacEncEncode()</i> - with zero samples of input - the flushing process is initiated; afterwards you may call - <i>faacEncEncode()</i> - with zero samples input only.<br> - <i>faacEncEncode()</i> will continue to write out data until all audio - samples have been encoded. -<li> - Once - <i>faacEncEncode()</i> - has returned with zero bytes written, - call <i>faacEncClose()</i> - to destroy this encoder instance. +<li>Zero-initialize a <i>faac_params</i> with <i>faac_params_init()</i>. This is + mandatory — it stamps <i>struct_size</i> and clears padding, which is how + the struct stays compatible as it grows in future releases. +<li>Set the fields you care about (at minimum <i>sample_rate</i> and + <i>num_channels</i>), then call <i>faac_encoder_open()</i>. +<li>Fill a <i>faac_encoder_info</i> with <i>faac_encoder_get_info()</i> (set its + <i>struct_size</i> first) and size your buffers from it: input PCM holds + <i>info.frame_samples</i> × <i>num_channels</i> samples; the output buffer + must be at least <i>info.max_output_bytes</i>. The same struct also reports the + resolved sample rate, object type, and rate-control settings. If you write a + raw stream, fetch the AudioSpecificConfig with <i>faac_encoder_asc()</i> + (library-owned — do <b>not</b> free it). +<li>Call <i>faac_encoder_encode()</i> for each block of input; it emits at most + one frame per call and reports the byte count via an out-parameter. +<li>Pass <i>in_samples</i> == 0 to flush; keep calling until + <i>bytes_written</i> is 0. +<li>Call <i>faac_encoder_close()</i>, passing the address of your handle; it is + set to NULL on success. </menu> -<a name="funcref"> -<h4>Function reference</h4> - -<a name="init"> -<h4>Initialization / De-initialization</h4> - -<a name="encopen"> -<h5><i>faacEncOpen()</i></h5> - -<pre> -<b>Prototype</b> -faacEncHandle FAACAPI faacEncOpen -( -unsigned long sampleRate, -unsigned int numChannels, -unsigned long *inputSamples, -unsigned long *maxOutputBytes -); -<b>Description</b> -Open and initialize one instance of the encoder. -<b>Parameters</b> -<li><i>sampleRate</i> - The samplerate of the encoder input data. -<li><i>numChannels</i> - The number of channels of the encoder input data. -<li><i>inputSamples</i> - Receives the total number of samples that should be fed to - faacEncEncode() in each call. -<li><i>maxOutputBytes</i> - Receives the maximum number of bytes that can be in the - output buffer after a call to faacEncEncode(). -<b>Return value</b> -An initialized encoder handle. If anything goes wrong NULL is returned. -</pre> - -<a name="encclose"> -<h5><i>faacEncClose()</i></h5> +<a name="api-errors"> +<h5>Error handling</h5> +Every fallible entry point returns a <i>faac_status</i>. <i>FAAC_OK</i> is 0 and +all error codes are negative, so <code>status < 0</code> tests for failure. +<i>faac_strerror()</i> maps any status to a static human-readable string (never +NULL). Notable codes: <i>FAAC_ERR_INVALID_ARGUMENT</i> (NULL, bad +<i>struct_size</i>, or an out-of-range field), <i>FAAC_ERR_UNSUPPORTED</i> (an +object type this build does not implement, or a request with no ASC), +<i>FAAC_ERR_OUTPUT_TOO_SMALL</i>, and <i>FAAC_ERR_INPUT_OVERFLOW</i>. + +<a name="api-funcref"> +<h5>Function reference</h5> <pre> -<b>Prototype</b> -void FAACAPI faacEncClose -( -faacEncHandle hEncoder -); -<b>Description</b> -Closes an encoder instance. -<b>Parameters</b> -<li>hEncoder - An encoder handle returned by faacEncOpen(). -</pre>
View file
_service:obs_scm:faac-1.50.obscpio/frontend/faacgui.rc -> _service:obs_scm:faac-2.0.obscpio/frontend/faacgui.rc
Changed
@@ -52,8 +52,8 @@ // Dialog // -IDD_MAINDIALOG DIALOGEX 0, 0, 264, 190 -STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | +IDD_MAINDIALOG DIALOGEX 0, 0, 264, 200 +STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "FAAC GUI" FONT 8, "MS Sans Serif" @@ -62,8 +62,8 @@ 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 + COMBOBOX IDC_JOINTMODE,14,126,71,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Joint Stereo",IDC_STATIC,14,117,56,8 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 @@ -71,12 +71,12 @@ | 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 + DEFPUSHBUTTON "Encode",IDOK,200,162,50,14,WS_DISABLED + PUSHBUTTON "Quit",IDCANCEL,200,180,50,14 + LTEXT "",IDC_TIME,7,161,190,20 + LTEXT "", IDC_COMPILEDATE, 20, 186, 150, 8 EDITTEXT IDC_INPUTFILENAME,61,12,158,14,ES_AUTOHSCROLL - EDITTEXT IDC_OUTPUTFILENAME,61,33,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 @@ -85,20 +85,20 @@ 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 | + 145,250,10 + GROUPBOX "Output Format",IDC_STATIC,93,62,164,77 + CONTROL "Use RAW output",IDC_USERAW,"Button",BS_AUTOCHECKBOX | + BS_LEFTTEXT | WS_TABSTOP,14,93,71,10 + CONTROL "Use TNS",IDC_USETNS,"Button",BS_AUTOCHECKBOX | + BS_LEFTTEXT | WS_TABSTOP,14,82,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 - 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 + CONTROL "Use LFE channel",IDC_USELFE,"Button",BS_AUTOCHECKBOX | + BS_LEFTTEXT | WS_DISABLED | WS_TABSTOP,14,104,71,10 END
View file
_service:obs_scm:faac-1.50.obscpio/frontend/getopt.c -> _service:obs_scm:faac-2.0.obscpio/frontend/getopt.c
Changed
@@ -1,756 +1,570 @@ -/* 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 <stdio.h>. */ -#ifndef _NO_PROTO -#define _NO_PROTO -#endif - -#include <stdio.h> -//#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. */ +/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Vendored from https://github.com/alex85k/wingetopt src/getopt.c, + * commit 98ea94f3d77890678da28230aa156b225cc14974, kept diff-minimal + * against upstream (see commit history for the local changes). + */ + +/* + * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <errno.h> #include <stdlib.h> -#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 <string.h> #include "getopt.h" +#include <stdarg.h> +#include <stdio.h> +#ifdef _WIN32 +#include <windows.h> +#endif -/* 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; +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ -/* Callers store zero here to inhibit the error message - for unrecognized options. */ +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif -int opterr = 1; +#define PRINT_ERROR ((opterr) && (*options != ':')) -/* 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 FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
View file
_service:obs_scm:faac-1.50.obscpio/frontend/getopt.h -> _service:obs_scm:faac-2.0.obscpio/frontend/getopt.h
Changed
@@ -1,130 +1,113 @@ -/* 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__ +/** + * DISCLAIMER + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the w64 mingw-runtime package. + * + * The w64 mingw-runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * Vendored from https://github.com/alex85k/wingetopt src/getopt.h, + * commit 98ea94f3d77890678da28230aa156b225cc14974, kept diff-minimal + * against upstream (see commit history for the local changes). + */ + +#define __GETOPT_H__ + +/* All the headers include this file. */ +#ifdef __MINGW32__ +#include <crtdefs.h> +#endif -#ifndef _GETOPT_H -#define _GETOPT_H 1 +#if defined( WINGETOPT_SHARED_LIB ) +# if defined( BUILDING_WINGETOPT_DLL ) +# define WINGETOPT_API __declspec(dllexport) +# else +# define WINGETOPT_API __declspec(dllimport) +# endif +#else +# define WINGETOPT_API +#endif -#ifdef __cplusplus +#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. */ +WINGETOPT_API extern int optind; /* index of first non-option in argv */ +WINGETOPT_API extern int optopt; /* single option character, as parsed */ +WINGETOPT_API extern int opterr; /* flag to enable built-in diagnostics... */ + /* (user may set to zero, to suppress) */ -extern int opterr; +WINGETOPT_API extern char *optarg; /* pointer to argument of current option */ -/* Set to an option character which was unrecognized. */ +WINGETOPT_API extern int getopt(int nargc, char * const *nargv, const char *options); -extern int optopt; +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset +WINGETOPT_API extern int optreset; +#endif +#ifdef __cplusplus +} +#endif +/* + * POSIX requires the `getopt' API to be specified in `unistd.h'; + * thus, `unistd.h' includes this header. However, we do not want + * to expose the `getopt_long' or `getopt_long_only' APIs, when + * included in this manner. Thus, close the standard __GETOPT_H__ + * declarations block, and open an additional __GETOPT_LONG_H__ + * specific block, only when *not* __UNISTD_H_SOURCED__, in which + * to declare the extended API. + */ +#endif /* !defined(__GETOPT_H__) */ + +#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { #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 /* specification for a long form option... */ +{ + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ +}; -struct option +enum /* permitted values for its `has_arg' field... */ { -#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; + no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ }; -/* 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);
View file
_service:obs_scm:faac-1.50.obscpio/frontend/input.c -> _service:obs_scm:faac-2.0.obscpio/frontend/input.c
Changed
@@ -11,12 +11,6 @@ * 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 @@ -118,10 +112,19 @@ static void seekcur(FILE *f, int ofs) { - int cnt; + if (ofs < 0) + return; - for (cnt = 0; cnt < ofs; cnt++) - fgetc(f); + if (fseek(f, ofs, SEEK_CUR) != 0) + { + /* fseek fails on non-seekable streams (stdin/pipes); fall back to + reading and discarding bytes one at a time */ + while (ofs--) + { + if (fgetc(f) == EOF) + break; + } + } } static int seekchunk(FILE *f, riffsub_t *riffsub, char *name) @@ -195,7 +198,7 @@ if (fmtsize < 16) return NULL; - if (fread(&wave, 1, fmtsize, wave_f) != fmtsize) + if (fread(&wave, 1, fmtsize, wave_f) != (size_t)fmtsize) return NULL; seekcur(wave_f, riffsub.len - fmtsize); @@ -228,6 +231,11 @@ } sndf = (pcmfile_t*)malloc(sizeof(*sndf)); + if (!sndf) + { + if (wave_f != stdin) fclose(wave_f); + return NULL; + } memset(sndf, 0, sizeof(*sndf)); sndf->f = wave_f; @@ -254,13 +262,26 @@ sndf->channels = UINT16(wave.Format.nChannels); sndf->samplebytes = UINT16(wave.Format.wBitsPerSample) / 8; sndf->samplerate = UINT32(wave.Format.nSamplesPerSec); - if (!sndf->samplebytes || !sndf->channels) + + /* channel/sample-width bounds guard against a corrupt header (e.g. a + bogus huge channel count) driving an oversized allocation downstream */ + if (sndf->channels < 1 || sndf->channels > 64 || + sndf->samplebytes < 1 || sndf->samplebytes > 4) { + if (wave_f != stdin) fclose(wave_f); free(sndf); return NULL; } + sndf->samples = riffsub.len / (sndf->samplebytes * sndf->channels); } + +#ifdef WORDS_BIGENDIAN + sndf->swap = !sndf->bigendian; +#else + sndf->swap = sndf->bigendian; +#endif + return sndf; } @@ -270,6 +291,8 @@ int i; int32_t *tmp = (int32_t*)malloc(channels * sizeof(int32_t)); + if (!tmp) return; + for (i = 0; i < blocks; i++) { int chn; @@ -298,77 +321,84 @@ isize /= sndf->samplebytes; // perform in-place conversion - for (cnt = 0; cnt < num; cnt++) - { - if (cnt >= isize) - break; + cnt = (num < isize) ? num : isize; - if (sndf->isfloat) + if (sndf->isfloat) + { + if (sndf->samplebytes == 4) { - switch (sndf->samplebytes) { - case 4: - bufcnt *= 32768.0; - break; - default: - return 0; - } - continue; + for (size_t i = 0; i < cnt; i++) + bufi *= 32768.0f; } - + else + { + return 0; + } + } + else + { switch (sndf->samplebytes) { case 1: { uint8_t *in = (uint8_t*)bufi; - uint8_t s = incnt; - - bufcnt = ((float)s - 128.0) * (float)256; + for (size_t i = 0; i < cnt; i++) + bufi = ((float)ini - 128.0f) * 256.0f; } break; case 2: { int16_t *in = (int16_t*)bufi; - int16_t s = incnt; -#ifdef WORDS_BIGENDIAN - if (!sndf->bigendian) -#else - if (sndf->bigendian) -#endif - bufcnt = (float)SWAP16(s); + int swap = sndf->swap; + if (swap) + { + for (size_t i = 0; i < cnt; i++) + bufi = (float)SWAP16(ini); + } else - bufcnt = (float)s; + { + for (size_t i = 0; i < cnt; i++) + bufi = (float)ini; + } } break; case 3: { - int s; uint8_t *in = (uint8_t*)bufi; - in += 3 * cnt; - if (!sndf->bigendian) - s = in0 | (in1 << 8) | (in2 << 16); + { + for (size_t i = 0; i < cnt; i++) + { + int s = in3*i | (in3*i+1 << 8) | (in3*i+2 << 16); + if (s & 0x800000) s |= 0xff000000; + bufi = (float)s / 256.0f; + } + } else - s = (in0 << 16) | (in1 << 8) | in2; - - // fix sign - if (s & 0x800000) - s |= 0xff000000; - - bufcnt = (float)s / 256; + { + for (size_t i = 0; i < cnt; i++) + { + int s = (in3*i << 16) | (in3*i+1 << 8) | in3*i+2; + if (s & 0x800000) s |= 0xff000000; + bufi = (float)s / 256.0f; + } + } } break; case 4: {
View file
_service:obs_scm:faac-1.50.obscpio/frontend/input.h -> _service:obs_scm:faac-2.0.obscpio/frontend/input.h
Changed
@@ -11,12 +11,6 @@ * 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 @@ -43,6 +37,7 @@ int samplerate; int samples; int bigendian; + int swap; int isfloat; } pcmfile_t;
View file
_service:obs_scm:faac-1.50.obscpio/frontend/main.c -> _service:obs_scm:faac-2.0.obscpio/frontend/main.c
Changed
@@ -13,11 +13,6 @@ * 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 - * */ @@ -45,8 +40,10 @@ #include <stdio.h> #include <stdlib.h> #include <ctype.h> -#include <math.h> #include <string.h> +#include <time.h> +#include <sys/stat.h> +#include <errno.h> #ifdef HAVE_GETOPT_H # include <getopt.h> @@ -89,12 +86,14 @@ WRITER_FLAG, WRITER_SORT_FLAG, TAG_FLAG, + CREATION_TIME_FLAG, HELP_QUAL, HELP_IO, HELP_MP4, HELP_ADVANCED, OPT_JOINT, - OPT_PNS + OPT_PNS, + OBJTYPE_FLAG }; typedef struct { @@ -118,7 +117,7 @@ {"-c <freq>\tSet the bandwidth in Hz.\n", "\t\tThe actual frequency is adjusted to maximize upper spectral band\n" "\t\tusage.\n"}, - {0} + {NULL, NULL} }; static help_t help_io = { @@ -132,7 +131,7 @@ "\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 <verbose>\t\tverbosity level (-v0 is quiet mode)\n"}, + {"-v <verbose>\t\tverbosity level (-v0 is quiet mode)\n", NULL}, {"-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"}, @@ -147,7 +146,7 @@ "\t\tRaw PCM input sample size (default: 16, also possible 8, 24, 32\n" "\t\tbit fixed or float input).\n"}, {"-C <channels>\tRaw PCM input channels.\n", - "\t\tRaw PCM input channels (default: 2, max. 33 + 1 LFE).\n"}, + "\t\tRaw PCM input channels (default: 2, max. 8).\n"}, {"-X\t\tRaw PCM swap input bytes\n", "\t\tRaw PCM swap input bytes (default: bigendian).\n"}, {"-I <C,LFE>\tInput channel config, default is 3,4 (Center third, LF fourth)\n", @@ -156,45 +155,48 @@ "\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} + {"--ignorelength\tIgnore wav length from header (useful with files over 4 GB)\n", NULL}, + {"--overwrite\t\tOverwrite existing output file", NULL}, + {NULL, NULL} }; static help_t help_mp4 = { - {"-w\tWrap AAC data in MP4 container (default for *.mp4, *.m4a and *.m4b)\n"}, - {"--tag <tagname,tagvalue> Add named tag (iTunes '----')\n"}, - {"--artist <name>\tSet artist name\n"}, - {"--artistsort <name>\tSet artist sort order\n"}, - {"--composer <name>\tSet composer name\n"}, - {"--composersort <name>\tSet composer sort order\n"}, - {"--title <name>\tSet title/track name\n"}, - {"--genre <number>\tSet genre number\n"}, - {"--album <name>\tSet album/performer\n"}, - {"--albumartist <name>\tSet album artist\n"}, - {"--albumartistsort <name>\tSet album artist sort order\n"}, - {"--albumsort <name>\tSet album sort order\n"}, - {"--compilation\tMark as compilation\n"}, - {"--track <number/total>\tSet track number\n"}, - {"--disc <number/total>\tSet disc number\n"}, - {"--year <number>\tSet year\n"}, + {"-w\tWrap AAC data in MP4 container (default for *.mp4, *.m4a and *.m4b)\n", NULL}, + {"--tag <tagname,tagvalue> Add named tag (iTunes '----')\n", NULL}, + {"--artist <name>\tSet artist name\n", NULL}, + {"--artistsort <name>\tSet artist sort order\n", NULL}, + {"--composer <name>\tSet composer name\n", NULL}, + {"--composersort <name>\tSet composer sort order\n", NULL}, + {"--title <name>\tSet title/track name\n", NULL}, + {"--genre <number>\tSet genre number\n", NULL}, + {"--album <name>\tSet album/performer\n", NULL}, + {"--albumartist <name>\tSet album artist\n", NULL}, + {"--albumartistsort <name>\tSet album artist sort order\n", NULL}, + {"--albumsort <name>\tSet album sort order\n", NULL}, + {"--compilation\tMark as compilation\n", NULL}, + {"--track <number/total>\tSet track number\n", NULL}, + {"--disc <number/total>\tSet disc number\n", NULL}, + {"--year <number>\tSet year\n", NULL}, {"--cover-art <filename>\tRead cover art from file X\n", "\t\tSupported image formats are GIF, JPEG, and PNG.\n"}, - {"--comment <string>\tSet comment\n"}, - {0} + {"--comment <string>\tSet comment\n", NULL}, + {"--creation-time <value>\tSet creation/modification time (auto, now, or timestamp)\n", NULL}, + {NULL, NULL} }; 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"}, + {"--tns \tEnable coding of TNS, temporal noise shaping.\n", NULL}, + {"--no-tns\tDisable coding of TNS, temporal noise shaping.\n", NULL}, + {"--joint 0\tDisable joint stereo coding.\n", NULL}, + {"--joint 1\tUse Mid/Side coding.\n", NULL}, + {"--joint 2\tUse Intensity Stereo coding.\n", NULL}, + {"--joint 3\tUse Mixed Mode (dynamic M/S and IS) coding (default).\n", NULL}, + {"--pns <0 .. 10>\tPNS level; 0=disabled.\n", NULL}, + {"--mpeg-vers X\tForce AAC MPEG version, X can be 2 or 4\n", NULL}, + {"--object-type X\tForce AAC object type: lc, he-aac-v1, or auto (default)\n", NULL}, {"--shortctl X\tEnforce block type (0 = both (default); 1 = no short; 2 = no\n" - "\t\tlong).\n"}, - {0} + "\t\tlong).\n", NULL}, + {NULL, NULL} }; static struct { @@ -216,44 +218,15 @@ "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" + "FAAC is free software, licensed under the GNU Lesser General Public\n" + "License (LGPL), version 2.1 or later:\n" "\n" "FAAC - Freeware Advanced Audio Coder\n" - "Copyright (C) 2001-2004 The individual contributors\n" + "Copyright (C) 1999-2001, Menno Bakker\n" + "Copyright (C) 2002-2017, Krzysztof Nikiel\n" + "Copyright (C) 2004, Dan Villiom P. Christiansen\n" + "Copyright (C) 2005-2026, Fabian Greffrath\n" + "Copyright (C) 2026, Nils Schimmelmann\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" @@ -264,10 +237,6 @@ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
View file
_service:obs_scm:faac-1.50.obscpio/frontend/maingui.c -> _service:obs_scm:faac-2.0.obscpio/frontend/maingui.c
Changed
@@ -11,12 +11,6 @@ * 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 <windows.h> @@ -141,55 +135,56 @@ unsigned long inputSamples; unsigned long maxOutputBytes; - /* open and setup the encoder */ - faacEncHandle hEncoder = faacEncOpen(sampleRate, numChannels, - &inputSamples, &maxOutputBytes); + /* set up parameters and open the encoder */ + faac_params params; + faac_encoder *hEncoder = NULL; + char szTemp256; - if (hEncoder) + faac_params_init(¶ms); + params.sample_rate = sampleRate; + params.num_channels = numChannels; + params.input_format = FAAC_INPUT_32BIT; /* wav_read_int24 -> 24-in-32 int */ { - HANDLE hOutfile; - char szTemp256; - - /* 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) - { + HWND hOT = GetDlgItem(hWnd, IDC_OBJECTTYPE); + LRESULT sel = SendMessage(hOT, CB_GETCURSEL, 0, 0); + LRESULT data = (sel != CB_ERR) ? SendMessage(hOT, CB_GETITEMDATA, (WPARAM)sel, 0) : CB_ERR; + params.object_type = (data != CB_ERR) ? (enum faac_object_type)data : FAAC_OBJ_AUTO; + } + { + LRESULT mode = SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_GETCURSEL, 0, 0); + params.joint_mode = (mode == CB_ERR) ? FAAC_JOINT_MIXED : (enum faac_joint_mode)mode; + } + params.use_tns = IsDlgButtonChecked(hWnd, IDC_USETNS) == BST_CHECKED; + params.use_lfe = IsDlgButtonChecked(hWnd, IDC_USELFE) == BST_CHECKED; + params.output_format = IsDlgButtonChecked(hWnd, IDC_USERAW) == BST_CHECKED + ? FAAC_STREAM_RAW : FAAC_STREAM_ADTS; + params.mpeg_version = (enum faac_mpeg_version) + SendMessage(GetDlgItem(hWnd, IDC_MPEGVERSION), CB_GETCURSEL, 0, 0); + + GetDlgItemText(hWnd, IDC_QUALITY, szTemp, sizeof(szTemp)); + params.quant_quality = atoi(szTemp); + params.bit_rate = 0; /* quality-driven; no bitrate control in this dialog */ + 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); + params.bandwidth = atoi(szTemp); + } - MessageBox (hWnd, "faacEncSetConfiguration failed!", "Error", MB_OK | MB_ICONSTOP); + if (faac_encoder_open(¶ms, &hEncoder) == FAAC_OK) + { + HANDLE hOutfile; - SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)"FAAC GUI"); - Encoding = FALSE; - SetDlgItemText(hWnd, IDOK, "Encode"); + faac_encoder_info info; + info.struct_size = sizeof(info); + faac_encoder_get_info(hEncoder, &info); - return 0; - } + inputSamples = (unsigned long)info.frame_samples * numChannels; + maxOutputBytes = info.max_output_bytes; - sprintf(szTemp, "%ld", config->quantqual); + sprintf(szTemp, "%u", info.quant_quality); SetDlgItemText(hWnd, IDC_QUALITY, szTemp); - sprintf(szTemp, "%d", config->bandWidth); + sprintf(szTemp, "%u", info.bandwidth); SetDlgItemText(hWnd, IDC_BANDWIDTH, szTemp); /* open the output file */ @@ -257,11 +252,16 @@ } /* call the actual encoding routine */ - bytesWritten = faacEncEncode(hEncoder, - pcmbuf, - bytesInput/sizeof(int), - bitbuf, - maxOutputBytes); + { + uint32_t nbytes = 0; + faac_status st = faac_encoder_encode(hEncoder, + pcmbuf, + (uint32_t)(bytesInput/sizeof(int)), + bitbuf, + (uint32_t)maxOutputBytes, + &nbytes); + bytesWritten = (st == FAAC_OK) ? (int)nbytes : -1; + } /* Stop Pressed */ if ( !Encoding ) @@ -273,7 +273,7 @@ if (bytesWritten < 0) { - MessageBox (hWnd, "faacEncEncodeFrame failed!", "Error", MB_OK | MB_ICONSTOP); + MessageBox (hWnd, "faac_encoder_encode failed!", "Error", MB_OK | MB_ICONSTOP); break; } @@ -286,7 +286,7 @@ if (bitbuf) LocalFree(bitbuf); } - faacEncClose(hEncoder); + faac_encoder_close(&hEncoder); } wav_close(infile); @@ -309,25 +309,11 @@ { 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 txt100; - 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); + faac_library_info libinfo = { .struct_size = sizeof(libinfo) }; + char txt100; + faac_get_library_info(&libinfo); + sprintf(txt, "libfaac version %s", libinfo.version ? libinfo.version : "?"); + SetDlgItemText(hWnd, IDC_COMPILEDATE, txt); } inputFilename0 = 0x00; @@ -336,13 +322,27 @@ 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); + { + HWND hOT = GetDlgItem(hWnd, IDC_OBJECTTYPE); + LRESULT idx; + idx = SendMessage(hOT, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Auto"); + SendMessage(hOT, CB_SETITEMDATA, idx, (LPARAM)FAAC_OBJ_AUTO); + idx = SendMessage(hOT, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Low Complexity"); + SendMessage(hOT, CB_SETITEMDATA, idx, (LPARAM)FAAC_OBJ_LOW); + idx = SendMessage(hOT, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"HE-AAC v1"); + SendMessage(hOT, CB_SETITEMDATA, idx, (LPARAM)FAAC_OBJ_HE_AAC_V1); + SendMessage(hOT, CB_SETCURSEL, 0, 0); + } + + SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"None");
View file
_service:obs_scm:faac-1.50.obscpio/frontend/mp4write.c -> _service:obs_scm:faac-2.0.obscpio/frontend/mp4write.c
Changed
@@ -1,30 +1,21 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +/* + * 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. + */ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <time.h> #ifdef _WIN32 #include <io.h> @@ -36,906 +27,668 @@ #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); +#if defined(__has_builtin) +#if __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap16) +#define MP4_HAVE_BSWAP_BUILTINS 1 #endif -#else - return u32; +#elif defined(__GNUC__) +#define MP4_HAVE_BSWAP_BUILTINS 1 #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); +#if defined(MP4_HAVE_BSWAP_BUILTINS) +#define BSWAP32 __builtin_bswap32 +#define BSWAP16 __builtin_bswap16 +#elif defined(_MSC_VER) +#define BSWAP32 _byteswap_ulong +#define BSWAP16 _byteswap_ushort #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 inline uint32_t BSWAP32(uint32_t x) { + return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); } - -static int stringout(const char *txt) -{ - return dataout(txt, strlen(txt)); +static inline uint16_t BSWAP16(uint16_t x) { + return (uint16_t)((x >> 8) | (x << 8)); } +#endif -static int u32out(uint32_t u32) -{ - u32 = be32(u32); - return dataout(&u32, 4); -} +enum { + MP4_EPOCH_OFFSET = 2082844800, /* seconds from 1904-01-01 to 1970-01-01 */ -static int u16out(uint16_t u16) -{ - u16 = be16(u16); - return dataout(&u16, 2); -} + /* identity transform: required by the spec even though audio-only + files never use it; fixed-point format differs per field */ + MP4_FP1616_ONE = 0x00010000, /* unity in 16.16 fixed point: rate, matrix a/d */ + MP4_FP0230_ONE = 0x40000000, /* unity in 2.30 fixed point: matrix w */ + MP4_FP0808_ONE = 0x0100, /* unity in 8.8 fixed point: volume */ -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; + MP4_DESC_HDR = 5, /* descriptor tag byte + 4-byte expandable size, see put_descriptor() */ - size += stringout("M4A "); - size += u32out(0); - size += stringout("M4A "); - size += stringout("mp42"); - size += stringout("isom"); - size += u32out(0); + /* iTunes 'data' atom type codes */ + ITUNES_DATA_BINARY = 0, + ITUNES_DATA_TEXT = 1, + ITUNES_DATA_UINT8 = 0x15, + ITUNES_DATA_IMAGE = 0x0d, - return size; -} + /* DecoderConfigDescriptor fixed fields (ISO/IEC 14496-1) */ + MP4_OBJECT_TYPE_AUDIO_ISO_14496_3 = 0x40, + MP4_STREAM_TYPE_AUDIO = 0x15, /* streamType=5 (audio) << 2 | upStream=0 | reserved=1 */ + MP4_DECODER_BUFFER_SIZE = 6144, /* bufferSizeDB, arbitrary but generous for one AAC frame */ -enum -{ SECSINDAY = 24 * 60 * 60 }; -static time_t mp4time(void) -{ - int y; - time_t t; + MP4_TRACK_ID = 1, /* single-track file: 'trak' and 'tkhd' both hardcode this */ + MP4_NEXT_TRACK_ID = 2, /* mvhd's hint for the next trak ID a future edit would use */ + MP4_URL_SELF_CONTAINED = 1, /* dref 'url ' flags bit: media data lives in this file, no external ref */ - time(&t); + MP4_IO_BUFSIZE = 65536, /* stdio buffer for the mdat write path, see mp4_open() */ +}; - // 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))
View file
_service:obs_scm:faac-1.50.obscpio/frontend/mp4write.h -> _service:obs_scm:faac-2.0.obscpio/frontend/mp4write.h
Changed
@@ -1,96 +1,58 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * 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. + */ + +#ifndef MP4WRITE_H +#define MP4WRITE_H #include <stdint.h> -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; - } extTAGMAX; - 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); +typedef enum { + MP4TAG_ARTIST, + MP4TAG_ARTISTSORT, + MP4TAG_COMPOSER, + MP4TAG_COMPOSERSORT, + MP4TAG_TITLE, + MP4TAG_ALBUM, + MP4TAG_ALBUMARTIST, + MP4TAG_ALBUMARTISTSORT, + MP4TAG_ALBUMSORT, + MP4TAG_YEAR, + MP4TAG_COMMENT, + MP4TAG_COUNT +} mp4_tag_id_t; + +int mp4_open(const char *path, int overwrite); +void mp4_set_creation_time(uint32_t t); +void mp4_set_format(uint32_t samplerate, uint32_t channels, uint32_t bits); +void mp4_set_decoder_config(const uint8_t *asc, unsigned long size); +void mp4_set_encoder(const char *value); +void mp4_set_tag(mp4_tag_id_t id, const char *value); +void mp4_set_genre(int genre); +void mp4_set_compilation(int flag); +void mp4_set_track(uint32_t num, uint32_t total); +void mp4_set_disc(uint32_t num, uint32_t total); +void mp4_set_cover(const uint8_t *data, int size); +int mp4_add_custom_tag(const char *name, const char *value); +int mp4_write_frame(const uint8_t *data, uint32_t size, uint32_t samples); +int mp4_finish(void); +int mp4_close(void); + +uint32_t mp4_frame_count(void); +uint32_t mp4_sample_count(void); +uint32_t mp4_max_bitrate(void); +uint32_t mp4_avg_bitrate(void); +uint32_t mp4_max_frame_size(void); + +#endif
View file
_service:obs_scm:faac-1.50.obscpio/frontend/resource.h -> _service:obs_scm:faac-2.0.obscpio/frontend/resource.h
Changed
@@ -10,7 +10,7 @@ #define IDC_SELECT_OUTPUTFILE 1003 #define IDC_INPUTPARAMS 1004 #define IDC_PROGRESS 1006 -#define IDC_ALLOWMIDSIDE 1007 +#define IDC_JOINTMODE 1007 #define IDC_TIME 1008 #define IDC_BANDWIDTH 1009 #define IDC_QUALITY 1010
View file
_service:obs_scm:faac-1.50.obscpio/include/faac.h -> _service:obs_scm:faac-2.0.obscpio/include/faac.h
Changed
@@ -1,6 +1,6 @@ /* * FAAC - Freeware Advanced Audio Coder - * Copyright (C) 2001 Menno Bakker + * 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 @@ -11,22 +11,56 @@ * 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 +/* + * libfaac encoder API. + * + * This is the only public surface for the encoder. The legacy faacEnc* API + * (faacEncOpen/faacEncGetCurrentConfiguration/faacEncSetConfiguration/ + * faacEncEncode/faacEncClose) has been removed; see docs/libfaac.html for a + * porting guide. * - * $Id: faac.h,v 1.38 2012/03/01 18:34:17 knik Exp $ + * Design summary (see docs/libfaac.html for the full narrative): + * - Parameters are supplied once, up front, to faac_encoder_open(), so the + * encoder never exists in a half-configured state and all derived values + * (frame size, output-buffer bound, effective sample rate, resolved object + * type) are known and queryable the instant open() returns. + * - Every fallible call returns a faac_status; faac_strerror() maps a status + * to a human-readable string. + * - Fixed-width integer types and width-pinned enums keep the ABI identical + * across LP64/LLP64 platforms and regardless of -fshort-enums. + * - faac_params grows only additively: new releases append named fields and + * grow sizeof(faac_params); callers MUST zero-initialize via + * faac_params_init() so struct_size lets the library reconcile versions. */ -#ifndef _FAAC_H_ -#define _FAAC_H_ +#ifndef FAAC_H +#define FAAC_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> +/* + * Tracks the libfaac SONAME, not the project release version. Lets callers + * tell this faac_* API (SONAME >= 1) apart from the removed legacy faacEnc* + * one (SONAME 0): + * + * #if defined(FAAC_VERSION_MAJOR) && (FAAC_VERSION_MAJOR >= 1) + */ +#define FAAC_VERSION_MAJOR 1 +#define FAAC_VERSION_MINOR 0 +#define FAAC_VERSION_PATCH 0 +#define FAAC_VERSION_HEX \ + ((FAAC_VERSION_MAJOR << 16) | (FAAC_VERSION_MINOR << 8) | FAAC_VERSION_PATCH) + +/* Export/visibility marker. Shared with <faac.h>; guarded so including both + * headers is harmless. */ #if !defined(FAACAPI) && defined(__GNUC__) && (__GNUC__ >= 4) # if defined(_WIN32) # define FAACAPI __stdcall __declspec(dllexport) @@ -38,61 +72,222 @@ # define FAACAPI #endif -#pragma pack(push, 1) +/* Opaque encoder handle */ +typedef struct faac_encoder faac_encoder; -typedef struct { - void *ptr; - char *name; -} -psymodellist_t; +/* + * Result codes. All values are negative except FAAC_OK so a caller can test + * `status < 0` for failure. The FAAC_STATUS_MAX sentinel pins the enum to a + * 32-bit underlying type for a stable ABI under -fshort-enums. + */ +typedef enum faac_status { + FAAC_OK = 0, + FAAC_ERR_INVALID_ARGUMENT = -1, /* NULL pointer, bad struct_size, or bad enum/field value */ + FAAC_ERR_UNSUPPORTED = -2, /* object type not implemented, or MPEG-2 ASC requested */ + FAAC_ERR_NO_MEMORY = -3, /* allocation failed */ + FAAC_ERR_OUTPUT_TOO_SMALL = -4, /* output buffer smaller than max_output_bytes */ + FAAC_ERR_INPUT_OVERFLOW = -5, /* in_samples exceeded the per-call frame capacity */ + FAAC_ERR_INTERNAL = -6, /* unexpected failure inside the encoder core */ + FAAC_STATUS_MAX = 0x7fffffff +} faac_status; -#include <stdint.h> -#include "faaccfg.h" +/* + * AAC object type, numbered per the MPEG-4 Audio Object Type (AOT) registry so + * a single collision-free namespace covers current and future profiles. + * FAAC_OBJ_AUTO lets the library pick AAC-LC or HE-AAC by bitrate. + */ +enum faac_object_type { + FAAC_OBJ_AUTO = 0, /* let the library choose LC or HE-AAC by bitrate */ + FAAC_OBJ_LOW = 2, /* AAC-LC */ + FAAC_OBJ_HE_AAC_V1 = 5, /* AAC-LC + SBR */ + FAAC_OBJ_HE_AAC_V2 = 29, /* AAC-LC + SBR + PS (reserved, unimplemented) */ + /* AOT 23 (LD), 39 (ELD), 42 (xHE-AAC/USAC) are intentionally NOT reserved + * here; each would need its own additive configuration surface. */ + FAAC_OBJ_MAX = 0x7fffffff +}; + +enum faac_mpeg_version { + FAAC_MPEG4 = 0, + FAAC_MPEG2 = 1, + FAAC_MPEG_MAX = 0x7fffffff +}; + +enum faac_joint_mode { + FAAC_JOINT_NONE = 0, /* independent (L/R) stereo */ + FAAC_JOINT_MS, /* mid/side */ + FAAC_JOINT_IS, /* intensity */ + FAAC_JOINT_MIXED, /* per-band mix of M/S and intensity */ + FAAC_JOINT_MAX = 0x7fffffff +}; +enum faac_shortctl_mode { + FAAC_SHORTCTL_NORMAL = 0, /* let block switching decide */ + FAAC_SHORTCTL_NOSHORT, /* force long blocks only */ + FAAC_SHORTCTL_NOLONG, /* force short blocks only */ + FAAC_SHORTCTL_MAX = 0x7fffffff +}; -typedef void *faacEncHandle; +enum faac_stream_format { + FAAC_STREAM_RAW = 0, /* raw AAC frames (needs out-of-band ASC) */ + FAAC_STREAM_ADTS = 1, /* self-framing ADTS */ + FAAC_STREAM_MAX = 0x7fffffff +}; + +/* Interpretation of the interleaved PCM handed to faac_encoder_encode(). */ +enum faac_input_format { + FAAC_INPUT_NULL = 0, /* invalid / unset */ + FAAC_INPUT_16BIT, /* native-endian int16 */ + FAAC_INPUT_24BIT, /* native-endian int24 in 24 bits (unimpl.) */ + FAAC_INPUT_32BIT, /* native-endian int24 in 32 bits */ + FAAC_INPUT_FLOAT, /* 32-bit float */ + FAAC_INPUT_MAX = 0x7fffffff +}; /* - Allows an application to get FAAC version info. This is intended - purely for informative purposes. + * Encoder parameters, supplied once to faac_encoder_open(). + * + * ALWAYS initialize with faac_params_init() before setting fields: it zeroes + * the whole struct (including padding) and stamps struct_size, which is how the + * library stays compatible as this struct grows. Construct one from scratch and + * open() will reject it. The struct only ever grows by appending named fields. + */ +typedef struct faac_params { + uint32_t struct_size; /* set by faac_params_init to sizeof(faac_params) */ - Returns FAAC_CFG_VERSION. -*/ -int FAACAPI faacEncGetVersion(char **faac_id_string, - char **faac_copyright_string); + uint32_t sample_rate; /* input/output sample rate in Hz (required) */ + uint32_t num_channels; /* channel count, 1..max_channels (required) */ + enum faac_mpeg_version mpeg_version; + enum faac_object_type object_type; + enum faac_joint_mode joint_mode; -faacEncConfigurationPtr FAACAPI - faacEncGetCurrentConfiguration(faacEncHandle hEncoder); + bool use_lfe; /* treat the last channel as LFE (>= 6 ch) */ + bool use_tns; /* temporal noise shaping */ + uint8_t reserved2; /* explicit pad; must remain 0 */ + uint32_t bit_rate; /* target bits/sec PER CHANNEL; 0 = use quant_quality */ + uint32_t bandwidth; /* cutoff in Hz; 0 = derive from bit_rate */ + uint32_t quant_quality; /* quantizer quality; 0 = derive from bit_rate */ -int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder, - faacEncConfigurationPtr config); + enum faac_stream_format output_format; + enum faac_input_format input_format; + enum faac_shortctl_mode short_control; + int32_t pns_level; /* perceptual noise substitution, 0..10 (0 = off) */ -faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate, - unsigned int numChannels, - unsigned long *inputSamples,
View file
_service:obs_scm:faac-1.50.obscpio/include/meson.build -> _service:obs_scm:faac-2.0.obscpio/include/meson.build
Changed
@@ -1,1 +1,1 @@ -install_headers('faac.h', 'faaccfg.h') +install_headers('faac.h')
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/bitstream.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/bitstream.c
Changed
@@ -1,871 +1,106 @@ -/********************************************************************** +/* + * 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. + */ -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 <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "coder.h" -#include "channels.h" -#include "huff2.h" #include "bitstream.h" #include "util.h" +#include <assert.h> +#include <string.h> +#include <stdlib.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 str200; - 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, stri, 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 (channelInfochannel.present) { - - /* Write out a single_channel_element */ - if (channelInfochannel.type != ELEMENT_CPE) { - - if (channelInfochannel.type == ELEMENT_LFE) { - /* Write out lfe */ - bits += WriteLFE(&coderInfochannel, - &channelInfochannel, - bitStream, - hEncoder->config.aacObjectType, - 1); - } else { - /* Write out sce */ - bits += WriteSCE(&coderInfochannel, - &channelInfochannel, - bitStream, - hEncoder->config.aacObjectType, - 1); - } - - } else { - - if (channelInfochannel.ch_is_left) { - /* Write out cpe */ - bits += WriteCPE(&coderInfochannel, - &coderInfochannelInfochannel.paired_ch, - &channelInfochannel,
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/bitstream.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/bitstream.h
Changed
@@ -1,125 +1,127 @@ -/********************************************************************** -MPEG-4 Audio VM -Bit stream module - - - -This software module was originally developed by - -Heiko Purnhagen (University of Hannover) - -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) 1996. -**********************************************************************/ +/* + * 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. + */ #ifndef BITSTREAM_H #define BITSTREAM_H #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif -#include "frame.h" -#include "coder.h" -#include "channels.h" +#include <stdint.h> -/* - * Raw bitstream constants +/** + * ADTS Constants (ISO/IEC 14496-3) */ -#define LEN_SE_ID 3 -#define LEN_TAG 4 -#define LEN_GLOB_GAIN 8 -#define LEN_COM_WIN 1 -#define LEN_ICS_RESERV 1 -#define LEN_WIN_SEQ 2 -#define LEN_WIN_SH 1 -#define LEN_MAX_SFBL 6 -#define LEN_MAX_SFBS 4 -#define LEN_PRED_PRES 1 -#define LEN_MASK_PRES 2 -#define LEN_MASK 1 -#define LEN_PULSE_PRES 1 - -#define LEN_TNS_PRES 1 -#define LEN_TNS_NFILTL 2 -#define LEN_TNS_NFILTS 1 -#define LEN_TNS_COEFF_RES 1 -#define LEN_TNS_LENGTHL 6 -#define LEN_TNS_LENGTHS 4 -#define LEN_TNS_ORDERL 5 -#define LEN_TNS_ORDERS 3 -#define LEN_TNS_DIRECTION 1 -#define LEN_TNS_COMPRESS 1 -#define LEN_GAIN_PRES 1 - -#define LEN_F_CNT 4 -#define LEN_BYTE 8 - - -#define ID_SCE 0 -#define ID_CPE 1 -#define ID_CCE 2 -#define ID_LFE 3 -#define ID_DSE 4 -#define ID_PCE 5 -#define ID_FIL 6 -#define ID_END 7 - -#define BYTE_NUMBIT 8 /* bits in byte (char) */ -#define LONG_NUMBIT 32 /* bits in unsigned long */ -#define bit2byte(a) (((a)+BYTE_NUMBIT-1)/BYTE_NUMBIT) - -enum {ADTS_FRAMESIZE = 1 << 13}; - -typedef struct -{ - unsigned char *data; /* data bits */ - long numBit; /* number of bits in buffer */ - long size; /* buffer size in bytes */ - long currentBit; /* current bit position in bit stream */ - long numByte; /* number of bytes read/written (only file) */ +enum { + ADTS_MAX_FRAME_SIZE = (1 << 13) - 1, + ADTS_FRAMESIZE = 1 << 13, /* Legacy name compatibility */ + ADTS_HEADER_SIZE = 7 /* 56 bits */ +}; + +/** + * @struct BitStream + * @brief Manages a bit-oriented buffer for AAC bitstream generation. + */ +typedef struct BitStream { + uint8_t *data; /**< Pointer to the start of the bitstream buffer */ + uint32_t size; /**< Size of the buffer in bytes */ + uint32_t currentBit; /**< Current write position in bits */ } BitStream; +BitStream *OpenBitStream(uint32_t size, uint8_t *buffer); +int CloseBitStream(BitStream *bs); + +/* Non-allocating alternative to OpenBitStream: initializes *bs to write into + * a caller-owned buffer (zeroing it, same as OpenBitStream) without the + * malloc/free of a heap BitStream. For scratch streams built over a + * reused/persistent buffer (e.g. a cache rebuilt once per frame) -- PutBit + * ORs bits into place and never zeroes them itself, so any such buffer must + * be zeroed before (re)use or stale bits from a prior, longer write leak + * through. */ +void InitBitStream(BitStream *bs, uint8_t *buffer, uint32_t size); + +int PutBit(BitStream *bs, uint32_t data, int numBits); +int ByteAlign(BitStream *bs); + +/* Batches small field writes into a register and flushes whole bytes as + * they fill, instead of touching the buffer on every write -- for hot + * loops (e.g. spectral coefficients) where PutBit's per-call overhead + * dominates. Bracket a self-contained span with no interleaved PutBit + * calls on the same stream: bs->currentBit is stale until AccumEnd. */ +typedef struct BitAccumulator { + uint64_t bits; /**< pending bits, left-justified in the register */ + uint8_t *out; /**< next byte to emit into bs->data */ + uint8_t *limit; /**< bs->data + bs->size (one-past-end guard) */ + BitStream *bs; /**< owning stream; currentBit is stale until AccumEnd */ + int fill; /**< pending bit count (0..7 between calls) */ + int overflow; /**< sticky: set if a store hit the buffer limit */ +} BitAccumulator; + +static inline void AccumBegin(BitAccumulator *a, BitStream *bs) +{ + uint32_t bytePos = bs->currentBit >> 3; + a->bs = bs; + a->out = bs->data + bytePos; + a->limit = bs->data + bs->size; + a->fill = (int)(bs->currentBit & 7); + a->overflow = 0; + /* Preload the in-progress byte so its already-written high bits are + * preserved; its low (8-fill) bits are 0 (the buffer starts zeroed and + * we only ever move forward), so this seed is exact. */ + a->bits = a->fill ? ((uint64_t)(*a->out) << 56) : 0; +} +static inline void AccumPutBits(BitAccumulator *a, uint32_t value, int numBits) +{ + if (numBits <= 0) + return; + + if (numBits < 32) + value &= (1U << numBits) - 1; + + a->bits |= (uint64_t)value << (64 - a->fill - numBits); + a->fill += numBits; + + while (a->fill >= 8) { + if (a->out < a->limit) + *a->out = (uint8_t)(a->bits >> 56); + else + a->overflow = 1; + a->out++; + a->bits <<= 8; + a->fill -= 8; + } +}
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/blockswitch.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/blockswitch.c
Changed
@@ -11,140 +11,85 @@ * 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: psychkni.c,v 1.19 2012/03/01 18:34:17 knik Exp $ */ +#include <math.h> #include <stdio.h> #include <stdlib.h> -#include <math.h> #include <string.h> #include "blockswitch.h" #include "coder.h" -#include "fft.h" #include "util.h" -#include "filtbank.h" -#include <faac.h> +#include "faac_internal.h" +#include "frame.h" typedef float psyfloat; +/* The high-pass energy timeline is held as one contiguous array of per-sub-block + energies rather than separate prev/curr/next arrays, so PsyCheckShort's +-2 + sub-block lookahead is a single sliding index instead of three-way stitching. + It holds three 2-frame energy windows back to back: PREV, CUR and the one + lookahead window NEXT. (Energy windows are 2 frames wide, which is why a single + "next" window consumes the two-frames-ahead sample slot in the input FIFO.) */ +#define SUBBLOCKS_PER_FRAME 8 +#define ENG_WIN_PREV (0 * SUBBLOCKS_PER_FRAME) +#define ENG_WIN_CUR (1 * SUBBLOCKS_PER_FRAME) +#define ENG_WIN_NEXT (2 * SUBBLOCKS_PER_FRAME) + typedef struct { - /* bandwidth */ - int bandS; - int lastband; - - /* band volumes */ - psyfloat *engPrev8; - psyfloat *eng8; - psyfloat *engNext8; - psyfloat *engNext28; + psyfloat eng3 * SUBBLOCKS_PER_FRAME; } psydata_t; +/* The high-pass first difference (dn=xn-xn-1) de-weights bass, whose + * broadband energy would otherwise mask HF attacks and false-trigger short + * blocks on stationary music; what's left tracks the band where pre-echo is + * audible. A relative energy jump between sub-blocks past this threshold is a + * transient. */ +#define PSY_TD_THRESH (0.5f) -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++) - inSamplesi *= gpsyInfo->hannWindowi; - } - else - { - for (i = 0; i < size; i++) - inSamplesi *= gpsyInfo->hannWindowSi; - } -} - -#define PRINTSTAT 0 -#if PRINTSTAT -static struct { - int tot; - int s; -} frames; -#endif - -static void PsyCheckShort(PsyInfo * psyInfo, faac_real quality) +static void PsyCheckShort(PsyInfo * psyInfo) { enum {PREVS = 2, NEXTS = 2}; - psydata_t *psydata = psyInfo->data; - int lastband = psydata->lastband; - int firstband = 2; - int sfb, win; - psyfloat *lasteng; + psydata_t *psydata = (psydata_t *)psyInfo->data; + int win; + float lasteng = (float)psydata->engENG_WIN_CUR - PREVS; /* start at PREVS before current */ psyInfo->block_type = ONLY_LONG_WINDOW; - lasteng = NULL; - for (win = 0; win < PREVS + 8 + NEXTS; win++) + /* Search for transients across the current frame and its immediate temporal context. + The search range is curr-2, curr+9. */ + for (win = 1; win < PREVS + SUBBLOCKS_PER_FRAME + NEXTS; win++) { - psyfloat *eng; + float eng = (float)psydata->engENG_WIN_CUR - PREVS + win; - if (win < PREVS) - eng = psydata->engPrevwin + 8 - PREVS; - else if (win < (PREVS + 8)) - eng = psydata->engwin - PREVS; - else - eng = psydata->engNextwin - PREVS - 8; + float toteng = (eng < lasteng) ? eng : lasteng; + float volchg = fabsf(eng - lasteng); - if (lasteng) + /* Relative energy jump indicates a transient. IEEE divide handles silence cases. */ + if (volchg / toteng > PSY_TD_THRESH) { - faac_real toteng = 0.0; - faac_real volchg = 0.0; - - for (sfb = firstband; sfb < lastband; sfb++) - { - toteng += (engsfb < lastengsfb) ? engsfb : lastengsfb; - volchg += FAAC_FABS(engsfb - lastengsfb); - } - - if ((volchg / toteng * quality) > 3.0) - { - psyInfo->block_type = ONLY_SHORT_WINDOW; - break; - } + 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) +void PsyInit(GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, unsigned int numChannels, + unsigned int sampleRate) { 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)); + int size; - for (i = 0; i < BLOCK_LEN_LONG * 2; i++) - gpsyInfo->hannWindowi = 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->hannWindowSi = 0.5 * (1 - FAAC_COS(2.0 * M_PI * (i + 0.5) / - (BLOCK_LEN_SHORT * 2))); - gpsyInfo->sampleRate = (faac_real) sampleRate; + gpsyInfo->sampleRate = (float) sampleRate; for (channel = 0; channel < numChannels; channel++) { - psydata_t *psydata = AllocMemory(sizeof(psydata_t)); + psydata_t *psydata = (psydata_t *)AllocMemory(sizeof(psydata_t)); + if (!psydata) return; + memset(psydata, 0, sizeof(psydata_t)); psyInfochannel.data = psydata; } @@ -152,192 +97,114 @@ for (channel = 0; channel < numChannels; channel++) { psyInfochannel.size = size; - - psyInfochannel.prevSamples = - (faac_real *) AllocMemory(size * sizeof(faac_real)); - memset(psyInfochannel.prevSamples, 0, size * sizeof(faac_real)); } size = BLOCK_LEN_SHORT; for (channel = 0; channel < numChannels; channel++) - { - psydata_t *psydata = psyInfochannel.data; - psyInfochannel.sizeS = size; -
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/blockswitch.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/blockswitch.h
Changed
@@ -11,82 +11,50 @@ * 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 +#ifndef BLOCKSWITCH_H +#define BLOCKSWITCH_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" + +struct faacEncStruct; 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; + float sampleRate; /* 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; + float *sharedWorkBuffLong; /* Used for 2048-sample windows (filtbank, psy, tns, mdct) */ } 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, +void PsyInit (GlobalPsyInfo *gpsyInfo, PsyInfo *psyInfo, + unsigned int numChannels, unsigned int sampleRate); +void PsyEnd (PsyInfo *psyInfo, unsigned int numChannels); +void PsyCalculate (AACElement *elements, int numElements, 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, +void PsyBufferUpdate (GlobalPsyInfo * gpsyInfo, PsyInfo * psyInfo, + float * restrict p_lookahead1, + float * restrict p_lookahead2); +void BlockSwitch (struct faacEncStruct *hEncoder, CoderInfo *coderInfo, PsyInfo *psyInfo, unsigned int numChannels); -} psymodel_t; - -extern psymodel_t psymodel2; #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* PSYCH_H */ \ No newline at end of file +#endif /* BLOCKSWITCH_H */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/channels.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/channels.c
Changed
@@ -1,105 +1,308 @@ -/************************* 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 $ + * 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. */ #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) +#include "huff2.h" +#include "frame.h" +#include "sbr.h" +#include <string.h> +#include <stdio.h> + +_Static_assert(TNS_MAX_FILTERS == (1 << LEN_TNS_NFILTL), + "coder.h's TnsWindowData.tnsFilter bound must match the LEN_TNS_NFILTL bitstream field width"); + +/** + * Maps input channels to AAC elements (SCE, CPE, LFE), per ISO/IEC 14496-3's + * channel configuration table: one SCE up front unless exactly 2 channels + * remain, then as many CPEs as fit two at a time, then a trailing odd + * channel becomes an LFE (if enabled) or a final SCE. + */ +int InitElements(AACElement * __restrict elements, int *numElements, int numChannels, bool 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) { - channelInfonumChannels-numChannelsLeft.present = 1; - channelInfonumChannels-numChannelsLeft.tag = sceTag++; - channelInfonumChannels-numChannelsLeft.type = ELEMENT_SCE; - numChannelsLeft--; + uint8_t sceTag = 0; + uint8_t cpeTag = 0; + uint8_t lfeTag = 0; + + int currentElem = 0; + int currentCh = 0; + int channelsRemaining = numChannels; + + memset(elements, 0, sizeof(AACElement) * MAX_CHANNELS); + + // Initial SCE for Config 1, 3, 4, 5, 6, 7 + if (channelsRemaining != 2 && channelsRemaining > 0) { + elementscurrentElem.type = ID_SCE; + elementscurrentElem.tag = sceTag++; + elementscurrentElem.channels0 = currentCh++; + elementscurrentElem.channels1 = -1; + + currentElem++; + channelsRemaining--; } - /* Next elements are cpe's */ - while (numChannelsLeft > 1) { - /* Left channel info */ - channelInfonumChannels-numChannelsLeft.present = 1; - channelInfonumChannels-numChannelsLeft.tag = cpeTag++; - channelInfonumChannels-numChannelsLeft.common_window = 0; - channelInfonumChannels-numChannelsLeft.ch_is_left = 1; - channelInfonumChannels-numChannelsLeft.paired_ch = numChannels-numChannelsLeft+1; - channelInfonumChannels-numChannelsLeft.type = ELEMENT_CPE; - numChannelsLeft--; - - /* Right channel info */ - channelInfonumChannels-numChannelsLeft.present = 1; - channelInfonumChannels-numChannelsLeft.common_window = 0; - channelInfonumChannels-numChannelsLeft.ch_is_left = 0; - channelInfonumChannels-numChannelsLeft.paired_ch = numChannels-numChannelsLeft-1; - channelInfonumChannels-numChannelsLeft.type = ELEMENT_CPE; - numChannelsLeft--; + // CPE groups + while (channelsRemaining > 1) { + elementscurrentElem.type = ID_CPE; + elementscurrentElem.tag = cpeTag++; + elementscurrentElem.channels0 = currentCh++; + elementscurrentElem.channels1 = currentCh++; + + currentElem++; + channelsRemaining -= 2; } - /* Is there another channel left ? */ - if (numChannelsLeft) { + // Residual SCE or LFE + if (channelsRemaining == 1) { if (useLfe) { - channelInfonumChannels-numChannelsLeft.present = 1; - channelInfonumChannels-numChannelsLeft.tag = lfeTag++; - channelInfonumChannels-numChannelsLeft.type = ELEMENT_LFE; + elementscurrentElem.type = ID_LFE; + elementscurrentElem.tag = lfeTag++; } else { - channelInfonumChannels-numChannelsLeft.present = 1; - channelInfonumChannels-numChannelsLeft.tag = sceTag++; - channelInfonumChannels-numChannelsLeft.type = ELEMENT_SCE; + elementscurrentElem.type = ID_SCE; + elementscurrentElem.tag = sceTag++; + } + elementscurrentElem.channels0 = currentCh++; + elementscurrentElem.channels1 = -1; + + currentElem++; + } + + *numElements = currentElem; + return 0; +} + +static int WriteICSInfo(BitStream *bs, CoderInfo *coder, bool writeFlag) +{ + if (writeFlag) { + PutBit(bs, 0, LEN_ICS_RESERV); + PutBit(bs, coder->block_type, LEN_WIN_SEQ); + PutBit(bs, coder->window_shape, LEN_WIN_SH); + } + int bits = LEN_ICS_RESERV + LEN_WIN_SEQ + LEN_WIN_SH; + + if (coder->block_type == ONLY_SHORT_WINDOW) { + if (writeFlag) { + PutBit(bs, coder->sfbn, LEN_MAX_SFBS); + + int grouping_bits = 0; + int tmpMAX_SHORT_WINDOWS, index = 0; + for (int i = 0; i < coder->groups.n; i++) + for (int j = 0; j < coder->groups.leni; j++) + tmpindex++ = i; + for (int i = 1; i < MAX_SHORT_WINDOWS; i++) { + grouping_bits <<= 1; + if (tmpi == tmpi-1) grouping_bits++; + } + PutBit(bs, grouping_bits, MAX_SHORT_WINDOWS - 1); + } + bits += LEN_MAX_SFBS + (MAX_SHORT_WINDOWS - 1);
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/channels.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/channels.h
Changed
@@ -1,6 +1,6 @@ /* * FAAC - Freeware Advanced Audio Coder - * Copyright (C) 2001 Menno Bakker + * 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 @@ -11,48 +11,107 @@ * 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 +#include <stdbool.h> +#include <stdint.h> +#include "bitstream.h" +#include "coder.h" + #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif -#include "coder.h" +/* Forward declaration for core struct to avoid circular dependency */ +struct faacEncStruct; + +/** + * AAC Syntax Element identifiers (ISO/IEC 14496-3, Table 4.1). + */ +typedef enum { + ID_SCE = 0, /**< Single Channel Element */ + ID_CPE = 1, /**< Channel Pair Element */ + ID_CCE = 2, /**< Coupling Channel Element */ + ID_LFE = 3, /**< Low Frequency Element */ + ID_DSE = 4, /**< Data Stream Element */ + ID_PCE = 5, /**< Program Config Element */ + ID_FIL = 6, /**< Fill Element */ + ID_END = 7 /**< Terminator */ +} ElementID; + +/** + * Bitstream field lengths (ISO/IEC 14496-3). + */ +enum { + LEN_SE_ID = 3, + LEN_TAG = 4, + LEN_COM_WIN = 1, + LEN_ICS_RESERV = 1, + LEN_WIN_SEQ = 2, + LEN_WIN_SH = 1, + LEN_MAX_SFBL = 6, + LEN_MAX_SFBS = 4, + LEN_GLOB_GAIN = 8, + LEN_PRED_PRES = 1, + LEN_MASK_PRES = 2, + LEN_MASK = 1, + LEN_PULSE_PRES = 1, + LEN_TNS_PRES = 1, + LEN_GAIN_PRES = 1, + LEN_TNS_NFILTL = 2, + LEN_TNS_NFILTS = 1, + LEN_TNS_COEFF_RES = 1, + LEN_TNS_LENGTHL = 6, + LEN_TNS_LENGTHS = 4, + LEN_TNS_ORDERL = 5, + LEN_TNS_ORDERS = 3, + LEN_TNS_DIRECTION = 1, + LEN_TNS_COMPRESS = 1, + LEN_ADTS_SYNC = 12, + LEN_ADTS_ID = 1, + LEN_ADTS_LAYER = 2, + LEN_ADTS_ABSENT = 1, + LEN_ADTS_PROFILE = 2, + LEN_ADTS_FREQ = 4, + LEN_ADTS_PRIV = 1, + LEN_ADTS_CH_CFG = 3, + LEN_ADTS_ORIG = 1, + LEN_ADTS_HOME = 1, + LEN_ADTS_COPY_ID = 1, + LEN_ADTS_COPY_ST = 1, + LEN_ADTS_FRAME = 13, + LEN_ADTS_FULL = 11, + LEN_ADTS_BLOCKS = 2 +}; typedef struct { - int is_present; - int ms_usedMAX_SCFAC_BANDS; + bool is_present; + uint8_t ms_usedMAX_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; + ElementID type; + uint8_t tag; + int channels2; + bool common_window; MSInfo msInfo; -} ChannelInfo; +} AACElement; + +int InitElements(AACElement * __restrict elements, int *numElements, int numChannels, bool useLfe); + +int WriteElement(BitStream *bs, AACElement *elem, CoderInfo *coder, bool writeFlag); -void GetChannelInfo(ChannelInfo *channelInfo, int numChannels, int useLfe); +int WriteBitstream(struct faacEncStruct* hEncoder, + CoderInfo *coderInfo, + AACElement *elements, + int numElements, + BitStream *bitStream); #ifdef __cplusplus } -#endif /* __cplusplus */ +#endif #endif /* CHANNEL_H */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/coder.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/coder.h
Changed
@@ -11,18 +11,11 @@ * 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" { @@ -44,42 +37,39 @@ SHORT_LONG_WINDOW }; -#define TNS_MAX_ORDER 20 -#define DEF_TNS_GAIN_THRESH 1.4 -#define DEF_TNS_COEFF_THRESH 0.1 +#define TNS_MAX_ORDER 12 +#define DEF_TNS_COEFF_THRESH 0.1f #define DEF_TNS_COEFF_RES 4 #define DEF_TNS_RES_OFFSET 3 -#define LEN_TNS_NFILTL 2 -#define LEN_TNS_NFILTS 1 +/* Bound on TnsWindowData.tnsFilter. Must stay in sync with the bitstream + * field width LEN_TNS_NFILTL (channels.h) -- checked by a _Static_assert in + * channels.c, since this header can't include channels.h without a cycle. */ +#define TNS_MAX_FILTERS 4 typedef struct { int order; /* Filter order */ int direction; /* Filtering direction */ int coefCompress; /* Are coeffs compressed? */ int length; /* Length, in bands */ - faac_real aCoeffsTNS_MAX_ORDER+1; /* AR Coefficients */ - faac_real kCoeffsTNS_MAX_ORDER+1; /* Reflection Coefficients */ - int indexTNS_MAX_ORDER+1; /* Coefficient indices */ + float aCoeffsTNS_MAX_ORDER+1; /* LPC (AR) coefficients */ + int indexTNS_MAX_ORDER+1; /* Quantized reflection-coeff indices */ } TnsFilterData; typedef struct { int numFilters; /* Number of filters */ int coefResolution; /* Coefficient resolution */ - TnsFilterData tnsFilter1<<LEN_TNS_NFILTL; /* TNS filters */ + TnsFilterData tnsFilterTNS_MAX_FILTERS; /* TNS filters */ } TnsWindowData; typedef struct { int tnsDataPresent; int tnsMinBandNumberLong; - int tnsMinBandNumberShort; int tnsMaxBandsLong; - int tnsMaxBandsShort; - int tnsMaxOrderLong; - int tnsMaxOrderShort; - TnsWindowData windowDataMAX_SHORT_WINDOWS; /* TNS data per window */ + int tnsNumSwbLong; /* full swb count for the sample rate (decoder's num_swb) */ + TnsWindowData windowData; /* long-only: one window per frame, not per-short-window */ } TnsInfo; -typedef struct { +typedef struct CoderInfo { int window_shape; int prev_window_shape; int block_type; @@ -118,6 +108,9 @@ int cb_width_shortNSFB_SHORT; } SR_INFO; +/* Scalefactor-band layout per sampling_rate_index, shared by frame.c and sbr.c. */ +extern SR_INFO srInfo12 + 1; + #ifdef __cplusplus } #endif /* __cplusplus */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/cpu_compute.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/cpu_compute.c
Changed
@@ -11,10 +11,6 @@ * 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
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/cpu_compute.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/cpu_compute.h
Changed
@@ -11,10 +11,6 @@ * 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
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/faac.c
Added
@@ -0,0 +1,349 @@ +/* + * 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. + */ + +/* + * The public faac_* encoder API (see include/faac.h). + * + * This is a thin facade over the private encoder core in frame.c (declared in + * faac_internal.h): it supplies the params-at-open entry point, uniform + * faac_status error reporting, resolved-property queries, and library-owned + * ASC. The opaque faac_encoder* is the core's faacEncStruct*. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#include <faac.h> +#include "frame.h" +#include "bitstream.h" +#include "sbr.h" + +/* The public enums are width-pinned to 32 bits by their FAAC_*_MAX sentinels; + * verify the compiler honored that so the ABI matches the documented layout. */ +_Static_assert(sizeof(enum faac_status) == 4, "faac_status must be 32-bit"); +_Static_assert(sizeof(enum faac_object_type) == 4, "faac_object_type must be 32-bit"); +_Static_assert(sizeof(enum faac_mpeg_version) == 4, "faac_mpeg_version must be 32-bit"); +_Static_assert(sizeof(enum faac_joint_mode) == 4, "faac_joint_mode must be 32-bit"); +_Static_assert(sizeof(enum faac_shortctl_mode) == 4, "faac_shortctl_mode must be 32-bit"); +_Static_assert(sizeof(enum faac_stream_format) == 4, "faac_stream_format must be 32-bit"); +_Static_assert(sizeof(enum faac_input_format) == 4, "faac_input_format must be 32-bit"); + +/* The modern enums mirror the legacy numeric values one-for-one, so parameter + * translation is a plain field copy. Guard that assumption. */ +_Static_assert((int)FAAC_MPEG4 == MPEG4 && (int)FAAC_MPEG2 == MPEG2, "mpeg version drift"); +_Static_assert((int)FAAC_OBJ_AUTO == AUTO && (int)FAAC_OBJ_LOW == LOW + && (int)FAAC_OBJ_HE_AAC_V1 == HE_V1, "object type drift"); +_Static_assert((int)FAAC_JOINT_NONE == JOINT_NONE && (int)FAAC_JOINT_MIXED == JOINT_MIXED, "joint mode drift"); +_Static_assert((int)FAAC_SHORTCTL_NORMAL == SHORTCTL_NORMAL && (int)FAAC_SHORTCTL_NOLONG == SHORTCTL_NOLONG, "shortctl drift"); +_Static_assert((int)FAAC_STREAM_RAW == RAW_STREAM && (int)FAAC_STREAM_ADTS == ADTS_STREAM, "stream format drift"); +_Static_assert((int)FAAC_INPUT_NULL == INPUT_NULL && (int)FAAC_INPUT_16BIT == INPUT_16BIT + && (int)FAAC_INPUT_24BIT == INPUT_24BIT && (int)FAAC_INPUT_32BIT == INPUT_32BIT + && (int)FAAC_INPUT_FLOAT == INPUT_FLOAT, "input format drift"); + +/* faac_encoder* and faacEncHandle are the same underlying object. */ +static inline faacEncStruct *unwrap(faac_encoder *enc) { return (faacEncStruct *)enc; } + +FAACAPI faac_status faac_get_library_info(faac_library_info *out) +{ + faac_library_info info; + char *vid = NULL, *vcopy = NULL; + uint32_t caller_size, n; + + if (!out) + return FAAC_ERR_INVALID_ARGUMENT; + caller_size = out->struct_size; + if (caller_size < sizeof(info.struct_size)) + return FAAC_ERR_INVALID_ARGUMENT; + + faacEncGetVersion(&vid, &vcopy); + + memset(&info, 0, sizeof(info)); + info.max_channels = (uint32_t)MAX_CHANNELS; + info.version = vid; + info.copyright = vcopy; + info.sbr_decimation = (uint32_t)FAAC_SBR_DECIMATION; + + /* Write at most the caller's struct_size so a newer library cannot overrun + * an older, smaller faac_library_info; report the byte count actually set. */ + n = caller_size < (uint32_t)sizeof(info) ? caller_size : (uint32_t)sizeof(info); + info.struct_size = n; + memcpy(out, &info, n); + return FAAC_OK; +} + +FAACAPI faac_status faac_params_init(faac_params *p) +{ + if (!p) + return FAAC_ERR_INVALID_ARGUMENT; + + memset(p, 0, sizeof(*p)); + p->struct_size = (uint32_t)sizeof(faac_params); + p->mpeg_version = FAAC_MPEG4; + p->object_type = FAAC_OBJ_LOW; + p->joint_mode = FAAC_JOINT_MIXED; + p->use_lfe = false; + p->use_tns = false; + p->bit_rate = 64000; /* per channel; 0 would defer to quant_quality */ + p->bandwidth = 0; /* derive from bit_rate */ + p->quant_quality = 0; /* derive from bit_rate */ + p->output_format = FAAC_STREAM_ADTS; + p->input_format = FAAC_INPUT_16BIT; + p->short_control = FAAC_SHORTCTL_NORMAL; + p->pns_level = 4; + return FAAC_OK; +} + +/* Validate the enumerated/range fields the caller supplied. Returns FAAC_OK, + * FAAC_ERR_INVALID_ARGUMENT for out-of-range values, or FAAC_ERR_UNSUPPORTED + * for values that are valid but not implemented in this build. */ +static faac_status validate_params(const faac_params *p) +{ + switch (p->mpeg_version) { + case FAAC_MPEG4: case FAAC_MPEG2: break; + default: return FAAC_ERR_INVALID_ARGUMENT; + } + switch (p->object_type) { + case FAAC_OBJ_AUTO: case FAAC_OBJ_LOW: case FAAC_OBJ_HE_AAC_V1: + break; + case FAAC_OBJ_HE_AAC_V2: + return FAAC_ERR_UNSUPPORTED; /* parametric stereo not implemented */ + default: + return FAAC_ERR_INVALID_ARGUMENT; + } + switch (p->joint_mode) { + case FAAC_JOINT_NONE: case FAAC_JOINT_MS: + case FAAC_JOINT_IS: case FAAC_JOINT_MIXED: break; + default: return FAAC_ERR_INVALID_ARGUMENT; + } + switch (p->short_control) { + case FAAC_SHORTCTL_NORMAL: case FAAC_SHORTCTL_NOSHORT: + case FAAC_SHORTCTL_NOLONG: break; + default: return FAAC_ERR_INVALID_ARGUMENT; + } + switch (p->output_format) { + case FAAC_STREAM_RAW: case FAAC_STREAM_ADTS: break; + default: return FAAC_ERR_INVALID_ARGUMENT; + } + switch (p->input_format) { + case FAAC_INPUT_16BIT: case FAAC_INPUT_32BIT: case FAAC_INPUT_FLOAT: + break; + case FAAC_INPUT_24BIT: + return FAAC_ERR_UNSUPPORTED; /* 24-in-24 not implemented */ + default: + return FAAC_ERR_INVALID_ARGUMENT; + } + if (p->sample_rate == 0) + return FAAC_ERR_INVALID_ARGUMENT; + if (p->num_channels < 1 || p->num_channels > (uint32_t)MAX_CHANNELS) + return FAAC_ERR_INVALID_ARGUMENT; + if (p->pns_level < 0 || p->pns_level > 10) + return FAAC_ERR_INVALID_ARGUMENT; + if (p->channel_map) { + uint32_t i; + if (p->channel_map_count < p->num_channels) + return FAAC_ERR_INVALID_ARGUMENT; + for (i = 0; i < p->num_channels; i++) + if (p->channel_mapi < 0 || (uint32_t)p->channel_mapi >= p->num_channels) + return FAAC_ERR_INVALID_ARGUMENT; + } + /* reserved padding must be zero so future fields can claim it safely */ + if (p->reserved0 || p->reserved1 || p->reserved_trailing) + return FAAC_ERR_INVALID_ARGUMENT; + return FAAC_OK; +} + +FAACAPI faac_status faac_encoder_open(const faac_params *p, faac_encoder **out) +{ + faacEncStruct *h; + faacEncConfiguration *cfg; + unsigned long inSamples = 0, maxOut = 0; + faac_status st; + + if (!out) + return FAAC_ERR_INVALID_ARGUMENT; + *out = NULL; + if (!p) + return FAAC_ERR_INVALID_ARGUMENT; + + /* struct_size lets the library reconcile a caller compiled against a + * different header revision. A caller must be at least as new as this + * build's struct (older/garbage/zero is rejected); newer callers are read + * only through the fields this build knows. */ + if (p->struct_size < sizeof(faac_params)) + return FAAC_ERR_INVALID_ARGUMENT; + + st = validate_params(p); + if (st != FAAC_OK) + return st; + + h = (faacEncStruct *)faacEncOpen(p->sample_rate, p->num_channels, + &inSamples, &maxOut); + if (!h) + return FAAC_ERR_NO_MEMORY; +
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/faac_internal.h
Added
@@ -0,0 +1,78 @@ +/* + * 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. + */ + +/* + * Private encoder core. What was historically the public faacEnc* C API is now + * an internal implementation detail behind the sole public API, faac_* in + * <faac.h>. These declarations are not installed and, lacking FAACAPI, not + * exported -- the facade in faac_encoder.c is their only caller. + */ + +#ifndef FAAC_INTERNAL_H +#define FAAC_INTERNAL_H + +#include <stdint.h> + +#define FAAC_CFG_VERSION 106 + +/* MPEG version */ +enum { MPEG4 = 0, MPEG2 = 1 }; + +/* AAC object types this build implements, numbered per the MPEG-4 AOT + * registry (mirrors the public FAAC_OBJ_* enum in <faac.h>). AUTO defers the + * choice between LOW and HE_V1 to faacEncApplyConfig. */ +enum { AUTO = 0, LOW = 2, HE_V1 = 5 }; + +/* PCM input sample format. Named distinctly from the public faac_input_format + * enumerators (<faac.h>) so the facade can include both headers; faac.c + * _Static_asserts the two enumerations agree value-for-value. */ +enum { INPUT_NULL = 0, INPUT_16BIT, INPUT_24BIT, INPUT_32BIT, INPUT_FLOAT }; + +/* Block-type control */ +enum { SHORTCTL_NORMAL = 0, SHORTCTL_NOSHORT = 1, SHORTCTL_NOLONG = 2 }; + +enum stream_format { RAW_STREAM = 0, ADTS_STREAM = 1 }; + +enum { JOINT_NONE = 0, JOINT_MS, JOINT_IS, JOINT_MIXED }; + +typedef struct faacEncConfiguration +{ + unsigned int mpegVersion; + unsigned int aacObjectType; + unsigned int jointmode; + unsigned int useLfe; + unsigned int useTns; + unsigned long bitRate; /* per channel */ + unsigned int bandWidth; + unsigned long quantqual; + unsigned int outputFormat; /* 0 = raw, 1 = ADTS */ + unsigned int inputFormat; + int shortctl; + int channel_map64; /* MAX_CHANNELS entries; identity by default */ + int pnslevel; +} faacEncConfiguration, *faacEncConfigurationPtr; + +typedef void *faacEncHandle; + +int faacEncGetVersion(char **id, char **copyright); +int faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder, unsigned char **ppBuffer, + unsigned long *pSizeOfDecoderSpecificInfo); +faacEncHandle faacEncOpen(unsigned long sampleRate, unsigned int numChannels, + unsigned long *inputSamples, unsigned long *maxOutputBytes); +int faacEncEncode(faacEncHandle hEncoder, int32_t *inputBuffer, unsigned int samplesInput, + unsigned char *outputBuffer, unsigned int bufferSize); +int faacEncClose(faacEncHandle hEncoder); + +#endif /* FAAC_INTERNAL_H */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/fft.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/fft.c
Changed
@@ -1,6 +1,5 @@ /* * 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 @@ -12,271 +11,304 @@ * 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 <math.h> #include <stdlib.h> -#include <stdio.h> -#include <string.h> #include "fft.h" #include "util.h" -#define MAXLOGM 9 -#define MAXLOGR 8 +#define LOGM_SHORT 6 /* logm for the 256-sample short block MDCT */ +#define LOGM_LONG FFT_MAXLOGM /* logm for the 2048-sample long block MDCT */ -void fft_initialize( FFT_Tables *fft_tables ) +void fft_initialize(FFT_Tables *fft_tables) { - int i; - fft_tables->costbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->costbl0 ) ); - fft_tables->negsintbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->negsintbl0 ) ); - fft_tables->reordertbl = AllocMemory( (MAXLOGM+1) * sizeof( fft_tables->reordertbl0 ) ); - - for( i = 0; i< MAXLOGM+1; i++ ) - { - fft_tables->costbli = NULL; - fft_tables->negsintbli = NULL; - fft_tables->reordertbli = NULL; - } + int i; + fft_tables->costbl = AllocMemory((FFT_MAXLOGM + 1) * sizeof(fft_tables->costbl0)); + fft_tables->negsintbl = AllocMemory((FFT_MAXLOGM + 1) * sizeof(fft_tables->negsintbl0)); + fft_tables->reordertbl = AllocMemory((FFT_MAXLOGM + 1) * sizeof(fft_tables->reordertbl0)); + + if (!fft_tables->costbl || !fft_tables->negsintbl || !fft_tables->reordertbl) + { + if (fft_tables->costbl) FreeMemory(fft_tables->costbl); + if (fft_tables->negsintbl) FreeMemory(fft_tables->negsintbl); + if (fft_tables->reordertbl) FreeMemory(fft_tables->reordertbl); + fft_tables->costbl = NULL; + fft_tables->negsintbl = NULL; + fft_tables->reordertbl = NULL; + return; + } + + for (i = 0; i < FFT_MAXLOGM + 1; i++) + { + fft_tables->costbli = NULL; + fft_tables->negsintbli = NULL; + fft_tables->reordertbli = NULL; + } + + for (i = 0; i < FFT_MAXLOGM + 1; i++) + { + fft_tables->mdct_cosi = NULL; + fft_tables->mdct_sini = NULL; + } + + /* Precompute MDCT pre/post-twiddles for both block sizes now, so the + per-frame twiddle loop is a table lookup instead of a cos/sin recurrence. */ + { + static const int logms2 = { LOGM_SHORT, LOGM_LONG }; + int t; + for (t = 0; t < 2; t++) + { + int logm = logmst; + int size = 1 << logm; + double freq = 2.0 * M_PI_DOUBLE / (double)(4 << logm); + fftfloat *c = AllocMemory(size * sizeof(fftfloat)); + fftfloat *s = AllocMemory(size * sizeof(fftfloat)); + + if (!c || !s) + { + if (c) FreeMemory(c); + if (s) FreeMemory(s); + continue; + } + + for (i = 0; i < size; i++) + { + double theta = freq * ((double)i + 0.125); + ci = (fftfloat)cos(theta); + si = (fftfloat)sin(theta); + } + fft_tables->mdct_coslogm = c; + fft_tables->mdct_sinlogm = s; + } + } } -void fft_terminate( FFT_Tables *fft_tables ) +void fft_terminate(FFT_Tables *fft_tables) { - int i; - - for( i = 0; i< MAXLOGM+1; i++ ) - { - if( fft_tables->costbli != NULL ) - FreeMemory( fft_tables->costbli ); - - if( fft_tables->negsintbli != NULL ) - FreeMemory( fft_tables->negsintbli ); - - if( fft_tables->reordertbli != NULL ) - FreeMemory( fft_tables->reordertbli ); - } - - FreeMemory( fft_tables->costbl ); - FreeMemory( fft_tables->negsintbl ); - FreeMemory( fft_tables->reordertbl ); - - fft_tables->costbl = NULL; - fft_tables->negsintbl = NULL; - fft_tables->reordertbl = NULL; + int i; + + for (i = 0; i < FFT_MAXLOGM + 1; i++) + { + if (fft_tables->costbli != NULL) + FreeMemory(fft_tables->costbli); + + if (fft_tables->negsintbli != NULL) + FreeMemory(fft_tables->negsintbli); + + if (fft_tables->reordertbli != NULL) + FreeMemory(fft_tables->reordertbli); + } + + for (i = 0; i < FFT_MAXLOGM + 1; i++) + { + if (fft_tables->mdct_cosi != NULL) + FreeMemory(fft_tables->mdct_cosi); + if (fft_tables->mdct_sini != NULL) + FreeMemory(fft_tables->mdct_sini); + fft_tables->mdct_cosi = NULL; + fft_tables->mdct_sini = NULL; + } + + 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->reordertbllogm == NULL ) // create bit reversing table - { - fft_tables->reordertbllogm = AllocMemory(size * sizeof(*(fft_tables->reordertbl0))); - - 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->reordertbllogmi = reversed; - } - } - - r = fft_tables->reordertbllogm; - - for (i = 0; i < size; i++) - { - int j = ri; - faac_real tmp; - - if (j <= i) - continue; - - tmp = xri;
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/fft.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/fft.h
Changed
@@ -1,6 +1,5 @@ /* * 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 @@ -12,31 +11,32 @@ * 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; +#define FFT_MAXLOGM 9 + +typedef float fftfloat; typedef struct { fftfloat **costbl; fftfloat **negsintbl; unsigned short **reordertbl; + /* MDCT pre/post-twiddle factors cos/sin(freq*(i+1/8)), one table pair per + * transform size (indexed by the size's fft logm). Precomputing them + * breaks the serial cos/sin recurrence that kept the MDCT twiddle loops + * from vectorizing, and is more accurate than the recurrence. */ + fftfloat *mdct_cosFFT_MAXLOGM + 1; + fftfloat *mdct_sinFFT_MAXLOGM + 1; } 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 ); +void fft ( FFT_Tables *fft_tables, float *xr, float *xi, int logm ); #endif
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/filtbank.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/filtbank.c
Changed
@@ -1,39 +1,21 @@ -/************************* 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. + * 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. */ +#include <float.h> #include <math.h> -#include <stdio.h> -#include <stdlib.h> +#include <stdbool.h> #include <string.h> #include "coder.h" @@ -42,40 +24,111 @@ #include "fft.h" #include "util.h" -#define TWOPI 2*M_PI +/* Sine and Kaiser-Bessel-Derived windows, ISO/IEC 13818-7 Annex 4.6.4. + * KBD argument uses the product form i*(halfLen-i) (a difference-of- + * squares factoring of the spec's (2i/halfLen-1)^2 shape term) so the + * Bessel argument is one multiply instead of a subtract-then-square. + * These tables are built once at encoder init, so the series and + * normalization run in double (rounding to float only when stored into + * win) for a correctly-rounded table at zero runtime cost. */ + +static double BesselI0(double x) +{ + const double tolerance = DBL_EPSILON; + double halfX = x * 0.5; + double term = 1.0; + double series = 1.0; + int k = 1; + + do { + double ratio = halfX / (double)k; + term *= ratio * ratio; + series += term; + k++; + } while (term > tolerance * series); + + return series; +} + +static void FillSineWindow(float *win, int halfLen) +{ + int i; + + for (i = 0; i < halfLen; i++) + wini = (float)sin((M_PI_DOUBLE / (2 * halfLen)) * (i + 0.5)); +} + +static void FillKbdWindow(float *win, int halfLen, double alpha) +{ + const double omega = alpha * M_PI_DOUBLE / (double)halfLen; + const double alpha2 = 4.0 * omega * omega; + const int quarterLen = halfLen / 2; + double shapeTermBLOCK_LEN_LONG / 2 + 1; + double weightedTotal = 0.0; + double running = 0.0; + double scale; + int i; + + /* Symmetric around quarterLen, so interior terms count twice below. */ + for (i = 0; i <= quarterLen; i++) { + double symmetric = (double)i * (double)(halfLen - i) * alpha2; + int isInterior = (i > 0) && (i < quarterLen); + shapeTermi = BesselI0(sqrt(symmetric)); + weightedTotal += shapeTermi * (isInterior ? 2 : 1); + } + scale = 1.0 / (weightedTotal + 1.0); -static void CalculateKBDWindow ( faac_real* win, faac_real alpha, int length ); -static faac_real Izero ( faac_real x); + for (i = 0; i <= quarterLen; i++) { + running += shapeTermi; + wini = (float)sqrt(running * scale); + } + /* Past the midpoint, reuse the mirrored term instead of recomputing it. */ + for (; i < halfLen; i++) { + running += shapeTermhalfLen - i; + wini = (float)sqrt(running * scale); + } +} +typedef struct { + float *sine; + float *kbd; +} WindowPair; + +static void BuildWindowPair(WindowPair *wp, int halfLen, double kbdAlpha) +{ + FillSineWindow(wp->sine, halfLen); + FillKbdWindow(wp->kbd, halfLen, kbdAlpha); +} void FilterBankInit(faacEncStruct* hEncoder) { - unsigned int i, channel; + unsigned int channel; + WindowPair longPair, shortPair; for (channel = 0; channel < hEncoder->numChannels; channel++) { - hEncoder->freqBuffchannel = (faac_real*)AllocMemory(2*FRAME_LEN*sizeof(faac_real)); - hEncoder->overlapBuffchannel = (faac_real*)AllocMemory(FRAME_LEN*sizeof(faac_real)); - SetMemory(hEncoder->overlapBuffchannel, 0, FRAME_LEN*sizeof(faac_real)); + hEncoder->freqBuffchannel = (float*)AllocMemory(2*FRAME_LEN*sizeof(float)); + if (!hEncoder->freqBuffchannel) return; } - 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)); + hEncoder->sin_window_long = (float*)AllocMemory(BLOCK_LEN_LONG*sizeof(float)); + hEncoder->sin_window_short = (float*)AllocMemory(BLOCK_LEN_SHORT*sizeof(float)); + hEncoder->kbd_window_long = (float*)AllocMemory(BLOCK_LEN_LONG*sizeof(float)); + hEncoder->kbd_window_short = (float*)AllocMemory(BLOCK_LEN_SHORT*sizeof(float)); - for( i=0; i<BLOCK_LEN_LONG; i++ ) - hEncoder->sin_window_longi = FAAC_SIN((M_PI/(2*BLOCK_LEN_LONG)) * (i + 0.5)); - for( i=0; i<BLOCK_LEN_SHORT; i++ ) - hEncoder->sin_window_shorti = FAAC_SIN((M_PI/(2*BLOCK_LEN_SHORT)) * (i + 0.5)); + if (!hEncoder->sin_window_long || !hEncoder->sin_window_short || + !hEncoder->kbd_window_long || !hEncoder->kbd_window_short) + return; - CalculateKBDWindow(hEncoder->kbd_window_long, 4, BLOCK_LEN_LONG*2); - CalculateKBDWindow(hEncoder->kbd_window_short, 6, BLOCK_LEN_SHORT*2); + longPair.sine = hEncoder->sin_window_long; + longPair.kbd = hEncoder->kbd_window_long; + shortPair.sine = hEncoder->sin_window_short; + shortPair.kbd = hEncoder->kbd_window_short; - 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)); + BuildWindowPair(&longPair, BLOCK_LEN_LONG, 4.0); + BuildWindowPair(&shortPair, BLOCK_LEN_SHORT, 6.0); + + hEncoder->gpsyInfo.sharedWorkBuffLong = (float*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(float)); } void FilterBankEnd(faacEncStruct* hEncoder) @@ -84,7 +137,6 @@ for (channel = 0; channel < hEncoder->numChannels; channel++) { if (hEncoder->freqBuffchannel) FreeMemory(hEncoder->freqBuffchannel); - if (hEncoder->overlapBuffchannel) FreeMemory(hEncoder->overlapBuffchannel); } if (hEncoder->sin_window_long) FreeMemory(hEncoder->sin_window_long); @@ -93,285 +145,179 @@ 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);
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/filtbank.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/filtbank.h
Changed
@@ -11,12 +11,6 @@ * 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 @@ -30,8 +24,6 @@ #define NFLAT_LS 448 -#define MOVERLAPPED 0 -#define MNON_OVERLAPPED 1 #define SINE_WINDOW 0 @@ -41,14 +33,13 @@ void FilterBankEnd ( faacEncStruct* hEncoder ); -void MDCT ( FFT_Tables *fft_tables, faac_real *data, int N, faac_real *xr, faac_real *xi ); +void MDCT ( FFT_Tables *fft_tables, float * restrict data, int N, float * restrict work ); void FilterBank( faacEncStruct* hEncoder, CoderInfo *coderInfo, - faac_real *p_in_data, - faac_real *p_out_mdct, - faac_real *p_overlap, - int overlap_select ); + float * restrict p_prev_data, + float * restrict p_in_data, + float * restrict p_out_mdct); #ifdef __cplusplus
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/frame.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/frame.c
Changed
@@ -11,11 +11,6 @@ * 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 <stdio.h> @@ -32,28 +27,30 @@ #include "util.h" #include "tns.h" #include "stereo.h" +#include "sbr.h" + +/* HE-AAC auto-mode thresholds; tuned via ViSQOL on a 49-clip corpus. */ +#define HE_MIN_SAMPLE_RATE 32000 /* Fs/2 < 16 kHz below this → core too narrow for SBR */ +#define HE_MIN_BITRATE_PER_CH 12000 /* below floor HE wins by an ever-widening margin */ +#define HE_MAX_BITRATE_PER_CH 28000 /* above ceiling LC wins: SBR costs up to 1 MOS on transients */ +#define HE_VBR_QUANTQUAL_MAX 60 /* quality ≤60 ≈ ≤100 kbps; HE saves bits */ #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 */ +#define RC_DEADBAND_THRESHOLD 0.05f /* +/- 5% deadband */ +#define RC_DAMPING_FACTOR 0.6f /* 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 srInfo12+1; + " Copyright (C) 1999-2001, Menno Bakker\n" + " Copyright (C) 2002-2017, Krzysztof Nikiel\n" + " Copyright (C) 2004, Dan Villiom P. Christiansen\n" + " Copyright (C) 2005-2026, Fabian Greffrath\n" + " Copyright (C) 2026, Nils Schimmelmann\n"; static unsigned int CalcBandwidth(unsigned long bitRate, unsigned long sampleRate) { @@ -90,7 +87,19 @@ return (bw > nyquist) ? nyquist : bw; } -int FAACAPI faacEncGetVersion( char **faac_id_string, +/* Element-to-channel mapping is fixed for the session once InitElements has + * run, so cache which channels are LFE here instead of rescanning + * hEncoder->elements for every channel on every frame. */ +static void RefreshLfeMap(faacEncStruct *hEncoder) +{ + memset(hEncoder->isLfeChannel, 0, sizeof(hEncoder->isLfeChannel)); + for (int e = 0; e < hEncoder->numElements; e++) { + if (hEncoder->elementse.type == ID_LFE) + hEncoder->isLfeChannelhEncoder->elementse.channels0 = true; + } +} + +int faacEncGetVersion( char **faac_id_string, char **faac_copyright_string) { if (faac_id_string) @@ -103,7 +112,7 @@ } -int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hpEncoder,unsigned char** ppBuffer,unsigned long* pSizeOfDecoderSpecificInfo) +int faacEncGetDecoderSpecificInfo(faacEncHandle hpEncoder,unsigned char** ppBuffer,unsigned long* pSizeOfDecoderSpecificInfo) { faacEncStruct* hEncoder = (faacEncStruct*)hpEncoder; BitStream* pBitStream = NULL; @@ -116,13 +125,21 @@ return -2; /* not supported */ } + if (hEncoder->config.aacObjectType == HE_V1 && hEncoder->sbrContext) { + return SbrContextGetASC(hEncoder->sbrContext, hEncoder->sampleRateIdx, hEncoder->numChannels, ppBuffer, pSizeOfDecoderSpecificInfo); + } + *pSizeOfDecoderSpecificInfo = 2; - *ppBuffer = malloc(2); + *ppBuffer = (unsigned char *)malloc(2); if(*ppBuffer != NULL){ - memset(*ppBuffer,0,*pSizeOfDecoderSpecificInfo); - pBitStream = OpenBitStream(*pSizeOfDecoderSpecificInfo, *ppBuffer); + pBitStream = OpenBitStream((uint32_t)*pSizeOfDecoderSpecificInfo, *ppBuffer); + if (!pBitStream) { + free(*ppBuffer); + *ppBuffer = NULL; + return -3; + } PutBit(pBitStream, hEncoder->config.aacObjectType, 5); PutBit(pBitStream, hEncoder->sampleRateIdx, 4); PutBit(pBitStream, hEncoder->numChannels, 4); @@ -135,18 +152,12 @@ } -faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hpEncoder) +/* Configuration worker behind faac_encoder_open(): validates the config, + * resolves AUTO/HE-AAC, and (re)initializes the encoder for it. Returns 1 on + * success, 0 on failure. */ +int faacEncApplyConfig(faacEncStruct* hEncoder, + faacEncConfigurationPtr config) { - 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; @@ -161,34 +172,78 @@ assert((hEncoder->config.outputFormat == 0) || (hEncoder->config.outputFormat == 1)); + /* If this handle was previously resolved to HE-AAC, restore the native Fs so + * object-type resolution below always starts from a consistent base (needed + * when a later call toggles between LC and HE-AAC). */ + SbrContextRestoreRate(hEncoder->sbrContext, &hEncoder->sampleRate, &hEncoder->sampleRateIdx, &hEncoder->srInfo); + switch( hEncoder->config.inputFormat ) { - case FAAC_INPUT_16BIT: - //case FAAC_INPUT_24BIT: - case FAAC_INPUT_32BIT: - case FAAC_INPUT_FLOAT: + case INPUT_16BIT: + case INPUT_32BIT: + case INPUT_FLOAT: break; - default: return 0; - break; } - if (hEncoder->config.aacObjectType != LOW) + /* Only LC, HE-AAC v1, and AUTO (which resolves to one of them) are + * supported object types. */ + if (hEncoder->config.aacObjectType != LOW && + hEncoder->config.aacObjectType != HE_V1 && + hEncoder->config.aacObjectType != AUTO) 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()) + /* Clamp against the full (pre-downsample) rate: for an already-resolved + * HE-AAC handle sampleRate is the halved core rate. */ + { + unsigned long fullRate = SbrContextGetFullRate(hEncoder->sbrContext, hEncoder->sampleRate); + if (config->bitRate > (MaxBitrate(fullRate) / hEncoder->numChannels)) + config->bitRate = MaxBitrate(fullRate) / hEncoder->numChannels; + } + + /* Resolve AUTO to LC or HE-AAC. HE-AAC wins for low rates, but only + * at Fs >= 32 kHz so the Fs/2 core stays >= 16 kHz; below that the + * narrow-band core + SBR reconstruction collapses. */ + if (hEncoder->config.aacObjectType == AUTO) { + unsigned long rate_per_ch = config->bitRate; + int rate_ok; + if (rate_per_ch > 0) { + /* Threshold scales with Fs: (3/4)*Fs - 4 kHz gives ~20 kbps at 32 kHz, + * saturating at HE_MAX_BITRATE_PER_CH for Fs ≥ 44.1 kHz. */ + unsigned int max_he_rate = (unsigned int)(hEncoder->sampleRate * 3 / 4 - 4000); + if (max_he_rate > HE_MAX_BITRATE_PER_CH) max_he_rate = HE_MAX_BITRATE_PER_CH; + rate_ok = (rate_per_ch >= HE_MIN_BITRATE_PER_CH && rate_per_ch <= max_he_rate); + } else { + rate_ok = (config->quantqual <= HE_VBR_QUANTQUAL_MAX); + }
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/frame.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/frame.h
Changed
@@ -11,21 +11,27 @@ * 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 +/* Input sample FIFO slots, each one frame (FRAME_LEN samples) wide, relative to + the frame currently being coded (FIFO_CURR): one frame behind (FIFO_PAST, + reused as the MDCT overlap) and two frames ahead. The two ahead slots are + needed because the block-switch energy analysis works on 2-frame-wide windows + and keeps one window of lookahead, whose far edge reaches two frames ahead. */ +#define LOOKAHEAD_DEPTH 2 +#define FIFO_PAST 0 +#define FIFO_CURR 1 +#define FIFO_AHEAD1 2 +#define FIFO_AHEAD2 3 + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <faac.h> +#include "faac_internal.h" #ifdef __cplusplus extern "C" { @@ -36,10 +42,9 @@ #include "blockswitch.h" #include "fft.h" #include "quantize.h" +#include "sbr.h" -#include <faaccfg.h> - -typedef struct { +typedef struct faacEncStruct { /* number of channels in AAC file */ unsigned int numChannels; @@ -56,21 +61,23 @@ /* Scalefactorband data */ SR_INFO *srInfo; - /* sample buffers of current next and next next frame*/ - faac_real *sampleBuffMAX_CHANNELS; - faac_real *next3SampleBuffMAX_CHANNELS; + /* sample buffers: FIFO_PAST (MDCT overlap), FIFO_CURR, FIFO_AHEAD1, FIFO_AHEAD2 */ + float *audioFIFOMAX_CHANNELS4; /* Filterbank buffers */ - faac_real *sin_window_long; - faac_real *sin_window_short; - faac_real *kbd_window_long; - faac_real *kbd_window_short; - faac_real *freqBuffMAX_CHANNELS; - faac_real *overlapBuffMAX_CHANNELS; + float *sin_window_long; + float *sin_window_short; + float *kbd_window_long; + float *kbd_window_short; + float *freqBuffMAX_CHANNELS; /* Channel and Coder data for all channels */ CoderInfo coderInfoMAX_CHANNELS; - ChannelInfo channelInfoMAX_CHANNELS; + + /* Element-centric configuration */ + AACElement elementsMAX_CHANNELS; + int numElements; + bool isLfeChannelMAX_CHANNELS; /* per-channel LFE lookup, derived from elements whenever it changes */ /* Psychoacoustics data */ PsyInfo psyInfoMAX_CHANNELS; @@ -79,15 +86,43 @@ /* Configuration data */ faacEncConfiguration config; - psymodel_t *psymodel; - /* quantizer specific config */ AACQuantCfg aacquantCfg; /* FFT Tables */ FFT_Tables fft_tables; + + /* Input FIFO: decouples the caller's per-call chunk size from the encoder + * frame size. faacEncEncode appends whatever it is handed (any count) and + * emits one frame once a full frame (mult*FRAME_LEN samples/ch, mult = 2 for + * HE-AAC, 1 for LC) has accumulated. Stores format-converted float. */ + float *inputFifoMAX_CHANNELS; + unsigned int inputFifoFill; /* samples per channel currently buffered */ + unsigned int inputFifoCap; /* per-channel capacity in samples */ + + /* faac_* API: AudioSpecificConfig cached on first request and owned by the + * handle (freed at close), so faac_encoder_asc() can hand back a pointer + * the caller never frees. NULL until first built. */ + unsigned char *ascCache; + unsigned long ascCacheLen; + + /* HE-AAC / SBR state */ + struct SBRContext *sbrContext; /* SBR analysis state and bitstream data */ } faacEncStruct; +/* Configuration worker behind faac_encoder_open(): validates the config, + * resolves AUTO/HE-AAC, and (re)initializes the encoder. Returns 1 on success, + * 0 on failure. */ +int faacEncApplyConfig(faacEncStruct* hEncoder, + faacEncConfigurationPtr config); + +/* Samples/channel per full frame: HE-AAC's core runs dual-rate at Fs/2, so it + * needs two FRAME_LENs of input to emit one frame at the full rate; LC needs one. */ +static inline unsigned int faacFrameSamples(const faacEncStruct *hEncoder) +{ + return (hEncoder->config.aacObjectType == HE_V1) ? 2 * FRAME_LEN : FRAME_LEN; +} + #ifdef __cplusplus } #endif /* __cplusplus */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/huff2.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/huff2.c
Changed
@@ -1,21 +1,18 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * FAAC - Freeware Advanced Audio Coder + * Huffman coding per ISO/IEC 14496-3 + * 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. + */ #include <stdio.h> #include <stdlib.h> @@ -23,472 +20,346 @@ #include "huffdata.h" #include "huff2.h" #include "bitstream.h" +#include "util.h" +/* Escape coding for HCB_ESC as per ISO/IEC 14496-3. + * Represents values |q| >= 16 by sending 16 plus an escape suffix. */ 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); + if (x > MAX_HUFF_ESC_VAL) { + fprintf(stderr, "Huffman escape value out of range: %d\n", x); return 0; } - *code = 0; - while (base <= x) - { - base <<= 1; - *code <<= 1; - *code |= 1; - preflen++; + int preflen = 31 - CountLeadingZeros(x) - 4; + int base = 1 << (preflen + 4); + + if (code) { + /* Unary prefix: preflen 1s followed by a 0 */ + *code = (1 << (preflen + 1)) - 2; + /* Escape suffix is (preflen+4) bits: base starts at 16 (= 2^4), so the + * value field is always at least 4 bits; each additional doubling adds one. */ + *code = (*code << (preflen + 4)) | (x - base); } - base >>= 1; - // separator - *code <<= 1; + return (preflen + 1) + (preflen + 4); +} - *code <<= (preflen + 4); - *code |= (x - base); +static hcode16_t * const hmap12 = { + NULL, book01, book02, book03, book04, book05, + book06, book07, book08, book09, book10, book11 +}; - return (preflen << 1) + 5; +/* Bitwise branchless non-zero check: returns 1 if x != 0, else 0. */ +static inline int is_nonzero(int x) +{ + return (int)(((unsigned int)x | (unsigned int)-x) >> 31); } -#define arrlen(array) (sizeof(array) / sizeof(*array)) - -static int huffcode(int *qs /* quantized spectrum */, - int len, - int bnum, - CoderInfo *coder) +/* Fast bit-length sizing for quantization trials. */ +static int huffcode_size(int *qs, int len, int bnum) { - static hcode16_t * const hmap12 = {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; + hcode16_t *book = hmapbnum; + int bits = 0; + int i; + + switch (bnum) { + case HCB_1: + case HCB_2: + for (i = 0; i < len; i += 4) { + int idx = 40 + DIM_S4*DIM_S4*DIM_S4 * qsi + DIM_S4*DIM_S4 * qsi+1 + DIM_S4 * qsi+2 + qsi+3; + bits += bookidx.len; + } + break; + case HCB_3: + case HCB_4: + for (i = 0; i < len; i += 4) { + int idx = DIM_M4*DIM_M4*DIM_M4 * abs(qsi) + DIM_M4*DIM_M4 * abs(qsi+1) + DIM_M4 * abs(qsi+2) + abs(qsi+3); + bits += bookidx.len; + /* Branchless sign-bit counting using bitwise logic */ + bits += is_nonzero(qsi) + is_nonzero(qsi+1) + is_nonzero(qsi+2) + is_nonzero(qsi+3); + } + break; + case HCB_5: + case HCB_6: + for (i = 0; i < len; i += 2) { + int idx = 40 + DIM_S2 * qsi + qsi+1; + bits += bookidx.len; + } + break; + case HCB_7: + case HCB_8: + for (i = 0; i < len; i += 2) { + int idx = DIM_M2_7 * abs(qsi) + abs(qsi+1); + bits += bookidx.len; + bits += is_nonzero(qsi) + is_nonzero(qsi+1); + } + break; + case HCB_9: + case HCB_10: + for (i = 0; i < len; i += 2) { + int idx = DIM_M2_12 * abs(qsi) + abs(qsi+1); + bits += bookidx.len; + bits += is_nonzero(qsi) + is_nonzero(qsi+1); + } + break; + case HCB_ESC: + for (i = 0; i < len; i += 2) { + int x0 = abs(qsi), x1 = abs(qsi+1); + int v0 = (x0 > LAV_ESC) ? LAV_ESC : x0; + int v1 = (x1 > LAV_ESC) ? LAV_ESC : x1; + int idx = DIM_ESC * v0 + v1; + bits += bookidx.len; + bits += is_nonzero(qsi) + is_nonzero(qsi+1); + if (x0 >= LAV_ESC) bits += escape(x0, NULL); + if (x1 >= LAV_ESC) bits += escape(x1, NULL); + } + break; + default: + break; + } - if (coder) - datacnt = coder->datacnt; - else - datacnt = 0; + return bits; +} - book = hmapbnum; - switch (bnum) - { - case 1: - case 2: - for(ofs = 0; ofs < len; ofs += 4) - { - qp = qs+ofs; - idx = 27 * qp0 + 9 * qp1 + 3 * qp2 + qp3 + 40; - if (idx < 0 || idx >= arrlen(book01)) - { - return -1; - } - blen = bookidx.len; - if (coder) - { - data = bookidx.data; - coder->sdatacnt.data = data; - coder->sdatacnt++.len = blen;
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/huff2.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/huff2.h
Changed
@@ -1,21 +1,18 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * FAAC - Freeware Advanced Audio Coder + * Huffman coding per ISO/IEC 14496-3 + * 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. + */ #ifndef HUFF2_H #define HUFF2_H @@ -25,17 +22,48 @@ /* Huffman Codebooks */ enum { HCB_ZERO = 0, + HCB_1, HCB_2, HCB_3, HCB_4, HCB_5, + HCB_6, HCB_7, HCB_8, HCB_9, HCB_10, HCB_ESC = 11, + HCB_DELTA = 12, /* scalefactor-delta book (book12) */ HCB_PNS = 13, HCB_INTENSITY2 = 14, HCB_INTENSITY = 15, HCB_NONE }; -/* Maximum value representable by Huffman Book 11 escape sequences. +/* Spectral books come in range-pairs {base, base+1} sharing a tuple shape but a + * different codeword table; the pair's reach is its Largest Absolute Value. */ +enum { + LAV_1 = 1, /* HCB_1, HCB_2 */ + LAV_2 = 2, /* HCB_3, HCB_4 */ + LAV_4 = 4, /* HCB_5, HCB_6 */ + LAV_7 = 7, /* HCB_7, HCB_8 */ + LAV_12 = 12, /* HCB_9, HCB_10 */ + LAV_ESC = 16 /* HCB_ESC: |q| >= 16 spills into an escape suffix */ +}; + +/* Radix of each book's positional codeword index (so the magic 27/9/13/17 read + * as the powers they are). 4-tuples pack as radix^3..^0, 2-tuples as radix^1..^0. */ +enum { + DIM_S4 = 3, /* HCB_1, HCB_2: signed 4-tuple, 3^4 = 81 */ + DIM_M4 = 3, /* HCB_3, HCB_4: mag 4-tuple, 3^4 = 81 */ + DIM_S2 = 9, /* HCB_5, HCB_6: signed 2-tuple, 9^2 = 81 */ + DIM_M2_7 = 8, /* HCB_7, HCB_8: mag 2-tuple, 8^2 = 64 */ + DIM_M2_12 = 13, /* HCB_9, HCB_10: mag 2-tuple, 13^2 = 169 */ + DIM_ESC = 17 /* HCB_ESC: mag 2-tuple, 17^2 = 289 */ +}; + +/* Maximum value representable by HCB_ESC escape sequences. * Values >= 8192 would cause bitstream overflow/sync loss. */ #define MAX_HUFF_ESC_VAL 8191 +/* Scalefactor step constants (ISO 14496-3 §8.3.4): one SF unit = 2^(1/4) in amplitude. + * AMPL converts a log10 amplitude ratio to scalefactor index steps (= 4/log10(2)). + * ENRG is AMPL/2 — use when the input ratio is energy (squared amplitude). */ +#define SF_STEP_AMPL 13.287712379549461f +#define SF_STEP_ENRG (SF_STEP_AMPL / 2.0f) + /* Scalefactor Management */ enum { /* Baseline scalefactor value used in bitstream */ @@ -46,11 +74,13 @@ SF_PNS_OFFSET = SF_OFFSET - SF_MIN, /* Max allowed difference between successive scalefactors (AAC spec) */ SF_DELTA = 60, + /* Max absolute scalefactor / global_gain (8-bit bitstream field) */ + SF_MAX_ABS = 255, }; /** * Restrict scalefactor delta to the spec-defined +/- SF_DELTA range. - * This ensures the delta remains valid for Book 12 Huffman encoding. + * This ensures the delta remains valid for HCB_DELTA Huffman encoding. */ static inline int clamp_sf_diff(int diff) { @@ -61,10 +91,11 @@ 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); +/* Forward declaration for CoderInfo */ +struct CoderInfo; + +int huffbook(struct CoderInfo *coder, int *qs, int len); +int writebooks(struct CoderInfo *coder, BitStream *stream, int writeFlag); +int writesf(struct CoderInfo *coder, BitStream *bitStream, int writeFlag); #endif /* HUFF2_H */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/huffdata.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/huffdata.c
Changed
@@ -1,19 +1,17 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * FAAC - Freeware Advanced Audio Coder + * Huffman codebook tables reproduced from ISO/IEC 14496-3 (non-copyrightable facts) + * + * 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. + */ #include "huffdata.h" @@ -231,4 +229,3 @@ {19,524257},{19,524258},{19,524259},{19,524260},{19,524261},{19,524247},{19,524268},{19,524276}, {19,524275}, }; -
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/huffdata.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/huffdata.h
Changed
@@ -1,19 +1,17 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * FAAC - Freeware Advanced Audio Coder + * Huffman codebook tables reproduced from ISO/IEC 14496-3 (non-copyrightable facts) + * + * 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. + */ #ifndef HUFFDATA_H #define HUFFDATA_H @@ -28,8 +26,8 @@ } hcode16_t; typedef struct { - const uint32_t len; - const uint32_t data; + const uint32_t len : 8; /* lengths <= 19 */ + const uint32_t data : 24; /* codes are <= 19 bits */ } hcode32_t; extern hcode16_t book0181;
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/libfaac.def -> _service:obs_scm:faac-2.0.obscpio/libfaac/libfaac.def
Changed
@@ -1,11 +1,12 @@ EXPORTS ; -; libfaac exports +; libfaac public API (faac.h) ; -faacEncOpen @1 -faacEncGetCurrentConfiguration @2 -faacEncSetConfiguration @3 -faacEncEncode @4 -faacEncClose @5 -faacEncGetDecoderSpecificInfo @6 -faacEncGetVersion @7 +faac_get_library_info @1 +faac_params_init @2 +faac_encoder_open @3 +faac_encoder_close @4 +faac_encoder_get_info @5 +faac_encoder_asc @6 +faac_encoder_encode @7 +faac_strerror @8
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/meson.build -> _service:obs_scm:faac-2.0.obscpio/libfaac/meson.build
Changed
@@ -27,6 +27,8 @@ 'coder.h', 'cpu_compute.c', 'cpu_compute.h', + 'faac.c', + 'faac_internal.h', 'filtbank.c', 'filtbank.h', 'fft.c', @@ -39,6 +41,16 @@ 'huffdata.h', 'quantize.c', 'quantize.h', + 'sbr.c', + 'sbr.h', + 'sbr_internal.h', + 'sbr_bitstream.c', + 'sbr_tables.c', + 'sbr_tables.h', + 'sbr_analysis.c', + 'sbr_analysis.h', + 'resample.c', + 'resample.h', 'stereo.c', 'stereo.h', 'tns.c', @@ -47,18 +59,50 @@ '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' -) +libfaac = disabler() + +common_args = { + 'include_directories' : '..', '../include', + 'c_args' : c_args, + 'link_args' : link_args, + 'dependencies' : libm, + 'link_with' : quantize_simd_libs, + 'install' : true, + 'gnu_symbol_visibility' : 'hidden', +} + +default_lib = get_option('default_library') + +# LTO on the static archive ships unportable compiler bytecode, so keep it off. +if default_lib == 'static' or default_lib == 'both' + libfaac_static = static_library( + 'faac', + common_src, + kwargs : common_args + { + 'override_options' : 'b_lto=false', + }, + ) +endif +if default_lib == 'shared' or default_lib == 'both' + libfaac_shared = shared_library( + 'faac', + common_src, + kwargs : common_args + { + # Keep in sync with FAAC_VERSION_MAJOR/MINOR/PATCH in include/faac.h. + 'version' : '1.0.0', + 'vs_module_defs' : 'libfaac.def', + 'override_options' : 'b_lto=true', + }, + ) +endif + +# Prefer the LTO shared library for the frontend and pkgconfig. +if default_lib == 'static' + libfaac = libfaac_static +else + libfaac = libfaac_shared +endif pkgconfig = import('pkgconfig') pkgconfig.generate(
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/quantize.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/quantize.c
Changed
@@ -1,22 +1,17 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * 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. + */ #include <limits.h> #include <math.h> @@ -27,40 +22,30 @@ #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); +typedef void (*QuantizeFunc)(const float * __restrict xr, int * __restrict xi, int n, float sfacfix); #if defined(HAVE_SSE2) -extern void quantize_sse2(const faac_real * __restrict xr, int * __restrict xi, int n, faac_real sfacfix); +extern void quantize_sse2(const float * __restrict xr, int * __restrict xi, int n, float sfacfix); #endif -static void quantize_scalar(const faac_real * __restrict xr, int * __restrict xi, int n, faac_real sfacfix) +static void quantize_scalar(const float * __restrict xr, int * __restrict xi, int n, float sfacfix) { - const faac_real magic = MAGIC_NUMBER; - int cnt; - for (cnt = 0; cnt < n; cnt++) + const float magic = MAGIC_NUMBER; + int i; + for (i = 0; i < n; i++) { - faac_real val = xrcnt; - faac_real tmp = FAAC_FABS(val); - - tmp *= sfacfix; - tmp = FAAC_SQRT(tmp * FAAC_SQRT(tmp)); - + float val = xri; + float tmp = fabsf(val) * sfacfix; + tmp = sqrtf(tmp * sqrtf(tmp)); int q = (int)(tmp + magic); - xicnt = (val < 0) ? -q : q; + xii = (val < 0) ? -q : q; } } static QuantizeFunc qfunc = quantize_scalar; -static faac_real sfstep; -static faac_real max_quant_limit; +static float sfstep; +static float max_quant_limit; -/* Sentinel: delta chain has no previous band yet (first active regular band). */ #define SF_CHAIN_UNSET INT_MIN void QuantizeInit(void) @@ -73,307 +58,296 @@ #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); + sfstep = SF_STEP_AMPL; + /* One-time constant: computed in double so the stored float is + * correctly rounded, at zero runtime cost. */ + max_quant_limit = (float)pow((double)MAX_HUFF_ESC_VAL + 1.0 - (double)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) +/* sfac and gain are coupled; clamping one forces a recompute of the other. */ +static float gain_with_overflow_clamp(int *sfac, float band_peak) { - faac_real gain = FAAC_POW(10, *sfac / sfstep); - if (band_peak > 0.0 && gain * band_peak > max_quant_limit) + float gain = powf(10, *sfac / sfstep); + if (band_peak > 0.0f && 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); + *sfac = (int)floorf(log10f(gain) * sfstep); + gain = powf(10, *sfac / sfstep); } return gain; } -#define NOISEFLOOR 0.4 +// masking target per scalefactor band: 0 marks a band inaudible +#define SILENCE_RMS 0.4f // per-sample RMS gate for silence +#define AVG_ENERGY_WEIGHT 0.2f // noise-like (average-energy) share of the target +#define PEAK_ENERGY_WEIGHT 0.45f // tonal (peak-energy) share of the remainder +#define SHORT_BLOCK_TIGHTEN 0.45f // short blocks get a tighter target per unit of energy +#define LOUDNESS_EXPONENT 0.4f // Zwicker-ish loudness compression +#define AVG_ENERGY_FLOOR_FRAC 0.0010f // -30 dB floor, keeps quiet bands from collapsing the target +#define PEAK_ENERGY_FLOOR_FRAC 0.0050f // ~-23 dB floor, same purpose for peak energy + +typedef struct +{ + float sum; /* energy summed across group windows */ + float peak_amp; /* sqrt of the largest single-coefficient energy seen */ +} BandEnergy; -// 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) +static void measure_band_energy(const CoderInfo * __restrict ci, const float * __restrict xr0, + int gnum, BandEnergy * __restrict out) { - 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.lengnum; - const faac_real *xr; - int win; - int enrgcnt = 0; - int total_len = coderInfo->sfb_offsetcoderInfo->sfbn; - - for (win = 0; win < gsize; win++) - { - xr = xr0 + win * BLOCK_LEN_SHORT; - for (cnt = 0; cnt < total_len; cnt++) - { - totenrg += xrcnt * xrcnt; - } - } - enrgcnt = gsize * total_len; - - if (totenrg < ((NOISEFLOOR * NOISEFLOOR) * (faac_real)enrgcnt)) - { - for (sfb = 0; sfb < coderInfo->sfbn; sfb++) - { - bandqualsfb = 0.0; - bandenrgsfb = 0.0; - } - - return; - } - - for (sfb = 0; sfb < coderInfo->sfbn; sfb++) - { - faac_real avge, maxe; - faac_real target; - - start = cb_offsetsfb; - end = cb_offsetsfb + 1; - - avge = 0.0; - maxe = 0.0; - for (win = 0; win < gsize; win++) + int gsize = ci->groups.lengnum; + int sfb; + + for (sfb = 0; sfb < ci->sfbn; sfb++) { - xr = xr0 + win * BLOCK_LEN_SHORT + start; - int n = end - start; - for (cnt = 0; cnt < n; cnt++)
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/quantize.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/quantize.h
Changed
@@ -1,43 +1,35 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * 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. + */ #ifndef QUANTIZE_H #define QUANTIZE_H #include "coder.h" -#include "faac_real.h" typedef struct { - faac_real quality; + float quality; int max_cbl; int max_cbs; int max_l; int pnslevel; } AACQuantCfg; -#ifdef FAAC_PRECISION_SINGLE +/* Rounding bias for the x^(3/4) quantization: 0.4054f minimizes average + * quantization error for a uniform distribution (ISO 14496-3 §8.3.5). */ #define MAGIC_NUMBER 0.4054f -#else -#define MAGIC_NUMBER 0.4054 -#endif enum { DEFQUAL = 100, @@ -46,10 +38,10 @@ MINQUAL = 10, }; -int BlocQuant(CoderInfo *coderInfo, faac_real *xr, AACQuantCfg *aacquantCfg); +void ResetCoderSections(CoderInfo *coderInfo); +int BlocQuant(CoderInfo *coderInfo, float *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 BlocGroup(float *xr, CoderInfo *coderInfo, AACQuantCfg *aacquantCfg); void QuantizeInit(void); #endif
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/quantize_sse.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/quantize_sse.c
Changed
@@ -11,10 +11,6 @@ * 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 @@ -22,10 +18,10 @@ #endif #include <immintrin.h> -#include "faac_real.h" +#include <math.h> #include "quantize.h" -void quantize_sse2(const faac_real * __restrict xr, int * __restrict xi, int n, faac_real sfacfix) +void quantize_sse2(const float * __restrict xr, int * __restrict xi, int n, float sfacfix) { const __m128 zero = _mm_setzero_ps(); const __m128 sfac = _mm_set1_ps(sfacfix); @@ -37,14 +33,7 @@ // Process 4 elements per iteration for (; cnt <= n - 4; cnt += 4) { -#ifdef FAAC_PRECISION_SINGLE __m128 x_orig = _mm_loadu_ps((const float*)&xrcnt); -#else - // Convert 4 doubles to 4 floats via two 128-bit loads - __m128 low = _mm_cvtpd_ps(_mm_loadu_pd(&xrcnt)); - __m128 high = _mm_cvtpd_ps(_mm_loadu_pd(&xrcnt + 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); @@ -69,11 +58,11 @@ // Safe scalar remainder loop for widths not multiple of 4 for (; cnt < n; cnt++) { - faac_real val = xrcnt; - faac_real tmp = FAAC_FABS(val); + float val = xrcnt; + float tmp = fabsf(val); tmp *= sfacfix; - tmp = FAAC_SQRT(tmp * FAAC_SQRT(tmp)); - int q = (int)(tmp + (faac_real)MAGIC_NUMBER); + tmp = sqrtf(tmp * sqrtf(tmp)); + int q = (int)(tmp + (float)MAGIC_NUMBER); xicnt = (val < 0) ? -q : q; } }
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/resample.c
Added
@@ -0,0 +1,90 @@ +/* + * 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. + */ + +#include <string.h> + +#include "resample.h" +#include "coder.h" +#include "util.h" + +/* Equiripple half-band FIR for 2:1 decimation. + * Leverages the zero-valued odd-indexed taps and symmetric even-indexed taps + * to reduce the computational load by ~75% compared to a general FIR. + * The passband is flat within 0.05 dB up to the SBR crossover region, + * ensuring the core signal remains transparent before SBR reconstruction. */ +#define HB_CENTER 0.5015570876767614f +static const resfloat hb_evenRESAMPLE_FILTER_LEN / 2 + 1 = { + -2.39042884e-03f, 2.03978735e-03f, -2.88625768e-03f, 3.94878764e-03f, + -5.26747336e-03f, 6.89408424e-03f, -8.89782634e-03f, 1.13774798e-02f, + -1.44815390e-02f, 1.84491642e-02f, -2.36937924e-02f, 3.10005784e-02f, + -4.20596122e-02f, 6.12815300e-02f, -1.04870415e-01f, 3.18777389e-01f, + 3.18777389e-01f, -1.04870415e-01f, 6.12815300e-02f, -4.20596122e-02f, + 3.10005784e-02f, -2.36937924e-02f, 1.84491642e-02f, -1.44815390e-02f, + 1.13774798e-02f, -8.89782634e-03f, 6.89408424e-03f, -5.26747336e-03f, + 3.94878764e-03f, -2.88625768e-03f, 2.03978735e-03f, -2.39042884e-03f, +}; + +Resampler *ResampleInit(int channels) +{ + Resampler *r = (Resampler *)AllocMemory(sizeof(Resampler)); + if (!r) return NULL; + SetMemory(r, 0, sizeof(Resampler)); + r->channels = channels; + return r; +} + +void ResampleEnd(Resampler *r) +{ + FreeMemory(r); +} + +/* The symmetric-fold gather below defeats autovectorization. */ +int Resample(Resampler *r, int input_len) +{ + int output_len = input_len / 2; + const int H = RESAMPLE_FILTER_LEN - 1; /* 62 */ + const int HALF = RESAMPLE_FILTER_LEN / 2; /* 31 */ + int ch, i, j; + + for (ch = 0; ch < r->channels; ch++) { + float * __restrict in = r->fullRatech; + float * __restrict out = r->halfRatech; + float * __restrict hist = r->bufch; + + /* Fixed-size buffers to avoid VLA (MSVC portability): history + one + * full-rate HE frame (2 * FRAME_LEN input samples). */ + float combinedRESAMPLE_FILTER_LEN - 1 + 2 * FRAME_LEN; + + memcpy(combined, hist, H * sizeof(float)); + memcpy(combined + H, in, input_len * sizeof(float)); + + /* Exploit FIR symmetry to fold the tap-delay line before multiplication. */ + for (i = 0; i < output_len; i++) { + const float * __restrict c = combined + 2 * i; + float a0 = 0, a1 = 0, a2 = 0, a3 = 0; + for (j = 0; j < 16; j += 4) { + a0 += hb_evenj + 0 * (c2 * (j + 0) + c2 * (31 - j - 0)); + a1 += hb_evenj + 1 * (c2 * (j + 1) + c2 * (31 - j - 1)); + a2 += hb_evenj + 2 * (c2 * (j + 2) + c2 * (31 - j - 2)); + a3 += hb_evenj + 3 * (c2 * (j + 3) + c2 * (31 - j - 3)); + } + *out++ = (a0 + a1) + (a2 + a3) + HB_CENTER * combined2 * i + HALF; + } + + memcpy(hist, combined + input_len, H * sizeof(float)); + } + + return output_len; +}
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/resample.h
Added
@@ -0,0 +1,53 @@ +/* + * 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. + */ + +/* 2:1 FIR downsampler for HE-AAC core signal preparation. + * Takes full-rate PCM (Fs) and produces half-rate PCM (Fs/2) + * for the AAC-LC core encoder. */ + +#ifndef RESAMPLE_H +#define RESAMPLE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "coder.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float resfloat; + +#define RESAMPLE_FILTER_LEN 63 + +typedef struct Resampler { + float buf MAX_CHANNELSRESAMPLE_FILTER_LEN; /* FIR overlap state (carries between frames) */ + float fullRateMAX_CHANNELS2 * FRAME_LEN; /* full-rate input: caller fills, SBR reads, FIR consumes */ + float halfRateMAX_CHANNELSFRAME_LEN; /* downsampled output: written by Resample */ + int channels; +} Resampler; + +Resampler *ResampleInit(int channels); +void ResampleEnd(Resampler *r); + +int Resample(Resampler *r, int input_len); + +#ifdef __cplusplus +} +#endif + +#endif /* RESAMPLE_H */
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr.c
Added
@@ -0,0 +1,466 @@ +/* + * 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. + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <assert.h> + +#include "sbr.h" +#include "sbr_tables.h" +#include "util.h" +#include "sbr_analysis.h" +#include "resample.h" +#include "bitstream.h" +#include "sbr_internal.h" +#include "faac_internal.h" + +/* SBR master frequency band table (ISO/IEC 14496-3:2005 §4.6.18.3.2). kx/k2 are + * spec-mandatory: the decoder reconstructs them from the sample rate alone, so + * these must match its table exactly or the envelope band count desyncs. The + * rate here is the full output rate (= 2*core), which is what the decoder uses. */ + +/* SBR start frequency (kx). Crossover alignment prevents aliasing/gaps. */ +static int compute_kx(int sampleRate, int bs_start_freq) +{ + int temp = (sampleRate < 32000) ? 3000 : (sampleRate < 64000) ? 4000 : 5000; + int start_min = ((temp << 7) + (sampleRate >> 1)) / sampleRate; + int row = (sampleRate <= 16000) ? 0 : (sampleRate <= 22050) ? 1 : (sampleRate <= 24000) ? 2 : (sampleRate <= 32000) ? 3 : (sampleRate <= 64000) ? 4 : 5; + return clamp_int(start_min + sbr_offsetrowbs_start_freq & 15, 1, 63); +} + +static int cmp_int16(const void *a, const void *b) { return (int)(*(const short *)a) - (int)(*(const short *)b); } + +/* SBR stop frequency (k2). Bark-scale distribution maximizes bit efficiency. */ +static int compute_k2(int sampleRate, int kx, int bs_stop_freq) +{ + if (bs_stop_freq == 14 || bs_stop_freq == 15) return 64; + int temp = (sampleRate < 32000) ? 3000 : (sampleRate < 64000) ? 4000 : 5000; + int stop_min = ((temp << 8) + (sampleRate >> 1)) / sampleRate; + int k2; + if (bs_stop_freq < 14) { + short stop_dk13; + float prod = (float)stop_min; + int prev = stop_min; + float base = powf(64.0f / (float)stop_min, (float)(1.0f / 13.0f)); + for (int i = 0; i < 12; i++) { + prod *= base; + int present = (int)lrintf(prod); + stop_dki = (short)(present - prev); + prev = present; + } + stop_dk12 = (short)(64 - prev); + qsort(stop_dk, 13, sizeof(short), cmp_int16); + k2 = stop_min; + for (int i = 0; i < bs_stop_freq; i++) k2 += stop_dki; + } else { + k2 = 64; + } + + int max_span = (sampleRate <= 32000) ? 48 : (sampleRate <= 44100) ? 35 : 32; + return clamp_int(k2, kx + 1, kx + max_span > 64 ? 64 : kx + max_span); +} + +/* Distribute QMF bands into SBR master bands using uniform dk-spacing. + * Residual bands are merged into the first/last pairs to maintain a + * monotonic frequency grid. */ +static int build_freq_table(SBRInfo *sbr) +{ + int kx = sbr->kx, k2 = sbr->k2, dk = sbr->dk; + int n_master = clamp_int(((k2 - kx + (dk & 2)) >> dk) << 1, 1, SBR_MAX_BANDS); + int f_masterSBR_MAX_BANDS + 1; + for (int k = 1; k <= n_master; k++) f_masterk = dk; + int k2diff = (k2 - kx) - n_master * dk; + if (k2diff < 0) { + f_master1--; + if (k2diff < -1) f_master2--; + } else if (k2diff > 0) f_mastern_master++; + f_master0 = kx; + for (int k = 1; k <= n_master; k++) f_masterk += f_masterk - 1; + sbr->numBands = n_master; + for (int b = 0; b <= n_master; b++) sbr->bandEdgesb = f_masterb; + sbr->numNoiseBands = 1; + return n_master; +} + +SBRInfo *SbrInit(int channels, int sampleRate, unsigned long bitRate, FFT_Tables *fft_tables) +{ + SBRInfo *sbr = (SBRInfo *)AllocMemory(sizeof(SBRInfo)); + if (!sbr) return NULL; + SetMemory(sbr, 0, sizeof(SBRInfo)); + sbr->sbrPresent = 1; + sbr->numChannels = channels; + sbr->sampleRate = sampleRate; + + /* Pre-calculate twiddle factors for the FFT-based QMF analysis. + * These coefficients rotate the subband indices into the odd-frequency + * DFT space required by the SBR modulation kernel. */ + for (int m = 0; m < SBR_QMF_BANDS_64; m++) { + sbr->twidCosm = (float)cos(M_PI_DOUBLE * m / 64.0); + sbr->twidSinm = (float)sin(M_PI_DOUBLE * m / 64.0); + sbr->oddCosm = (float)cos(M_PI_DOUBLE * (2 * m + 1) / 128.0); + sbr->oddSinm = (float)sin(M_PI_DOUBLE * (2 * m + 1) / 128.0); + } + /* Borrow the encoder's shared core FFT tables (same fft() routine, same + * logm=6 size as the short-block MDCT). The core owns init/terminate; the + * logm=6 table is built lazily on first use, single-threaded per encoder. */ + sbr->fftTables = fft_tables; + + SbrUpdate(sbr, bitRate); + return sbr; +} + +/* Re-resolve SBR operational parameters (crossover, resolution) when the + * bitrate or sample rate changes, avoiding handle reallocation. */ +void SbrUpdate(SBRInfo *sbr, unsigned long bitRate) +{ + int sampleRate = sbr->sampleRate; + unsigned long rate_per_ch = bitRate / sbr->numChannels; + sbr->bs_amp_res = (rate_per_ch < SBR_AMP_RES_BITRATE_BPS) ? 0 : 1; + /* Target crossover near the core ceiling (~11.6 kHz) maximizes MOS. + * Higher-order parametric reconstruction below 10 kHz is audible and + * generally inferior to the bit-starved LC core. */ + if (rate_per_ch <= SBR_COARSE_TABLE_BITRATE_BPS) { + sbr->bs_start_freq = 15; + sbr->bs_alter_scale = 1; + sbr->dk = 2; + } else { + sbr->bs_start_freq = 15; + sbr->bs_alter_scale = 0; + sbr->dk = 1; + } + /* Stop frequency covers approximately 75% of the upper octave. */ + sbr->bs_stop_freq = 10; + sbr->bs_freq_res = 1; /* HIGH resolution */ + sbr->bs_xover_band = 0; /* every master band is an SBR band; no low-res split */ + sbr->numEnvelopes = 1; + sbr->eff_amp_res = (sbr->numEnvelopes == 1) ? 0 : sbr->bs_amp_res; + sbr->kx = compute_kx(sampleRate, sbr->bs_start_freq); + sbr->k2 = compute_k2(sampleRate, sbr->kx, sbr->bs_stop_freq); + + build_freq_table(sbr); +} + +void SbrEnd(SBRInfo *sbr) +{ + if (!sbr) return; + /* fftTables is borrowed from the encoder; the core terminates it. */ + FreeMemory(sbr); +} + +SBRContext *SbrContextInit(int channels) +{ + SBRContext *sbrCtx = (SBRContext *)AllocMemory(sizeof(SBRContext)); + if (sbrCtx) { + SetMemory(sbrCtx, 0, sizeof(SBRContext)); + sbrCtx->resampler = ResampleInit(channels); + if (!sbrCtx->resampler) { + FreeMemory(sbrCtx); + return NULL; + } + } + return sbrCtx; +} + +void SbrContextEnd(SBRContext *sbrCtx) +{ + if (!sbrCtx) return; + if (sbrCtx->sbrInfo) { + SbrEnd(sbrCtx->sbrInfo); + } + if (sbrCtx->resampler) { + ResampleEnd(sbrCtx->resampler); + } + FreeMemory(sbrCtx); +} + +int SbrContextGetASC(SBRContext *sbrCtx, int coreSRIdx, int channels, unsigned char** ppBuffer, unsigned long* pSize) +{ + /* Explicit-hierarchy ASC: AAC-LC core wrapped with an SBR extension + * (sync 0x2b7, type 5) carrying the full output rate. The core rate is + * Fs/2 (dual-rate SBR); the extension declares the full output rate. */ + *pSize = 5; + *ppBuffer = (unsigned char *)malloc(5); + if (*ppBuffer == NULL) return -3; + memset(*ppBuffer, 0, 5); + BitStream *pBitStream = OpenBitStream(5, *ppBuffer); + PutBit(pBitStream, LOW, 5); /* core object type */
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr.h
Added
@@ -0,0 +1,116 @@ +/* + * 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. + */ + +#ifndef SBR_H +#define SBR_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "coder.h" +#include "fft.h" +#include "sbr_analysis.h" + +/* Input sample FIFO slots, each one frame (FRAME_LEN samples) wide, relative to + the frame currently being coded (FIFO_CURR): one frame behind (FIFO_PAST, + reused as the MDCT overlap) and two frames ahead. The two ahead slots are + needed because the block-switch energy analysis works on 2-frame-wide windows + and keeps one window of lookahead, whose far edge reaches two frames ahead. */ +#define LOOKAHEAD_DEPTH 2 +#define FIFO_PAST 0 +#define FIFO_CURR 1 +#define FIFO_AHEAD1 2 +#define FIFO_AHEAD2 3 + +/* Depth of the HE shared-detector decision FIFO. Sized so index 0 lines up with + the core frame currently being coded: the core lags the freshest SBR analysis + by LOOKAHEAD_DEPTH frames, so index 0 must be LOOKAHEAD_DEPTH entries behind + the newest (one extra slot for the newest entry itself). */ +#define SBR_DETECT_FIFO (LOOKAHEAD_DEPTH + 1) + +#ifdef __cplusplus +extern "C" { +#endif + +struct BitStream; + +#define SBR_QMF_BANDS_64 64 +#define SBR_QMF_OVL_LEN_64 576 +#define SBR_MAX_BANDS 64 +#define SBR_MAX_ENVELOPES 2 +#define SBR_MAX_NOISE_ENVELOPES 2 +#define SBR_MAX_NOISE_BANDS 5 +#define SBR_HEADER_PERIOD 30 + +/* SBR frame classes (ISO 14496-3:2009 §4.6.18.3, Table 4.80). */ +#define SBR_FRAME_CLASS_FIXFIX 0 +#define SBR_FRAME_CLASS_FIXVAR 1 +#define SBR_FRAME_CLASS_VARFIX 2 +#define SBR_FRAME_CLASS_VARVAR 3 + +/* Envelope time-slot resolution the decoder uses for an AAC-LC core frame + * (FFmpeg/FAAD2 pass numTimeSlots=16). All bs_rel_bord/t_env values written in + * a variable grid live in 0, SBR_NUM_TIME_SLOTS. */ +#define SBR_NUM_TIME_SLOTS 16 + +/* SBR extension types (ISO 14496-3 §4.6.18). */ +#define SBR_EXT_TYPE_SBR 0xd +#define SBR_EXT_TYPE_SBR_CRC 0xe + +/* Transient detection threshold (peak-to-mean power ratio). */ +#define SBR_TRANSIENT_THRESH_DEFAULT (4.0f) +/* div-by-zero guard for the peak/mean ratio in silence frames (~-150 dBFS^2). */ +#define SBR_ENERGY_FLOOR (1e-15f) +/* log2(0) guard in envelope quantization: -200 dBFS^2, below all SBR quantizer ranges. */ +#define SBR_LOG_ENERGY_FLOOR (1e-20f) +/* Default noise floor level (ISO 14496-3 §4.6.18.6.4). */ +#define SBR_NOISE_LEVEL_DEFAULT 4 +/* 6 = log2(64): normalises 64-band QMF energy to per-band level. ISO 14496-3 §4.6.18.6.3. */ +#define SBR_ENV_LEVEL_LOG2_OFFSET (6.0f) +/* Rate-dependent resolution thresholds. */ +#define SBR_AMP_RES_BITRATE_BPS 20000u +#define SBR_COARSE_TABLE_BITRATE_BPS 32000u +/* Max delta-coded step for envelope data, per bs_amp_res grid (ISO 14496-3 + * §4.6.18.3.6): the fine (amp_res=1) grid has half the step size of the coarse + * grid, so its delta range must be roughly double to cover the same dB span. */ +#define SBR_ENV_DELTA_LIMIT_HIRES 31 +#define SBR_ENV_DELTA_LIMIT_LORES 60 + +typedef struct SBRInfo SBRInfo; +struct SignalAnalysis; + +typedef struct SBRContext SBRContext; + +SBRContext *SbrContextInit(int channels); +void SbrContextEnd(SBRContext *sbrCtx); +int SbrContextGetASC(SBRContext *sbrCtx, int coreSRIdx, int channels, unsigned char** ppBuffer, unsigned long* pSize); +unsigned int SbrContextGetXOverBandwidth(SBRContext *sbrCtx); +void SbrContextUpdateConfig(SBRContext *sCtx, int channels, unsigned long bitrate, FFT_Tables *fft_tables); +void SbrContextProcessFrame(SBRContext *sCtx, int numChannels, int realPerCh, float *inputFifoMAX_CHANNELS, float *heHalfRateMAX_CHANNELS); +int SbrContextIsPresent(SBRContext *sCtx); +void SbrContextRestoreRate(SBRContext *sCtx, unsigned long *sampleRate, unsigned int *sampleRateIdx, SR_INFO **srInfo); +unsigned long SbrContextGetFullRate(SBRContext *sCtx, unsigned long defaultRate); +void SbrContextResolveRate(SBRContext *sCtx, unsigned long *sampleRate, unsigned int *sampleRateIdx, SR_INFO **srInfo); +int SbrContextIsAnalysisValid(SBRContext *sCtx); +int SbrContextGetWantShort(SBRContext *sCtx, int channel, int index); + +int SbrContextGetBits(SBRContext *sCtx, struct BitStream *bs, int channels, int aacObjectType, int writeFlag); + +#ifdef __cplusplus +} +#endif + +#endif
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr_analysis.c
Added
@@ -0,0 +1,169 @@ +/* + * 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. + */ + +#include "sbr_analysis.h" +#include "sbr.h" +#include "sbr_internal.h" +#include "util.h" +#include <string.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Multi-pass signal analysis: transient detection, temporal grid selection, + * and subband energy accumulation. hot keeps it vectorized under LTO despite + * only being reached through the cold dispatcher; SbrQmfAnalysis is inlined + * here (not split out) to stay under GCC's LTO auto-inline threshold. */ +#if defined(__GNUC__) +__attribute__((hot)) +#endif +void SbrAnalyze(SignalAnalysis *sa, float *fullPtrs, int nch, int numSamples, struct SBRInfo *sbr) +{ + int num_slots = numSamples / SBR_QMF_BANDS_64; + int sampled = (num_slots - 1) / FAAC_SBR_DECIMATION + 1; + float workspaceSBR_QMF_OVL_LEN_64 + 2 * FRAME_LEN; + + sa->valid = 1; + sa->numSlots = num_slots; + sa->sampled = sampled; + + /* Pass 1: Time-domain transient detection. Identifies the temporal position + * and strength of transients across all channels. */ + for (int ch = 0; ch < nch; ch++) { + float smax = 0.0f, ssum = 0.0f; + int smax_idx = 0; + float slot_hp_eng128; /* high-pass energy per slot (max slots = 2*1024/64 = 32) */ + + sa->chch.wantShort = 0; + float val_in = sa->chch.lastVal; + const float * restrict p_in = fullPtrsch; + for (int slot = 0; slot < num_slots; slot++) { + float stot = 0.0f; + float hp_stot = 0.0f; + for (int n = 0; n < SBR_QMF_BANDS_64; n += 4) { + float v0 = p_in0, v1 = p_in1, v2 = p_in2, v3 = p_in3; + stot += v0 * v0 + v1 * v1 + v2 * v2 + v3 * v3; + float d0 = v0 - val_in, d1 = v1 - v0, d2 = v2 - v1, d3 = v3 - v2; + hp_stot += d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3; + val_in = v3; p_in += 4; + } + if (slot < 128) slot_hp_engslot = hp_stot; + + if (stot > smax) { + smax = stot; + smax_idx = slot; + } + ssum += stot; + } + sa->chch.lastVal = val_in; + + sa->chch.transientStrength = smax * (float)sampled / (ssum + SBR_ENERGY_FLOOR); + sa->chch.transientSlot = smax_idx; + + /* Evaluate relative energy jumps to inform block switching. */ + float last_hp_eng = 0.0f; + int have_last = 0; + for (int slot = 0; slot < num_slots; slot++) { + if (slot >= 128) break; + float hp_eng = slot_hp_engslot; + if (have_last) { + float toteng = (hp_eng < last_hp_eng) ? hp_eng : last_hp_eng; + float volchg = (hp_eng > last_hp_eng) ? (hp_eng - last_hp_eng) : (last_hp_eng - hp_eng); + /* PSY_TD_THRESH = 0.5 */ + if (volchg > (0.5f * toteng)) { + sa->chch.wantShort = 1; + break; + } + } + last_hp_eng = hp_eng; + have_last = 1; + } + } + + /* Choose the temporal grid based on the strongest transient. Synchronizes + * envelope borders across all channels to maintain spatial imaging. */ + float frameStrength = 0.0f; + int frameSlot = 0; + for (int ch = 0; ch < nch; ch++) { + if (sa->chch.transientStrength > frameStrength) { + frameStrength = sa->chch.transientStrength; + frameSlot = sa->chch.transientSlot; + } + } + + int split = num_slots; /* default: single envelope spans the whole frame */ + if (frameStrength > SBR_TRANSIENT_THRESH_DEFAULT) { + int Ts = (num_slots > 0) ? frameSlot * SBR_NUM_TIME_SLOTS / num_slots : 0; /* 0..16 */ + int rel = clamp_int((Ts - 2) / 2, 0, 3); + int innerSbr = 2 * rel + 2; /* {2,4,6,8} */ + sa->numEnvelopes = 2; + sa->frameClass = SBR_FRAME_CLASS_VARFIX; + sa->tEnv0 = 0; + sa->tEnv1 = innerSbr; + sa->tEnv2 = SBR_NUM_TIME_SLOTS; + sa->bsPointer = 0; + split = clamp_int(innerSbr * num_slots / SBR_NUM_TIME_SLOTS, 1, num_slots - 1); + } else { + sa->numEnvelopes = 1; + sa->frameClass = SBR_FRAME_CLASS_FIXFIX; + sa->tEnv0 = 0; + sa->tEnv1 = SBR_NUM_TIME_SLOTS; + sa->bsPointer = 0; + } + + /* Count slots per envelope for power normalization. */ + sa->envSampled0 = sa->envSampled1 = 0; + for (int slot = 0; slot < num_slots; slot++) { +#if FAAC_SBR_DECIMATION > 1 + if (slot % FAAC_SBR_DECIMATION != 0) continue; +#endif + int h = (sa->numEnvelopes > 1 && slot >= split) ? 1 : 0; + sa->envSampledh++; + } + if (sa->envSampled0 < 1) sa->envSampled0 = 1; + if (sa->numEnvelopes > 1 && sa->envSampled1 < 1) sa->envSampled1 = 1; + + /* Pass 2: Subband analysis. Accumulates energy across QMF bands within + * the selected temporal envelopes. */ + /* Only kx, k2) feeds the envelope quantizer; bands below kx are core-coded + * and never read, so skip their post-FFT extraction and accumulation. */ + int kx = sbr ? sbr->kx : 0; + int kEnd = sbr ? sbr->k2 : SBR_QMF_BANDS_64; + for (int ch = 0; ch < nch; ch++) { + memset(sa->chch.bandHalfE, 0, sizeof(sa->chch.bandHalfE)); + + if (sbr) { + memcpy(workspace, sbr->chch.qmfOvl64, SBR_QMF_OVL_LEN_64 * sizeof(float)); + memcpy(workspace + SBR_QMF_OVL_LEN_64, fullPtrsch, numSamples * sizeof(float)); + + for (int slot = 0; slot < num_slots; slot++) { +#if FAAC_SBR_DECIMATION > 1 + if (slot % FAAC_SBR_DECIMATION == 0) +#endif + { + float slotEnergySBR_QMF_BANDS_64; + SbrQmfAnalysis(sbr, workspace + slot * SBR_QMF_BANDS_64, slotEnergy, kx, kEnd); + + int h = (sa->numEnvelopes > 1 && slot >= split) ? 1 : 0; + + float * restrict bE = sa->chch.bandHalfEh; + for (int k = kx; k < kEnd; k++) + bEk += slotEnergyk; + } + } + } + } +}
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr_analysis.h
Added
@@ -0,0 +1,71 @@ +/* + * 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. + */ + +#ifndef SBR_ANALYSIS_H +#define SBR_ANALYSIS_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SBR_QMF_BANDS_64 +#define SBR_QMF_BANDS_64 64 +#endif + +#ifndef SBR_MAX_ENVELOPES +#define SBR_MAX_ENVELOPES 2 +#endif + +#ifndef MAX_CHANNELS +#define MAX_CHANNELS 64 +#endif + +struct SBRInfo; + +typedef struct SignalAnalysisChannel { + int transientSlot; + float transientStrength; + int wantShort; + float lastVal; + float bandHalfE2SBR_QMF_BANDS_64; +} SignalAnalysisChannel; + +typedef struct SignalAnalysis { + int valid; + int numSlots; + int sampled; + + /* Frame envelope grid configuration. Synchronized across all channels. */ + int frameClass; + int numEnvelopes; + int tEnvSBR_MAX_ENVELOPES + 1; + int bsPointer; + int envSampledSBR_MAX_ENVELOPES; + + SignalAnalysisChannel chMAX_CHANNELS; +} SignalAnalysis; + +void SbrAnalyze(SignalAnalysis *sa, float *fullPtrs, int nch, int numSamples, struct SBRInfo *sbr); + +#ifdef __cplusplus +} +#endif + +#endif
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr_bitstream.c
Added
@@ -0,0 +1,235 @@ +/* + * 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. + */ + +#include <assert.h> + +#include "sbr.h" +#include "sbr_internal.h" +#include "sbr_tables.h" +#include "bitstream.h" +#include "channels.h" +#include "util.h" +#include "faac_internal.h" + +/* count-and-write helper: matches channels.c's WriteElement/WriteICS style -- + * every write_sbr_* function below takes a `write` flag, always returns the + * bit count, and only touches `bs` (which may be NULL) when `write` is set. */ +static int put_huff(BitStream *bs, bool write, const SBRHuffEntry *table, int nsyms, int offset, int delta) +{ + int sym = clamp_int(delta + offset, 0, nsyms - 1); + if (write) PutBit(bs, tablesym.code, tablesym.len); + return tablesym.len; +} + +static int write_sbr_header(SBRInfo *sbr, BitStream *bs, bool write) +{ + int bits = 0; +#define WB(v,n) do { if (write) PutBit(bs,(v),(n)); bits += (n); } while(0) + /* ISO 14496-3:2009 §4.6.18.5 sbr_header() (21 bits) */ + WB(sbr->bs_amp_res, 1); /* bs_amp_res: 0=1.5dB, 1=3dB */ + WB(sbr->bs_start_freq, 4); /* bs_start_freq: crossover index */ + WB(sbr->bs_stop_freq, 4); /* bs_stop_freq: high-band ceil */ + WB(sbr->bs_xover_band, 3); /* bs_xover_band: low-res split (0=none) */ + WB(0, 2); /* bs_reserved */ + WB(1, 1); /* bs_header_extra_1 = 1 (alter_scale present) */ + WB(0, 1); /* bs_header_extra_2 = 0 (limiter fields absent) */ + /* bs_header_extra_1 fields: */ + WB(0, 2); /* bs_freq_scale = 0 (linear master table) */ + WB(sbr->bs_alter_scale, 1); /* bs_alter_scale: 1=coarser at low bitrate */ + WB(0, 2); /* bs_noise_bands = 0 (→ 1 noise band) */ +#undef WB + return bits; +} + +/* Width of the transient pointer field, indexed by number of envelopes. */ +static const int sbr_ceil_log2 = { 0, 1, 2, 2, 3, 3 }; + +static int write_sbr_grid(SBRInfo *sbr, BitStream *bs, bool write) +{ + int bits = 0; +#define WB(v,n) do { if (write) PutBit(bs,(v),(n)); bits += (n); } while(0) + if (sbr->frameClass == SBR_FRAME_CLASS_VARFIX) { + /* VARFIX: variable leading borders, fixed trailing border. Mirrors the + * inverse of FFmpeg read_sbr_grid()'s VARFIX case: t_env0=bs_var_bord_0, + * each lead border adds 2*bs_rel+2, the trailing border is numTimeSlots + * (not transmitted), then bs_pointer and per-envelope bs_freq_res. */ + int num_env = sbr->numEnvelopes; + WB(SBR_FRAME_CLASS_VARFIX, 2); + WB(sbr->tEnv0, 2); /* bs_var_bord_0 */ + WB(num_env - 1, 2); /* bs_num_rel_0 */ + for (int i = 0; i < num_env - 1; i++) + WB((sbr->tEnvi + 1 - sbr->tEnvi - 2) / 2, 2); /* bs_rel_bord */ + WB(sbr->bsPointer, sbr_ceil_log2num_env); + for (int i = 0; i < num_env; i++) /* bs_freq_res1..num_env */ + WB(sbr->bs_freq_res, 1); + } else { + /* FIXFIX: equal-spaced borders, one bs_freq_res for all envelopes. */ + WB(SBR_FRAME_CLASS_FIXFIX, 2); + WB(sbr->numEnvelopes > 1 ? 1 : 0, 2); + WB(sbr->bs_freq_res, 1); + } +#undef WB + return bits; +} + +static int write_sbr_dtdf(SBRInfo *sbr, BitStream *bs, bool write) +{ + int n_q = sbr->numEnvelopes > 1 ? 2 : 1; + int bits = sbr->numEnvelopes + n_q; + if (write) for (int i = 0; i < bits; i++) PutBit(bs, 0, 1); + return bits; +} + +static int write_sbr_invf(SBRInfo *sbr, BitStream *bs, int ch, bool write) +{ + if (write) for (int nb = 0; nb < sbr->numNoiseBands; nb++) PutBit(bs, sbr->chch.invfMode, 2); + return sbr->numNoiseBands * 2; +} + +static int write_sbr_envelope(SBRInfo *sbr, BitStream *bs, int ch, bool write) +{ + const SBRHuffEntry *table = sbr->eff_amp_res ? f_huff_env_3_0dB : f_huff_env_1_5dB; + int nsyms = sbr->eff_amp_res ? F_HUFF_ENV_3_0DB_NSYMS : F_HUFF_ENV_1_5DB_NSYMS; + int offset = sbr->eff_amp_res ? F_HUFF_ENV_3_0DB_OFFSET : F_HUFF_ENV_1_5DB_OFFSET; + int bits = 0; + + for (int e = 0; e < sbr->numEnvelopes; e++) { + for (int b = 0; b < sbr->numBands; b++) { + int val = sbr->chch.envDataeb; + if (b == 0) { + int first_bits = sbr->eff_amp_res ? 6 : 7; + if (write) PutBit(bs, clamp_int(val, 0, (1 << first_bits) - 1), first_bits); + bits += first_bits; + } else { + bits += put_huff(bs, write, table, nsyms, offset, val); + } + } + } + return bits; +} + +static int write_sbr_noise(SBRInfo *sbr, BitStream *bs, int ch, bool write) +{ + int n_q = sbr->numEnvelopes > 1 ? 2 : 1; + int bits = 0; + for (int ne = 0; ne < n_q; ne++) { + for (int nb = 0; nb < sbr->numNoiseBands; nb++) { + int val = sbr->chch.noiseDatanenb; + if (nb == 0) { + if (write) PutBit(bs, clamp_int(val, 0, 30), 5); + bits += 5; + } else { + bits += put_huff(bs, write, f_huff_env_3_0dB, F_HUFF_ENV_3_0DB_NSYMS, F_HUFF_ENV_3_0DB_OFFSET, val); + } + } + } + return bits; +} + +static int write_sbr_data(SBRInfo *sbr, BitStream *bs, int id_aac, bool write) +{ + int bits = 0; +#define WB(v,n) do { if (write) PutBit(bs,(v),(n)); bits += (n); } while(0) + if (id_aac == ID_CPE) { + WB(0, 1); WB(0, 1); /* bs_coupling=0, reserved */ + bits += write_sbr_grid(sbr, bs, write); + bits += write_sbr_grid(sbr, bs, write); + bits += write_sbr_dtdf(sbr, bs, write); + bits += write_sbr_dtdf(sbr, bs, write); + bits += write_sbr_invf(sbr, bs, 0, write); + bits += write_sbr_invf(sbr, bs, 1, write); + bits += write_sbr_envelope(sbr, bs, 0, write); + bits += write_sbr_envelope(sbr, bs, 1, write); + bits += write_sbr_noise(sbr, bs, 0, write); + bits += write_sbr_noise(sbr, bs, 1, write); + WB(0, 1); WB(0, 1); WB(0, 1); /* add_harmonic / extended data flags */ + } else { + WB(0, 1); /* reserved */ + bits += write_sbr_grid(sbr, bs, write); + bits += write_sbr_dtdf(sbr, bs, write); + bits += write_sbr_invf(sbr, bs, 0, write); + bits += write_sbr_envelope(sbr, bs, 0, write); + bits += write_sbr_noise(sbr, bs, 0, write); + WB(0, 1); WB(0, 1); /* add_harmonic / extended data flags */ + } +#undef WB + return bits; +} + +/* Emit the full extension_payload body for EXT_SBR_DATA: the 4-bit extension + * type, the 1-bit header flag, the optional header, and the channel data. */ +static int emit_sbr_payload(SBRInfo *sbr, BitStream *bs, int id_aac, int sendHeader, bool write) +{ + int bits = 0; +#define WB(v,n) do { if (write) PutBit(bs,(v),(n)); bits += (n); } while(0) + WB(SBR_EXT_TYPE_SBR, 4); + WB(sendHeader, 1); +#undef WB + if (sendHeader) bits += write_sbr_header(sbr, bs, write); + bits += write_sbr_data(sbr, bs, id_aac, write); + return bits; +} + +int SbrWrite(SBRInfo *sbr, BitStream *bs, int id_aac, int writeFlag) +{ + if (!sbr || !sbr->sbrPresent) return 0; + + int sendHeader = sbr->sendHeaderThisFrame; + + /* The fill_element's cnt field must precede the payload in the bitstream, + * so its size is needed before anything is written. Re-deriving it with a + * dry (write=false) pass is cheap -- a few hundred fixed-width/Huffman + * fields, not a hot loop -- so there's no need to cache the emitted bits + * across a frame's several SbrWrite calls (BuildFrame's count and write + * passes, plus frame.c's rate-control bit-accounting call): every call + * just re-derives them from sbr's already-quantized envelope/noise data, + * the same way channels.c's WriteElement/WriteICS do for the rest of the + * frame. */
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr_internal.h
Added
@@ -0,0 +1,110 @@ +/* + * 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. + */ + +#ifndef SBR_INTERNAL_H +#define SBR_INTERNAL_H + +#include "sbr.h" +#include "sbr_analysis.h" +#include "resample.h" + +/* Per-channel SBR state. Everything indexed ch in SBRInfo lives here. */ +typedef struct SBRChannel { + float qmfOvl64SBR_QMF_OVL_LEN_64; /* QMF overlap state (carries across frames) */ + int envData SBR_MAX_ENVELOPESSBR_MAX_BANDS; /* quantised envelope indices */ + int noiseDataSBR_MAX_NOISE_ENVELOPESSBR_MAX_NOISE_BANDS; /* quantised noise floor indices */ + int invfMode; /* bs_invf_mode (0–3) */ +} SBRChannel; + +struct SBRInfo { + int sbrPresent; + int headerSent; + int frameCount; + int numChannels; + int sampleRate; /* full output rate; the dual-rate core runs at sampleRate/2 */ + + /* --- frequency band configuration (set at init, constant per stream) --- */ + int kx; + int k2; + int dk; /* master frequency table step (1 or 2 QMF bands) */ + int numBands; + int bandEdgesSBR_MAX_BANDS + 1; + int numNoiseBands; + + /* --- bitstream header fields --- */ + int bs_amp_res; + int bs_freq_res; /* envelope frequency resolution: 1 = HIGH (f_master) */ + int bs_start_freq; + int bs_stop_freq; + int bs_xover_band; + int bs_alter_scale; + + /* --- per-frame state --- */ + int numEnvelopes; /* 1 or 2, set by transient detection in SbrEncode */ + int eff_amp_res; /* forced to 0 for single-envelope FIXFIX (ISO 14496-3:2009 §4.6.18.3) */ + + /* Envelope time grid for the frame (frame-global, shared by both channels of + * a CPE). frameClass selects FIXFIX or VARFIX; tEnv0..numEnvelopes are the + * envelope borders in SBR time slots (0, SBR_NUM_TIME_SLOTS) and are only + * emitted for the variable classes. bsPointer marks the transient envelope. */ + int frameClass; + int tEnvSBR_MAX_ENVELOPES + 1; + int bsPointer; + + /* Whether SbrWrite should (re)send the sbr_header this frame. Frozen once + * per frame (in SbrEncode) rather than recomputed in SbrWrite, since + * headerSent/frameCount only advance on SbrWrite's real write pass, and + * SbrWrite is called multiple times per frame (BuildFrame's count and + * write passes, plus frame.c's rate-control bit-accounting call). */ + int sendHeaderThisFrame; + + /* --- per-channel state --- */ + SBRChannel chMAX_CHANNELS; + + /* QMF analysis twiddle factors. */ + float twidCosSBR_QMF_BANDS_64; + float twidSinSBR_QMF_BANDS_64; + float oddCos SBR_QMF_BANDS_64; + float oddSin SBR_QMF_BANDS_64; + FFT_Tables *fftTables; /* borrowed: the encoder's shared core FFT tables */ +}; + +struct SBRContext { + unsigned long fullSampleRate; + unsigned int fullSampleRateIdx; + SBRInfo *sbrInfo; + struct Resampler *resampler; + + /* Shared signal analysis */ + SignalAnalysis signalAnalysis; + /* Shared-detector FIFO: holds the HE block-switch decision for the last + SBR_DETECT_FIFO analyzed frames. Index 0 is the decision aligned to the + core frame being coded now, which lags the freshest analysis by the core + lookahead (LOOKAHEAD_DEPTH frames); newest sits at SBR_DETECT_FIFO-1. */ + float transientStrengthFIFOMAX_CHANNELSSBR_DETECT_FIFO; + int wantShortFIFOMAX_CHANNELSSBR_DETECT_FIFO; +}; + +SBRInfo *SbrInit(int channels, int sampleRate, unsigned long bitRate, FFT_Tables *fft_tables); +/* Recompute the bitrate-dependent band config without reallocating; lets + * SetConfiguration adjust an existing handle. */ +void SbrUpdate(SBRInfo *sbr, unsigned long bitRate); +void SbrEnd(SBRInfo *sbr); + +void SbrQmfAnalysis(SBRInfo *sbr, const float * restrict ovl_pos, float * restrict energy, int kx, int k2); +void SbrEncode(SBRInfo *sbr, float *timeDomainMAX_CHANNELS, int numChannels, int numSamples, struct SignalAnalysis *sa); +int SbrWrite(SBRInfo *sbr, struct BitStream *bs, int id_aac, int writeFlag); + +#endif
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr_tables.c
Added
@@ -0,0 +1,378 @@ +/* + * FAAC - Freeware Advanced Audio Coder + * SBR tables reproduced from ISO/IEC 14496-3:2005 (non-copyrightable facts) + * + * 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. + */ + +#include "sbr_tables.h" + +const sbrfloat qmf_c640 = { + +0.0000000000e+00f, -5.5252865047e-04f, -5.6176925738e-04f, -4.9475180896e-04f, + -4.8752279712e-04f, -4.8937912498e-04f, -5.0407143497e-04f, -5.2265642972e-04f, + -5.4665656337e-04f, -5.6778025613e-04f, -5.8709304852e-04f, -6.1327473938e-04f, + -6.3124935319e-04f, -6.5403333621e-04f, -6.7776907764e-04f, -6.9416146273e-04f, + -7.1577364744e-04f, -7.2550431222e-04f, -7.4409418541e-04f, -7.4905980532e-04f, + -7.6813719270e-04f, -7.7248485949e-04f, -7.8343322877e-04f, -7.7798694927e-04f, + -7.8036647100e-04f, -7.8014496257e-04f, -7.7579773310e-04f, -7.6307935757e-04f, + -7.5300014201e-04f, -7.3193571525e-04f, -7.2153919876e-04f, -6.9179375372e-04f, + -6.6504150893e-04f, -6.3415949025e-04f, -5.9461189330e-04f, -5.5645763906e-04f, + -5.1455722108e-04f, -4.6063254803e-04f, -4.0951214522e-04f, -3.5011758756e-04f, + -2.8969811748e-04f, -2.0983373440e-04f, -1.4463809349e-04f, -6.1733440720e-05f, + +1.3494974180e-05f, +1.0943831274e-04f, +2.0430170688e-04f, +2.9495311041e-04f, + +4.0265402160e-04f, +5.1073884952e-04f, +6.2393761391e-04f, +7.4580258865e-04f, + +8.6084433262e-04f, +9.8859883015e-04f, +1.1250155131e-03f, +1.2577884647e-03f, + +1.3902494827e-03f, +1.5443219847e-03f, +1.6868083253e-03f, +1.8348265422e-03f, + +1.9841140737e-03f, +2.1461583556e-03f, +2.3017254775e-03f, +2.4625616913e-03f, + +2.6201758690e-03f, +2.7870464347e-03f, +2.9469447716e-03f, +3.1125420653e-03f, + +3.2739613485e-03f, +3.4418874183e-03f, +3.6008268123e-03f, +3.7603922910e-03f, + +3.9207432370e-03f, +4.0819753194e-03f, +4.2264269227e-03f, +4.3730719678e-03f, + +4.5209852783e-03f, +4.6606460612e-03f, +4.7932560850e-03f, +4.9137603574e-03f, + +5.0393022601e-03f, +5.1407353903e-03f, +5.2461166132e-03f, +5.3471681198e-03f, + +5.4196775931e-03f, +5.4876040151e-03f, +5.5475714509e-03f, +5.5938023005e-03f, + +5.6220643210e-03f, +5.6455196916e-03f, +5.6389199515e-03f, +5.6266114193e-03f, + +5.5917128663e-03f, +5.5404363940e-03f, +5.4753783077e-03f, +5.3838975897e-03f, + +5.2715758727e-03f, +5.1382275451e-03f, +4.9839687763e-03f, +4.8109469060e-03f, + +4.6039530147e-03f, +4.3801861745e-03f, +4.1251642327e-03f, +3.8456408125e-03f, + +3.5401246551e-03f, +3.2091885810e-03f, +2.8446757862e-03f, +2.4508540032e-03f, + +2.0274176185e-03f, +1.5784682577e-03f, +1.0902329051e-03f, +5.8322642480e-04f, + +2.7604519050e-05f, -5.4642808664e-04f, -1.1568135523e-03f, -1.8039472589e-03f, + -2.4826723645e-03f, -3.1933778390e-03f, -3.9401124052e-03f, -4.7222596240e-03f, + -5.5337211109e-03f, -6.3792293269e-03f, -7.2615816852e-03f, -8.1798233373e-03f, + -9.1325329609e-03f, -1.0115021550e-02f, -1.1131554803e-02f, -1.2184999595e-02f, + +1.3271822004e-02f, +1.4390466608e-02f, +1.5540555334e-02f, +1.6732471300e-02f, + +1.7943338134e-02f, +1.9187243137e-02f, +2.0453179336e-02f, +2.1746755025e-02f, + +2.3068016929e-02f, +2.4416099203e-02f, +2.5787584755e-02f, +2.7185942963e-02f, + +2.8607217364e-02f, +3.0050265743e-02f, +3.1501760874e-02f, +3.2975408103e-02f, + +3.4462094877e-02f, +3.5969756055e-02f, +3.7481285043e-02f, +3.9005367947e-02f, + +4.0534917056e-02f, +4.2064909464e-02f, +4.3609754213e-02f, +4.5148840564e-02f, + +4.6684302726e-02f, +4.8216572007e-02f, +4.9738575560e-02f, +5.1255615552e-02f, + +5.2763074652e-02f, +5.4245276836e-02f, +5.5717364821e-02f, +5.7161645013e-02f, + +5.8591568363e-02f, +5.9983748018e-02f, +6.1345517172e-02f, +6.2685780812e-02f, + +6.3971589807e-02f, +6.5224710644e-02f, +6.6436751221e-02f, +6.7607598512e-02f, + +6.8704382835e-02f, +6.9763024471e-02f, +7.0762871073e-02f, +7.1700267311e-02f, + +7.2568258331e-02f, +7.3362025508e-02f, +7.4100364243e-02f, +7.4745255812e-02f, + +7.5313733620e-02f, +7.5800835866e-02f, +7.6199247934e-02f, +7.6499217041e-02f, + +7.6709349042e-02f, +7.6817397570e-02f, +7.6823001139e-02f, +7.6720492417e-02f, + +7.6505071832e-02f, +7.6174832185e-02f, +7.5730575651e-02f, +7.5157625529e-02f, + +7.4466439476e-02f, +7.3640600576e-02f, +7.2677464273e-02f, +7.1582636479e-02f, + +7.0353307351e-02f, +6.8966401320e-02f, +6.7452502152e-02f, +6.5769066865e-02f, + +6.3944480596e-02f, +6.1960277904e-02f, +5.9816657081e-02f, +5.7515269199e-02f, + +5.5046003430e-02f, +5.2409382174e-02f, +4.9597867634e-02f, +4.6630330517e-02f, + +4.3476878220e-02f, +4.0145827841e-02f, +3.6641811681e-02f, +3.2958393067e-02f, + +2.9082400601e-02f, +2.5030756189e-02f, +2.0799707286e-02f, +1.6370125822e-02f, + +1.1762383279e-02f, +6.9636862162e-03f, +1.9765601450e-03f, -3.2086896830e-03f, + -8.5711749137e-03f, -1.4128882736e-02f, -1.9883412926e-02f, -2.5822728881e-02f, + -3.1953127453e-02f, -3.8277657208e-02f, -4.4780682159e-02f, -5.1480417679e-02f, + -5.8370532683e-02f, -6.5440985314e-02f, -7.2694330081e-02f, -8.0137293443e-02f, + -8.7754753656e-02f, -9.5553335289e-02f, -1.0353295311e-01f, -1.1168269318e-01f, + -1.2000779847e-01f, -1.2850028504e-01f, -1.3715517612e-01f, -1.4597664912e-01f, + -1.5496070711e-01f, -1.6409588557e-01f, -1.7338081722e-01f, -1.8281725485e-01f, + -1.9239667457e-01f, -2.0212501768e-01f, -2.1197358538e-01f, -2.2196526964e-01f, + -2.3206908707e-01f, -2.4230168846e-01f, -2.5264803096e-01f, -2.6310532995e-01f, + -2.7366340406e-01f, -2.8432141891e-01f, -2.9507167171e-01f, -3.0590985752e-01f, + -3.1682789136e-01f, -3.2781137272e-01f, -3.3887226939e-01f, -3.4999141229e-01f, + +3.6115899031e-01f, +3.7237955463e-01f, +3.8363500139e-01f, +3.9492117616e-01f, + +4.0623176768e-01f, +4.1756968968e-01f, +4.2891199207e-01f, +4.4025537544e-01f, + +4.5159965357e-01f, +4.6293080853e-01f, +4.7424532146e-01f, +4.8552530911e-01f, + +4.9677082546e-01f, +5.0798175000e-01f, +5.1912349702e-01f, +5.3022408957e-01f, + +5.4125534487e-01f, +5.5220512585e-01f, +5.6307891401e-01f, +5.7385241317e-01f, + +5.8454032355e-01f, +5.9511230862e-01f, +6.0557835389e-01f, +6.1591099320e-01f, + +6.2612426956e-01f, +6.3619801077e-01f, +6.4612696959e-01f, +6.5590163025e-01f, + +6.6551398802e-01f, +6.7496631902e-01f, +6.8423532935e-01f, +6.9332823767e-01f, + +7.0223887194e-01f, +7.1094104263e-01f, +7.1944626350e-01f, +7.2774489003e-01f, + +7.3582117583e-01f, +7.4368278636e-01f, +7.5131374561e-01f, +7.5870807608e-01f, + +7.6586748651e-01f, +7.7277808813e-01f, +7.7942875190e-01f, +7.8583531204e-01f, + +7.9197358416e-01f, +7.9784664138e-01f, +8.0344857519e-01f, +8.0876950044e-01f, + +8.1381912706e-01f, +8.1857760046e-01f, +8.2304198905e-01f, +8.2722753473e-01f, + +8.3110384572e-01f, +8.3469373618e-01f, +8.3797173379e-01f, +8.4095413925e-01f, + +8.4362382812e-01f, +8.4598184698e-01f, +8.4803157771e-01f, +8.4978051984e-01f, + +8.5119715249e-01f, +8.5230470352e-01f, +8.5310209497e-01f, +8.5357205739e-01f, + +8.5373856006e-01f, +8.5357205739e-01f, +8.5310209497e-01f, +8.5230470352e-01f, + +8.5119715249e-01f, +8.4978051984e-01f, +8.4803157771e-01f, +8.4598184698e-01f, + +8.4362382812e-01f, +8.4095413925e-01f, +8.3797173379e-01f, +8.3469373618e-01f, + +8.3110384572e-01f, +8.2722753473e-01f, +8.2304198905e-01f, +8.1857760046e-01f, + +8.1381912706e-01f, +8.0876950044e-01f, +8.0344857519e-01f, +7.9784664138e-01f, + +7.9197358416e-01f, +7.8583531204e-01f, +7.7942875190e-01f, +7.7277808813e-01f, + +7.6586748651e-01f, +7.5870807608e-01f, +7.5131374561e-01f, +7.4368278636e-01f, + +7.3582117583e-01f, +7.2774489003e-01f, +7.1944626350e-01f, +7.1094104263e-01f, + +7.0223887194e-01f, +6.9332823767e-01f, +6.8423532935e-01f, +6.7496631902e-01f, + +6.6551398802e-01f, +6.5590163025e-01f, +6.4612696959e-01f, +6.3619801077e-01f, + +6.2612426956e-01f, +6.1591099320e-01f, +6.0557835389e-01f, +5.9511230862e-01f, + +5.8454032355e-01f, +5.7385241317e-01f, +5.6307891401e-01f, +5.5220512585e-01f, + +5.4125534487e-01f, +5.3022408957e-01f, +5.1912349702e-01f, +5.0798175000e-01f, + +4.9677082546e-01f, +4.8552530911e-01f, +4.7424532146e-01f, +4.6293080853e-01f, + +4.5159965357e-01f, +4.4025537544e-01f, +4.2891199207e-01f, +4.1756968968e-01f, + +4.0623176768e-01f, +3.9492117616e-01f, +3.8363500139e-01f, +3.7237955463e-01f, + -3.6115899031e-01f, -3.4999141229e-01f, -3.3887226939e-01f, -3.2781137272e-01f, + -3.1682789136e-01f, -3.0590985752e-01f, -2.9507167171e-01f, -2.8432141891e-01f, + -2.7366340406e-01f, -2.6310532995e-01f, -2.5264803096e-01f, -2.4230168846e-01f, + -2.3206908707e-01f, -2.2196526964e-01f, -2.1197358538e-01f, -2.0212501768e-01f, + -1.9239667457e-01f, -1.8281725485e-01f, -1.7338081722e-01f, -1.6409588557e-01f, + -1.5496070711e-01f, -1.4597664912e-01f, -1.3715517612e-01f, -1.2850028504e-01f, + -1.2000779847e-01f, -1.1168269318e-01f, -1.0353295311e-01f, -9.5553335289e-02f, + -8.7754753656e-02f, -8.0137293443e-02f, -7.2694330081e-02f, -6.5440985314e-02f, + -5.8370532683e-02f, -5.1480417679e-02f, -4.4780682159e-02f, -3.8277657208e-02f, + -3.1953127453e-02f, -2.5822728881e-02f, -1.9883412926e-02f, -1.4128882736e-02f, + -8.5711749137e-03f, -3.2086896830e-03f, +1.9765601450e-03f, +6.9636862162e-03f, + +1.1762383279e-02f, +1.6370125822e-02f, +2.0799707286e-02f, +2.5030756189e-02f, + +2.9082400601e-02f, +3.2958393067e-02f, +3.6641811681e-02f, +4.0145827841e-02f, + +4.3476878220e-02f, +4.6630330517e-02f, +4.9597867634e-02f, +5.2409382174e-02f, + +5.5046003430e-02f, +5.7515269199e-02f, +5.9816657081e-02f, +6.1960277904e-02f, + +6.3944480596e-02f, +6.5769066865e-02f, +6.7452502152e-02f, +6.8966401320e-02f, + +7.0353307351e-02f, +7.1582636479e-02f, +7.2677464273e-02f, +7.3640600576e-02f, + +7.4466439476e-02f, +7.5157625529e-02f, +7.5730575651e-02f, +7.6174832185e-02f, + +7.6505071832e-02f, +7.6720492417e-02f, +7.6823001139e-02f, +7.6817397570e-02f, + +7.6709349042e-02f, +7.6499217041e-02f, +7.6199247934e-02f, +7.5800835866e-02f, + +7.5313733620e-02f, +7.4745255812e-02f, +7.4100364243e-02f, +7.3362025508e-02f, + +7.2568258331e-02f, +7.1700267311e-02f, +7.0762871073e-02f, +6.9763024471e-02f, + +6.8704382835e-02f, +6.7607598512e-02f, +6.6436751221e-02f, +6.5224710644e-02f, + +6.3971589807e-02f, +6.2685780812e-02f, +6.1345517172e-02f, +5.9983748018e-02f, + +5.8591568363e-02f, +5.7161645013e-02f, +5.5717364821e-02f, +5.4245276836e-02f, + +5.2763074652e-02f, +5.1255615552e-02f, +4.9738575560e-02f, +4.8216572007e-02f, + +4.6684302726e-02f, +4.5148840564e-02f, +4.3609754213e-02f, +4.2064909464e-02f, + +4.0534917056e-02f, +3.9005367947e-02f, +3.7481285043e-02f, +3.5969756055e-02f, + +3.4462094877e-02f, +3.2975408103e-02f, +3.1501760874e-02f, +3.0050265743e-02f, + +2.8607217364e-02f, +2.7185942963e-02f, +2.5787584755e-02f, +2.4416099203e-02f, + +2.3068016929e-02f, +2.1746755025e-02f, +2.0453179336e-02f, +1.9187243137e-02f, + +1.7943338134e-02f, +1.6732471300e-02f, +1.5540555334e-02f, +1.4390466608e-02f, + -1.3271822004e-02f, -1.2184999595e-02f, -1.1131554803e-02f, -1.0115021550e-02f, + -9.1325329609e-03f, -8.1798233373e-03f, -7.2615816852e-03f, -6.3792293269e-03f, + -5.5337211109e-03f, -4.7222596240e-03f, -3.9401124052e-03f, -3.1933778390e-03f, + -2.4826723645e-03f, -1.8039472589e-03f, -1.1568135523e-03f, -5.4642808664e-04f, + +2.7604519050e-05f, +5.8322642480e-04f, +1.0902329051e-03f, +1.5784682577e-03f, + +2.0274176185e-03f, +2.4508540032e-03f, +2.8446757862e-03f, +3.2091885810e-03f, + +3.5401246551e-03f, +3.8456408125e-03f, +4.1251642327e-03f, +4.3801861745e-03f, + +4.6039530147e-03f, +4.8109469060e-03f, +4.9839687763e-03f, +5.1382275451e-03f, + +5.2715758727e-03f, +5.3838975897e-03f, +5.4753783077e-03f, +5.5404363940e-03f, + +5.5917128663e-03f, +5.6266114193e-03f, +5.6389199515e-03f, +5.6455196916e-03f, + +5.6220643210e-03f, +5.5938023005e-03f, +5.5475714509e-03f, +5.4876040151e-03f, + +5.4196775931e-03f, +5.3471681198e-03f, +5.2461166132e-03f, +5.1407353903e-03f, + +5.0393022601e-03f, +4.9137603574e-03f, +4.7932560850e-03f, +4.6606460612e-03f, + +4.5209852783e-03f, +4.3730719678e-03f, +4.2264269227e-03f, +4.0819753194e-03f, + +3.9207432370e-03f, +3.7603922910e-03f, +3.6008268123e-03f, +3.4418874183e-03f, + +3.2739613485e-03f, +3.1125420653e-03f, +2.9469447716e-03f, +2.7870464347e-03f, + +2.6201758690e-03f, +2.4625616913e-03f, +2.3017254775e-03f, +2.1461583556e-03f, + +1.9841140737e-03f, +1.8348265422e-03f, +1.6868083253e-03f, +1.5443219847e-03f, + +1.3902494827e-03f, +1.2577884647e-03f, +1.1250155131e-03f, +9.8859883015e-04f, + +8.6084433262e-04f, +7.4580258865e-04f, +6.2393761391e-04f, +5.1073884952e-04f, + +4.0265402160e-04f, +2.9495311041e-04f, +2.0430170688e-04f, +1.0943831274e-04f, + +1.3494974180e-05f, -6.1733440720e-05f, -1.4463809349e-04f, -2.0983373440e-04f, + -2.8969811748e-04f, -3.5011758756e-04f, -4.0951214522e-04f, -4.6063254803e-04f, + -5.1455722108e-04f, -5.5645763906e-04f, -5.9461189330e-04f, -6.3415949025e-04f, + -6.6504150893e-04f, -6.9179375372e-04f, -7.2153919876e-04f, -7.3193571525e-04f, + -7.5300014201e-04f, -7.6307935757e-04f, -7.7579773310e-04f, -7.8014496257e-04f, + -7.8036647100e-04f, -7.7798694927e-04f, -7.8343322877e-04f, -7.7248485949e-04f, + -7.6813719270e-04f, -7.4905980532e-04f, -7.4409418541e-04f, -7.2550431222e-04f, + -7.1577364744e-04f, -6.9416146273e-04f, -6.7776907764e-04f, -6.5403333621e-04f, + -6.3124935319e-04f, -6.1327473938e-04f, -5.8709304852e-04f, -5.6778025613e-04f, + -5.4665656337e-04f, -5.2265642972e-04f, -5.0407143497e-04f, -4.8937912498e-04f, + -4.8752279712e-04f, -4.9475180896e-04f, -5.6176925738e-04f, -5.5252865047e-04f, +}; + +const signed char sbr_offset616 = { + /* 16000 */ {-8,-7,-6,-5,-4,-3,-2,-1, 0, 1, 2, 3, 4, 5, 6, 7}, + /* 22050 */ {-5,-4,-3,-2,-1, 0, 1, 2, 3, 4, 5, 6, 7, 9,11,13}, + /* 24000 */ {-5,-3,-2,-1, 0, 1, 2, 3, 4, 5, 6, 7, 9,11,13,16}, + /* 32000 */ {-6,-4,-2,-1, 0, 1, 2, 3, 4, 5, 6, 7, 9,11,13,16}, + /* 44-64k */ {-4,-2,-1, 0, 1, 2, 3, 4, 5, 6, 7, 9,11,13,16,20}, + /* >64k */ {-2,-1, 0, 1, 2, 3, 4, 5, 6, 7, 9,11,13,16,20,24}, +}; + +const SBRHuffEntry f_huff_env_1_5dBF_HUFF_ENV_1_5DB_NSYMS = { + /* -60 */ { 0x0007ffe7u, 19 }, + /* -59 */ { 0x0007ffe8u, 19 }, + /* -58 */ { 0x000fffd2u, 20 }, + /* -57 */ { 0x000fffd3u, 20 }, + /* -56 */ { 0x000fffd4u, 20 }, + /* -55 */ { 0x000fffd5u, 20 }, + /* -54 */ { 0x000fffd6u, 20 }, + /* -53 */ { 0x000fffd7u, 20 }, + /* -52 */ { 0x000fffd8u, 20 },
View file
_service:obs_scm:faac-2.0.obscpio/libfaac/sbr_tables.h
Added
@@ -0,0 +1,49 @@ +/* + * FAAC - Freeware Advanced Audio Coder + * SBR tables reproduced from ISO/IEC 14496-3 (non-copyrightable facts) + * + * 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. + */ + +/* SBR tables: QMF prototype filter, frequency-band offsets, Huffman tables. + * All values are normative data from ISO/IEC 14496-3:2005. */ + +#ifndef SBR_TABLES_H +#define SBR_TABLES_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float sbrfloat; + +typedef struct { + uint32_t code : 24; + uint32_t len : 8; +} SBRHuffEntry; + +#define F_HUFF_ENV_1_5DB_OFFSET 60 +#define F_HUFF_ENV_1_5DB_NSYMS 121 +#define F_HUFF_ENV_3_0DB_OFFSET 31 +#define F_HUFF_ENV_3_0DB_NSYMS 63 + +extern const sbrfloat qmf_c640; +extern const signed char sbr_offset616; +extern const SBRHuffEntry f_huff_env_1_5dBF_HUFF_ENV_1_5DB_NSYMS; +extern const SBRHuffEntry f_huff_env_3_0dBF_HUFF_ENV_3_0DB_NSYMS; + +#ifdef __cplusplus +} +#endif + +#endif /* SBR_TABLES_H */
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/stereo.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/stereo.c
Changed
@@ -1,389 +1,310 @@ -/**************************************************************************** - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +/* + * 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. + */ #define _USE_MATH_DEFINES - #include <math.h> +#include <string.h> #include "stereo.h" #include "huff2.h" +#include "util.h" +#include "faac_internal.h" + +/* Intensity stereo applies only at and above this frequency; below it the ear + * localizes from waveform detail, so panning the band would be audible. */ +#define IS_START_FREQ_HZ 5500 +/* Upper bound on the crossover, as a fraction of the sample rate (0.35*Fs = + * 0.7*Nyquist), so the band stays well inside the coded spectrum. */ +#define IS_FREQ_CAP_NUM 7 +#define IS_FREQ_CAP_DEN 20 +/* Pan, in SF_STEP_ENRG steps, beyond which the quieter channel is inaudible + * and is dropped to HCB_ZERO rather than intensity-coded. */ +#define IS_PAN_LIMIT 30 + +/* Accumulate channel energies and cross-correlation for a scale factor band. + * Using three independent accumulators maximizes instruction-level parallelism + * by avoiding read-after-write dependencies on the FPU pipeline. */ +static inline void calculate_energies(const float * restrict sl0, const float * restrict sr0, + int start, int len, int wstart, int wend, + float * restrict el_out, float * restrict er_out, float * restrict elr_out) +{ + float el = 0, er = 0, elr = 0; + int win, i; + + for (win = wstart; win < wend; win++) { + const float * restrict sl = sl0 + win * BLOCK_LEN_SHORT + start; + const float * restrict sr = sr0 + win * BLOCK_LEN_SHORT + start; + for (i = 0; i < len; i++) { + float l = sli; + float r = sri; + el += l * l; + er += r * r; + elr += l * r; + } + } + *el_out = el; + *er_out = er; + *elr_out = elr; +} - -static void stereo(CoderInfo *cl, CoderInfo *cr, - faac_real *sl0, faac_real *sr0, int *sfcnt, - int wstart, int wend, faac_real phthr - ) +/* Fast memory-clearing utility for suppressed channels. */ +static inline void apply_mute(float * restrict s0, int start, int len, int wstart, int wend) { - 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_offsetsfb; - end = cl->sfb_offsetsfb + 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 = sll; - faac_real rx = srl; - - sum = lx + rx; - diff = lx - rx; + for (win = wstart; win < wend; win++) { + float * restrict s = s0 + win * BLOCK_LEN_SHORT + start; + memset(s, 0, len * sizeof(float)); + } +} - enrgs += sum * sum; - enrgd += diff * diff; - enrgl += lx * lx; - enrgr += rx * rx; +/* When one component (mid or side) dominates, collapse both channels to that + * component and zero the other — it costs no bits and the signal loss is masked. + * Factor of 0.5 keeps the coded amplitude on the same scale as L/R. */ +static inline void apply_ms(float * restrict sl0, float * restrict sr0, + int start, int len, int wstart, int wend, int in_phase) +{ + int win, i; + if (in_phase) { + for (win = wstart; win < wend; win++) { + float * restrict sl = sl0 + win * BLOCK_LEN_SHORT + start; + float * restrict sr = sr0 + win * BLOCK_LEN_SHORT + start; + for (i = 0; i < len; i++) { + sli = 0.5f * (sli + sri); + sri = 0.0f; } } - - 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; + } else { + for (win = wstart; win < wend; win++) { + float * restrict sl = sl0 + win * BLOCK_LEN_SHORT + start; + float * restrict sr = sr0 + win * BLOCK_LEN_SHORT + start; + for (i = 0; i < len; i++) { + sri = 0.5f * (sli - sri); + sli = 0.0f; } - int sf = FAAC_LRINT(FAAC_LOG10(enrgl / efix) * step); - int pan = FAAC_LRINT(FAAC_LOG10(enrgr/efix) * step) - sf; + } + } +}
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/stereo.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/stereo.h
Changed
@@ -1,29 +1,35 @@ -/**************************************************************************** - Intensity Stereo +/* + * 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. + */ - Copyright (C) 2017 Krzysztof Nikiel +#ifndef STEREO_H +#define STEREO_H - 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 <http://www.gnu.org/licenses/>. -****************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "channels.h" #include "util.h" void AACstereo(CoderInfo *coder, - ChannelInfo *channel, - faac_real *sMAX_CHANNELS, - int maxchan, - faac_real quality, - int mode + AACElement *elements, + int numElements, + float *sMAX_CHANNELS, + float quality, + int mode, + int sampleRate ); + +#endif
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/tns.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/tns.c
Changed
@@ -1,500 +1,372 @@ -/********************************************************************** - -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 $ + * 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. */ #include <math.h> +#include <string.h> #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 tnsMinBandNumberLong12 = -{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 }; -static unsigned short tnsMinBandNumberShort12 = -{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 }; - -/**************************************/ -/* Main/Low Profile TNS Parameters */ -/**************************************/ -static unsigned short tnsMaxBandsLongMainLow12 = -{ 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 }; - -static unsigned short tnsMaxBandsShortMainLow12 = -{ 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; - +/* Per-sample-rate scalefactor-band range TNS is allowed to filter over, from + * ISO/IEC 13818-7/14496-3's TNS tool tables (indexed by sampleRateIdx). Not + * an original heuristic: this is the spec's fixed table. */ +static const struct { + unsigned char min; + unsigned char max; +} tns_sfb_range12 = { + {11, 31}, {12, 31}, {15, 34}, {16, 40}, {17, 42}, {20, 51}, + {25, 46}, {26, 46}, {24, 42}, {28, 42}, {30, 42}, {31, 39} +}; + +#define TNS_LPC_ORDER 8 /* fixed filter order; spec allows up to TNS_MAX_ORDER but higher orders rarely paid for themselves here */ +#define TNS_GAIN_LIMIT 1.4f /* Levinson-Durbin prediction gain below this isn't worth the filter's bit cost */ +#define TNS_GAIN_CLAMP 6.0f /* gain above this means a near-singular fit (e.g. a single strong tone); reject rather than risk an unstable filter */ +#define TNS_MEASURED_GAIN 1.4f /* post-quantization re-check: same bar as TNS_GAIN_LIMIT, applied to the filter actually being transmitted */ + +/* Below this, a band's spectral energy is indistinguishable from float + * rounding noise, so there's nothing real for TNS to whiten. Also reused + * below as the floor for RMS-normalization and the LPC residual check, + * rather than inventing a separate near-zero constant for each. */ +#define TNS_MIN_ENERGY 1e-9f +/* SFM (geomean/arithmean of per-band RMS) near 1.0 means the band is + * noise-like, which PNS (quantize.c) is about to replace anyway -- skip + * TNS's LPC work there; it only pays off on tonal/peaky bands. */ +#define TNS_PNS_SFM_SKIP 0.85f + +static void calc_autocorr_f(int order, int length, const float * work, float * r) +{ + int lag, i; -/*************************/ -/* 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 */ + for (lag = 0; lag <= order; lag++) { + float acc = 0.0f; + const float * p1 = work; + const float * p2 = work + lag; + int n = length - lag; -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 */ + for (i = 0; i < n; i++) + acc += p1i * p2i; + rlag = acc; + } +} -static void StepUp(int fOrder, faac_real* kArray, faac_real* aArray); +/* Reflection coefficients are clamped to +-0.999, short of the unstable + * +-1 limit, so the resulting filter is guaranteed stable regardless of + * input. The returned prediction gain (r0/final residual error) lets + * TnsEncode reject a bad fit before spending any bits on coefficients -- + * free to report here, since the recursion already has both numbers. */ +static float compute_lpc(int order, const float * r, float * k) +{ + float aTNS_MAX_ORDER + 1; + float err; + int i, j; + + if (r0 <= 0.0f) { + for (i = 1; i <= order; i++) + ki = 0.0f; + return 1.0f; + } -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); + err = r0; + a0 = 1.0f; + for (i = 1; i <= order; i++) { + float lambda = ri; + float rc; + int half; + for (j = 1; j < i; j++) + lambda += aj * ri - j; -/*****************************************************/ -/* 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->coderInfochannel.tnsInfo; - - switch( profile ) { - case MAIN: - case LTP: - tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLowfsIndex; - tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLowfsIndex; - 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 = tnsMaxBandsLongMainLowfsIndex; - tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLowfsIndex; - 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; + if (err <= 0.0f) { + for (; i <= order; i++) + ki = 0.0f; break; }
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/tns.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/tns.h
Changed
@@ -1,47 +1,41 @@ -/********************************************************************** - -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. -**********************************************************************/ /* - * $Id: tns.h,v 1.6 2012/03/01 18:34:17 knik Exp $ + * 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. + */ + +/* + * Temporal Noise Shaping (TNS): a predictive filter along the frequency axis + * that reshapes quantization noise in time so it hides behind transients + * instead of leaking out as pre-echo. Long-window only here; short windows + * already have the temporal resolution to not need it. */ #ifndef TNS_H #define TNS_H -#include "faac_real.h" +#include "coder.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - +/* Latch the per-channel band limits from the sample rate's TNS tool table. */ void TnsInit(faacEncStruct* hEncoder); -void TnsEncode(TnsInfo* tnsInfo, int numberOfBands,int maxSfb,enum WINDOW_TYPE blockType, - int* sfbOffsetTable,faac_real* spec, faac_real* temp); -void TnsEncodeFilterOnly(TnsInfo* tnsInfo, int numberOfBands, int maxSfb, - enum WINDOW_TYPE blockType, int *sfbOffsetTable, faac_real *spec, faac_real *temp); + +/* Analyse one channel and, if it pays off, whiten `spec` in place. */ +void TnsEncode(TnsInfo* tnsInfo, int numBands, + enum WINDOW_TYPE blockType, int* sfbOffsetTable, + float* spec); #ifdef __cplusplus }
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/util.c -> _service:obs_scm:faac-2.0.obscpio/libfaac/util.c
Changed
@@ -11,18 +11,15 @@ * 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 <math.h> - #include "util.h" #include "coder.h" // FRAME_LEN +#ifdef _MSC_VER +#include <intrin.h> +#endif + /* Returns the sample rate index */ int GetSRIndex(unsigned int sampleRate) { @@ -45,12 +42,34 @@ unsigned int MaxBitrate(unsigned long sampleRate) { /* max ADTS frame size 8k */ - return 0x2000 * 8 * (faac_real)sampleRate/(faac_real)FRAME_LEN; + return 0x2000 * 8 * (float)sampleRate/(float)FRAME_LEN; } /* Returns the minimum bitrate per channel for that sampling frequency */ -unsigned int MinBitrate() +unsigned int MinBitrate(void) { return 8000; } +/* Portable CLZ (returns 32 for x==0); lets escape() get a magnitude's bit-length + * in O(1) instead of the old shift-until-fits loop. */ +int CountLeadingZeros(unsigned int x) +{ + if (x == 0) return 32; +#ifdef _MSC_VER + unsigned long leading_zero; + _BitScanReverse(&leading_zero, x); + return 31 - leading_zero; +#elif defined(__GNUC__) || defined(__clang__) + return __builtin_clz(x); +#else + int n = 0; + if (x <= 0x0000FFFF) { n += 16; x <<= 16; } + if (x <= 0x00FFFFFF) { n += 8; x <<= 8; } + if (x <= 0x0FFFFFFF) { n += 4; x <<= 4; } + if (x <= 0x3FFFFFFF) { n += 2; x <<= 2; } + if (x <= 0x7FFFFFFF) { n += 1; x <<= 1; } + return n; +#endif +} +
View file
_service:obs_scm:faac-1.50.obscpio/libfaac/util.h -> _service:obs_scm:faac-2.0.obscpio/libfaac/util.h
Changed
@@ -11,25 +11,18 @@ * 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 <stdlib.h> -#include <memory.h> +#include <string.h> #ifndef max #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -38,10 +31,25 @@ #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif +static inline int clamp_int(int x, int lo, int hi) +{ + if (x < lo) return lo; + if (x > hi) return hi; + return x; +} + #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846f +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880f #endif +/* Double-precision pi, for one-time table/window generation at encoder init + * (FFT/MDCT twiddles, SBR QMF twiddles, MDCT window shapes) where the extra + * precision is free — these run once, never in the per-sample hot path. */ +#define M_PI_DOUBLE 3.14159265358979323846 + /* Memory functions */ #define AllocMemory(size) malloc(size) #define FreeMemory(block) free(block) @@ -49,7 +57,8 @@ int GetSRIndex(unsigned int sampleRate); unsigned int MaxBitrate(unsigned long sampleRate); -unsigned int MinBitrate(); +unsigned int MinBitrate(void); +int CountLeadingZeros(unsigned int x); #ifdef __cplusplus }
View file
_service:obs_scm:faac-1.50.obscpio/meson.build -> _service:obs_scm:faac-2.0.obscpio/meson.build
Changed
@@ -1,11 +1,10 @@ project('faac', 'c', - version: '1.50.0', + version: '2.0.0', default_options: 'default_library=both', 'buildtype=release', - 'warning_level=1', - 'c_std=gnu99,c99', - 'b_lto=true' + 'warning_level=3', + 'c_std=gnu11,c11', ) add_global_arguments('-DHAVE_CONFIG_H', language: 'c') @@ -19,6 +18,8 @@ config_h.set('HAVE_' + h.underscorify().to_upper(), cc.has_header(h)) endforeach +config_h.set('WORDS_BIGENDIAN', host_machine.endian() == 'big') + libm = cc.find_library('m', required: false) @@ -26,11 +27,7 @@ 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('FAAC_SBR_DECIMATION', get_option('sbr-decimation')) config_h.set('MAX_CHANNELS', get_option('max-channels'))
View file
_service:obs_scm:faac-1.50.obscpio/meson_options.txt -> _service:obs_scm:faac-2.0.obscpio/meson_options.txt
Changed
@@ -3,11 +3,20 @@ type: 'boolean', value: true) -option('floating-point', - description: 'Floating point precision', - type: 'combo', - choices: 'single', 'double', - value: 'double') +# SBR spectral analysis density: analyse every Nth slot per frame. +# 1 = full quality (every slot); higher values trade MOS for faster encode. +# Max 8: above that, both halves of the frame are sampled but the gain is negligible. +# Only affects HE-AAC; LC encodes are identical regardless of this setting. +# 1: every slot -- reference quality (MOS d: 0) +# 2: every 2nd -- ~20% faster HE-AAC encode; MOS d: -0.004 +# 4: every 4th -- ~30% faster HE-AAC encode; MOS d: -0.015 +# 8: every 8th -- ~36% faster HE-AAC encode; MOS d: -0.028 +option('sbr-decimation', + description: 'SBR spectral analysis density: analyse every Nth slot (1=full quality, max=8)', + type: 'integer', + min: 1, + max: 8, + value: 1) option('max-channels', description: 'Maximum number of channels',
View file
_service:obs_scm:faac.obsinfo
Changed
@@ -1,4 +1,4 @@ name: faac -version: 1.50 -mtime: 1776322708 -commit: 79329efee51c9d3545bc4c7179b43a23fe350b6b +version: 2.0 +mtime: 1784530335 +commit: 19504462aef3d444aa09b9cfcad0e2146889fb3b
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.