diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/LGPL.txt b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/LGPL.txt new file mode 100644 index 000000000..1e0991447 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/LGPL.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/Makefile b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/Makefile new file mode 100644 index 000000000..df27432cd --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/Makefile @@ -0,0 +1,39 @@ +# note: this Makefile builds the Linux version only + +CFLAGS = -Wall -Os -march=pentium +CFLAGS += -ffast-math +CFLAGS += -finline-functions-called-once +CFLAGS += -fno-loop-optimize +CFLAGS += -fexpensive-optimizations +CFLAGS += -fpeephole2 + +STRIPFLAGS = -R .comment +STRIPFLAGS += -R .note +STRIPFLAGS += -R .note.ABI-tag +STRIPFLAGS += -R .gnu.version + +BIN = minimp3 +FINALBIN = $(BIN)-linux +OBJS = player_oss.o minimp3.o + +all: $(BIN) + +release: $(BIN) + strip $(STRIPFLAGS) $(BIN) + upx --brute $(BIN) + +test: $(BIN) + ./$(BIN) "../../../Gargaj -- Rude Awakening.mp3" + +$(BIN): $(OBJS) + gcc $(OBJS) -o $(BIN) -lm + +%.o: %.c + gcc $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(BIN) $(OBJS) + +dist: clean release + mv $(BIN) $(FINALBIN) + rm -f $(OBJS) diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/libc.h b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/libc.h new file mode 100644 index 000000000..4986fc8fc --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/libc.h @@ -0,0 +1,184 @@ +// a libc replacement (more or less) for the Microsoft Visual C compiler +// this file is public domain -- do with it whatever you want! +#ifndef __LIBC_H_INCLUDED__ +#define __LIBC_H_INCLUDED__ + +// check if minilibc is required +#ifndef NEED_MINILIBC + #ifndef NOLIBC + #define NEED_MINILIBC 0 + #else + #define NEED_MINILIBC 1 + #endif +#endif + +#ifdef _MSC_VER + #define INLINE __forceinline + #define FASTCALL __fastcall + #ifdef NOLIBC + #ifdef MAIN_PROGRAM + int _fltused=0; + #endif + #endif +#else + #define INLINE inline + #define FASTCALL __attribute__((fastcall)) + #include +#endif + +#ifdef _WIN32 + #ifndef WIN32 + #define WIN32 + #endif +#endif +#ifdef WIN32 + #include +#endif + +#if !NEED_MINILIBC + #include + #include + #include +#endif +#include + +#ifndef __int8_t_defined + #define __int8_t_defined + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef signed short int16_t; + typedef unsigned int uint32_t; + typedef signed int int32_t; + #ifdef _MSC_VER + typedef unsigned __int64 uint64_t; + typedef signed __int64 int64_t; + #else + typedef unsigned long long uint64_t; + typedef signed long long int64_t; + #endif +#endif + +#ifndef NULL + #define NULL 0 +#endif + +#ifndef M_PI + #define M_PI 3.14159265358979 +#endif + +/////////////////////////////////////////////////////////////////////////////// + +#if NEED_MINILIBC + +static INLINE void libc_memset(void *dest, int value, int count) { + if (!count) return; + __asm { + cld + mov edi, dest + mov eax, value + mov ecx, count + rep stosb + } +} + +static INLINE void libc_memcpy(void *dest, const void *src, int count) { + if (!count) return; + __asm { + cld + mov esi, src + mov edi, dest + mov ecx, count + rep movsb + } +} + +#define libc_memmove libc_memcpy + +static INLINE void* libc_malloc(int size) { + return (void*) LocalAlloc(LMEM_FIXED, size); +} + +static INLINE void* libc_calloc(int size, int nmemb) { + return (void*) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, size * nmemb); +} + +static INLINE void* libc_realloc(void* old, int size) { + int oldsize = (int) LocalSize((HLOCAL) old); + void *mem; + if (size <= oldsize) return old; + mem = LocalAlloc(LMEM_FIXED, size); + libc_memcpy(mem, old, oldsize); + LocalFree((HLOCAL) old); + return mem; +} + +static INLINE void libc_free(void *mem) { + LocalFree((HLOCAL) mem); +} + +static INLINE double libc_frexp(double x, int *e) { + double res = -9999.999; + unsigned __int64 i = *(unsigned __int64*)(&x); + if (!(i & 0x7F00000000000000UL)) { + *e = 0; + return x; + } + *e = ((i << 1) >> 53) - 1022; + i &= 0x800FFFFFFFFFFFFFUL; + i |= 0x3FF0000000000000UL; + return *(double*)(&i) * 0.5; +} + +static INLINE double __declspec(naked) libc_exp(double x) { __asm { + fldl2e + fld qword ptr [esp+4] + fmul + fst st(1) + frndint + fxch + fsub st(0), st(1) + f2xm1 + fld1 + fadd + fscale + ret +} } + + +static INLINE double __declspec(naked) libc_pow(double b, double e) { __asm { + fld qword ptr [esp+12] + fld qword ptr [esp+4] + fyl2x +// following is a copy of libc_exp: + fst st(1) + frndint + fxch + fsub st(0), st(1) + f2xm1 + fld1 + fadd + fscale + ret +} } + + + +#else // NEED_MINILIBC == 0 + +#define libc_malloc malloc +#define libc_calloc calloc +#define libc_realloc realloc +#define libc_free free + +#define libc_memset memset +#define libc_memcpy memcpy +#define libc_memmove memmove + +#define libc_frexp frexp +#define libc_exp exp +#define libc_pow pow + +#endif // NEED_MINILIBC + +#endif//__LIBC_H_INCLUDED__ diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.c b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.c new file mode 100644 index 000000000..b2cfd2391 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.c @@ -0,0 +1,2656 @@ +/* + * MPEG Audio Layer III decoder + * Copyright (c) 2001, 2002 Fabrice Bellard, + * (c) 2007 Martin J. Fiedler + * + * This file is a stripped-down version of the MPEG Audio decoder from + * the FFmpeg libavcodec library. + * + * FFmpeg and minimp3 are 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. + * + * FFmpeg and minimp3 are 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libc.h" +#include "minimp3.h" + +#define MP3_FRAME_SIZE 1152 +#define MP3_MAX_CODED_FRAME_SIZE 1792 +#define MP3_MAX_CHANNELS 2 +#define SBLIMIT 32 + +#define MP3_STEREO 0 +#define MP3_JSTEREO 1 +#define MP3_DUAL 2 +#define MP3_MONO 3 + +#define SAME_HEADER_MASK \ + (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) + +#define FRAC_BITS 15 +#define WFRAC_BITS 14 + +#define OUT_MAX (32767) +#define OUT_MIN (-32768) +#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15) + +#define MODE_EXT_MS_STEREO 2 +#define MODE_EXT_I_STEREO 1 + +#define FRAC_ONE (1 << FRAC_BITS) +#define FIX(a) ((int)((a) * FRAC_ONE)) +#define FIXR(a) ((int)((a) * FRAC_ONE + 0.5)) +#define FRAC_RND(a) (((a) + (FRAC_ONE/2)) >> FRAC_BITS) +#define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5)) + +#ifndef _MSC_VER + #define MULL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) + #define MULH(a,b) (((int64_t)(a) * (int64_t)(b)) >> 32) +#else + static INLINE int MULL(int a, int b) { + int res; + __asm { + mov eax, a + imul b + shr eax, 15 + shl edx, 17 + or eax, edx + mov res, eax + } + return res; + } + static INLINE int MULH(int a, int b) { + int res; + __asm { + mov eax, a + imul b + mov res, edx + } + return res; + } +#endif +#define MULS(ra, rb) ((ra) * (rb)) + +#define ISQRT2 FIXR(0.70710678118654752440) + +#define HEADER_SIZE 4 +#define BACKSTEP_SIZE 512 +#define EXTRABYTES 24 + +#define VLC_TYPE int16_t + +//////////////////////////////////////////////////////////////////////////////// + +struct _granule; + +typedef struct _bitstream { + const uint8_t *buffer, *buffer_end; + int index; + int size_in_bits; +} bitstream_t; + +typedef struct _vlc { + int bits; + VLC_TYPE (*table)[2]; ///< code, bits + int table_size, table_allocated; +} vlc_t; + +typedef struct _mp3_context { + uint8_t last_buf[2*BACKSTEP_SIZE + EXTRABYTES]; + int last_buf_size; + int frame_size; + uint32_t free_format_next_header; + int error_protection; + int sample_rate; + int sample_rate_index; + int bit_rate; + bitstream_t gb; + bitstream_t in_gb; + int nb_channels; + int mode; + int mode_ext; + int lsf; + int16_t synth_buf[MP3_MAX_CHANNELS][512 * 2]; + int synth_buf_offset[MP3_MAX_CHANNELS]; + int32_t sb_samples[MP3_MAX_CHANNELS][36][SBLIMIT]; + int32_t mdct_buf[MP3_MAX_CHANNELS][SBLIMIT * 18]; + int dither_state; +} mp3_context_t; + +typedef struct _granule { + uint8_t scfsi; + int part2_3_length; + int big_values; + int global_gain; + int scalefac_compress; + uint8_t block_type; + uint8_t switch_point; + int table_select[3]; + int subblock_gain[3]; + uint8_t scalefac_scale; + uint8_t count1table_select; + int region_size[3]; + int preflag; + int short_start, long_end; + uint8_t scale_factors[40]; + int32_t sb_hybrid[SBLIMIT * 18]; +} granule_t; + +typedef struct _huff_table { + int xsize; + const uint8_t *bits; + const uint16_t *codes; +} huff_table_t; + +static vlc_t huff_vlc[16]; +static vlc_t huff_quad_vlc[2]; +static uint16_t band_index_long[9][23]; +#define TABLE_4_3_SIZE (8191 + 16)*4 +static int8_t *table_4_3_exp; +static uint32_t *table_4_3_value; +static uint32_t exp_table[512]; +static uint32_t expval_table[512][16]; +static int32_t is_table[2][16]; +static int32_t is_table_lsf[2][2][16]; +static int32_t csa_table[8][4]; +static float csa_table_float[8][4]; +static int32_t mdct_win[8][36]; +static int16_t window[512]; + +//////////////////////////////////////////////////////////////////////////////// + +static const uint16_t mp3_bitrate_tab[2][15] = { + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} +}; + +static const uint16_t mp3_freq_tab[3] = { 44100, 48000, 32000 }; + +static const int32_t mp3_enwindow[257] = { + 0, -1, -1, -1, -1, -1, -1, -2, + -2, -2, -2, -3, -3, -4, -4, -5, + -5, -6, -7, -7, -8, -9, -10, -11, + -13, -14, -16, -17, -19, -21, -24, -26, + -29, -31, -35, -38, -41, -45, -49, -53, + -58, -63, -68, -73, -79, -85, -91, -97, + -104, -111, -117, -125, -132, -139, -147, -154, + -161, -169, -176, -183, -190, -196, -202, -208, + 213, 218, 222, 225, 227, 228, 228, 227, + 224, 221, 215, 208, 200, 189, 177, 163, + 146, 127, 106, 83, 57, 29, -2, -36, + -72, -111, -153, -197, -244, -294, -347, -401, + -459, -519, -581, -645, -711, -779, -848, -919, + -991, -1064, -1137, -1210, -1283, -1356, -1428, -1498, + -1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962, + -2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063, + 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535, + 1414, 1280, 1131, 970, 794, 605, 402, 185, + -45, -288, -545, -814, -1095, -1388, -1692, -2006, + -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, + -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, + -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585, + -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750, + -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134, + 6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082, + 70, -998, -2122, -3300, -4533, -5818, -7154, -8540, + -9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189, +-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640, +-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137, +-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684, +-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420, +-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992, + 75038, +}; + +static const uint8_t slen_table[2][16] = { + { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, + { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }, +}; + +static const uint8_t lsf_nsf_table[6][3][4] = { + { { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } }, + { { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } }, + { { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } }, + { { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } }, + { { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } }, + { { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } }, +}; + +static const uint16_t mp3_huffcodes_1[4] = { + 0x0001, 0x0001, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_1[4] = { + 1, 3, 2, 3, +}; + +static const uint16_t mp3_huffcodes_2[9] = { + 0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002, + 0x0000, +}; + +static const uint8_t mp3_huffbits_2[9] = { + 1, 3, 6, 3, 3, 5, 5, 5, + 6, +}; + +static const uint16_t mp3_huffcodes_3[9] = { + 0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002, + 0x0000, +}; + +static const uint8_t mp3_huffbits_3[9] = { + 2, 2, 6, 3, 2, 5, 5, 5, + 6, +}; + +static const uint16_t mp3_huffcodes_5[16] = { + 0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004, + 0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_5[16] = { + 1, 3, 6, 7, 3, 3, 6, 7, + 6, 6, 7, 8, 7, 6, 7, 8, +}; + +static const uint16_t mp3_huffcodes_6[16] = { + 0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002, + 0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_6[16] = { + 3, 3, 5, 7, 3, 2, 4, 5, + 4, 4, 5, 6, 6, 5, 6, 7, +}; + +static const uint16_t mp3_huffcodes_7[36] = { + 0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003, + 0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011, + 0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002, + 0x0007, 0x0006, 0x0009, 0x000e, 0x0003, 0x0001, 0x0006, 0x0004, + 0x0005, 0x0003, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_7[36] = { + 1, 3, 6, 8, 8, 9, 3, 4, + 6, 7, 7, 8, 6, 5, 7, 8, + 8, 9, 7, 7, 8, 9, 9, 9, + 7, 7, 8, 9, 9, 10, 8, 8, + 9, 10, 10, 10, +}; + +static const uint16_t mp3_huffcodes_8[36] = { + 0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001, + 0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e, + 0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004, + 0x000d, 0x0005, 0x0008, 0x000b, 0x0005, 0x0001, 0x000c, 0x0004, + 0x0004, 0x0001, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_8[36] = { + 2, 3, 6, 8, 8, 9, 3, 2, + 4, 8, 8, 8, 6, 4, 6, 8, + 8, 9, 8, 8, 8, 9, 9, 10, + 8, 7, 8, 9, 10, 10, 9, 8, + 9, 9, 11, 11, +}; + +static const uint16_t mp3_huffcodes_9[36] = { + 0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004, + 0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008, + 0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001, + 0x000b, 0x0007, 0x0009, 0x0006, 0x0004, 0x0001, 0x000e, 0x0004, + 0x0006, 0x0002, 0x0006, 0x0000, +}; + +static const uint8_t mp3_huffbits_9[36] = { + 3, 3, 5, 6, 8, 9, 3, 3, + 4, 5, 6, 8, 4, 4, 5, 6, + 7, 8, 6, 5, 6, 7, 7, 8, + 7, 6, 7, 7, 8, 9, 8, 7, + 8, 8, 9, 9, +}; + +static const uint16_t mp3_huffcodes_10[64] = { + 0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011, + 0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007, + 0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006, + 0x000e, 0x000d, 0x0016, 0x0022, 0x002e, 0x0017, 0x0012, 0x0007, + 0x0014, 0x0013, 0x0021, 0x002f, 0x001b, 0x0016, 0x0009, 0x0003, + 0x001f, 0x0016, 0x0029, 0x001a, 0x0015, 0x0014, 0x0005, 0x0003, + 0x000e, 0x000d, 0x000a, 0x000b, 0x0010, 0x0006, 0x0005, 0x0001, + 0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_10[64] = { + 1, 3, 6, 8, 9, 9, 9, 10, + 3, 4, 6, 7, 8, 9, 8, 8, + 6, 6, 7, 8, 9, 10, 9, 9, + 7, 7, 8, 9, 10, 10, 9, 10, + 8, 8, 9, 10, 10, 10, 10, 10, + 9, 9, 10, 10, 11, 11, 10, 11, + 8, 8, 9, 10, 10, 10, 11, 11, + 9, 8, 9, 10, 10, 11, 11, 11, +}; + +static const uint16_t mp3_huffcodes_11[64] = { + 0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f, + 0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a, + 0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005, + 0x0019, 0x000b, 0x0013, 0x003b, 0x001b, 0x0012, 0x000c, 0x0005, + 0x0023, 0x0021, 0x001f, 0x003a, 0x001e, 0x0010, 0x0007, 0x0005, + 0x001c, 0x001a, 0x0020, 0x0013, 0x0011, 0x000f, 0x0008, 0x000e, + 0x000e, 0x000c, 0x0009, 0x000d, 0x000e, 0x0009, 0x0004, 0x0001, + 0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_11[64] = { + 2, 3, 5, 7, 8, 9, 8, 9, + 3, 3, 4, 6, 8, 8, 7, 8, + 5, 5, 6, 7, 8, 9, 8, 8, + 7, 6, 7, 9, 8, 10, 8, 9, + 8, 8, 8, 9, 9, 10, 9, 10, + 8, 8, 9, 10, 10, 11, 10, 11, + 8, 7, 7, 8, 9, 10, 10, 10, + 8, 7, 8, 9, 10, 10, 10, 10, +}; + +static const uint16_t mp3_huffcodes_12[64] = { + 0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a, + 0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b, + 0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007, + 0x0011, 0x000a, 0x000f, 0x000c, 0x0012, 0x001c, 0x000e, 0x0005, + 0x0020, 0x000d, 0x0016, 0x0013, 0x0012, 0x0010, 0x0009, 0x0005, + 0x0028, 0x0011, 0x001f, 0x001d, 0x0011, 0x000d, 0x0004, 0x0002, + 0x001b, 0x000c, 0x000b, 0x000f, 0x000a, 0x0007, 0x0004, 0x0001, + 0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_12[64] = { + 4, 3, 5, 7, 8, 9, 9, 9, + 3, 3, 4, 5, 7, 7, 8, 8, + 5, 4, 5, 6, 7, 8, 7, 8, + 6, 5, 6, 6, 7, 8, 8, 8, + 7, 6, 7, 7, 8, 8, 8, 9, + 8, 7, 8, 8, 8, 9, 8, 9, + 8, 7, 7, 8, 8, 9, 9, 10, + 9, 8, 8, 9, 9, 9, 9, 10, +}; + +static const uint16_t mp3_huffcodes_13[256] = { + 0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047, + 0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013, + 0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021, + 0x001f, 0x0018, 0x0020, 0x0018, 0x001f, 0x0023, 0x0016, 0x000e, + 0x000f, 0x000d, 0x0017, 0x0024, 0x003b, 0x0031, 0x004d, 0x0041, + 0x001d, 0x0028, 0x001e, 0x0028, 0x001b, 0x0021, 0x002a, 0x0010, + 0x0016, 0x0014, 0x0025, 0x003d, 0x0038, 0x004f, 0x0049, 0x0040, + 0x002b, 0x004c, 0x0038, 0x0025, 0x001a, 0x001f, 0x0019, 0x000e, + 0x0023, 0x0010, 0x003c, 0x0039, 0x0061, 0x004b, 0x0072, 0x005b, + 0x0036, 0x0049, 0x0037, 0x0029, 0x0030, 0x0035, 0x0017, 0x0018, + 0x003a, 0x001b, 0x0032, 0x0060, 0x004c, 0x0046, 0x005d, 0x0054, + 0x004d, 0x003a, 0x004f, 0x001d, 0x004a, 0x0031, 0x0029, 0x0011, + 0x002f, 0x002d, 0x004e, 0x004a, 0x0073, 0x005e, 0x005a, 0x004f, + 0x0045, 0x0053, 0x0047, 0x0032, 0x003b, 0x0026, 0x0024, 0x000f, + 0x0048, 0x0022, 0x0038, 0x005f, 0x005c, 0x0055, 0x005b, 0x005a, + 0x0056, 0x0049, 0x004d, 0x0041, 0x0033, 0x002c, 0x002b, 0x002a, + 0x002b, 0x0014, 0x001e, 0x002c, 0x0037, 0x004e, 0x0048, 0x0057, + 0x004e, 0x003d, 0x002e, 0x0036, 0x0025, 0x001e, 0x0014, 0x0010, + 0x0035, 0x0019, 0x0029, 0x0025, 0x002c, 0x003b, 0x0036, 0x0051, + 0x0042, 0x004c, 0x0039, 0x0036, 0x0025, 0x0012, 0x0027, 0x000b, + 0x0023, 0x0021, 0x001f, 0x0039, 0x002a, 0x0052, 0x0048, 0x0050, + 0x002f, 0x003a, 0x0037, 0x0015, 0x0016, 0x001a, 0x0026, 0x0016, + 0x0035, 0x0019, 0x0017, 0x0026, 0x0046, 0x003c, 0x0033, 0x0024, + 0x0037, 0x001a, 0x0022, 0x0017, 0x001b, 0x000e, 0x0009, 0x0007, + 0x0022, 0x0020, 0x001c, 0x0027, 0x0031, 0x004b, 0x001e, 0x0034, + 0x0030, 0x0028, 0x0034, 0x001c, 0x0012, 0x0011, 0x0009, 0x0005, + 0x002d, 0x0015, 0x0022, 0x0040, 0x0038, 0x0032, 0x0031, 0x002d, + 0x001f, 0x0013, 0x000c, 0x000f, 0x000a, 0x0007, 0x0006, 0x0003, + 0x0030, 0x0017, 0x0014, 0x0027, 0x0024, 0x0023, 0x0035, 0x0015, + 0x0010, 0x0017, 0x000d, 0x000a, 0x0006, 0x0001, 0x0004, 0x0002, + 0x0010, 0x000f, 0x0011, 0x001b, 0x0019, 0x0014, 0x001d, 0x000b, + 0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001, +}; + +static const uint8_t mp3_huffbits_13[256] = { + 1, 4, 6, 7, 8, 9, 9, 10, + 9, 10, 11, 11, 12, 12, 13, 13, + 3, 4, 6, 7, 8, 8, 9, 9, + 9, 9, 10, 10, 11, 12, 12, 12, + 6, 6, 7, 8, 9, 9, 10, 10, + 9, 10, 10, 11, 11, 12, 13, 13, + 7, 7, 8, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 12, 13, 13, + 8, 7, 9, 9, 10, 10, 11, 11, + 10, 11, 11, 12, 12, 13, 13, 14, + 9, 8, 9, 10, 10, 10, 11, 11, + 11, 11, 12, 11, 13, 13, 14, 14, + 9, 9, 10, 10, 11, 11, 11, 11, + 11, 12, 12, 12, 13, 13, 14, 14, + 10, 9, 10, 11, 11, 11, 12, 12, + 12, 12, 13, 13, 13, 14, 16, 16, + 9, 8, 9, 10, 10, 11, 11, 12, + 12, 12, 12, 13, 13, 14, 15, 15, + 10, 9, 10, 10, 11, 11, 11, 13, + 12, 13, 13, 14, 14, 14, 16, 15, + 10, 10, 10, 11, 11, 12, 12, 13, + 12, 13, 14, 13, 14, 15, 16, 17, + 11, 10, 10, 11, 12, 12, 12, 12, + 13, 13, 13, 14, 15, 15, 15, 16, + 11, 11, 11, 12, 12, 13, 12, 13, + 14, 14, 15, 15, 15, 16, 16, 16, + 12, 11, 12, 13, 13, 13, 14, 14, + 14, 14, 14, 15, 16, 15, 16, 16, + 13, 12, 12, 13, 13, 13, 15, 14, + 14, 17, 15, 15, 15, 17, 16, 16, + 12, 12, 13, 14, 14, 14, 15, 14, + 15, 15, 16, 16, 19, 18, 19, 16, +}; + +static const uint16_t mp3_huffcodes_15[256] = { + 0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c, + 0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f, + 0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033, + 0x002a, 0x0046, 0x0034, 0x0053, 0x0041, 0x0029, 0x003b, 0x0024, + 0x0013, 0x0011, 0x000f, 0x0018, 0x0029, 0x0022, 0x003b, 0x0030, + 0x0028, 0x0040, 0x0032, 0x004e, 0x003e, 0x0050, 0x0038, 0x0021, + 0x001d, 0x001c, 0x0019, 0x002b, 0x0027, 0x003f, 0x0037, 0x005d, + 0x004c, 0x003b, 0x005d, 0x0048, 0x0036, 0x004b, 0x0032, 0x001d, + 0x0034, 0x0016, 0x002a, 0x0028, 0x0043, 0x0039, 0x005f, 0x004f, + 0x0048, 0x0039, 0x0059, 0x0045, 0x0031, 0x0042, 0x002e, 0x001b, + 0x004d, 0x0025, 0x0023, 0x0042, 0x003a, 0x0034, 0x005b, 0x004a, + 0x003e, 0x0030, 0x004f, 0x003f, 0x005a, 0x003e, 0x0028, 0x0026, + 0x007d, 0x0020, 0x003c, 0x0038, 0x0032, 0x005c, 0x004e, 0x0041, + 0x0037, 0x0057, 0x0047, 0x0033, 0x0049, 0x0033, 0x0046, 0x001e, + 0x006d, 0x0035, 0x0031, 0x005e, 0x0058, 0x004b, 0x0042, 0x007a, + 0x005b, 0x0049, 0x0038, 0x002a, 0x0040, 0x002c, 0x0015, 0x0019, + 0x005a, 0x002b, 0x0029, 0x004d, 0x0049, 0x003f, 0x0038, 0x005c, + 0x004d, 0x0042, 0x002f, 0x0043, 0x0030, 0x0035, 0x0024, 0x0014, + 0x0047, 0x0022, 0x0043, 0x003c, 0x003a, 0x0031, 0x0058, 0x004c, + 0x0043, 0x006a, 0x0047, 0x0036, 0x0026, 0x0027, 0x0017, 0x000f, + 0x006d, 0x0035, 0x0033, 0x002f, 0x005a, 0x0052, 0x003a, 0x0039, + 0x0030, 0x0048, 0x0039, 0x0029, 0x0017, 0x001b, 0x003e, 0x0009, + 0x0056, 0x002a, 0x0028, 0x0025, 0x0046, 0x0040, 0x0034, 0x002b, + 0x0046, 0x0037, 0x002a, 0x0019, 0x001d, 0x0012, 0x000b, 0x000b, + 0x0076, 0x0044, 0x001e, 0x0037, 0x0032, 0x002e, 0x004a, 0x0041, + 0x0031, 0x0027, 0x0018, 0x0010, 0x0016, 0x000d, 0x000e, 0x0007, + 0x005b, 0x002c, 0x0027, 0x0026, 0x0022, 0x003f, 0x0034, 0x002d, + 0x001f, 0x0034, 0x001c, 0x0013, 0x000e, 0x0008, 0x0009, 0x0003, + 0x007b, 0x003c, 0x003a, 0x0035, 0x002f, 0x002b, 0x0020, 0x0016, + 0x0025, 0x0018, 0x0011, 0x000c, 0x000f, 0x000a, 0x0002, 0x0001, + 0x0047, 0x0025, 0x0022, 0x001e, 0x001c, 0x0014, 0x0011, 0x001a, + 0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_15[256] = { + 3, 4, 5, 7, 7, 8, 9, 9, + 9, 10, 10, 11, 11, 11, 12, 13, + 4, 3, 5, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 11, 11, + 5, 5, 5, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 11, 11, 11, + 6, 6, 6, 7, 7, 8, 8, 9, + 9, 9, 10, 10, 10, 11, 11, 11, + 7, 6, 7, 7, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 11, + 8, 7, 7, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 11, 11, 11, 12, + 9, 7, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 11, 11, 12, 12, + 9, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 11, 11, 11, 12, + 9, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 11, 11, 12, 12, 12, + 9, 8, 9, 9, 9, 9, 10, 10, + 10, 11, 11, 11, 11, 12, 12, 12, + 10, 9, 9, 9, 10, 10, 10, 10, + 10, 11, 11, 11, 11, 12, 13, 12, + 10, 9, 9, 9, 10, 10, 10, 10, + 11, 11, 11, 11, 12, 12, 12, 13, + 11, 10, 9, 10, 10, 10, 11, 11, + 11, 11, 11, 11, 12, 12, 13, 13, + 11, 10, 10, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 13, 13, + 12, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 12, 13, + 12, 11, 11, 11, 11, 11, 11, 12, + 12, 12, 12, 12, 13, 13, 13, 13, +}; + +static const uint16_t mp3_huffcodes_16[256] = { + 0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d, + 0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011, + 0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f, + 0x0053, 0x004b, 0x0044, 0x0077, 0x00c9, 0x006b, 0x00cf, 0x0009, + 0x000f, 0x000d, 0x0017, 0x0026, 0x0043, 0x003a, 0x0067, 0x005a, + 0x00a1, 0x0048, 0x007f, 0x0075, 0x006e, 0x00d1, 0x00ce, 0x0010, + 0x002d, 0x0015, 0x0027, 0x0045, 0x0040, 0x0072, 0x0063, 0x0057, + 0x009e, 0x008c, 0x00fc, 0x00d4, 0x00c7, 0x0183, 0x016d, 0x001a, + 0x004b, 0x0024, 0x0044, 0x0041, 0x0073, 0x0065, 0x00b3, 0x00a4, + 0x009b, 0x0108, 0x00f6, 0x00e2, 0x018b, 0x017e, 0x016a, 0x0009, + 0x0042, 0x001e, 0x003b, 0x0038, 0x0066, 0x00b9, 0x00ad, 0x0109, + 0x008e, 0x00fd, 0x00e8, 0x0190, 0x0184, 0x017a, 0x01bd, 0x0010, + 0x006f, 0x0036, 0x0034, 0x0064, 0x00b8, 0x00b2, 0x00a0, 0x0085, + 0x0101, 0x00f4, 0x00e4, 0x00d9, 0x0181, 0x016e, 0x02cb, 0x000a, + 0x0062, 0x0030, 0x005b, 0x0058, 0x00a5, 0x009d, 0x0094, 0x0105, + 0x00f8, 0x0197, 0x018d, 0x0174, 0x017c, 0x0379, 0x0374, 0x0008, + 0x0055, 0x0054, 0x0051, 0x009f, 0x009c, 0x008f, 0x0104, 0x00f9, + 0x01ab, 0x0191, 0x0188, 0x017f, 0x02d7, 0x02c9, 0x02c4, 0x0007, + 0x009a, 0x004c, 0x0049, 0x008d, 0x0083, 0x0100, 0x00f5, 0x01aa, + 0x0196, 0x018a, 0x0180, 0x02df, 0x0167, 0x02c6, 0x0160, 0x000b, + 0x008b, 0x0081, 0x0043, 0x007d, 0x00f7, 0x00e9, 0x00e5, 0x00db, + 0x0189, 0x02e7, 0x02e1, 0x02d0, 0x0375, 0x0372, 0x01b7, 0x0004, + 0x00f3, 0x0078, 0x0076, 0x0073, 0x00e3, 0x00df, 0x018c, 0x02ea, + 0x02e6, 0x02e0, 0x02d1, 0x02c8, 0x02c2, 0x00df, 0x01b4, 0x0006, + 0x00ca, 0x00e0, 0x00de, 0x00da, 0x00d8, 0x0185, 0x0182, 0x017d, + 0x016c, 0x0378, 0x01bb, 0x02c3, 0x01b8, 0x01b5, 0x06c0, 0x0004, + 0x02eb, 0x00d3, 0x00d2, 0x00d0, 0x0172, 0x017b, 0x02de, 0x02d3, + 0x02ca, 0x06c7, 0x0373, 0x036d, 0x036c, 0x0d83, 0x0361, 0x0002, + 0x0179, 0x0171, 0x0066, 0x00bb, 0x02d6, 0x02d2, 0x0166, 0x02c7, + 0x02c5, 0x0362, 0x06c6, 0x0367, 0x0d82, 0x0366, 0x01b2, 0x0000, + 0x000c, 0x000a, 0x0007, 0x000b, 0x000a, 0x0011, 0x000b, 0x0009, + 0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003, +}; + +static const uint8_t mp3_huffbits_16[256] = { + 1, 4, 6, 8, 9, 9, 10, 10, + 11, 11, 11, 12, 12, 12, 13, 9, + 3, 4, 6, 7, 8, 9, 9, 9, + 10, 10, 10, 11, 12, 11, 12, 8, + 6, 6, 7, 8, 9, 9, 10, 10, + 11, 10, 11, 11, 11, 12, 12, 9, + 8, 7, 8, 9, 9, 10, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 10, + 9, 8, 9, 9, 10, 10, 11, 11, + 11, 12, 12, 12, 13, 13, 13, 9, + 9, 8, 9, 9, 10, 11, 11, 12, + 11, 12, 12, 13, 13, 13, 14, 10, + 10, 9, 9, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 14, 10, + 10, 9, 10, 10, 11, 11, 11, 12, + 12, 13, 13, 13, 13, 15, 15, 10, + 10, 10, 10, 11, 11, 11, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 10, + 11, 10, 10, 11, 11, 12, 12, 13, + 13, 13, 13, 14, 13, 14, 13, 11, + 11, 11, 10, 11, 12, 12, 12, 12, + 13, 14, 14, 14, 15, 15, 14, 10, + 12, 11, 11, 11, 12, 12, 13, 14, + 14, 14, 14, 14, 14, 13, 14, 11, + 12, 12, 12, 12, 12, 13, 13, 13, + 13, 15, 14, 14, 14, 14, 16, 11, + 14, 12, 12, 12, 13, 13, 14, 14, + 14, 16, 15, 15, 15, 17, 15, 11, + 13, 13, 11, 12, 14, 14, 13, 14, + 14, 15, 16, 15, 17, 15, 14, 11, + 9, 8, 8, 9, 9, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 8, +}; + +static const uint16_t mp3_huffcodes_24[256] = { + 0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2, + 0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058, + 0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8, + 0x00d1, 0x00c6, 0x0147, 0x0159, 0x013f, 0x0129, 0x0117, 0x002a, + 0x002f, 0x0016, 0x0029, 0x004a, 0x0044, 0x0080, 0x0078, 0x00dd, + 0x00cf, 0x00c2, 0x00b6, 0x0154, 0x013b, 0x0127, 0x021d, 0x0012, + 0x0051, 0x0027, 0x004b, 0x0046, 0x0086, 0x007d, 0x0074, 0x00dc, + 0x00cc, 0x00be, 0x00b2, 0x0145, 0x0137, 0x0125, 0x010f, 0x0010, + 0x0093, 0x0048, 0x0045, 0x0087, 0x007f, 0x0076, 0x0070, 0x00d2, + 0x00c8, 0x00bc, 0x0160, 0x0143, 0x0132, 0x011d, 0x021c, 0x000e, + 0x0107, 0x0042, 0x0081, 0x007e, 0x0077, 0x0072, 0x00d6, 0x00ca, + 0x00c0, 0x00b4, 0x0155, 0x013d, 0x012d, 0x0119, 0x0106, 0x000c, + 0x00f9, 0x007b, 0x0079, 0x0075, 0x0071, 0x00d7, 0x00ce, 0x00c3, + 0x00b9, 0x015b, 0x014a, 0x0134, 0x0123, 0x0110, 0x0208, 0x000a, + 0x01b3, 0x0073, 0x006f, 0x006d, 0x00d3, 0x00cb, 0x00c4, 0x00bb, + 0x0161, 0x014c, 0x0139, 0x012a, 0x011b, 0x0213, 0x017d, 0x0011, + 0x01ab, 0x00d4, 0x00d0, 0x00cd, 0x00c9, 0x00c1, 0x00ba, 0x00b1, + 0x00a9, 0x0140, 0x012f, 0x011e, 0x010c, 0x0202, 0x0179, 0x0010, + 0x014f, 0x00c7, 0x00c5, 0x00bf, 0x00bd, 0x00b5, 0x00ae, 0x014d, + 0x0141, 0x0131, 0x0121, 0x0113, 0x0209, 0x017b, 0x0173, 0x000b, + 0x029c, 0x00b8, 0x00b7, 0x00b3, 0x00af, 0x0158, 0x014b, 0x013a, + 0x0130, 0x0122, 0x0115, 0x0212, 0x017f, 0x0175, 0x016e, 0x000a, + 0x028c, 0x015a, 0x00ab, 0x00a8, 0x00a4, 0x013e, 0x0135, 0x012b, + 0x011f, 0x0114, 0x0107, 0x0201, 0x0177, 0x0170, 0x016a, 0x0006, + 0x0288, 0x0142, 0x013c, 0x0138, 0x0133, 0x012e, 0x0124, 0x011c, + 0x010d, 0x0105, 0x0200, 0x0178, 0x0172, 0x016c, 0x0167, 0x0004, + 0x026c, 0x012c, 0x0128, 0x0126, 0x0120, 0x011a, 0x0111, 0x010a, + 0x0203, 0x017c, 0x0176, 0x0171, 0x016d, 0x0169, 0x0165, 0x0002, + 0x0409, 0x0118, 0x0116, 0x0112, 0x010b, 0x0108, 0x0103, 0x017e, + 0x017a, 0x0174, 0x016f, 0x016b, 0x0168, 0x0166, 0x0164, 0x0000, + 0x002b, 0x0014, 0x0013, 0x0011, 0x000f, 0x000d, 0x000b, 0x0009, + 0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003, +}; + +static const uint8_t mp3_huffbits_24[256] = { + 4, 4, 6, 7, 8, 9, 9, 10, + 10, 11, 11, 11, 11, 11, 12, 9, + 4, 4, 5, 6, 7, 8, 8, 9, + 9, 9, 10, 10, 10, 10, 10, 8, + 6, 5, 6, 7, 7, 8, 8, 9, + 9, 9, 9, 10, 10, 10, 11, 7, + 7, 6, 7, 7, 8, 8, 8, 9, + 9, 9, 9, 10, 10, 10, 10, 7, + 8, 7, 7, 8, 8, 8, 8, 9, + 9, 9, 10, 10, 10, 10, 11, 7, + 9, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 7, + 9, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 11, 7, + 10, 8, 8, 8, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 11, 11, 8, + 10, 9, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 8, + 10, 9, 9, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 11, 11, 11, 8, + 11, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 8, + 11, 10, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 8, + 11, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 8, + 11, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 8, + 12, 10, 10, 10, 10, 10, 10, 11, + 11, 11, 11, 11, 11, 11, 11, 8, + 8, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 4, +}; + +static const huff_table_t mp3_huff_tables[16] = { +{ 1, NULL, NULL }, +{ 2, mp3_huffbits_1, mp3_huffcodes_1 }, +{ 3, mp3_huffbits_2, mp3_huffcodes_2 }, +{ 3, mp3_huffbits_3, mp3_huffcodes_3 }, +{ 4, mp3_huffbits_5, mp3_huffcodes_5 }, +{ 4, mp3_huffbits_6, mp3_huffcodes_6 }, +{ 6, mp3_huffbits_7, mp3_huffcodes_7 }, +{ 6, mp3_huffbits_8, mp3_huffcodes_8 }, +{ 6, mp3_huffbits_9, mp3_huffcodes_9 }, +{ 8, mp3_huffbits_10, mp3_huffcodes_10 }, +{ 8, mp3_huffbits_11, mp3_huffcodes_11 }, +{ 8, mp3_huffbits_12, mp3_huffcodes_12 }, +{ 16, mp3_huffbits_13, mp3_huffcodes_13 }, +{ 16, mp3_huffbits_15, mp3_huffcodes_15 }, +{ 16, mp3_huffbits_16, mp3_huffcodes_16 }, +{ 16, mp3_huffbits_24, mp3_huffcodes_24 }, +}; + +static const uint8_t mp3_huff_data[32][2] = { +{ 0, 0 }, +{ 1, 0 }, +{ 2, 0 }, +{ 3, 0 }, +{ 0, 0 }, +{ 4, 0 }, +{ 5, 0 }, +{ 6, 0 }, +{ 7, 0 }, +{ 8, 0 }, +{ 9, 0 }, +{ 10, 0 }, +{ 11, 0 }, +{ 12, 0 }, +{ 0, 0 }, +{ 13, 0 }, +{ 14, 1 }, +{ 14, 2 }, +{ 14, 3 }, +{ 14, 4 }, +{ 14, 6 }, +{ 14, 8 }, +{ 14, 10 }, +{ 14, 13 }, +{ 15, 4 }, +{ 15, 5 }, +{ 15, 6 }, +{ 15, 7 }, +{ 15, 8 }, +{ 15, 9 }, +{ 15, 11 }, +{ 15, 13 }, +}; + +static const uint8_t mp3_quad_codes[2][16] = { + { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, }, + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, }, +}; + +static const uint8_t mp3_quad_bits[2][16] = { + { 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, }, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, }, +}; + +static const uint8_t band_size_long[9][22] = { +{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, + 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */ +{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, + 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */ +{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, + 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */ +{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, + 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */ +}; + +static const uint8_t band_size_short[9][13] = { +{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */ +{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */ +{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */ +{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */ +{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */ +}; + +static const uint8_t mp3_pretab[2][22] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }, +}; + +static const float ci_table[8] = { + -0.6f, -0.535f, -0.33f, -0.185f, -0.095f, -0.041f, -0.0142f, -0.0037f, +}; + +#define C1 FIXHR(0.98480775301220805936/2) +#define C2 FIXHR(0.93969262078590838405/2) +#define C3 FIXHR(0.86602540378443864676/2) +#define C4 FIXHR(0.76604444311897803520/2) +#define C5 FIXHR(0.64278760968653932632/2) +#define C6 FIXHR(0.5/2) +#define C7 FIXHR(0.34202014332566873304/2) +#define C8 FIXHR(0.17364817766693034885/2) + +static const int icos36[9] = { + FIXR(0.50190991877167369479), + FIXR(0.51763809020504152469), //0 + FIXR(0.55168895948124587824), + FIXR(0.61038729438072803416), + FIXR(0.70710678118654752439), //1 + FIXR(0.87172339781054900991), + FIXR(1.18310079157624925896), + FIXR(1.93185165257813657349), //2 + FIXR(5.73685662283492756461), +}; + +static const int icos36h[9] = { + FIXHR(0.50190991877167369479/2), + FIXHR(0.51763809020504152469/2), //0 + FIXHR(0.55168895948124587824/2), + FIXHR(0.61038729438072803416/2), + FIXHR(0.70710678118654752439/2), //1 + FIXHR(0.87172339781054900991/2), + FIXHR(1.18310079157624925896/4), + FIXHR(1.93185165257813657349/4), //2 +// FIXHR(5.73685662283492756461), +}; + +//////////////////////////////////////////////////////////////////////////////// + +static INLINE int unaligned32_be(const uint8_t *p) +{ + return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]); +} + +#define MIN_CACHE_BITS 25 + +#define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) +#define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) + +#define OPEN_READER(name, gb) \ + int name##_index= (gb)->index;\ + int name##_cache= 0;\ + +#define CLOSE_READER(name, gb)\ + (gb)->index= name##_index;\ + +#define UPDATE_CACHE(name, gb)\ + name##_cache= unaligned32_be(&((gb)->buffer[name##_index>>3])) << (name##_index&0x07); \ + +#define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num); + +#define SKIP_COUNTER(name, gb, num)\ + name##_index += (num);\ + +#define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) +#define LAST_SKIP_CACHE(name, gb, num) ; + +#define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache, num) + +#define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) + +#define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static INLINE int get_bits_count(bitstream_t *s){ + return s->index; +} + +static INLINE void skip_bits_long(bitstream_t *s, int n){ + s->index += n; +} +#define skip_bits skip_bits_long + +static void init_get_bits(bitstream_t *s, const uint8_t *buffer, int bit_size) { + int buffer_size= (bit_size+7)>>3; + if(buffer_size < 0 || bit_size < 0) { + buffer_size = bit_size = 0; + buffer = NULL; + } + s->buffer= buffer; + s->size_in_bits= bit_size; + s->buffer_end= buffer + buffer_size; + s->index=0; +} + +static INLINE unsigned int get_bits(bitstream_t *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +static INLINE int get_bitsz(bitstream_t *s, int n) +{ + if (n == 0) + return 0; + else + return get_bits(s, n); +} + +static INLINE unsigned int get_bits1(bitstream_t *s){ + int index= s->index; + uint8_t result= s->buffer[ index>>3 ]; + result<<= (index&0x07); + result>>= 8 - 1; + index++; + s->index= index; + return result; +} + +static INLINE void align_get_bits(bitstream_t *s) +{ + int n= (-get_bits_count(s)) & 7; + if(n) skip_bits(s, n); +} + +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + switch(size) {\ + case 1:\ + v = *(const uint8_t *)ptr;\ + break;\ + case 2:\ + v = *(const uint16_t *)ptr;\ + break;\ + default:\ + v = *(const uint32_t *)ptr;\ + break;\ + }\ +} + +static INLINE int alloc_table(vlc_t *vlc, int size) { + int index; + index = vlc->table_size; + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + vlc->table_allocated += (1 << vlc->bits); + vlc->table = libc_realloc(vlc->table, sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + if (!vlc->table) + return -1; + } + return index; +} + +static int build_table( + vlc_t *vlc, int table_nb_bits, + int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + uint32_t code_prefix, int n_prefix +) { + int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2; + uint32_t code; + VLC_TYPE (*table)[2]; + + table_size = 1 << table_nb_bits; + table_index = alloc_table(vlc, table_size); + if (table_index < 0) + return -1; + table = &vlc->table[table_index]; + + for(i=0;i> n; + if (n > 0 && code_prefix2 == code_prefix) { + if (n <= table_nb_bits) { + j = (code << (table_nb_bits - n)) & (table_size - 1); + nb = 1 << (table_nb_bits - n); + for(k=0;k> n) & ((1 << table_nb_bits) - 1); + n1 = -table[j][1]; //bits + if (n > n1) + n1 = n; + table[j][1] = -n1; //bits + } + } + } + for(i=0;i table_nb_bits) { + n = table_nb_bits; + table[i][1] = -n; //bits + } + index = build_table(vlc, n, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + (code_prefix << table_nb_bits) | i, + n_prefix + table_nb_bits); + if (index < 0) + return -1; + table = &vlc->table[table_index]; + table[i][0] = index; //code + } + } + return table_index; +} + +static INLINE int init_vlc( + vlc_t *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size +) { + vlc->bits = nb_bits; + if (build_table(vlc, nb_bits, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + 0, 0) < 0) { + libc_free(vlc->table); + return -1; + } + return 0; +} + +#define GET_VLC(code, name, gb, table, bits, max_depth)\ +{\ + int n, index, nb_bits;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + code = table[index][0];\ + n = table[index][1];\ +\ + if(max_depth > 1 && n < 0){\ + LAST_SKIP_BITS(name, gb, bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + if(max_depth > 2 && n < 0){\ + LAST_SKIP_BITS(name, gb, nb_bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + }\ + }\ + SKIP_BITS(name, gb, n)\ +} + +static INLINE int get_vlc2(bitstream_t *s, VLC_TYPE (*table)[2], int bits, int max_depth) { + int code; + + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + + GET_VLC(code, re, s, table, bits, max_depth) + + CLOSE_READER(re, s) + return code; +} + +static void switch_buffer(mp3_context_t *s, int *pos, int *end_pos, int *end_pos2) { + if(s->in_gb.buffer && *pos >= s->gb.size_in_bits){ + s->gb= s->in_gb; + s->in_gb.buffer=NULL; + skip_bits_long(&s->gb, *pos - *end_pos); + *end_pos2= + *end_pos= *end_pos2 + get_bits_count(&s->gb) - *pos; + *pos= get_bits_count(&s->gb); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +static INLINE int mp3_check_header(uint32_t header){ + /* header */ + if ((header & 0xffe00000) != 0xffe00000) + return -1; + /* layer check */ + if ((header & (3<<17)) != (1 << 17)) + return -1; + /* bit rate */ + if ((header & (0xf<<12)) == 0xf<<12) + return -1; + /* frequency */ + if ((header & (3<<10)) == 3<<10) + return -1; + return 0; +} + + +static void lsf_sf_expand( + int *slen, int sf, int n1, int n2, int n3 +) { + if (n3) { + slen[3] = sf % n3; + sf /= n3; + } else { + slen[3] = 0; + } + if (n2) { + slen[2] = sf % n2; + sf /= n2; + } else { + slen[2] = 0; + } + slen[1] = sf % n1; + sf /= n1; + slen[0] = sf; +} + +static INLINE int l3_unscale(int value, int exponent) +{ + unsigned int m; + int e; + + e = table_4_3_exp [4*value + (exponent&3)]; + m = table_4_3_value[4*value + (exponent&3)]; + e -= (exponent >> 2); + if (e > 31) + return 0; + m = (m + (1 << (e-1))) >> e; + + return m; +} + +static INLINE int round_sample(int *sum) { + int sum1; + sum1 = (*sum) >> OUT_SHIFT; + *sum &= (1< OUT_MAX) + sum1 = OUT_MAX; + return sum1; +} + +static void exponents_from_scale_factors( + mp3_context_t *s, granule_t *g, int16_t *exponents +) { + const uint8_t *bstab, *pretab; + int len, i, j, k, l, v0, shift, gain, gains[3]; + int16_t *exp_ptr; + + exp_ptr = exponents; + gain = g->global_gain - 210; + shift = g->scalefac_scale + 1; + + bstab = band_size_long[s->sample_rate_index]; + pretab = mp3_pretab[g->preflag]; + for(i=0;ilong_end;i++) { + v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400; + len = bstab[i]; + for(j=len;j>0;j--) + *exp_ptr++ = v0; + } + + if (g->short_start < 13) { + bstab = band_size_short[s->sample_rate_index]; + gains[0] = gain - (g->subblock_gain[0] << 3); + gains[1] = gain - (g->subblock_gain[1] << 3); + gains[2] = gain - (g->subblock_gain[2] << 3); + k = g->long_end; + for(i=g->short_start;i<13;i++) { + len = bstab[i]; + for(l=0;l<3;l++) { + v0 = gains[l] - (g->scale_factors[k++] << shift) + 400; + for(j=len;j>0;j--) + *exp_ptr++ = v0; + } + } + } +} + +static void reorder_block(mp3_context_t *s, granule_t *g) +{ + int i, j, len; + int32_t *ptr, *dst, *ptr1; + int32_t tmp[576]; + + if (g->block_type != 2) + return; + + if (g->switch_point) { + if (s->sample_rate_index != 8) { + ptr = g->sb_hybrid + 36; + } else { + ptr = g->sb_hybrid + 48; + } + } else { + ptr = g->sb_hybrid; + } + + for(i=g->short_start;i<13;i++) { + len = band_size_short[s->sample_rate_index][i]; + ptr1 = ptr; + dst = tmp; + for(j=len;j>0;j--) { + *dst++ = ptr[0*len]; + *dst++ = ptr[1*len]; + *dst++ = ptr[2*len]; + ptr++; + } + ptr+=2*len; + libc_memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1)); + } +} + +static void compute_antialias(mp3_context_t *s, granule_t *g) { + int32_t *ptr, *csa; + int n, i; + + /* we antialias only "long" bands */ + if (g->block_type == 2) { + if (!g->switch_point) + return; + /* XXX: check this for 8000Hz case */ + n = 1; + } else { + n = SBLIMIT - 1; + } + + ptr = g->sb_hybrid + 18; + for(i = n;i > 0;i--) { + int tmp0, tmp1, tmp2; + csa = &csa_table[0][0]; +#define INT_AA(j) \ + tmp0 = ptr[-1-j];\ + tmp1 = ptr[ j];\ + tmp2= MULH(tmp0 + tmp1, csa[0+4*j]);\ + ptr[-1-j] = 4*(tmp2 - MULH(tmp1, csa[2+4*j]));\ + ptr[ j] = 4*(tmp2 + MULH(tmp0, csa[3+4*j])); + + INT_AA(0) + INT_AA(1) + INT_AA(2) + INT_AA(3) + INT_AA(4) + INT_AA(5) + INT_AA(6) + INT_AA(7) + + ptr += 18; + } +} + +static void compute_stereo( + mp3_context_t *s, granule_t *g0, granule_t *g1 +) { + int i, j, k, l; + int32_t v1, v2; + int sf_max, tmp0, tmp1, sf, len, non_zero_found; + int32_t (*is_tab)[16]; + int32_t *tab0, *tab1; + int non_zero_found_short[3]; + + if (s->mode_ext & MODE_EXT_I_STEREO) { + if (!s->lsf) { + is_tab = is_table; + sf_max = 7; + } else { + is_tab = is_table_lsf[g1->scalefac_compress & 1]; + sf_max = 16; + } + + tab0 = g0->sb_hybrid + 576; + tab1 = g1->sb_hybrid + 576; + + non_zero_found_short[0] = 0; + non_zero_found_short[1] = 0; + non_zero_found_short[2] = 0; + k = (13 - g1->short_start) * 3 + g1->long_end - 3; + for(i = 12;i >= g1->short_start;i--) { + /* for last band, use previous scale factor */ + if (i != 11) + k -= 3; + len = band_size_short[s->sample_rate_index][i]; + for(l=2;l>=0;l--) { + tab0 -= len; + tab1 -= len; + if (!non_zero_found_short[l]) { + /* test if non zero band. if so, stop doing i-stereo */ + for(j=0;jscale_factors[k + l]; + if (sf >= sf_max) + goto found1; + + v1 = is_tab[0][sf]; + v2 = is_tab[1][sf]; + for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { + /* lower part of the spectrum : do ms stereo + if enabled */ + for(j=0;jlong_end - 1;i >= 0;i--) { + len = band_size_long[s->sample_rate_index][i]; + tab0 -= len; + tab1 -= len; + /* test if non zero band. if so, stop doing i-stereo */ + if (!non_zero_found) { + for(j=0;jscale_factors[k]; + if (sf >= sf_max) + goto found2; + v1 = is_tab[0][sf]; + v2 = is_tab[1][sf]; + for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { + /* lower part of the spectrum : do ms stereo + if enabled */ + for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { + /* ms stereo ONLY */ + /* NOTE: the 1/sqrt(2) normalization factor is included in the + global gain */ + tab0 = g0->sb_hybrid; + tab1 = g1->sb_hybrid; + for(i=0;i<576;i++) { + tmp0 = tab0[i]; + tmp1 = tab1[i]; + tab0[i] = tmp0 + tmp1; + tab1[i] = tmp0 - tmp1; + } + } +} + +static int huffman_decode( + mp3_context_t *s, granule_t *g, int16_t *exponents, int end_pos2 +) { + int s_index; + int i; + int last_pos, bits_left; + vlc_t *vlc; + int end_pos= s->gb.size_in_bits; + if (end_pos2 < end_pos) end_pos = end_pos2; + + /* low frequencies (called big values) */ + s_index = 0; + for(i=0;i<3;i++) { + int j, k, l, linbits; + j = g->region_size[i]; + if (j == 0) + continue; + /* select vlc table */ + k = g->table_select[i]; + l = mp3_huff_data[k][0]; + linbits = mp3_huff_data[k][1]; + vlc = &huff_vlc[l]; + + if(!l){ + libc_memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*2*j); + s_index += 2*j; + continue; + } + + /* read huffcode and compute each couple */ + for(;j>0;j--) { + int exponent, x, y, v; + int pos= get_bits_count(&s->gb); + + if (pos >= end_pos){ + switch_buffer(s, &pos, &end_pos, &end_pos2); + if(pos >= end_pos) + break; + } + y = get_vlc2(&s->gb, vlc->table, 7, 3); + + if(!y){ + g->sb_hybrid[s_index ] = + g->sb_hybrid[s_index+1] = 0; + s_index += 2; + continue; + } + + exponent= exponents[s_index]; + + if(y&16){ + x = y >> 5; + y = y & 0x0f; + if (x < 15){ + v = expval_table[ exponent ][ x ]; + }else{ + x += get_bitsz(&s->gb, linbits); + v = l3_unscale(x, exponent); + } + if (get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[s_index] = v; + if (y < 15){ + v = expval_table[ exponent ][ y ]; + }else{ + y += get_bitsz(&s->gb, linbits); + v = l3_unscale(y, exponent); + } + if (get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[s_index+1] = v; + }else{ + x = y >> 5; + y = y & 0x0f; + x += y; + if (x < 15){ + v = expval_table[ exponent ][ x ]; + }else{ + x += get_bitsz(&s->gb, linbits); + v = l3_unscale(x, exponent); + } + if (get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[s_index+!!y] = v; + g->sb_hybrid[s_index+ !y] = 0; + } + s_index+=2; + } + } + + /* high frequencies */ + vlc = &huff_quad_vlc[g->count1table_select]; + last_pos=0; + while (s_index <= 572) { + int pos, code; + pos = get_bits_count(&s->gb); + if (pos >= end_pos) { + if (pos > end_pos2 && last_pos){ + /* some encoders generate an incorrect size for this + part. We must go back into the data */ + s_index -= 4; + skip_bits_long(&s->gb, last_pos - pos); + break; + } + switch_buffer(s, &pos, &end_pos, &end_pos2); + if(pos >= end_pos) + break; + } + last_pos= pos; + + code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1); + g->sb_hybrid[s_index+0]= + g->sb_hybrid[s_index+1]= + g->sb_hybrid[s_index+2]= + g->sb_hybrid[s_index+3]= 0; + while(code){ + const static int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; + int v; + int pos= s_index+idxtab[code]; + code ^= 8>>idxtab[code]; + v = exp_table[ exponents[pos] ]; + if(get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[pos] = v; + } + s_index+=4; + } + libc_memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*(576 - s_index)); + + /* skip extension bits */ + bits_left = end_pos2 - get_bits_count(&s->gb); + if (bits_left < 0) { + return -1; + } + skip_bits_long(&s->gb, bits_left); + + i= get_bits_count(&s->gb); + switch_buffer(s, &i, &end_pos, &end_pos2); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// + +static void imdct12(int *out, int *in) +{ + int in0, in1, in2, in3, in4, in5, t1, t2; + + in0= in[0*3]; + in1= in[1*3] + in[0*3]; + in2= in[2*3] + in[1*3]; + in3= in[3*3] + in[2*3]; + in4= in[4*3] + in[3*3]; + in5= in[5*3] + in[4*3]; + in5 += in3; + in3 += in1; + + in2= MULH(2*in2, C3); + in3= MULH(4*in3, C3); + + t1 = in0 - in4; + t2 = MULH(2*(in1 - in5), icos36h[4]); + + out[ 7]= + out[10]= t1 + t2; + out[ 1]= + out[ 4]= t1 - t2; + + in0 += in4>>1; + in4 = in0 + in2; + in5 += 2*in1; + in1 = MULH(in5 + in3, icos36h[1]); + out[ 8]= + out[ 9]= in4 + in1; + out[ 2]= + out[ 3]= in4 - in1; + + in0 -= in2; + in5 = MULH(2*(in5 - in3), icos36h[7]); + out[ 0]= + out[ 5]= in0 - in5; + out[ 6]= + out[11]= in0 + in5; +} + +static void imdct36(int *out, int *buf, int *in, int *win) +{ + int i, j, t0, t1, t2, t3, s0, s1, s2, s3; + int tmp[18], *tmp1, *in1; + + for(i=17;i>=1;i--) + in[i] += in[i-1]; + for(i=17;i>=3;i-=2) + in[i] += in[i-2]; + + for(j=0;j<2;j++) { + tmp1 = tmp + j; + in1 = in + j; + t2 = in1[2*4] + in1[2*8] - in1[2*2]; + + t3 = in1[2*0] + (in1[2*6]>>1); + t1 = in1[2*0] - in1[2*6]; + tmp1[ 6] = t1 - (t2>>1); + tmp1[16] = t1 + t2; + + t0 = MULH(2*(in1[2*2] + in1[2*4]), C2); + t1 = MULH( in1[2*4] - in1[2*8] , -2*C8); + t2 = MULH(2*(in1[2*2] + in1[2*8]), -C4); + + tmp1[10] = t3 - t0 - t2; + tmp1[ 2] = t3 + t0 + t1; + tmp1[14] = t3 + t2 - t1; + + tmp1[ 4] = MULH(2*(in1[2*5] + in1[2*7] - in1[2*1]), -C3); + t2 = MULH(2*(in1[2*1] + in1[2*5]), C1); + t3 = MULH( in1[2*5] - in1[2*7] , -2*C7); + t0 = MULH(2*in1[2*3], C3); + + t1 = MULH(2*(in1[2*1] + in1[2*7]), -C5); + + tmp1[ 0] = t2 + t3 + t0; + tmp1[12] = t2 + t1 - t0; + tmp1[ 8] = t3 - t1 - t0; + } + + i = 0; + for(j=0;j<4;j++) { + t0 = tmp[i]; + t1 = tmp[i + 2]; + s0 = t1 + t0; + s2 = t1 - t0; + + t2 = tmp[i + 1]; + t3 = tmp[i + 3]; + s1 = MULH(2*(t3 + t2), icos36h[j]); + s3 = MULL(t3 - t2, icos36[8 - j]); + + t0 = s0 + s1; + t1 = s0 - s1; + out[(9 + j)*SBLIMIT] = MULH(t1, win[9 + j]) + buf[9 + j]; + out[(8 - j)*SBLIMIT] = MULH(t1, win[8 - j]) + buf[8 - j]; + buf[9 + j] = MULH(t0, win[18 + 9 + j]); + buf[8 - j] = MULH(t0, win[18 + 8 - j]); + + t0 = s2 + s3; + t1 = s2 - s3; + out[(9 + 8 - j)*SBLIMIT] = MULH(t1, win[9 + 8 - j]) + buf[9 + 8 - j]; + out[( j)*SBLIMIT] = MULH(t1, win[ j]) + buf[ j]; + buf[9 + 8 - j] = MULH(t0, win[18 + 9 + 8 - j]); + buf[ + j] = MULH(t0, win[18 + j]); + i += 4; + } + + s0 = tmp[16]; + s1 = MULH(2*tmp[17], icos36h[4]); + t0 = s0 + s1; + t1 = s0 - s1; + out[(9 + 4)*SBLIMIT] = MULH(t1, win[9 + 4]) + buf[9 + 4]; + out[(8 - 4)*SBLIMIT] = MULH(t1, win[8 - 4]) + buf[8 - 4]; + buf[9 + 4] = MULH(t0, win[18 + 9 + 4]); + buf[8 - 4] = MULH(t0, win[18 + 8 - 4]); +} + +static void compute_imdct( + mp3_context_t *s, granule_t *g, int32_t *sb_samples, int32_t *mdct_buf +) { + int32_t *ptr, *win, *win1, *buf, *out_ptr, *ptr1; + int32_t out2[12]; + int i, j, mdct_long_end, v, sblimit; + + /* find last non zero block */ + ptr = g->sb_hybrid + 576; + ptr1 = g->sb_hybrid + 2 * 18; + while (ptr >= ptr1) { + ptr -= 6; + v = ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5]; + if (v != 0) + break; + } + sblimit = ((ptr - g->sb_hybrid) / 18) + 1; + + if (g->block_type == 2) { + /* XXX: check for 8000 Hz */ + if (g->switch_point) + mdct_long_end = 2; + else + mdct_long_end = 0; + } else { + mdct_long_end = sblimit; + } + + buf = mdct_buf; + ptr = g->sb_hybrid; + for(j=0;jswitch_point && j < 2) + win1 = mdct_win[0]; + else + win1 = mdct_win[g->block_type]; + /* select frequency inversion */ + win = win1 + ((4 * 36) & -(j & 1)); + imdct36(out_ptr, buf, ptr, win); + out_ptr += 18*SBLIMIT; + ptr += 18; + buf += 18; + } + for(j=mdct_long_end;j 32767) + v = 32767; + else if (v < -32768) + v = -32768; + synth_buf[j] = v; + } + /* copy to avoid wrap */ + libc_memcpy(synth_buf + 512, synth_buf, 32 * sizeof(int16_t)); + + samples2 = samples + 31 * incr; + w = window; + w2 = window + 31; + + sum = *dither_state; + p = synth_buf + 16; + SUM8(sum, +=, w, p); + p = synth_buf + 48; + SUM8(sum, -=, w + 32, p); + *samples = round_sample(&sum); + samples += incr; + w++; + + /* we calculate two samples at the same time to avoid one memory + access per two sample */ + for(j=1;j<16;j++) { + sum2 = 0; + p = synth_buf + 16 + j; + SUM8P2(sum, +=, sum2, -=, w, w2, p); + p = synth_buf + 48 - j; + SUM8P2(sum, -=, sum2, -=, w + 32, w2 + 32, p); + + *samples = round_sample(&sum); + samples += incr; + sum += sum2; + *samples2 = round_sample(&sum); + samples2 -= incr; + w++; + w2--; + } + + p = synth_buf + 32; + SUM8(sum, -=, w + 32, p); + *samples = round_sample(&sum); + *dither_state= sum; + + offset = (offset - 32) & 511; + *synth_buf_offset = offset; +} + +//////////////////////////////////////////////////////////////////////////////// + +static int decode_header(mp3_context_t *s, uint32_t header) { + int sample_rate, frame_size, mpeg25, padding; + int sample_rate_index, bitrate_index; + if (header & (1<<20)) { + s->lsf = (header & (1<<19)) ? 0 : 1; + mpeg25 = 0; + } else { + s->lsf = 1; + mpeg25 = 1; + } + + sample_rate_index = (header >> 10) & 3; + sample_rate = mp3_freq_tab[sample_rate_index] >> (s->lsf + mpeg25); + sample_rate_index += 3 * (s->lsf + mpeg25); + s->sample_rate_index = sample_rate_index; + s->error_protection = ((header >> 16) & 1) ^ 1; + s->sample_rate = sample_rate; + + bitrate_index = (header >> 12) & 0xf; + padding = (header >> 9) & 1; + s->mode = (header >> 6) & 3; + s->mode_ext = (header >> 4) & 3; + s->nb_channels = (s->mode == MP3_MONO) ? 1 : 2; + + if (bitrate_index != 0) { + frame_size = mp3_bitrate_tab[s->lsf][bitrate_index]; + s->bit_rate = frame_size * 1000; + s->frame_size = (frame_size * 144000) / (sample_rate << s->lsf) + padding; + } else { + /* if no frame size computed, signal it */ + return 1; + } + return 0; +} + +static int mp_decode_layer3(mp3_context_t *s) { + int nb_granules, main_data_begin, private_bits; + int gr, ch, blocksplit_flag, i, j, k, n, bits_pos; + granule_t *g; + static granule_t granules[2][2]; + static int16_t exponents[576]; + const uint8_t *ptr; + + if (s->lsf) { + main_data_begin = get_bits(&s->gb, 8); + private_bits = get_bits(&s->gb, s->nb_channels); + nb_granules = 1; + } else { + main_data_begin = get_bits(&s->gb, 9); + if (s->nb_channels == 2) + private_bits = get_bits(&s->gb, 3); + else + private_bits = get_bits(&s->gb, 5); + nb_granules = 2; + for(ch=0;chnb_channels;ch++) { + granules[ch][0].scfsi = 0; /* all scale factors are transmitted */ + granules[ch][1].scfsi = get_bits(&s->gb, 4); + } + } + + for(gr=0;grnb_channels;ch++) { + g = &granules[ch][gr]; + g->part2_3_length = get_bits(&s->gb, 12); + g->big_values = get_bits(&s->gb, 9); + g->global_gain = get_bits(&s->gb, 8); + /* if MS stereo only is selected, we precompute the + 1/sqrt(2) renormalization factor */ + if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) == + MODE_EXT_MS_STEREO) + g->global_gain -= 2; + if (s->lsf) + g->scalefac_compress = get_bits(&s->gb, 9); + else + g->scalefac_compress = get_bits(&s->gb, 4); + blocksplit_flag = get_bits(&s->gb, 1); + if (blocksplit_flag) { + g->block_type = get_bits(&s->gb, 2); + if (g->block_type == 0) + return -1; + g->switch_point = get_bits(&s->gb, 1); + for(i=0;i<2;i++) + g->table_select[i] = get_bits(&s->gb, 5); + for(i=0;i<3;i++) + g->subblock_gain[i] = get_bits(&s->gb, 3); + /* compute huffman coded region sizes */ + if (g->block_type == 2) + g->region_size[0] = (36 / 2); + else { + if (s->sample_rate_index <= 2) + g->region_size[0] = (36 / 2); + else if (s->sample_rate_index != 8) + g->region_size[0] = (54 / 2); + else + g->region_size[0] = (108 / 2); + } + g->region_size[1] = (576 / 2); + } else { + int region_address1, region_address2, l; + g->block_type = 0; + g->switch_point = 0; + for(i=0;i<3;i++) + g->table_select[i] = get_bits(&s->gb, 5); + /* compute huffman coded region sizes */ + region_address1 = get_bits(&s->gb, 4); + region_address2 = get_bits(&s->gb, 3); + g->region_size[0] = + band_index_long[s->sample_rate_index][region_address1 + 1] >> 1; + l = region_address1 + region_address2 + 2; + /* should not overflow */ + if (l > 22) + l = 22; + g->region_size[1] = + band_index_long[s->sample_rate_index][l] >> 1; + } + /* convert region offsets to region sizes and truncate + size to big_values */ + g->region_size[2] = (576 / 2); + j = 0; + for(i=0;i<3;i++) { + k = g->region_size[i]; + if (g->big_values < k) k = g->big_values; + g->region_size[i] = k - j; + j = k; + } + + /* compute band indexes */ + if (g->block_type == 2) { + if (g->switch_point) { + /* if switched mode, we handle the 36 first samples as + long blocks. For 8000Hz, we handle the 48 first + exponents as long blocks (XXX: check this!) */ + if (s->sample_rate_index <= 2) + g->long_end = 8; + else if (s->sample_rate_index != 8) + g->long_end = 6; + else + g->long_end = 4; /* 8000 Hz */ + + g->short_start = 2 + (s->sample_rate_index != 8); + } else { + g->long_end = 0; + g->short_start = 0; + } + } else { + g->short_start = 13; + g->long_end = 22; + } + + g->preflag = 0; + if (!s->lsf) + g->preflag = get_bits(&s->gb, 1); + g->scalefac_scale = get_bits(&s->gb, 1); + g->count1table_select = get_bits(&s->gb, 1); + } + } + + ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); + /* now we get bits from the main_data_begin offset */ + if(main_data_begin > s->last_buf_size){ + s->last_buf_size= main_data_begin; + } + + memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES); + s->in_gb= s->gb; + init_get_bits(&s->gb, s->last_buf + s->last_buf_size - main_data_begin, main_data_begin*8); + + for(gr=0;grnb_channels;ch++) { + g = &granules[ch][gr]; + + bits_pos = get_bits_count(&s->gb); + + if (!s->lsf) { + uint8_t *sc; + int slen, slen1, slen2; + + /* MPEG1 scale factors */ + slen1 = slen_table[0][g->scalefac_compress]; + slen2 = slen_table[1][g->scalefac_compress]; + if (g->block_type == 2) { + n = g->switch_point ? 17 : 18; + j = 0; + if(slen1){ + for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen1); + }else{ + libc_memset((void*) &g->scale_factors[j], 0, n); + j += n; +// for(i=0;iscale_factors[j++] = 0; + } + if(slen2){ + for(i=0;i<18;i++) + g->scale_factors[j++] = get_bits(&s->gb, slen2); + for(i=0;i<3;i++) + g->scale_factors[j++] = 0; + }else{ + for(i=0;i<21;i++) + g->scale_factors[j++] = 0; + } + } else { + sc = granules[ch][0].scale_factors; + j = 0; + for(k=0;k<4;k++) { + n = (k == 0 ? 6 : 5); + if ((g->scfsi & (0x8 >> k)) == 0) { + slen = (k < 2) ? slen1 : slen2; + if(slen){ + for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen); + }else{ + libc_memset((void*) &g->scale_factors[j], 0, n); + j += n; +// for(i=0;iscale_factors[j++] = 0; + } + } else { + /* simply copy from last granule */ + for(i=0;iscale_factors[j] = sc[j]; + j++; + } + } + } + g->scale_factors[j++] = 0; + } + } else { + int tindex, tindex2, slen[4], sl, sf; + + /* LSF scale factors */ + if (g->block_type == 2) { + tindex = g->switch_point ? 2 : 1; + } else { + tindex = 0; + } + sf = g->scalefac_compress; + if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) { + /* intensity stereo case */ + sf >>= 1; + if (sf < 180) { + lsf_sf_expand(slen, sf, 6, 6, 0); + tindex2 = 3; + } else if (sf < 244) { + lsf_sf_expand(slen, sf - 180, 4, 4, 0); + tindex2 = 4; + } else { + lsf_sf_expand(slen, sf - 244, 3, 0, 0); + tindex2 = 5; + } + } else { + /* normal case */ + if (sf < 400) { + lsf_sf_expand(slen, sf, 5, 4, 4); + tindex2 = 0; + } else if (sf < 500) { + lsf_sf_expand(slen, sf - 400, 5, 4, 0); + tindex2 = 1; + } else { + lsf_sf_expand(slen, sf - 500, 3, 0, 0); + tindex2 = 2; + g->preflag = 1; + } + } + + j = 0; + for(k=0;k<4;k++) { + n = lsf_nsf_table[tindex2][tindex][k]; + sl = slen[k]; + if(sl){ + for(i=0;iscale_factors[j++] = get_bits(&s->gb, sl); + }else{ + libc_memset((void*) &g->scale_factors[j], 0, n); + j += n; +// for(i=0;iscale_factors[j++] = 0; + } + } + /* XXX: should compute exact size */ + libc_memset((void*) &g->scale_factors[j], 0, 40 - j); +// for(;j<40;j++) +// g->scale_factors[j] = 0; + } + + exponents_from_scale_factors(s, g, exponents); + + /* read Huffman coded residue */ + if (huffman_decode(s, g, exponents, + bits_pos + g->part2_3_length) < 0) + return -1; + } /* ch */ + + if (s->nb_channels == 2) + compute_stereo(s, &granules[0][gr], &granules[1][gr]); + + for(ch=0;chnb_channels;ch++) { + g = &granules[ch][gr]; + reorder_block(s, g); + compute_antialias(s, g); + compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]); + } + } /* gr */ + return nb_granules * 18; +} + +static int mp3_decode_main( + mp3_context_t *s, + int16_t *samples, const uint8_t *buf, int buf_size +) { + int i, nb_frames, ch; + int16_t *samples_ptr; + + init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE)*8); + + if (s->error_protection) + get_bits(&s->gb, 16); + + nb_frames = mp_decode_layer3(s); + + s->last_buf_size=0; + if(s->in_gb.buffer){ + align_get_bits(&s->gb); + i= (s->gb.size_in_bits - get_bits_count(&s->gb))>>3; + if(i >= 0 && i <= BACKSTEP_SIZE){ + libc_memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i); + s->last_buf_size=i; + } + s->gb= s->in_gb; + } + + align_get_bits(&s->gb); + i= (s->gb.size_in_bits - get_bits_count(&s->gb))>>3; + + if(i<0 || i > BACKSTEP_SIZE || nb_frames<0){ + i = buf_size - HEADER_SIZE; + if (BACKSTEP_SIZE < i) i = BACKSTEP_SIZE; + } + libc_memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i); + s->last_buf_size += i; + + /* apply the synthesis filter */ + for(ch=0;chnb_channels;ch++) { + samples_ptr = samples + ch; + for(i=0;isynth_buf[ch], &(s->synth_buf_offset[ch]), + window, &s->dither_state, + samples_ptr, s->nb_channels, + s->sb_samples[ch][i] + ); + samples_ptr += 32 * s->nb_channels; + } + } + return nb_frames * 32 * sizeof(uint16_t) * s->nb_channels; +} + +//////////////////////////////////////////////////////////////////////////////// + +static int mp3_decode_init(mp3_context_t *s) { + static int init=0; + int i, j, k; + + if (!init) { + /* synth init */ + for(i=0;i<257;i++) { + int v; + v = mp3_enwindow[i]; + #if WFRAC_BITS < 16 + v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); + #endif + window[i] = v; + if ((i & 63) != 0) + v = -v; + if (i != 0) + window[512 - i] = v; + } + + /* huffman decode tables */ + for(i=1;i<16;i++) { + const huff_table_t *h = &mp3_huff_tables[i]; + int xsize, x, y; + unsigned int n; + uint8_t tmp_bits [512]; + uint16_t tmp_codes[512]; + + libc_memset(tmp_bits , 0, sizeof(tmp_bits )); + libc_memset(tmp_codes, 0, sizeof(tmp_codes)); + + xsize = h->xsize; + n = xsize * xsize; + + j = 0; + for(x=0;xbits [j ]; + tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++]; + } + } + + init_vlc(&huff_vlc[i], 7, 512, + tmp_bits, 1, 1, tmp_codes, 2, 2); + } + for(i=0;i<2;i++) { + init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16, + mp3_quad_bits[i], 1, 1, mp3_quad_codes[i], 1, 1); + } + + for(i=0;i<9;i++) { + k = 0; + for(j=0;j<22;j++) { + band_index_long[i][j] = k; + k += band_size_long[i][j]; + } + band_index_long[i][22] = k; + } + + /* compute n ^ (4/3) and store it in mantissa/exp format */ + table_4_3_exp= libc_malloc(TABLE_4_3_SIZE * sizeof(table_4_3_exp[0])); + if(!table_4_3_exp) + return -1; + table_4_3_value= libc_malloc(TABLE_4_3_SIZE * sizeof(table_4_3_value[0])); + if(!table_4_3_value) + return -1; + + for(i=1;i>4); + double f= libc_pow(i&15, 4.0 / 3.0) * libc_pow(2, (exponent-400)*0.25 + FRAC_BITS + 5); + expval_table[exponent][i&15]= f; + if((i&15)==1) + exp_table[exponent]= f; + } + + for(i=0;i<7;i++) { + float f; + int v; + if (i != 6) { + f = tan((double)i * M_PI / 12.0); + v = FIXR(f / (1.0 + f)); + } else { + v = FIXR(1.0); + } + is_table[0][i] = v; + is_table[1][6 - i] = v; + } + for(i=7;i<16;i++) + is_table[0][i] = is_table[1][i] = 0.0; + + for(i=0;i<16;i++) { + double f; + int e, k; + + for(j=0;j<2;j++) { + e = -(j + 1) * ((i + 1) >> 1); + f = libc_pow(2.0, e / 4.0); + k = i & 1; + is_table_lsf[j][k ^ 1][i] = FIXR(f); + is_table_lsf[j][k][i] = FIXR(1.0); + } + } + + for(i=0;i<8;i++) { + float ci, cs, ca; + ci = ci_table[i]; + cs = 1.0 / sqrt(1.0 + ci * ci); + ca = cs * ci; + csa_table[i][0] = FIXHR(cs/4); + csa_table[i][1] = FIXHR(ca/4); + csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4); + csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4); + csa_table_float[i][0] = cs; + csa_table_float[i][1] = ca; + csa_table_float[i][2] = ca + cs; + csa_table_float[i][3] = ca - cs; + } + + /* compute mdct windows */ + for(i=0;i<36;i++) { + for(j=0; j<4; j++){ + double d; + + if(j==2 && i%3 != 1) + continue; + + d= sin(M_PI * (i + 0.5) / 36.0); + if(j==1){ + if (i>=30) d= 0; + else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0); + else if(i>=18) d= 1; + }else if(j==3){ + if (i< 6) d= 0; + else if(i< 12) d= sin(M_PI * (i - 6 + 0.5) / 12.0); + else if(i< 18) d= 1; + } + d*= 0.5 / cos(M_PI*(2*i + 19)/72); + if(j==2) + mdct_win[j][i/3] = FIXHR((d / (1<<5))); + else + mdct_win[j][i ] = FIXHR((d / (1<<5))); + } + } + for(j=0;j<4;j++) { + for(i=0;i<36;i+=2) { + mdct_win[j + 4][i] = mdct_win[j][i]; + mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1]; + } + } + init = 1; + } + return 0; +} + +static int mp3_decode_frame( + mp3_context_t *s, + int16_t *out_samples, int *data_size, + uint8_t *buf, int buf_size +) { + uint32_t header; + int out_size; + int extra_bytes = 0; + +retry: + if(buf_size < HEADER_SIZE) + return -1; + + header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + if(mp3_check_header(header) < 0){ + buf++; + buf_size--; + extra_bytes++; + goto retry; + } + + if (decode_header(s, header) == 1) { + s->frame_size = -1; + return -1; + } + + if(s->frame_size<=0 || s->frame_size > buf_size){ + return -1; // incomplete frame + } + if(s->frame_size < buf_size) { + buf_size = s->frame_size; + } + + out_size = mp3_decode_main(s, out_samples, buf, buf_size); + if(out_size>=0) + *data_size = out_size; + // else: Error while decoding MPEG audio frame. + s->frame_size += extra_bytes; + return buf_size; +} + +//////////////////////////////////////////////////////////////////////////////// + +mp3_decoder_t mp3_create(void) { + void *dec = libc_calloc(sizeof(mp3_context_t), 1); + if (dec) mp3_decode_init((mp3_context_t*) dec); + return (mp3_decoder_t) dec; +} + +void mp3_done(mp3_decoder_t *dec) { + if (dec) libc_free(dec); +} + +int mp3_decode(mp3_decoder_t *dec, void *buf, int bytes, signed short *out, mp3_info_t *info) { + int res, size = -1; + mp3_context_t *s = (mp3_context_t*) dec; + if (!s) return 0; + res = mp3_decode_frame(s, (int16_t*) out, &size, buf, bytes); + if (res < 0) return 0; + if (info) { + info->sample_rate = s->sample_rate; + info->channels = s->nb_channels; + info->audio_bytes = size; + } + return s->frame_size; +} diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.h b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.h new file mode 100644 index 000000000..fa29a9747 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.h @@ -0,0 +1,19 @@ +#ifndef __MINIMP3_H_INCLUDED__ +#define __MINIMP3_H_INCLUDED__ + +#define MP3_MAX_SAMPLES_PER_FRAME (1152*2) + +typedef struct _mp3_info { + int sample_rate; + int channels; + int audio_bytes; // generated amount of audio per frame +} mp3_info_t; + +typedef void* mp3_decoder_t; + +extern mp3_decoder_t mp3_create(void); +extern int mp3_decode(mp3_decoder_t *dec, void *buf, int bytes, signed short *out, mp3_info_t *info); +extern void mp3_done(mp3_decoder_t *dec); +#define mp3_free(dec) do { mp3_done(dec); dec = NULL; } while(0) + +#endif//__MINIMP3_H_INCLUDED__ diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.vcproj b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.vcproj new file mode 100644 index 000000000..0eed9b066 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/minimp3.vcproj @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/player_oss.c b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/player_oss.c new file mode 100644 index 000000000..dfe5bd9ea --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/player_oss.c @@ -0,0 +1,84 @@ +// minimp3 example player application for Linux/OSS +// this file is public domain -- do with it whatever you want! +#include "libc.h" +#include "minimp3.h" +#include +#include +#include +#include +#include +#include +#include + +size_t strlen(const char *s); +#define out(text) write(1, (const void *) text, strlen(text)) + +int main(int argc, char *argv[]) { + mp3_decoder_t mp3; + mp3_info_t info; + int fd, pcm; + void *file_data; + unsigned char *stream_pos; + signed short sample_buf[MP3_MAX_SAMPLES_PER_FRAME]; + int bytes_left; + int frame_size; + int value; + + out("minimp3 -- a small MPEG-1 Audio Layer III player based on ffmpeg\n\n"); + if (argc < 2) { + out("Error: no input file specified!\n"); + return 1; + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + out("Error: cannot open `"); + out(argv[1]); + out("'!\n"); + return 1; + } + + bytes_left = lseek(fd, 0, SEEK_END); + file_data = mmap(0, bytes_left, PROT_READ, MAP_PRIVATE, fd, 0); + stream_pos = (unsigned char *) file_data; + bytes_left -= 100; + out("Now Playing: "); + out(argv[1]); + + mp3 = mp3_create(); + frame_size = mp3_decode(mp3, stream_pos, bytes_left, sample_buf, &info); + if (!frame_size) { + out("\nError: not a valid MP3 audio file!\n"); + return 1; + } + + #define FAIL(msg) { \ + out("\nError: " msg "\n"); \ + return 1; \ + } + + pcm = open("/dev/dsp", O_WRONLY); + if (pcm < 0) FAIL("cannot open DSP"); + + value = AFMT_S16_LE; + if (ioctl(pcm, SNDCTL_DSP_SETFMT, &value) < 0) + FAIL("cannot set audio format"); + + if (ioctl(pcm, SNDCTL_DSP_CHANNELS, &info.channels) < 0) + FAIL("cannot set audio channels"); + + if (ioctl(pcm, SNDCTL_DSP_SPEED, &info.sample_rate) < 0) + FAIL("cannot set audio sample rate"); + + out("\n\nPress Ctrl+C to stop playback.\n"); + + while ((bytes_left >= 0) && (frame_size > 0)) { + stream_pos += frame_size; + bytes_left -= frame_size; + write(pcm, (const void *) sample_buf, info.audio_bytes); + frame_size = mp3_decode(mp3, stream_pos, bytes_left, sample_buf, NULL); + } + + close(pcm); + return 0; +} diff --git a/internal/c/parts/audio/decode/mp3_mini/download/minimp3/player_win32.c b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/player_win32.c new file mode 100644 index 000000000..970456fa5 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/download/minimp3/player_win32.c @@ -0,0 +1,177 @@ +// minimp3 example player application for Win32 +// this file is public domain -- do with it whatever you want! +#define MAIN_PROGRAM + +#include "libc.h" +#include "minimp3.h" + +#define BUFFER_COUNT 8 + +static WAVEFORMATEX wf = { + 1, // wFormatTag + 0, // nChannels + 0, // nSamplesPerSec + 0, // nAvgBytesPerSec + 4, // nBlockAlign + 16, // wBitsPerSample + sizeof(WAVEFORMATEX) // cbSize +}; + +static const WAVEHDR wh_template = { + NULL, // lpData + 0, // dwBufferLength + 0, // dwBytesRecorded + 0, // dwUser + 0, // dwFlags + 1, // dwLoops + NULL, // lpNext + 0 // reserved +}; + + +static mp3_decoder_t mp3; +static mp3_info_t info; +static unsigned char *stream_pos; +static int bytes_left; +static int byte_count; +static WAVEHDR wh[BUFFER_COUNT]; +static signed short sample_buffer[MP3_MAX_SAMPLES_PER_FRAME * BUFFER_COUNT]; + +static HANDLE local_stdout; +#define out(text) WriteFile(local_stdout, (LPCVOID) text, strlen(text), NULL, NULL) + + +void CALLBACK AudioCallback( + HWAVEOUT hwo, + UINT uMsg, + DWORD_PTR dwInstance, + DWORD dwParam1, + DWORD dwParam2 +) { + LPWAVEHDR wh = (LPWAVEHDR) dwParam1; + if (!wh) return; + if (byte_count) { + stream_pos += byte_count; + bytes_left -= byte_count; + waveOutUnprepareHeader(hwo, wh, sizeof(WAVEHDR)); + waveOutPrepareHeader(hwo, wh, sizeof(WAVEHDR)); + waveOutWrite(hwo, wh, sizeof(WAVEHDR)); + } + byte_count = mp3_decode(mp3, stream_pos, bytes_left, (signed short *) wh->lpData, &info); +} + + +void ShowTag(const char *caption, const unsigned char *src, int max_length) { + static char tagbuf[32]; + char *tagpos = tagbuf; + tagbuf[max_length] = '\0'; + __asm { + cld + mov esi, src + mov edi, tagpos + mov ecx, max_length + rep movsb + } + if (!*tagbuf) + return; + out(caption); + out(tagbuf); +} + + +int main(void) { + char input_file_name[256]; + char *inptr, *outptr = input_file_name; + HANDLE hFile, hMap; + HWAVEOUT hwo; + int i; + + // init stdout and write banner + local_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + out("minimp3 -- a small MPEG Audio Layer III player based on ffmpeg\n\n"); + + // read arguments, but skip the program name + for (inptr = GetCommandLine(); (*inptr) && (*inptr != ' '); ++inptr) { + if (*inptr == '"') // skip "quoted arguments" + do { ++inptr; } while (*inptr != '"'); + } + // skip whitespace + while (*inptr == ' ') ++inptr; + // check for a parameter + if (!*inptr) { + // no parameter -> quit + out("Error: no input file specified!\n"); + return 1; + } else if (*inptr == '"') { + // "quoted parameter" + ++inptr; + while (*inptr != '"') + *outptr++ = *inptr++; + } else { + // unquoted parameter + do { + *outptr++ = *inptr++; + } while(*inptr); + } + *outptr = '\0'; + + // open and mmap() the file + hFile = CreateFile(input_file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + bytes_left = GetFileSize(hFile, NULL) - 128; + hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + stream_pos = (unsigned char*) MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); + + // check if the result is valid + if (!stream_pos) { + out("Error: cannot open `"); + out(input_file_name); + out("'!\n"); + return 1; + } else { + out("Now Playing: "); + out(input_file_name); + } + + // check for a ID3 tag + inptr = stream_pos + bytes_left; + if (((*(unsigned long *)inptr) & 0xFFFFFF) == 0x474154) { + ShowTag("\nTitle: ", inptr + 3, 30); + ShowTag("\nArtist: ", inptr + 33, 30); + ShowTag("\nAlbum: ", inptr + 63, 30); + ShowTag("\nYear: ", inptr + 93, 4); + ShowTag("\nComment: ", inptr + 97, 30); + } + + // set up minimp3 and decode the first frame + mp3 = mp3_create(); + byte_count = mp3_decode(mp3, stream_pos, bytes_left, sample_buffer, &info); + if (!byte_count) { + out("\nError: not a valid MP2 audio file!\n"); + return 1; + } + + // set up wave output + wf.nSamplesPerSec = info.sample_rate; + wf.nChannels = info.channels; + if(waveOutOpen(&hwo, WAVE_MAPPER, &wf, (INT_PTR) AudioCallback, (INT_PTR) NULL, CALLBACK_FUNCTION) + != MMSYSERR_NOERROR) { + out("\nError: cannot open wave output!\n"); + return 1; + } + + // allocate buffers + out("\n\nPress Ctrl+C or close the console window to stop playback.\n"); + inptr = (char*) sample_buffer; + for (i = 0; i < BUFFER_COUNT; ++i) { + wh[i] = wh_template; + wh[i].lpData = inptr; + wh[i].dwBufferLength = info.audio_bytes; + AudioCallback(hwo, 0, 0, (DWORD) &wh[i], 0); + inptr += MP3_MAX_SAMPLES_PER_FRAME * 2; + } + + // endless loop + while (1) Sleep(10); + + return 0; +} diff --git a/internal/c/parts/audio/decode/mp3_mini/os/lnx/build.sh b/internal/c/parts/audio/decode/mp3_mini/os/lnx/build.sh new file mode 100644 index 000000000..d4dc5ba43 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/os/lnx/build.sh @@ -0,0 +1,13 @@ +#!/bin/sh +gcc -c ../../src/minimp3.c -o temp/minimp3.o +ar rcs src.a temp/minimp3.o +echo "Press any key to continue..." +Pause() +{ +OLDCONFIG=`stty -g` +stty -icanon -echo min 1 time 0 +dd count=1 2>/dev/null +stty $OLDCONFIG +} +Pause + diff --git a/internal/c/parts/audio/decode/mp3_mini/os/lnx/temp/temp.bin b/internal/c/parts/audio/decode/mp3_mini/os/lnx/temp/temp.bin new file mode 100644 index 000000000..e69de29bb diff --git a/internal/c/parts/audio/decode/mp3_mini/os/osx/build.command b/internal/c/parts/audio/decode/mp3_mini/os/osx/build.command new file mode 100644 index 000000000..dabea0015 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/os/osx/build.command @@ -0,0 +1,13 @@ +cd "$(dirname "$0")" +gcc -c ../../src/minimp3.c -o temp/minimp3.o +ar rcs src.a temp/minimp3.o +echo "Press any key to continue..." +Pause() +{ +OLDCONFIG=`stty -g` +stty -icanon -echo min 1 time 0 +dd count=1 2>/dev/null +stty $OLDCONFIG +} +Pause + diff --git a/internal/c/parts/audio/decode/mp3_mini/os/osx/temp/temp.bin b/internal/c/parts/audio/decode/mp3_mini/os/osx/temp/temp.bin new file mode 100644 index 000000000..e69de29bb diff --git a/internal/c/parts/audio/decode/mp3_mini/os/win/build.bat b/internal/c/parts/audio/decode/mp3_mini/os/win/build.bat new file mode 100644 index 000000000..edbac9e5b --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/os/win/build.bat @@ -0,0 +1,3 @@ +..\..\..\..\..\..\c_compiler\bin\gcc -c ..\..\src\minimp3.c -o temp\minimp3.o +..\..\..\..\..\..\c_compiler\bin\ar rcs src.a temp\minimp3.o +pause diff --git a/internal/c/parts/audio/decode/mp3_mini/os/win/src.a b/internal/c/parts/audio/decode/mp3_mini/os/win/src.a new file mode 100644 index 000000000..e723c93e0 Binary files /dev/null and b/internal/c/parts/audio/decode/mp3_mini/os/win/src.a differ diff --git a/internal/c/parts/audio/decode/mp3_mini/os/win/temp/minimp3.o b/internal/c/parts/audio/decode/mp3_mini/os/win/temp/minimp3.o new file mode 100644 index 000000000..fdc5f65dd Binary files /dev/null and b/internal/c/parts/audio/decode/mp3_mini/os/win/temp/minimp3.o differ diff --git a/internal/c/parts/audio/decode/mp3_mini/os/win/temp/temp.bin b/internal/c/parts/audio/decode/mp3_mini/os/win/temp/temp.bin new file mode 100644 index 000000000..e69de29bb diff --git a/internal/c/parts/audio/decode/mp3_mini/src.c b/internal/c/parts/audio/decode/mp3_mini/src.c new file mode 100644 index 000000000..6e45a7f1f --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/src.c @@ -0,0 +1,76 @@ +#ifndef DEPENDENCY_AUDIO_DECODE_MP3 +//Stubs: +//(none required) +#else + +extern "C" { +#ifdef QB64_BACKSLASH_FILESYSTEM + #include "src\\minimp3.h" +#else + #include "src/minimp3.h" +#endif +} + +snd_sequence_struct *snd_decode_mp3(uint8 *buffer,int32 bytes){ + +mp3_decoder_t mp3; +mp3_info_t info; +memset(&info,0,sizeof(mp3_info_t)); + +unsigned char *stream_pos; +int bytes_left; +int bytes_read; + +int sample_buffer_allocated_bytes=2000000; +int16* sample_buffer=(int16*)malloc(2000000); +int16* sample_buffer_offset; + +bytes_left=bytes; +stream_pos=(unsigned char*)buffer; + +mp3 = mp3_create(); + +int bytes_out=0; + +int firstTry=1; + +sample_buffer_offset=sample_buffer; +mp3getmore: +bytes_read = mp3_decode((void**)mp3, stream_pos, bytes_left, sample_buffer_offset, &info); +if (firstTry==1 && info.audio_bytes<=0){ + free(sample_buffer); + return NULL; +} +firstTry=0; +bytes_left-=bytes_read; +stream_pos+=bytes_read; +sample_buffer_offset=(int16*)(((uint8*)sample_buffer_offset)+info.audio_bytes); +bytes_out+=info.audio_bytes; + +if (bytes_out+1000000>sample_buffer_allocated_bytes){ + sample_buffer_allocated_bytes+=1000000; + sample_buffer=(int16*)realloc(sample_buffer,sample_buffer_allocated_bytes); + sample_buffer_offset=(int16*)(((uint8*)sample_buffer)+bytes_out); +} + +if (bytes_left>0 && bytes_read!=0) goto mp3getmore; + +//attach bufout to new sequence +static int32 seq_handle; seq_handle=list_add(snd_sequences); +static snd_sequence_struct *seq; seq=(snd_sequence_struct*)list_get(snd_sequences,seq_handle); +memset(seq,0,sizeof(snd_sequence_struct)); +seq->references=1; +seq->data=(uint8*)sample_buffer; +seq->data_size=bytes_out; +seq->channels=info.channels; +seq->endian=0;//native +seq->is_unsigned=0; +seq->sample_rate=info.sample_rate; +seq->bits_per_sample=16; + +return seq; + +} + +#endif + diff --git a/internal/c/parts/audio/decode/mp3_mini/src/LGPL.txt b/internal/c/parts/audio/decode/mp3_mini/src/LGPL.txt new file mode 100644 index 000000000..1e0991447 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/src/LGPL.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/internal/c/parts/audio/decode/mp3_mini/src/Makefile b/internal/c/parts/audio/decode/mp3_mini/src/Makefile new file mode 100644 index 000000000..df27432cd --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/src/Makefile @@ -0,0 +1,39 @@ +# note: this Makefile builds the Linux version only + +CFLAGS = -Wall -Os -march=pentium +CFLAGS += -ffast-math +CFLAGS += -finline-functions-called-once +CFLAGS += -fno-loop-optimize +CFLAGS += -fexpensive-optimizations +CFLAGS += -fpeephole2 + +STRIPFLAGS = -R .comment +STRIPFLAGS += -R .note +STRIPFLAGS += -R .note.ABI-tag +STRIPFLAGS += -R .gnu.version + +BIN = minimp3 +FINALBIN = $(BIN)-linux +OBJS = player_oss.o minimp3.o + +all: $(BIN) + +release: $(BIN) + strip $(STRIPFLAGS) $(BIN) + upx --brute $(BIN) + +test: $(BIN) + ./$(BIN) "../../../Gargaj -- Rude Awakening.mp3" + +$(BIN): $(OBJS) + gcc $(OBJS) -o $(BIN) -lm + +%.o: %.c + gcc $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(BIN) $(OBJS) + +dist: clean release + mv $(BIN) $(FINALBIN) + rm -f $(OBJS) diff --git a/internal/c/parts/audio/decode/mp3_mini/src/libc.h b/internal/c/parts/audio/decode/mp3_mini/src/libc.h new file mode 100644 index 000000000..4986fc8fc --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/src/libc.h @@ -0,0 +1,184 @@ +// a libc replacement (more or less) for the Microsoft Visual C compiler +// this file is public domain -- do with it whatever you want! +#ifndef __LIBC_H_INCLUDED__ +#define __LIBC_H_INCLUDED__ + +// check if minilibc is required +#ifndef NEED_MINILIBC + #ifndef NOLIBC + #define NEED_MINILIBC 0 + #else + #define NEED_MINILIBC 1 + #endif +#endif + +#ifdef _MSC_VER + #define INLINE __forceinline + #define FASTCALL __fastcall + #ifdef NOLIBC + #ifdef MAIN_PROGRAM + int _fltused=0; + #endif + #endif +#else + #define INLINE inline + #define FASTCALL __attribute__((fastcall)) + #include +#endif + +#ifdef _WIN32 + #ifndef WIN32 + #define WIN32 + #endif +#endif +#ifdef WIN32 + #include +#endif + +#if !NEED_MINILIBC + #include + #include + #include +#endif +#include + +#ifndef __int8_t_defined + #define __int8_t_defined + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef signed short int16_t; + typedef unsigned int uint32_t; + typedef signed int int32_t; + #ifdef _MSC_VER + typedef unsigned __int64 uint64_t; + typedef signed __int64 int64_t; + #else + typedef unsigned long long uint64_t; + typedef signed long long int64_t; + #endif +#endif + +#ifndef NULL + #define NULL 0 +#endif + +#ifndef M_PI + #define M_PI 3.14159265358979 +#endif + +/////////////////////////////////////////////////////////////////////////////// + +#if NEED_MINILIBC + +static INLINE void libc_memset(void *dest, int value, int count) { + if (!count) return; + __asm { + cld + mov edi, dest + mov eax, value + mov ecx, count + rep stosb + } +} + +static INLINE void libc_memcpy(void *dest, const void *src, int count) { + if (!count) return; + __asm { + cld + mov esi, src + mov edi, dest + mov ecx, count + rep movsb + } +} + +#define libc_memmove libc_memcpy + +static INLINE void* libc_malloc(int size) { + return (void*) LocalAlloc(LMEM_FIXED, size); +} + +static INLINE void* libc_calloc(int size, int nmemb) { + return (void*) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, size * nmemb); +} + +static INLINE void* libc_realloc(void* old, int size) { + int oldsize = (int) LocalSize((HLOCAL) old); + void *mem; + if (size <= oldsize) return old; + mem = LocalAlloc(LMEM_FIXED, size); + libc_memcpy(mem, old, oldsize); + LocalFree((HLOCAL) old); + return mem; +} + +static INLINE void libc_free(void *mem) { + LocalFree((HLOCAL) mem); +} + +static INLINE double libc_frexp(double x, int *e) { + double res = -9999.999; + unsigned __int64 i = *(unsigned __int64*)(&x); + if (!(i & 0x7F00000000000000UL)) { + *e = 0; + return x; + } + *e = ((i << 1) >> 53) - 1022; + i &= 0x800FFFFFFFFFFFFFUL; + i |= 0x3FF0000000000000UL; + return *(double*)(&i) * 0.5; +} + +static INLINE double __declspec(naked) libc_exp(double x) { __asm { + fldl2e + fld qword ptr [esp+4] + fmul + fst st(1) + frndint + fxch + fsub st(0), st(1) + f2xm1 + fld1 + fadd + fscale + ret +} } + + +static INLINE double __declspec(naked) libc_pow(double b, double e) { __asm { + fld qword ptr [esp+12] + fld qword ptr [esp+4] + fyl2x +// following is a copy of libc_exp: + fst st(1) + frndint + fxch + fsub st(0), st(1) + f2xm1 + fld1 + fadd + fscale + ret +} } + + + +#else // NEED_MINILIBC == 0 + +#define libc_malloc malloc +#define libc_calloc calloc +#define libc_realloc realloc +#define libc_free free + +#define libc_memset memset +#define libc_memcpy memcpy +#define libc_memmove memmove + +#define libc_frexp frexp +#define libc_exp exp +#define libc_pow pow + +#endif // NEED_MINILIBC + +#endif//__LIBC_H_INCLUDED__ diff --git a/internal/c/parts/audio/decode/mp3_mini/src/minimp3.c b/internal/c/parts/audio/decode/mp3_mini/src/minimp3.c new file mode 100644 index 000000000..b2cfd2391 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/src/minimp3.c @@ -0,0 +1,2656 @@ +/* + * MPEG Audio Layer III decoder + * Copyright (c) 2001, 2002 Fabrice Bellard, + * (c) 2007 Martin J. Fiedler + * + * This file is a stripped-down version of the MPEG Audio decoder from + * the FFmpeg libavcodec library. + * + * FFmpeg and minimp3 are 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. + * + * FFmpeg and minimp3 are 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libc.h" +#include "minimp3.h" + +#define MP3_FRAME_SIZE 1152 +#define MP3_MAX_CODED_FRAME_SIZE 1792 +#define MP3_MAX_CHANNELS 2 +#define SBLIMIT 32 + +#define MP3_STEREO 0 +#define MP3_JSTEREO 1 +#define MP3_DUAL 2 +#define MP3_MONO 3 + +#define SAME_HEADER_MASK \ + (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) + +#define FRAC_BITS 15 +#define WFRAC_BITS 14 + +#define OUT_MAX (32767) +#define OUT_MIN (-32768) +#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15) + +#define MODE_EXT_MS_STEREO 2 +#define MODE_EXT_I_STEREO 1 + +#define FRAC_ONE (1 << FRAC_BITS) +#define FIX(a) ((int)((a) * FRAC_ONE)) +#define FIXR(a) ((int)((a) * FRAC_ONE + 0.5)) +#define FRAC_RND(a) (((a) + (FRAC_ONE/2)) >> FRAC_BITS) +#define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5)) + +#ifndef _MSC_VER + #define MULL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) + #define MULH(a,b) (((int64_t)(a) * (int64_t)(b)) >> 32) +#else + static INLINE int MULL(int a, int b) { + int res; + __asm { + mov eax, a + imul b + shr eax, 15 + shl edx, 17 + or eax, edx + mov res, eax + } + return res; + } + static INLINE int MULH(int a, int b) { + int res; + __asm { + mov eax, a + imul b + mov res, edx + } + return res; + } +#endif +#define MULS(ra, rb) ((ra) * (rb)) + +#define ISQRT2 FIXR(0.70710678118654752440) + +#define HEADER_SIZE 4 +#define BACKSTEP_SIZE 512 +#define EXTRABYTES 24 + +#define VLC_TYPE int16_t + +//////////////////////////////////////////////////////////////////////////////// + +struct _granule; + +typedef struct _bitstream { + const uint8_t *buffer, *buffer_end; + int index; + int size_in_bits; +} bitstream_t; + +typedef struct _vlc { + int bits; + VLC_TYPE (*table)[2]; ///< code, bits + int table_size, table_allocated; +} vlc_t; + +typedef struct _mp3_context { + uint8_t last_buf[2*BACKSTEP_SIZE + EXTRABYTES]; + int last_buf_size; + int frame_size; + uint32_t free_format_next_header; + int error_protection; + int sample_rate; + int sample_rate_index; + int bit_rate; + bitstream_t gb; + bitstream_t in_gb; + int nb_channels; + int mode; + int mode_ext; + int lsf; + int16_t synth_buf[MP3_MAX_CHANNELS][512 * 2]; + int synth_buf_offset[MP3_MAX_CHANNELS]; + int32_t sb_samples[MP3_MAX_CHANNELS][36][SBLIMIT]; + int32_t mdct_buf[MP3_MAX_CHANNELS][SBLIMIT * 18]; + int dither_state; +} mp3_context_t; + +typedef struct _granule { + uint8_t scfsi; + int part2_3_length; + int big_values; + int global_gain; + int scalefac_compress; + uint8_t block_type; + uint8_t switch_point; + int table_select[3]; + int subblock_gain[3]; + uint8_t scalefac_scale; + uint8_t count1table_select; + int region_size[3]; + int preflag; + int short_start, long_end; + uint8_t scale_factors[40]; + int32_t sb_hybrid[SBLIMIT * 18]; +} granule_t; + +typedef struct _huff_table { + int xsize; + const uint8_t *bits; + const uint16_t *codes; +} huff_table_t; + +static vlc_t huff_vlc[16]; +static vlc_t huff_quad_vlc[2]; +static uint16_t band_index_long[9][23]; +#define TABLE_4_3_SIZE (8191 + 16)*4 +static int8_t *table_4_3_exp; +static uint32_t *table_4_3_value; +static uint32_t exp_table[512]; +static uint32_t expval_table[512][16]; +static int32_t is_table[2][16]; +static int32_t is_table_lsf[2][2][16]; +static int32_t csa_table[8][4]; +static float csa_table_float[8][4]; +static int32_t mdct_win[8][36]; +static int16_t window[512]; + +//////////////////////////////////////////////////////////////////////////////// + +static const uint16_t mp3_bitrate_tab[2][15] = { + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} +}; + +static const uint16_t mp3_freq_tab[3] = { 44100, 48000, 32000 }; + +static const int32_t mp3_enwindow[257] = { + 0, -1, -1, -1, -1, -1, -1, -2, + -2, -2, -2, -3, -3, -4, -4, -5, + -5, -6, -7, -7, -8, -9, -10, -11, + -13, -14, -16, -17, -19, -21, -24, -26, + -29, -31, -35, -38, -41, -45, -49, -53, + -58, -63, -68, -73, -79, -85, -91, -97, + -104, -111, -117, -125, -132, -139, -147, -154, + -161, -169, -176, -183, -190, -196, -202, -208, + 213, 218, 222, 225, 227, 228, 228, 227, + 224, 221, 215, 208, 200, 189, 177, 163, + 146, 127, 106, 83, 57, 29, -2, -36, + -72, -111, -153, -197, -244, -294, -347, -401, + -459, -519, -581, -645, -711, -779, -848, -919, + -991, -1064, -1137, -1210, -1283, -1356, -1428, -1498, + -1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962, + -2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063, + 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535, + 1414, 1280, 1131, 970, 794, 605, 402, 185, + -45, -288, -545, -814, -1095, -1388, -1692, -2006, + -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, + -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, + -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585, + -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750, + -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134, + 6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082, + 70, -998, -2122, -3300, -4533, -5818, -7154, -8540, + -9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189, +-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640, +-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137, +-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684, +-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420, +-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992, + 75038, +}; + +static const uint8_t slen_table[2][16] = { + { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, + { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }, +}; + +static const uint8_t lsf_nsf_table[6][3][4] = { + { { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } }, + { { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } }, + { { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } }, + { { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } }, + { { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } }, + { { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } }, +}; + +static const uint16_t mp3_huffcodes_1[4] = { + 0x0001, 0x0001, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_1[4] = { + 1, 3, 2, 3, +}; + +static const uint16_t mp3_huffcodes_2[9] = { + 0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002, + 0x0000, +}; + +static const uint8_t mp3_huffbits_2[9] = { + 1, 3, 6, 3, 3, 5, 5, 5, + 6, +}; + +static const uint16_t mp3_huffcodes_3[9] = { + 0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002, + 0x0000, +}; + +static const uint8_t mp3_huffbits_3[9] = { + 2, 2, 6, 3, 2, 5, 5, 5, + 6, +}; + +static const uint16_t mp3_huffcodes_5[16] = { + 0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004, + 0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_5[16] = { + 1, 3, 6, 7, 3, 3, 6, 7, + 6, 6, 7, 8, 7, 6, 7, 8, +}; + +static const uint16_t mp3_huffcodes_6[16] = { + 0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002, + 0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_6[16] = { + 3, 3, 5, 7, 3, 2, 4, 5, + 4, 4, 5, 6, 6, 5, 6, 7, +}; + +static const uint16_t mp3_huffcodes_7[36] = { + 0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003, + 0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011, + 0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002, + 0x0007, 0x0006, 0x0009, 0x000e, 0x0003, 0x0001, 0x0006, 0x0004, + 0x0005, 0x0003, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_7[36] = { + 1, 3, 6, 8, 8, 9, 3, 4, + 6, 7, 7, 8, 6, 5, 7, 8, + 8, 9, 7, 7, 8, 9, 9, 9, + 7, 7, 8, 9, 9, 10, 8, 8, + 9, 10, 10, 10, +}; + +static const uint16_t mp3_huffcodes_8[36] = { + 0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001, + 0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e, + 0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004, + 0x000d, 0x0005, 0x0008, 0x000b, 0x0005, 0x0001, 0x000c, 0x0004, + 0x0004, 0x0001, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_8[36] = { + 2, 3, 6, 8, 8, 9, 3, 2, + 4, 8, 8, 8, 6, 4, 6, 8, + 8, 9, 8, 8, 8, 9, 9, 10, + 8, 7, 8, 9, 10, 10, 9, 8, + 9, 9, 11, 11, +}; + +static const uint16_t mp3_huffcodes_9[36] = { + 0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004, + 0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008, + 0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001, + 0x000b, 0x0007, 0x0009, 0x0006, 0x0004, 0x0001, 0x000e, 0x0004, + 0x0006, 0x0002, 0x0006, 0x0000, +}; + +static const uint8_t mp3_huffbits_9[36] = { + 3, 3, 5, 6, 8, 9, 3, 3, + 4, 5, 6, 8, 4, 4, 5, 6, + 7, 8, 6, 5, 6, 7, 7, 8, + 7, 6, 7, 7, 8, 9, 8, 7, + 8, 8, 9, 9, +}; + +static const uint16_t mp3_huffcodes_10[64] = { + 0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011, + 0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007, + 0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006, + 0x000e, 0x000d, 0x0016, 0x0022, 0x002e, 0x0017, 0x0012, 0x0007, + 0x0014, 0x0013, 0x0021, 0x002f, 0x001b, 0x0016, 0x0009, 0x0003, + 0x001f, 0x0016, 0x0029, 0x001a, 0x0015, 0x0014, 0x0005, 0x0003, + 0x000e, 0x000d, 0x000a, 0x000b, 0x0010, 0x0006, 0x0005, 0x0001, + 0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_10[64] = { + 1, 3, 6, 8, 9, 9, 9, 10, + 3, 4, 6, 7, 8, 9, 8, 8, + 6, 6, 7, 8, 9, 10, 9, 9, + 7, 7, 8, 9, 10, 10, 9, 10, + 8, 8, 9, 10, 10, 10, 10, 10, + 9, 9, 10, 10, 11, 11, 10, 11, + 8, 8, 9, 10, 10, 10, 11, 11, + 9, 8, 9, 10, 10, 11, 11, 11, +}; + +static const uint16_t mp3_huffcodes_11[64] = { + 0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f, + 0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a, + 0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005, + 0x0019, 0x000b, 0x0013, 0x003b, 0x001b, 0x0012, 0x000c, 0x0005, + 0x0023, 0x0021, 0x001f, 0x003a, 0x001e, 0x0010, 0x0007, 0x0005, + 0x001c, 0x001a, 0x0020, 0x0013, 0x0011, 0x000f, 0x0008, 0x000e, + 0x000e, 0x000c, 0x0009, 0x000d, 0x000e, 0x0009, 0x0004, 0x0001, + 0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_11[64] = { + 2, 3, 5, 7, 8, 9, 8, 9, + 3, 3, 4, 6, 8, 8, 7, 8, + 5, 5, 6, 7, 8, 9, 8, 8, + 7, 6, 7, 9, 8, 10, 8, 9, + 8, 8, 8, 9, 9, 10, 9, 10, + 8, 8, 9, 10, 10, 11, 10, 11, + 8, 7, 7, 8, 9, 10, 10, 10, + 8, 7, 8, 9, 10, 10, 10, 10, +}; + +static const uint16_t mp3_huffcodes_12[64] = { + 0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a, + 0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b, + 0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007, + 0x0011, 0x000a, 0x000f, 0x000c, 0x0012, 0x001c, 0x000e, 0x0005, + 0x0020, 0x000d, 0x0016, 0x0013, 0x0012, 0x0010, 0x0009, 0x0005, + 0x0028, 0x0011, 0x001f, 0x001d, 0x0011, 0x000d, 0x0004, 0x0002, + 0x001b, 0x000c, 0x000b, 0x000f, 0x000a, 0x0007, 0x0004, 0x0001, + 0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000, +}; + +static const uint8_t mp3_huffbits_12[64] = { + 4, 3, 5, 7, 8, 9, 9, 9, + 3, 3, 4, 5, 7, 7, 8, 8, + 5, 4, 5, 6, 7, 8, 7, 8, + 6, 5, 6, 6, 7, 8, 8, 8, + 7, 6, 7, 7, 8, 8, 8, 9, + 8, 7, 8, 8, 8, 9, 8, 9, + 8, 7, 7, 8, 8, 9, 9, 10, + 9, 8, 8, 9, 9, 9, 9, 10, +}; + +static const uint16_t mp3_huffcodes_13[256] = { + 0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047, + 0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013, + 0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021, + 0x001f, 0x0018, 0x0020, 0x0018, 0x001f, 0x0023, 0x0016, 0x000e, + 0x000f, 0x000d, 0x0017, 0x0024, 0x003b, 0x0031, 0x004d, 0x0041, + 0x001d, 0x0028, 0x001e, 0x0028, 0x001b, 0x0021, 0x002a, 0x0010, + 0x0016, 0x0014, 0x0025, 0x003d, 0x0038, 0x004f, 0x0049, 0x0040, + 0x002b, 0x004c, 0x0038, 0x0025, 0x001a, 0x001f, 0x0019, 0x000e, + 0x0023, 0x0010, 0x003c, 0x0039, 0x0061, 0x004b, 0x0072, 0x005b, + 0x0036, 0x0049, 0x0037, 0x0029, 0x0030, 0x0035, 0x0017, 0x0018, + 0x003a, 0x001b, 0x0032, 0x0060, 0x004c, 0x0046, 0x005d, 0x0054, + 0x004d, 0x003a, 0x004f, 0x001d, 0x004a, 0x0031, 0x0029, 0x0011, + 0x002f, 0x002d, 0x004e, 0x004a, 0x0073, 0x005e, 0x005a, 0x004f, + 0x0045, 0x0053, 0x0047, 0x0032, 0x003b, 0x0026, 0x0024, 0x000f, + 0x0048, 0x0022, 0x0038, 0x005f, 0x005c, 0x0055, 0x005b, 0x005a, + 0x0056, 0x0049, 0x004d, 0x0041, 0x0033, 0x002c, 0x002b, 0x002a, + 0x002b, 0x0014, 0x001e, 0x002c, 0x0037, 0x004e, 0x0048, 0x0057, + 0x004e, 0x003d, 0x002e, 0x0036, 0x0025, 0x001e, 0x0014, 0x0010, + 0x0035, 0x0019, 0x0029, 0x0025, 0x002c, 0x003b, 0x0036, 0x0051, + 0x0042, 0x004c, 0x0039, 0x0036, 0x0025, 0x0012, 0x0027, 0x000b, + 0x0023, 0x0021, 0x001f, 0x0039, 0x002a, 0x0052, 0x0048, 0x0050, + 0x002f, 0x003a, 0x0037, 0x0015, 0x0016, 0x001a, 0x0026, 0x0016, + 0x0035, 0x0019, 0x0017, 0x0026, 0x0046, 0x003c, 0x0033, 0x0024, + 0x0037, 0x001a, 0x0022, 0x0017, 0x001b, 0x000e, 0x0009, 0x0007, + 0x0022, 0x0020, 0x001c, 0x0027, 0x0031, 0x004b, 0x001e, 0x0034, + 0x0030, 0x0028, 0x0034, 0x001c, 0x0012, 0x0011, 0x0009, 0x0005, + 0x002d, 0x0015, 0x0022, 0x0040, 0x0038, 0x0032, 0x0031, 0x002d, + 0x001f, 0x0013, 0x000c, 0x000f, 0x000a, 0x0007, 0x0006, 0x0003, + 0x0030, 0x0017, 0x0014, 0x0027, 0x0024, 0x0023, 0x0035, 0x0015, + 0x0010, 0x0017, 0x000d, 0x000a, 0x0006, 0x0001, 0x0004, 0x0002, + 0x0010, 0x000f, 0x0011, 0x001b, 0x0019, 0x0014, 0x001d, 0x000b, + 0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001, +}; + +static const uint8_t mp3_huffbits_13[256] = { + 1, 4, 6, 7, 8, 9, 9, 10, + 9, 10, 11, 11, 12, 12, 13, 13, + 3, 4, 6, 7, 8, 8, 9, 9, + 9, 9, 10, 10, 11, 12, 12, 12, + 6, 6, 7, 8, 9, 9, 10, 10, + 9, 10, 10, 11, 11, 12, 13, 13, + 7, 7, 8, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 12, 13, 13, + 8, 7, 9, 9, 10, 10, 11, 11, + 10, 11, 11, 12, 12, 13, 13, 14, + 9, 8, 9, 10, 10, 10, 11, 11, + 11, 11, 12, 11, 13, 13, 14, 14, + 9, 9, 10, 10, 11, 11, 11, 11, + 11, 12, 12, 12, 13, 13, 14, 14, + 10, 9, 10, 11, 11, 11, 12, 12, + 12, 12, 13, 13, 13, 14, 16, 16, + 9, 8, 9, 10, 10, 11, 11, 12, + 12, 12, 12, 13, 13, 14, 15, 15, + 10, 9, 10, 10, 11, 11, 11, 13, + 12, 13, 13, 14, 14, 14, 16, 15, + 10, 10, 10, 11, 11, 12, 12, 13, + 12, 13, 14, 13, 14, 15, 16, 17, + 11, 10, 10, 11, 12, 12, 12, 12, + 13, 13, 13, 14, 15, 15, 15, 16, + 11, 11, 11, 12, 12, 13, 12, 13, + 14, 14, 15, 15, 15, 16, 16, 16, + 12, 11, 12, 13, 13, 13, 14, 14, + 14, 14, 14, 15, 16, 15, 16, 16, + 13, 12, 12, 13, 13, 13, 15, 14, + 14, 17, 15, 15, 15, 17, 16, 16, + 12, 12, 13, 14, 14, 14, 15, 14, + 15, 15, 16, 16, 19, 18, 19, 16, +}; + +static const uint16_t mp3_huffcodes_15[256] = { + 0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c, + 0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f, + 0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033, + 0x002a, 0x0046, 0x0034, 0x0053, 0x0041, 0x0029, 0x003b, 0x0024, + 0x0013, 0x0011, 0x000f, 0x0018, 0x0029, 0x0022, 0x003b, 0x0030, + 0x0028, 0x0040, 0x0032, 0x004e, 0x003e, 0x0050, 0x0038, 0x0021, + 0x001d, 0x001c, 0x0019, 0x002b, 0x0027, 0x003f, 0x0037, 0x005d, + 0x004c, 0x003b, 0x005d, 0x0048, 0x0036, 0x004b, 0x0032, 0x001d, + 0x0034, 0x0016, 0x002a, 0x0028, 0x0043, 0x0039, 0x005f, 0x004f, + 0x0048, 0x0039, 0x0059, 0x0045, 0x0031, 0x0042, 0x002e, 0x001b, + 0x004d, 0x0025, 0x0023, 0x0042, 0x003a, 0x0034, 0x005b, 0x004a, + 0x003e, 0x0030, 0x004f, 0x003f, 0x005a, 0x003e, 0x0028, 0x0026, + 0x007d, 0x0020, 0x003c, 0x0038, 0x0032, 0x005c, 0x004e, 0x0041, + 0x0037, 0x0057, 0x0047, 0x0033, 0x0049, 0x0033, 0x0046, 0x001e, + 0x006d, 0x0035, 0x0031, 0x005e, 0x0058, 0x004b, 0x0042, 0x007a, + 0x005b, 0x0049, 0x0038, 0x002a, 0x0040, 0x002c, 0x0015, 0x0019, + 0x005a, 0x002b, 0x0029, 0x004d, 0x0049, 0x003f, 0x0038, 0x005c, + 0x004d, 0x0042, 0x002f, 0x0043, 0x0030, 0x0035, 0x0024, 0x0014, + 0x0047, 0x0022, 0x0043, 0x003c, 0x003a, 0x0031, 0x0058, 0x004c, + 0x0043, 0x006a, 0x0047, 0x0036, 0x0026, 0x0027, 0x0017, 0x000f, + 0x006d, 0x0035, 0x0033, 0x002f, 0x005a, 0x0052, 0x003a, 0x0039, + 0x0030, 0x0048, 0x0039, 0x0029, 0x0017, 0x001b, 0x003e, 0x0009, + 0x0056, 0x002a, 0x0028, 0x0025, 0x0046, 0x0040, 0x0034, 0x002b, + 0x0046, 0x0037, 0x002a, 0x0019, 0x001d, 0x0012, 0x000b, 0x000b, + 0x0076, 0x0044, 0x001e, 0x0037, 0x0032, 0x002e, 0x004a, 0x0041, + 0x0031, 0x0027, 0x0018, 0x0010, 0x0016, 0x000d, 0x000e, 0x0007, + 0x005b, 0x002c, 0x0027, 0x0026, 0x0022, 0x003f, 0x0034, 0x002d, + 0x001f, 0x0034, 0x001c, 0x0013, 0x000e, 0x0008, 0x0009, 0x0003, + 0x007b, 0x003c, 0x003a, 0x0035, 0x002f, 0x002b, 0x0020, 0x0016, + 0x0025, 0x0018, 0x0011, 0x000c, 0x000f, 0x000a, 0x0002, 0x0001, + 0x0047, 0x0025, 0x0022, 0x001e, 0x001c, 0x0014, 0x0011, 0x001a, + 0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000, +}; + +static const uint8_t mp3_huffbits_15[256] = { + 3, 4, 5, 7, 7, 8, 9, 9, + 9, 10, 10, 11, 11, 11, 12, 13, + 4, 3, 5, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 11, 11, + 5, 5, 5, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 11, 11, 11, + 6, 6, 6, 7, 7, 8, 8, 9, + 9, 9, 10, 10, 10, 11, 11, 11, + 7, 6, 7, 7, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 11, + 8, 7, 7, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 11, 11, 11, 12, + 9, 7, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 11, 11, 12, 12, + 9, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 11, 11, 11, 12, + 9, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 11, 11, 12, 12, 12, + 9, 8, 9, 9, 9, 9, 10, 10, + 10, 11, 11, 11, 11, 12, 12, 12, + 10, 9, 9, 9, 10, 10, 10, 10, + 10, 11, 11, 11, 11, 12, 13, 12, + 10, 9, 9, 9, 10, 10, 10, 10, + 11, 11, 11, 11, 12, 12, 12, 13, + 11, 10, 9, 10, 10, 10, 11, 11, + 11, 11, 11, 11, 12, 12, 13, 13, + 11, 10, 10, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 13, 13, + 12, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 12, 13, + 12, 11, 11, 11, 11, 11, 11, 12, + 12, 12, 12, 12, 13, 13, 13, 13, +}; + +static const uint16_t mp3_huffcodes_16[256] = { + 0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d, + 0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011, + 0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f, + 0x0053, 0x004b, 0x0044, 0x0077, 0x00c9, 0x006b, 0x00cf, 0x0009, + 0x000f, 0x000d, 0x0017, 0x0026, 0x0043, 0x003a, 0x0067, 0x005a, + 0x00a1, 0x0048, 0x007f, 0x0075, 0x006e, 0x00d1, 0x00ce, 0x0010, + 0x002d, 0x0015, 0x0027, 0x0045, 0x0040, 0x0072, 0x0063, 0x0057, + 0x009e, 0x008c, 0x00fc, 0x00d4, 0x00c7, 0x0183, 0x016d, 0x001a, + 0x004b, 0x0024, 0x0044, 0x0041, 0x0073, 0x0065, 0x00b3, 0x00a4, + 0x009b, 0x0108, 0x00f6, 0x00e2, 0x018b, 0x017e, 0x016a, 0x0009, + 0x0042, 0x001e, 0x003b, 0x0038, 0x0066, 0x00b9, 0x00ad, 0x0109, + 0x008e, 0x00fd, 0x00e8, 0x0190, 0x0184, 0x017a, 0x01bd, 0x0010, + 0x006f, 0x0036, 0x0034, 0x0064, 0x00b8, 0x00b2, 0x00a0, 0x0085, + 0x0101, 0x00f4, 0x00e4, 0x00d9, 0x0181, 0x016e, 0x02cb, 0x000a, + 0x0062, 0x0030, 0x005b, 0x0058, 0x00a5, 0x009d, 0x0094, 0x0105, + 0x00f8, 0x0197, 0x018d, 0x0174, 0x017c, 0x0379, 0x0374, 0x0008, + 0x0055, 0x0054, 0x0051, 0x009f, 0x009c, 0x008f, 0x0104, 0x00f9, + 0x01ab, 0x0191, 0x0188, 0x017f, 0x02d7, 0x02c9, 0x02c4, 0x0007, + 0x009a, 0x004c, 0x0049, 0x008d, 0x0083, 0x0100, 0x00f5, 0x01aa, + 0x0196, 0x018a, 0x0180, 0x02df, 0x0167, 0x02c6, 0x0160, 0x000b, + 0x008b, 0x0081, 0x0043, 0x007d, 0x00f7, 0x00e9, 0x00e5, 0x00db, + 0x0189, 0x02e7, 0x02e1, 0x02d0, 0x0375, 0x0372, 0x01b7, 0x0004, + 0x00f3, 0x0078, 0x0076, 0x0073, 0x00e3, 0x00df, 0x018c, 0x02ea, + 0x02e6, 0x02e0, 0x02d1, 0x02c8, 0x02c2, 0x00df, 0x01b4, 0x0006, + 0x00ca, 0x00e0, 0x00de, 0x00da, 0x00d8, 0x0185, 0x0182, 0x017d, + 0x016c, 0x0378, 0x01bb, 0x02c3, 0x01b8, 0x01b5, 0x06c0, 0x0004, + 0x02eb, 0x00d3, 0x00d2, 0x00d0, 0x0172, 0x017b, 0x02de, 0x02d3, + 0x02ca, 0x06c7, 0x0373, 0x036d, 0x036c, 0x0d83, 0x0361, 0x0002, + 0x0179, 0x0171, 0x0066, 0x00bb, 0x02d6, 0x02d2, 0x0166, 0x02c7, + 0x02c5, 0x0362, 0x06c6, 0x0367, 0x0d82, 0x0366, 0x01b2, 0x0000, + 0x000c, 0x000a, 0x0007, 0x000b, 0x000a, 0x0011, 0x000b, 0x0009, + 0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003, +}; + +static const uint8_t mp3_huffbits_16[256] = { + 1, 4, 6, 8, 9, 9, 10, 10, + 11, 11, 11, 12, 12, 12, 13, 9, + 3, 4, 6, 7, 8, 9, 9, 9, + 10, 10, 10, 11, 12, 11, 12, 8, + 6, 6, 7, 8, 9, 9, 10, 10, + 11, 10, 11, 11, 11, 12, 12, 9, + 8, 7, 8, 9, 9, 10, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 10, + 9, 8, 9, 9, 10, 10, 11, 11, + 11, 12, 12, 12, 13, 13, 13, 9, + 9, 8, 9, 9, 10, 11, 11, 12, + 11, 12, 12, 13, 13, 13, 14, 10, + 10, 9, 9, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 14, 10, + 10, 9, 10, 10, 11, 11, 11, 12, + 12, 13, 13, 13, 13, 15, 15, 10, + 10, 10, 10, 11, 11, 11, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 10, + 11, 10, 10, 11, 11, 12, 12, 13, + 13, 13, 13, 14, 13, 14, 13, 11, + 11, 11, 10, 11, 12, 12, 12, 12, + 13, 14, 14, 14, 15, 15, 14, 10, + 12, 11, 11, 11, 12, 12, 13, 14, + 14, 14, 14, 14, 14, 13, 14, 11, + 12, 12, 12, 12, 12, 13, 13, 13, + 13, 15, 14, 14, 14, 14, 16, 11, + 14, 12, 12, 12, 13, 13, 14, 14, + 14, 16, 15, 15, 15, 17, 15, 11, + 13, 13, 11, 12, 14, 14, 13, 14, + 14, 15, 16, 15, 17, 15, 14, 11, + 9, 8, 8, 9, 9, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 8, +}; + +static const uint16_t mp3_huffcodes_24[256] = { + 0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2, + 0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058, + 0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8, + 0x00d1, 0x00c6, 0x0147, 0x0159, 0x013f, 0x0129, 0x0117, 0x002a, + 0x002f, 0x0016, 0x0029, 0x004a, 0x0044, 0x0080, 0x0078, 0x00dd, + 0x00cf, 0x00c2, 0x00b6, 0x0154, 0x013b, 0x0127, 0x021d, 0x0012, + 0x0051, 0x0027, 0x004b, 0x0046, 0x0086, 0x007d, 0x0074, 0x00dc, + 0x00cc, 0x00be, 0x00b2, 0x0145, 0x0137, 0x0125, 0x010f, 0x0010, + 0x0093, 0x0048, 0x0045, 0x0087, 0x007f, 0x0076, 0x0070, 0x00d2, + 0x00c8, 0x00bc, 0x0160, 0x0143, 0x0132, 0x011d, 0x021c, 0x000e, + 0x0107, 0x0042, 0x0081, 0x007e, 0x0077, 0x0072, 0x00d6, 0x00ca, + 0x00c0, 0x00b4, 0x0155, 0x013d, 0x012d, 0x0119, 0x0106, 0x000c, + 0x00f9, 0x007b, 0x0079, 0x0075, 0x0071, 0x00d7, 0x00ce, 0x00c3, + 0x00b9, 0x015b, 0x014a, 0x0134, 0x0123, 0x0110, 0x0208, 0x000a, + 0x01b3, 0x0073, 0x006f, 0x006d, 0x00d3, 0x00cb, 0x00c4, 0x00bb, + 0x0161, 0x014c, 0x0139, 0x012a, 0x011b, 0x0213, 0x017d, 0x0011, + 0x01ab, 0x00d4, 0x00d0, 0x00cd, 0x00c9, 0x00c1, 0x00ba, 0x00b1, + 0x00a9, 0x0140, 0x012f, 0x011e, 0x010c, 0x0202, 0x0179, 0x0010, + 0x014f, 0x00c7, 0x00c5, 0x00bf, 0x00bd, 0x00b5, 0x00ae, 0x014d, + 0x0141, 0x0131, 0x0121, 0x0113, 0x0209, 0x017b, 0x0173, 0x000b, + 0x029c, 0x00b8, 0x00b7, 0x00b3, 0x00af, 0x0158, 0x014b, 0x013a, + 0x0130, 0x0122, 0x0115, 0x0212, 0x017f, 0x0175, 0x016e, 0x000a, + 0x028c, 0x015a, 0x00ab, 0x00a8, 0x00a4, 0x013e, 0x0135, 0x012b, + 0x011f, 0x0114, 0x0107, 0x0201, 0x0177, 0x0170, 0x016a, 0x0006, + 0x0288, 0x0142, 0x013c, 0x0138, 0x0133, 0x012e, 0x0124, 0x011c, + 0x010d, 0x0105, 0x0200, 0x0178, 0x0172, 0x016c, 0x0167, 0x0004, + 0x026c, 0x012c, 0x0128, 0x0126, 0x0120, 0x011a, 0x0111, 0x010a, + 0x0203, 0x017c, 0x0176, 0x0171, 0x016d, 0x0169, 0x0165, 0x0002, + 0x0409, 0x0118, 0x0116, 0x0112, 0x010b, 0x0108, 0x0103, 0x017e, + 0x017a, 0x0174, 0x016f, 0x016b, 0x0168, 0x0166, 0x0164, 0x0000, + 0x002b, 0x0014, 0x0013, 0x0011, 0x000f, 0x000d, 0x000b, 0x0009, + 0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003, +}; + +static const uint8_t mp3_huffbits_24[256] = { + 4, 4, 6, 7, 8, 9, 9, 10, + 10, 11, 11, 11, 11, 11, 12, 9, + 4, 4, 5, 6, 7, 8, 8, 9, + 9, 9, 10, 10, 10, 10, 10, 8, + 6, 5, 6, 7, 7, 8, 8, 9, + 9, 9, 9, 10, 10, 10, 11, 7, + 7, 6, 7, 7, 8, 8, 8, 9, + 9, 9, 9, 10, 10, 10, 10, 7, + 8, 7, 7, 8, 8, 8, 8, 9, + 9, 9, 10, 10, 10, 10, 11, 7, + 9, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 7, + 9, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 11, 7, + 10, 8, 8, 8, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 11, 11, 8, + 10, 9, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 8, + 10, 9, 9, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 11, 11, 11, 8, + 11, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 8, + 11, 10, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 8, + 11, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 8, + 11, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 8, + 12, 10, 10, 10, 10, 10, 10, 11, + 11, 11, 11, 11, 11, 11, 11, 8, + 8, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 4, +}; + +static const huff_table_t mp3_huff_tables[16] = { +{ 1, NULL, NULL }, +{ 2, mp3_huffbits_1, mp3_huffcodes_1 }, +{ 3, mp3_huffbits_2, mp3_huffcodes_2 }, +{ 3, mp3_huffbits_3, mp3_huffcodes_3 }, +{ 4, mp3_huffbits_5, mp3_huffcodes_5 }, +{ 4, mp3_huffbits_6, mp3_huffcodes_6 }, +{ 6, mp3_huffbits_7, mp3_huffcodes_7 }, +{ 6, mp3_huffbits_8, mp3_huffcodes_8 }, +{ 6, mp3_huffbits_9, mp3_huffcodes_9 }, +{ 8, mp3_huffbits_10, mp3_huffcodes_10 }, +{ 8, mp3_huffbits_11, mp3_huffcodes_11 }, +{ 8, mp3_huffbits_12, mp3_huffcodes_12 }, +{ 16, mp3_huffbits_13, mp3_huffcodes_13 }, +{ 16, mp3_huffbits_15, mp3_huffcodes_15 }, +{ 16, mp3_huffbits_16, mp3_huffcodes_16 }, +{ 16, mp3_huffbits_24, mp3_huffcodes_24 }, +}; + +static const uint8_t mp3_huff_data[32][2] = { +{ 0, 0 }, +{ 1, 0 }, +{ 2, 0 }, +{ 3, 0 }, +{ 0, 0 }, +{ 4, 0 }, +{ 5, 0 }, +{ 6, 0 }, +{ 7, 0 }, +{ 8, 0 }, +{ 9, 0 }, +{ 10, 0 }, +{ 11, 0 }, +{ 12, 0 }, +{ 0, 0 }, +{ 13, 0 }, +{ 14, 1 }, +{ 14, 2 }, +{ 14, 3 }, +{ 14, 4 }, +{ 14, 6 }, +{ 14, 8 }, +{ 14, 10 }, +{ 14, 13 }, +{ 15, 4 }, +{ 15, 5 }, +{ 15, 6 }, +{ 15, 7 }, +{ 15, 8 }, +{ 15, 9 }, +{ 15, 11 }, +{ 15, 13 }, +}; + +static const uint8_t mp3_quad_codes[2][16] = { + { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, }, + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, }, +}; + +static const uint8_t mp3_quad_bits[2][16] = { + { 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, }, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, }, +}; + +static const uint8_t band_size_long[9][22] = { +{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, + 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */ +{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, + 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */ +{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, + 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */ +{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, + 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */ +{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, + 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */ +}; + +static const uint8_t band_size_short[9][13] = { +{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */ +{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */ +{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */ +{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */ +{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */ +{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */ +}; + +static const uint8_t mp3_pretab[2][22] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }, +}; + +static const float ci_table[8] = { + -0.6f, -0.535f, -0.33f, -0.185f, -0.095f, -0.041f, -0.0142f, -0.0037f, +}; + +#define C1 FIXHR(0.98480775301220805936/2) +#define C2 FIXHR(0.93969262078590838405/2) +#define C3 FIXHR(0.86602540378443864676/2) +#define C4 FIXHR(0.76604444311897803520/2) +#define C5 FIXHR(0.64278760968653932632/2) +#define C6 FIXHR(0.5/2) +#define C7 FIXHR(0.34202014332566873304/2) +#define C8 FIXHR(0.17364817766693034885/2) + +static const int icos36[9] = { + FIXR(0.50190991877167369479), + FIXR(0.51763809020504152469), //0 + FIXR(0.55168895948124587824), + FIXR(0.61038729438072803416), + FIXR(0.70710678118654752439), //1 + FIXR(0.87172339781054900991), + FIXR(1.18310079157624925896), + FIXR(1.93185165257813657349), //2 + FIXR(5.73685662283492756461), +}; + +static const int icos36h[9] = { + FIXHR(0.50190991877167369479/2), + FIXHR(0.51763809020504152469/2), //0 + FIXHR(0.55168895948124587824/2), + FIXHR(0.61038729438072803416/2), + FIXHR(0.70710678118654752439/2), //1 + FIXHR(0.87172339781054900991/2), + FIXHR(1.18310079157624925896/4), + FIXHR(1.93185165257813657349/4), //2 +// FIXHR(5.73685662283492756461), +}; + +//////////////////////////////////////////////////////////////////////////////// + +static INLINE int unaligned32_be(const uint8_t *p) +{ + return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]); +} + +#define MIN_CACHE_BITS 25 + +#define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) +#define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) + +#define OPEN_READER(name, gb) \ + int name##_index= (gb)->index;\ + int name##_cache= 0;\ + +#define CLOSE_READER(name, gb)\ + (gb)->index= name##_index;\ + +#define UPDATE_CACHE(name, gb)\ + name##_cache= unaligned32_be(&((gb)->buffer[name##_index>>3])) << (name##_index&0x07); \ + +#define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num); + +#define SKIP_COUNTER(name, gb, num)\ + name##_index += (num);\ + +#define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) +#define LAST_SKIP_CACHE(name, gb, num) ; + +#define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache, num) + +#define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) + +#define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static INLINE int get_bits_count(bitstream_t *s){ + return s->index; +} + +static INLINE void skip_bits_long(bitstream_t *s, int n){ + s->index += n; +} +#define skip_bits skip_bits_long + +static void init_get_bits(bitstream_t *s, const uint8_t *buffer, int bit_size) { + int buffer_size= (bit_size+7)>>3; + if(buffer_size < 0 || bit_size < 0) { + buffer_size = bit_size = 0; + buffer = NULL; + } + s->buffer= buffer; + s->size_in_bits= bit_size; + s->buffer_end= buffer + buffer_size; + s->index=0; +} + +static INLINE unsigned int get_bits(bitstream_t *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +static INLINE int get_bitsz(bitstream_t *s, int n) +{ + if (n == 0) + return 0; + else + return get_bits(s, n); +} + +static INLINE unsigned int get_bits1(bitstream_t *s){ + int index= s->index; + uint8_t result= s->buffer[ index>>3 ]; + result<<= (index&0x07); + result>>= 8 - 1; + index++; + s->index= index; + return result; +} + +static INLINE void align_get_bits(bitstream_t *s) +{ + int n= (-get_bits_count(s)) & 7; + if(n) skip_bits(s, n); +} + +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + switch(size) {\ + case 1:\ + v = *(const uint8_t *)ptr;\ + break;\ + case 2:\ + v = *(const uint16_t *)ptr;\ + break;\ + default:\ + v = *(const uint32_t *)ptr;\ + break;\ + }\ +} + +static INLINE int alloc_table(vlc_t *vlc, int size) { + int index; + index = vlc->table_size; + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + vlc->table_allocated += (1 << vlc->bits); + vlc->table = libc_realloc(vlc->table, sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + if (!vlc->table) + return -1; + } + return index; +} + +static int build_table( + vlc_t *vlc, int table_nb_bits, + int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + uint32_t code_prefix, int n_prefix +) { + int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2; + uint32_t code; + VLC_TYPE (*table)[2]; + + table_size = 1 << table_nb_bits; + table_index = alloc_table(vlc, table_size); + if (table_index < 0) + return -1; + table = &vlc->table[table_index]; + + for(i=0;i> n; + if (n > 0 && code_prefix2 == code_prefix) { + if (n <= table_nb_bits) { + j = (code << (table_nb_bits - n)) & (table_size - 1); + nb = 1 << (table_nb_bits - n); + for(k=0;k> n) & ((1 << table_nb_bits) - 1); + n1 = -table[j][1]; //bits + if (n > n1) + n1 = n; + table[j][1] = -n1; //bits + } + } + } + for(i=0;i table_nb_bits) { + n = table_nb_bits; + table[i][1] = -n; //bits + } + index = build_table(vlc, n, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + (code_prefix << table_nb_bits) | i, + n_prefix + table_nb_bits); + if (index < 0) + return -1; + table = &vlc->table[table_index]; + table[i][0] = index; //code + } + } + return table_index; +} + +static INLINE int init_vlc( + vlc_t *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size +) { + vlc->bits = nb_bits; + if (build_table(vlc, nb_bits, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + 0, 0) < 0) { + libc_free(vlc->table); + return -1; + } + return 0; +} + +#define GET_VLC(code, name, gb, table, bits, max_depth)\ +{\ + int n, index, nb_bits;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + code = table[index][0];\ + n = table[index][1];\ +\ + if(max_depth > 1 && n < 0){\ + LAST_SKIP_BITS(name, gb, bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + if(max_depth > 2 && n < 0){\ + LAST_SKIP_BITS(name, gb, nb_bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + }\ + }\ + SKIP_BITS(name, gb, n)\ +} + +static INLINE int get_vlc2(bitstream_t *s, VLC_TYPE (*table)[2], int bits, int max_depth) { + int code; + + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + + GET_VLC(code, re, s, table, bits, max_depth) + + CLOSE_READER(re, s) + return code; +} + +static void switch_buffer(mp3_context_t *s, int *pos, int *end_pos, int *end_pos2) { + if(s->in_gb.buffer && *pos >= s->gb.size_in_bits){ + s->gb= s->in_gb; + s->in_gb.buffer=NULL; + skip_bits_long(&s->gb, *pos - *end_pos); + *end_pos2= + *end_pos= *end_pos2 + get_bits_count(&s->gb) - *pos; + *pos= get_bits_count(&s->gb); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +static INLINE int mp3_check_header(uint32_t header){ + /* header */ + if ((header & 0xffe00000) != 0xffe00000) + return -1; + /* layer check */ + if ((header & (3<<17)) != (1 << 17)) + return -1; + /* bit rate */ + if ((header & (0xf<<12)) == 0xf<<12) + return -1; + /* frequency */ + if ((header & (3<<10)) == 3<<10) + return -1; + return 0; +} + + +static void lsf_sf_expand( + int *slen, int sf, int n1, int n2, int n3 +) { + if (n3) { + slen[3] = sf % n3; + sf /= n3; + } else { + slen[3] = 0; + } + if (n2) { + slen[2] = sf % n2; + sf /= n2; + } else { + slen[2] = 0; + } + slen[1] = sf % n1; + sf /= n1; + slen[0] = sf; +} + +static INLINE int l3_unscale(int value, int exponent) +{ + unsigned int m; + int e; + + e = table_4_3_exp [4*value + (exponent&3)]; + m = table_4_3_value[4*value + (exponent&3)]; + e -= (exponent >> 2); + if (e > 31) + return 0; + m = (m + (1 << (e-1))) >> e; + + return m; +} + +static INLINE int round_sample(int *sum) { + int sum1; + sum1 = (*sum) >> OUT_SHIFT; + *sum &= (1< OUT_MAX) + sum1 = OUT_MAX; + return sum1; +} + +static void exponents_from_scale_factors( + mp3_context_t *s, granule_t *g, int16_t *exponents +) { + const uint8_t *bstab, *pretab; + int len, i, j, k, l, v0, shift, gain, gains[3]; + int16_t *exp_ptr; + + exp_ptr = exponents; + gain = g->global_gain - 210; + shift = g->scalefac_scale + 1; + + bstab = band_size_long[s->sample_rate_index]; + pretab = mp3_pretab[g->preflag]; + for(i=0;ilong_end;i++) { + v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400; + len = bstab[i]; + for(j=len;j>0;j--) + *exp_ptr++ = v0; + } + + if (g->short_start < 13) { + bstab = band_size_short[s->sample_rate_index]; + gains[0] = gain - (g->subblock_gain[0] << 3); + gains[1] = gain - (g->subblock_gain[1] << 3); + gains[2] = gain - (g->subblock_gain[2] << 3); + k = g->long_end; + for(i=g->short_start;i<13;i++) { + len = bstab[i]; + for(l=0;l<3;l++) { + v0 = gains[l] - (g->scale_factors[k++] << shift) + 400; + for(j=len;j>0;j--) + *exp_ptr++ = v0; + } + } + } +} + +static void reorder_block(mp3_context_t *s, granule_t *g) +{ + int i, j, len; + int32_t *ptr, *dst, *ptr1; + int32_t tmp[576]; + + if (g->block_type != 2) + return; + + if (g->switch_point) { + if (s->sample_rate_index != 8) { + ptr = g->sb_hybrid + 36; + } else { + ptr = g->sb_hybrid + 48; + } + } else { + ptr = g->sb_hybrid; + } + + for(i=g->short_start;i<13;i++) { + len = band_size_short[s->sample_rate_index][i]; + ptr1 = ptr; + dst = tmp; + for(j=len;j>0;j--) { + *dst++ = ptr[0*len]; + *dst++ = ptr[1*len]; + *dst++ = ptr[2*len]; + ptr++; + } + ptr+=2*len; + libc_memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1)); + } +} + +static void compute_antialias(mp3_context_t *s, granule_t *g) { + int32_t *ptr, *csa; + int n, i; + + /* we antialias only "long" bands */ + if (g->block_type == 2) { + if (!g->switch_point) + return; + /* XXX: check this for 8000Hz case */ + n = 1; + } else { + n = SBLIMIT - 1; + } + + ptr = g->sb_hybrid + 18; + for(i = n;i > 0;i--) { + int tmp0, tmp1, tmp2; + csa = &csa_table[0][0]; +#define INT_AA(j) \ + tmp0 = ptr[-1-j];\ + tmp1 = ptr[ j];\ + tmp2= MULH(tmp0 + tmp1, csa[0+4*j]);\ + ptr[-1-j] = 4*(tmp2 - MULH(tmp1, csa[2+4*j]));\ + ptr[ j] = 4*(tmp2 + MULH(tmp0, csa[3+4*j])); + + INT_AA(0) + INT_AA(1) + INT_AA(2) + INT_AA(3) + INT_AA(4) + INT_AA(5) + INT_AA(6) + INT_AA(7) + + ptr += 18; + } +} + +static void compute_stereo( + mp3_context_t *s, granule_t *g0, granule_t *g1 +) { + int i, j, k, l; + int32_t v1, v2; + int sf_max, tmp0, tmp1, sf, len, non_zero_found; + int32_t (*is_tab)[16]; + int32_t *tab0, *tab1; + int non_zero_found_short[3]; + + if (s->mode_ext & MODE_EXT_I_STEREO) { + if (!s->lsf) { + is_tab = is_table; + sf_max = 7; + } else { + is_tab = is_table_lsf[g1->scalefac_compress & 1]; + sf_max = 16; + } + + tab0 = g0->sb_hybrid + 576; + tab1 = g1->sb_hybrid + 576; + + non_zero_found_short[0] = 0; + non_zero_found_short[1] = 0; + non_zero_found_short[2] = 0; + k = (13 - g1->short_start) * 3 + g1->long_end - 3; + for(i = 12;i >= g1->short_start;i--) { + /* for last band, use previous scale factor */ + if (i != 11) + k -= 3; + len = band_size_short[s->sample_rate_index][i]; + for(l=2;l>=0;l--) { + tab0 -= len; + tab1 -= len; + if (!non_zero_found_short[l]) { + /* test if non zero band. if so, stop doing i-stereo */ + for(j=0;jscale_factors[k + l]; + if (sf >= sf_max) + goto found1; + + v1 = is_tab[0][sf]; + v2 = is_tab[1][sf]; + for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { + /* lower part of the spectrum : do ms stereo + if enabled */ + for(j=0;jlong_end - 1;i >= 0;i--) { + len = band_size_long[s->sample_rate_index][i]; + tab0 -= len; + tab1 -= len; + /* test if non zero band. if so, stop doing i-stereo */ + if (!non_zero_found) { + for(j=0;jscale_factors[k]; + if (sf >= sf_max) + goto found2; + v1 = is_tab[0][sf]; + v2 = is_tab[1][sf]; + for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { + /* lower part of the spectrum : do ms stereo + if enabled */ + for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { + /* ms stereo ONLY */ + /* NOTE: the 1/sqrt(2) normalization factor is included in the + global gain */ + tab0 = g0->sb_hybrid; + tab1 = g1->sb_hybrid; + for(i=0;i<576;i++) { + tmp0 = tab0[i]; + tmp1 = tab1[i]; + tab0[i] = tmp0 + tmp1; + tab1[i] = tmp0 - tmp1; + } + } +} + +static int huffman_decode( + mp3_context_t *s, granule_t *g, int16_t *exponents, int end_pos2 +) { + int s_index; + int i; + int last_pos, bits_left; + vlc_t *vlc; + int end_pos= s->gb.size_in_bits; + if (end_pos2 < end_pos) end_pos = end_pos2; + + /* low frequencies (called big values) */ + s_index = 0; + for(i=0;i<3;i++) { + int j, k, l, linbits; + j = g->region_size[i]; + if (j == 0) + continue; + /* select vlc table */ + k = g->table_select[i]; + l = mp3_huff_data[k][0]; + linbits = mp3_huff_data[k][1]; + vlc = &huff_vlc[l]; + + if(!l){ + libc_memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*2*j); + s_index += 2*j; + continue; + } + + /* read huffcode and compute each couple */ + for(;j>0;j--) { + int exponent, x, y, v; + int pos= get_bits_count(&s->gb); + + if (pos >= end_pos){ + switch_buffer(s, &pos, &end_pos, &end_pos2); + if(pos >= end_pos) + break; + } + y = get_vlc2(&s->gb, vlc->table, 7, 3); + + if(!y){ + g->sb_hybrid[s_index ] = + g->sb_hybrid[s_index+1] = 0; + s_index += 2; + continue; + } + + exponent= exponents[s_index]; + + if(y&16){ + x = y >> 5; + y = y & 0x0f; + if (x < 15){ + v = expval_table[ exponent ][ x ]; + }else{ + x += get_bitsz(&s->gb, linbits); + v = l3_unscale(x, exponent); + } + if (get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[s_index] = v; + if (y < 15){ + v = expval_table[ exponent ][ y ]; + }else{ + y += get_bitsz(&s->gb, linbits); + v = l3_unscale(y, exponent); + } + if (get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[s_index+1] = v; + }else{ + x = y >> 5; + y = y & 0x0f; + x += y; + if (x < 15){ + v = expval_table[ exponent ][ x ]; + }else{ + x += get_bitsz(&s->gb, linbits); + v = l3_unscale(x, exponent); + } + if (get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[s_index+!!y] = v; + g->sb_hybrid[s_index+ !y] = 0; + } + s_index+=2; + } + } + + /* high frequencies */ + vlc = &huff_quad_vlc[g->count1table_select]; + last_pos=0; + while (s_index <= 572) { + int pos, code; + pos = get_bits_count(&s->gb); + if (pos >= end_pos) { + if (pos > end_pos2 && last_pos){ + /* some encoders generate an incorrect size for this + part. We must go back into the data */ + s_index -= 4; + skip_bits_long(&s->gb, last_pos - pos); + break; + } + switch_buffer(s, &pos, &end_pos, &end_pos2); + if(pos >= end_pos) + break; + } + last_pos= pos; + + code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1); + g->sb_hybrid[s_index+0]= + g->sb_hybrid[s_index+1]= + g->sb_hybrid[s_index+2]= + g->sb_hybrid[s_index+3]= 0; + while(code){ + const static int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; + int v; + int pos= s_index+idxtab[code]; + code ^= 8>>idxtab[code]; + v = exp_table[ exponents[pos] ]; + if(get_bits1(&s->gb)) + v = -v; + g->sb_hybrid[pos] = v; + } + s_index+=4; + } + libc_memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*(576 - s_index)); + + /* skip extension bits */ + bits_left = end_pos2 - get_bits_count(&s->gb); + if (bits_left < 0) { + return -1; + } + skip_bits_long(&s->gb, bits_left); + + i= get_bits_count(&s->gb); + switch_buffer(s, &i, &end_pos, &end_pos2); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// + +static void imdct12(int *out, int *in) +{ + int in0, in1, in2, in3, in4, in5, t1, t2; + + in0= in[0*3]; + in1= in[1*3] + in[0*3]; + in2= in[2*3] + in[1*3]; + in3= in[3*3] + in[2*3]; + in4= in[4*3] + in[3*3]; + in5= in[5*3] + in[4*3]; + in5 += in3; + in3 += in1; + + in2= MULH(2*in2, C3); + in3= MULH(4*in3, C3); + + t1 = in0 - in4; + t2 = MULH(2*(in1 - in5), icos36h[4]); + + out[ 7]= + out[10]= t1 + t2; + out[ 1]= + out[ 4]= t1 - t2; + + in0 += in4>>1; + in4 = in0 + in2; + in5 += 2*in1; + in1 = MULH(in5 + in3, icos36h[1]); + out[ 8]= + out[ 9]= in4 + in1; + out[ 2]= + out[ 3]= in4 - in1; + + in0 -= in2; + in5 = MULH(2*(in5 - in3), icos36h[7]); + out[ 0]= + out[ 5]= in0 - in5; + out[ 6]= + out[11]= in0 + in5; +} + +static void imdct36(int *out, int *buf, int *in, int *win) +{ + int i, j, t0, t1, t2, t3, s0, s1, s2, s3; + int tmp[18], *tmp1, *in1; + + for(i=17;i>=1;i--) + in[i] += in[i-1]; + for(i=17;i>=3;i-=2) + in[i] += in[i-2]; + + for(j=0;j<2;j++) { + tmp1 = tmp + j; + in1 = in + j; + t2 = in1[2*4] + in1[2*8] - in1[2*2]; + + t3 = in1[2*0] + (in1[2*6]>>1); + t1 = in1[2*0] - in1[2*6]; + tmp1[ 6] = t1 - (t2>>1); + tmp1[16] = t1 + t2; + + t0 = MULH(2*(in1[2*2] + in1[2*4]), C2); + t1 = MULH( in1[2*4] - in1[2*8] , -2*C8); + t2 = MULH(2*(in1[2*2] + in1[2*8]), -C4); + + tmp1[10] = t3 - t0 - t2; + tmp1[ 2] = t3 + t0 + t1; + tmp1[14] = t3 + t2 - t1; + + tmp1[ 4] = MULH(2*(in1[2*5] + in1[2*7] - in1[2*1]), -C3); + t2 = MULH(2*(in1[2*1] + in1[2*5]), C1); + t3 = MULH( in1[2*5] - in1[2*7] , -2*C7); + t0 = MULH(2*in1[2*3], C3); + + t1 = MULH(2*(in1[2*1] + in1[2*7]), -C5); + + tmp1[ 0] = t2 + t3 + t0; + tmp1[12] = t2 + t1 - t0; + tmp1[ 8] = t3 - t1 - t0; + } + + i = 0; + for(j=0;j<4;j++) { + t0 = tmp[i]; + t1 = tmp[i + 2]; + s0 = t1 + t0; + s2 = t1 - t0; + + t2 = tmp[i + 1]; + t3 = tmp[i + 3]; + s1 = MULH(2*(t3 + t2), icos36h[j]); + s3 = MULL(t3 - t2, icos36[8 - j]); + + t0 = s0 + s1; + t1 = s0 - s1; + out[(9 + j)*SBLIMIT] = MULH(t1, win[9 + j]) + buf[9 + j]; + out[(8 - j)*SBLIMIT] = MULH(t1, win[8 - j]) + buf[8 - j]; + buf[9 + j] = MULH(t0, win[18 + 9 + j]); + buf[8 - j] = MULH(t0, win[18 + 8 - j]); + + t0 = s2 + s3; + t1 = s2 - s3; + out[(9 + 8 - j)*SBLIMIT] = MULH(t1, win[9 + 8 - j]) + buf[9 + 8 - j]; + out[( j)*SBLIMIT] = MULH(t1, win[ j]) + buf[ j]; + buf[9 + 8 - j] = MULH(t0, win[18 + 9 + 8 - j]); + buf[ + j] = MULH(t0, win[18 + j]); + i += 4; + } + + s0 = tmp[16]; + s1 = MULH(2*tmp[17], icos36h[4]); + t0 = s0 + s1; + t1 = s0 - s1; + out[(9 + 4)*SBLIMIT] = MULH(t1, win[9 + 4]) + buf[9 + 4]; + out[(8 - 4)*SBLIMIT] = MULH(t1, win[8 - 4]) + buf[8 - 4]; + buf[9 + 4] = MULH(t0, win[18 + 9 + 4]); + buf[8 - 4] = MULH(t0, win[18 + 8 - 4]); +} + +static void compute_imdct( + mp3_context_t *s, granule_t *g, int32_t *sb_samples, int32_t *mdct_buf +) { + int32_t *ptr, *win, *win1, *buf, *out_ptr, *ptr1; + int32_t out2[12]; + int i, j, mdct_long_end, v, sblimit; + + /* find last non zero block */ + ptr = g->sb_hybrid + 576; + ptr1 = g->sb_hybrid + 2 * 18; + while (ptr >= ptr1) { + ptr -= 6; + v = ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5]; + if (v != 0) + break; + } + sblimit = ((ptr - g->sb_hybrid) / 18) + 1; + + if (g->block_type == 2) { + /* XXX: check for 8000 Hz */ + if (g->switch_point) + mdct_long_end = 2; + else + mdct_long_end = 0; + } else { + mdct_long_end = sblimit; + } + + buf = mdct_buf; + ptr = g->sb_hybrid; + for(j=0;jswitch_point && j < 2) + win1 = mdct_win[0]; + else + win1 = mdct_win[g->block_type]; + /* select frequency inversion */ + win = win1 + ((4 * 36) & -(j & 1)); + imdct36(out_ptr, buf, ptr, win); + out_ptr += 18*SBLIMIT; + ptr += 18; + buf += 18; + } + for(j=mdct_long_end;j 32767) + v = 32767; + else if (v < -32768) + v = -32768; + synth_buf[j] = v; + } + /* copy to avoid wrap */ + libc_memcpy(synth_buf + 512, synth_buf, 32 * sizeof(int16_t)); + + samples2 = samples + 31 * incr; + w = window; + w2 = window + 31; + + sum = *dither_state; + p = synth_buf + 16; + SUM8(sum, +=, w, p); + p = synth_buf + 48; + SUM8(sum, -=, w + 32, p); + *samples = round_sample(&sum); + samples += incr; + w++; + + /* we calculate two samples at the same time to avoid one memory + access per two sample */ + for(j=1;j<16;j++) { + sum2 = 0; + p = synth_buf + 16 + j; + SUM8P2(sum, +=, sum2, -=, w, w2, p); + p = synth_buf + 48 - j; + SUM8P2(sum, -=, sum2, -=, w + 32, w2 + 32, p); + + *samples = round_sample(&sum); + samples += incr; + sum += sum2; + *samples2 = round_sample(&sum); + samples2 -= incr; + w++; + w2--; + } + + p = synth_buf + 32; + SUM8(sum, -=, w + 32, p); + *samples = round_sample(&sum); + *dither_state= sum; + + offset = (offset - 32) & 511; + *synth_buf_offset = offset; +} + +//////////////////////////////////////////////////////////////////////////////// + +static int decode_header(mp3_context_t *s, uint32_t header) { + int sample_rate, frame_size, mpeg25, padding; + int sample_rate_index, bitrate_index; + if (header & (1<<20)) { + s->lsf = (header & (1<<19)) ? 0 : 1; + mpeg25 = 0; + } else { + s->lsf = 1; + mpeg25 = 1; + } + + sample_rate_index = (header >> 10) & 3; + sample_rate = mp3_freq_tab[sample_rate_index] >> (s->lsf + mpeg25); + sample_rate_index += 3 * (s->lsf + mpeg25); + s->sample_rate_index = sample_rate_index; + s->error_protection = ((header >> 16) & 1) ^ 1; + s->sample_rate = sample_rate; + + bitrate_index = (header >> 12) & 0xf; + padding = (header >> 9) & 1; + s->mode = (header >> 6) & 3; + s->mode_ext = (header >> 4) & 3; + s->nb_channels = (s->mode == MP3_MONO) ? 1 : 2; + + if (bitrate_index != 0) { + frame_size = mp3_bitrate_tab[s->lsf][bitrate_index]; + s->bit_rate = frame_size * 1000; + s->frame_size = (frame_size * 144000) / (sample_rate << s->lsf) + padding; + } else { + /* if no frame size computed, signal it */ + return 1; + } + return 0; +} + +static int mp_decode_layer3(mp3_context_t *s) { + int nb_granules, main_data_begin, private_bits; + int gr, ch, blocksplit_flag, i, j, k, n, bits_pos; + granule_t *g; + static granule_t granules[2][2]; + static int16_t exponents[576]; + const uint8_t *ptr; + + if (s->lsf) { + main_data_begin = get_bits(&s->gb, 8); + private_bits = get_bits(&s->gb, s->nb_channels); + nb_granules = 1; + } else { + main_data_begin = get_bits(&s->gb, 9); + if (s->nb_channels == 2) + private_bits = get_bits(&s->gb, 3); + else + private_bits = get_bits(&s->gb, 5); + nb_granules = 2; + for(ch=0;chnb_channels;ch++) { + granules[ch][0].scfsi = 0; /* all scale factors are transmitted */ + granules[ch][1].scfsi = get_bits(&s->gb, 4); + } + } + + for(gr=0;grnb_channels;ch++) { + g = &granules[ch][gr]; + g->part2_3_length = get_bits(&s->gb, 12); + g->big_values = get_bits(&s->gb, 9); + g->global_gain = get_bits(&s->gb, 8); + /* if MS stereo only is selected, we precompute the + 1/sqrt(2) renormalization factor */ + if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) == + MODE_EXT_MS_STEREO) + g->global_gain -= 2; + if (s->lsf) + g->scalefac_compress = get_bits(&s->gb, 9); + else + g->scalefac_compress = get_bits(&s->gb, 4); + blocksplit_flag = get_bits(&s->gb, 1); + if (blocksplit_flag) { + g->block_type = get_bits(&s->gb, 2); + if (g->block_type == 0) + return -1; + g->switch_point = get_bits(&s->gb, 1); + for(i=0;i<2;i++) + g->table_select[i] = get_bits(&s->gb, 5); + for(i=0;i<3;i++) + g->subblock_gain[i] = get_bits(&s->gb, 3); + /* compute huffman coded region sizes */ + if (g->block_type == 2) + g->region_size[0] = (36 / 2); + else { + if (s->sample_rate_index <= 2) + g->region_size[0] = (36 / 2); + else if (s->sample_rate_index != 8) + g->region_size[0] = (54 / 2); + else + g->region_size[0] = (108 / 2); + } + g->region_size[1] = (576 / 2); + } else { + int region_address1, region_address2, l; + g->block_type = 0; + g->switch_point = 0; + for(i=0;i<3;i++) + g->table_select[i] = get_bits(&s->gb, 5); + /* compute huffman coded region sizes */ + region_address1 = get_bits(&s->gb, 4); + region_address2 = get_bits(&s->gb, 3); + g->region_size[0] = + band_index_long[s->sample_rate_index][region_address1 + 1] >> 1; + l = region_address1 + region_address2 + 2; + /* should not overflow */ + if (l > 22) + l = 22; + g->region_size[1] = + band_index_long[s->sample_rate_index][l] >> 1; + } + /* convert region offsets to region sizes and truncate + size to big_values */ + g->region_size[2] = (576 / 2); + j = 0; + for(i=0;i<3;i++) { + k = g->region_size[i]; + if (g->big_values < k) k = g->big_values; + g->region_size[i] = k - j; + j = k; + } + + /* compute band indexes */ + if (g->block_type == 2) { + if (g->switch_point) { + /* if switched mode, we handle the 36 first samples as + long blocks. For 8000Hz, we handle the 48 first + exponents as long blocks (XXX: check this!) */ + if (s->sample_rate_index <= 2) + g->long_end = 8; + else if (s->sample_rate_index != 8) + g->long_end = 6; + else + g->long_end = 4; /* 8000 Hz */ + + g->short_start = 2 + (s->sample_rate_index != 8); + } else { + g->long_end = 0; + g->short_start = 0; + } + } else { + g->short_start = 13; + g->long_end = 22; + } + + g->preflag = 0; + if (!s->lsf) + g->preflag = get_bits(&s->gb, 1); + g->scalefac_scale = get_bits(&s->gb, 1); + g->count1table_select = get_bits(&s->gb, 1); + } + } + + ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); + /* now we get bits from the main_data_begin offset */ + if(main_data_begin > s->last_buf_size){ + s->last_buf_size= main_data_begin; + } + + memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES); + s->in_gb= s->gb; + init_get_bits(&s->gb, s->last_buf + s->last_buf_size - main_data_begin, main_data_begin*8); + + for(gr=0;grnb_channels;ch++) { + g = &granules[ch][gr]; + + bits_pos = get_bits_count(&s->gb); + + if (!s->lsf) { + uint8_t *sc; + int slen, slen1, slen2; + + /* MPEG1 scale factors */ + slen1 = slen_table[0][g->scalefac_compress]; + slen2 = slen_table[1][g->scalefac_compress]; + if (g->block_type == 2) { + n = g->switch_point ? 17 : 18; + j = 0; + if(slen1){ + for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen1); + }else{ + libc_memset((void*) &g->scale_factors[j], 0, n); + j += n; +// for(i=0;iscale_factors[j++] = 0; + } + if(slen2){ + for(i=0;i<18;i++) + g->scale_factors[j++] = get_bits(&s->gb, slen2); + for(i=0;i<3;i++) + g->scale_factors[j++] = 0; + }else{ + for(i=0;i<21;i++) + g->scale_factors[j++] = 0; + } + } else { + sc = granules[ch][0].scale_factors; + j = 0; + for(k=0;k<4;k++) { + n = (k == 0 ? 6 : 5); + if ((g->scfsi & (0x8 >> k)) == 0) { + slen = (k < 2) ? slen1 : slen2; + if(slen){ + for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen); + }else{ + libc_memset((void*) &g->scale_factors[j], 0, n); + j += n; +// for(i=0;iscale_factors[j++] = 0; + } + } else { + /* simply copy from last granule */ + for(i=0;iscale_factors[j] = sc[j]; + j++; + } + } + } + g->scale_factors[j++] = 0; + } + } else { + int tindex, tindex2, slen[4], sl, sf; + + /* LSF scale factors */ + if (g->block_type == 2) { + tindex = g->switch_point ? 2 : 1; + } else { + tindex = 0; + } + sf = g->scalefac_compress; + if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) { + /* intensity stereo case */ + sf >>= 1; + if (sf < 180) { + lsf_sf_expand(slen, sf, 6, 6, 0); + tindex2 = 3; + } else if (sf < 244) { + lsf_sf_expand(slen, sf - 180, 4, 4, 0); + tindex2 = 4; + } else { + lsf_sf_expand(slen, sf - 244, 3, 0, 0); + tindex2 = 5; + } + } else { + /* normal case */ + if (sf < 400) { + lsf_sf_expand(slen, sf, 5, 4, 4); + tindex2 = 0; + } else if (sf < 500) { + lsf_sf_expand(slen, sf - 400, 5, 4, 0); + tindex2 = 1; + } else { + lsf_sf_expand(slen, sf - 500, 3, 0, 0); + tindex2 = 2; + g->preflag = 1; + } + } + + j = 0; + for(k=0;k<4;k++) { + n = lsf_nsf_table[tindex2][tindex][k]; + sl = slen[k]; + if(sl){ + for(i=0;iscale_factors[j++] = get_bits(&s->gb, sl); + }else{ + libc_memset((void*) &g->scale_factors[j], 0, n); + j += n; +// for(i=0;iscale_factors[j++] = 0; + } + } + /* XXX: should compute exact size */ + libc_memset((void*) &g->scale_factors[j], 0, 40 - j); +// for(;j<40;j++) +// g->scale_factors[j] = 0; + } + + exponents_from_scale_factors(s, g, exponents); + + /* read Huffman coded residue */ + if (huffman_decode(s, g, exponents, + bits_pos + g->part2_3_length) < 0) + return -1; + } /* ch */ + + if (s->nb_channels == 2) + compute_stereo(s, &granules[0][gr], &granules[1][gr]); + + for(ch=0;chnb_channels;ch++) { + g = &granules[ch][gr]; + reorder_block(s, g); + compute_antialias(s, g); + compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]); + } + } /* gr */ + return nb_granules * 18; +} + +static int mp3_decode_main( + mp3_context_t *s, + int16_t *samples, const uint8_t *buf, int buf_size +) { + int i, nb_frames, ch; + int16_t *samples_ptr; + + init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE)*8); + + if (s->error_protection) + get_bits(&s->gb, 16); + + nb_frames = mp_decode_layer3(s); + + s->last_buf_size=0; + if(s->in_gb.buffer){ + align_get_bits(&s->gb); + i= (s->gb.size_in_bits - get_bits_count(&s->gb))>>3; + if(i >= 0 && i <= BACKSTEP_SIZE){ + libc_memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i); + s->last_buf_size=i; + } + s->gb= s->in_gb; + } + + align_get_bits(&s->gb); + i= (s->gb.size_in_bits - get_bits_count(&s->gb))>>3; + + if(i<0 || i > BACKSTEP_SIZE || nb_frames<0){ + i = buf_size - HEADER_SIZE; + if (BACKSTEP_SIZE < i) i = BACKSTEP_SIZE; + } + libc_memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i); + s->last_buf_size += i; + + /* apply the synthesis filter */ + for(ch=0;chnb_channels;ch++) { + samples_ptr = samples + ch; + for(i=0;isynth_buf[ch], &(s->synth_buf_offset[ch]), + window, &s->dither_state, + samples_ptr, s->nb_channels, + s->sb_samples[ch][i] + ); + samples_ptr += 32 * s->nb_channels; + } + } + return nb_frames * 32 * sizeof(uint16_t) * s->nb_channels; +} + +//////////////////////////////////////////////////////////////////////////////// + +static int mp3_decode_init(mp3_context_t *s) { + static int init=0; + int i, j, k; + + if (!init) { + /* synth init */ + for(i=0;i<257;i++) { + int v; + v = mp3_enwindow[i]; + #if WFRAC_BITS < 16 + v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); + #endif + window[i] = v; + if ((i & 63) != 0) + v = -v; + if (i != 0) + window[512 - i] = v; + } + + /* huffman decode tables */ + for(i=1;i<16;i++) { + const huff_table_t *h = &mp3_huff_tables[i]; + int xsize, x, y; + unsigned int n; + uint8_t tmp_bits [512]; + uint16_t tmp_codes[512]; + + libc_memset(tmp_bits , 0, sizeof(tmp_bits )); + libc_memset(tmp_codes, 0, sizeof(tmp_codes)); + + xsize = h->xsize; + n = xsize * xsize; + + j = 0; + for(x=0;xbits [j ]; + tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++]; + } + } + + init_vlc(&huff_vlc[i], 7, 512, + tmp_bits, 1, 1, tmp_codes, 2, 2); + } + for(i=0;i<2;i++) { + init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16, + mp3_quad_bits[i], 1, 1, mp3_quad_codes[i], 1, 1); + } + + for(i=0;i<9;i++) { + k = 0; + for(j=0;j<22;j++) { + band_index_long[i][j] = k; + k += band_size_long[i][j]; + } + band_index_long[i][22] = k; + } + + /* compute n ^ (4/3) and store it in mantissa/exp format */ + table_4_3_exp= libc_malloc(TABLE_4_3_SIZE * sizeof(table_4_3_exp[0])); + if(!table_4_3_exp) + return -1; + table_4_3_value= libc_malloc(TABLE_4_3_SIZE * sizeof(table_4_3_value[0])); + if(!table_4_3_value) + return -1; + + for(i=1;i>4); + double f= libc_pow(i&15, 4.0 / 3.0) * libc_pow(2, (exponent-400)*0.25 + FRAC_BITS + 5); + expval_table[exponent][i&15]= f; + if((i&15)==1) + exp_table[exponent]= f; + } + + for(i=0;i<7;i++) { + float f; + int v; + if (i != 6) { + f = tan((double)i * M_PI / 12.0); + v = FIXR(f / (1.0 + f)); + } else { + v = FIXR(1.0); + } + is_table[0][i] = v; + is_table[1][6 - i] = v; + } + for(i=7;i<16;i++) + is_table[0][i] = is_table[1][i] = 0.0; + + for(i=0;i<16;i++) { + double f; + int e, k; + + for(j=0;j<2;j++) { + e = -(j + 1) * ((i + 1) >> 1); + f = libc_pow(2.0, e / 4.0); + k = i & 1; + is_table_lsf[j][k ^ 1][i] = FIXR(f); + is_table_lsf[j][k][i] = FIXR(1.0); + } + } + + for(i=0;i<8;i++) { + float ci, cs, ca; + ci = ci_table[i]; + cs = 1.0 / sqrt(1.0 + ci * ci); + ca = cs * ci; + csa_table[i][0] = FIXHR(cs/4); + csa_table[i][1] = FIXHR(ca/4); + csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4); + csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4); + csa_table_float[i][0] = cs; + csa_table_float[i][1] = ca; + csa_table_float[i][2] = ca + cs; + csa_table_float[i][3] = ca - cs; + } + + /* compute mdct windows */ + for(i=0;i<36;i++) { + for(j=0; j<4; j++){ + double d; + + if(j==2 && i%3 != 1) + continue; + + d= sin(M_PI * (i + 0.5) / 36.0); + if(j==1){ + if (i>=30) d= 0; + else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0); + else if(i>=18) d= 1; + }else if(j==3){ + if (i< 6) d= 0; + else if(i< 12) d= sin(M_PI * (i - 6 + 0.5) / 12.0); + else if(i< 18) d= 1; + } + d*= 0.5 / cos(M_PI*(2*i + 19)/72); + if(j==2) + mdct_win[j][i/3] = FIXHR((d / (1<<5))); + else + mdct_win[j][i ] = FIXHR((d / (1<<5))); + } + } + for(j=0;j<4;j++) { + for(i=0;i<36;i+=2) { + mdct_win[j + 4][i] = mdct_win[j][i]; + mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1]; + } + } + init = 1; + } + return 0; +} + +static int mp3_decode_frame( + mp3_context_t *s, + int16_t *out_samples, int *data_size, + uint8_t *buf, int buf_size +) { + uint32_t header; + int out_size; + int extra_bytes = 0; + +retry: + if(buf_size < HEADER_SIZE) + return -1; + + header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + if(mp3_check_header(header) < 0){ + buf++; + buf_size--; + extra_bytes++; + goto retry; + } + + if (decode_header(s, header) == 1) { + s->frame_size = -1; + return -1; + } + + if(s->frame_size<=0 || s->frame_size > buf_size){ + return -1; // incomplete frame + } + if(s->frame_size < buf_size) { + buf_size = s->frame_size; + } + + out_size = mp3_decode_main(s, out_samples, buf, buf_size); + if(out_size>=0) + *data_size = out_size; + // else: Error while decoding MPEG audio frame. + s->frame_size += extra_bytes; + return buf_size; +} + +//////////////////////////////////////////////////////////////////////////////// + +mp3_decoder_t mp3_create(void) { + void *dec = libc_calloc(sizeof(mp3_context_t), 1); + if (dec) mp3_decode_init((mp3_context_t*) dec); + return (mp3_decoder_t) dec; +} + +void mp3_done(mp3_decoder_t *dec) { + if (dec) libc_free(dec); +} + +int mp3_decode(mp3_decoder_t *dec, void *buf, int bytes, signed short *out, mp3_info_t *info) { + int res, size = -1; + mp3_context_t *s = (mp3_context_t*) dec; + if (!s) return 0; + res = mp3_decode_frame(s, (int16_t*) out, &size, buf, bytes); + if (res < 0) return 0; + if (info) { + info->sample_rate = s->sample_rate; + info->channels = s->nb_channels; + info->audio_bytes = size; + } + return s->frame_size; +} diff --git a/internal/c/parts/audio/decode/mp3_mini/src/minimp3.h b/internal/c/parts/audio/decode/mp3_mini/src/minimp3.h new file mode 100644 index 000000000..fa29a9747 --- /dev/null +++ b/internal/c/parts/audio/decode/mp3_mini/src/minimp3.h @@ -0,0 +1,19 @@ +#ifndef __MINIMP3_H_INCLUDED__ +#define __MINIMP3_H_INCLUDED__ + +#define MP3_MAX_SAMPLES_PER_FRAME (1152*2) + +typedef struct _mp3_info { + int sample_rate; + int channels; + int audio_bytes; // generated amount of audio per frame +} mp3_info_t; + +typedef void* mp3_decoder_t; + +extern mp3_decoder_t mp3_create(void); +extern int mp3_decode(mp3_decoder_t *dec, void *buf, int bytes, signed short *out, mp3_info_t *info); +extern void mp3_done(mp3_decoder_t *dec); +#define mp3_free(dec) do { mp3_done(dec); dec = NULL; } while(0) + +#endif//__MINIMP3_H_INCLUDED__ diff --git a/internal/c/parts/audio/decode/src.c b/internal/c/parts/audio/decode/src.c index 75530a83b..1e7651b61 100644 --- a/internal/c/parts/audio/decode/src.c +++ b/internal/c/parts/audio/decode/src.c @@ -8,8 +8,8 @@ #define DEPENDENCY_AUDIO_DECODE_WAV #ifdef QB64_BACKSLASH_FILESYSTEM - #ifdef DEPENDENCY_AUDIO_DECODE_MP3 - #include "mp3\\src.c" + #ifdef DEPENDENCY_AUDIO_DECODE_MP3 + #include "mp3_mini\\src.c" #endif #ifdef DEPENDENCY_AUDIO_DECODE_WAV #include "wav\\src.c" @@ -19,7 +19,7 @@ #endif #else #ifdef DEPENDENCY_AUDIO_DECODE_MP3 - #include "mp3/src.c" + #include "mp3_mini/src.c" #endif #ifdef DEPENDENCY_AUDIO_DECODE_WAV #include "wav/src.c" @@ -133,6 +133,9 @@ incorrect_format=0; if (seq->bits_per_sample!=16) incorrect_format=1; if (seq->is_unsigned) incorrect_format=1; //todo... if (seq->endian==???) + +//this section does not fix the frequency, only the bits per sample +//and signed-ness of the data if (incorrect_format){ static int32 bps; bps=seq->bits_per_sample/8; static int32 samples; samples=seq->data_size/bps; @@ -193,13 +196,13 @@ if (seq->sample_rate!=snd_frequency){ s.data_out=f_out; s.output_frames=out_samples_max;//limit s.src_ratio=ratio;//Equal to output_sample_rate / input_sample_rate. - /* - SRC_SINC_BEST_QUALITY = 0, - SRC_SINC_MEDIUM_QUALITY = 1, - SRC_SINC_FASTEST = 2, - SRC_ZERO_ORDER_HOLD = 3, - SRC_LINEAR = 4 - */ + // + // SRC_SINC_BEST_QUALITY = 0, + // SRC_SINC_MEDIUM_QUALITY = 1, + // SRC_SINC_FASTEST = 2, + // SRC_ZERO_ORDER_HOLD = 3, + // SRC_LINEAR = 4 + // if (src_simple(&s,SRC_LINEAR,channels)){ //error! free(seq->data); @@ -215,6 +218,7 @@ if (seq->sample_rate!=snd_frequency){ seq->sample_rate=snd_frequency; } + if (seq->channels==1){ seq->data_mono=seq->data; seq->data_mono_size=seq->data_size; diff --git a/source/qb64.bas b/source/qb64.bas index 9a3e0d8d4..c7729b196 100644 --- a/source/qb64.bas +++ b/source/qb64.bas @@ -10857,7 +10857,7 @@ END IF IF DEPENDENCY(DEPENDENCY_AUDIO_DECODE) THEN 'General decoder defines$ = defines$ + defines_header$ + "DEPENDENCY_AUDIO_DECODE" - 'MP3 decoder + 'MP3 decoder (deprecated) d1$ = "parts\audio\decode\mp3" d2$ = d1$ + "\os\" + o$ d3$ = "internal\c\" + d2$ @@ -10865,6 +10865,14 @@ IF DEPENDENCY(DEPENDENCY_AUDIO_DECODE) THEN Build d3$ END IF libs$ = libs$ + " " + d2$ + "\src.a" + 'MINI_MP3 decoder + d1$ = "parts\audio\decode\mp3_mini" + d2$ = d1$ + "\os\" + o$ + d3$ = "internal\c\" + d2$ + IF _FILEEXISTS(d3$ + "\src.a") = 0 THEN 'rebuild? + Build d3$ + END IF + libs$ = libs$ + " " + d2$ + "\src.a" 'OGG decoder d1$ = "parts\audio\decode\ogg" d2$ = d1$ + "\os\" + o$