libmpg123 1.15.4

git-svn-id: svn://kolibrios.org@3960 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-10-02 16:44:03 +00:00
parent 44d189b67c
commit 2217a37e5b
68 changed files with 11403 additions and 1285 deletions

View File

@ -0,0 +1,151 @@
This is an attempt to give credit to the people who contributed in some way to the mpg123 project.
There are names and email addresses listed. Please use these addresses only to contact contributors with some question about their mpg123 contribution.
You are explicitly not allowed to send them unwanted business offers or to question the quality of their sex life.
--------------------
Current maintainers with various sorts of contributions:
Thomas Orgis <thomas@orgis.org>
Patrick Dehne <patrick@steidle.net>
Jonathan Yong <10walls@gmail.com>
Co-initiator of the revived mpg123 project, but not that involved anymore:
Nicholas J Humfrey <njh@ecs.soton.ac.uk>
Generic address pointing to the current maintainer (hopefully still works in future in case maintainership will change again): <maintainer@mpg123.org>
The creator: Michael Hipp (email: hippm@informatik.uni-tuebingen.de - please bother maintainers first)
Contributions/ideas Thomas Orgis era (includes backports from mhipp trunk):
Mike Gorchak <mike.gorchak.qnx@gmail.com>: QNX native audio output (QSA)
Dan McGee <dpmcgee@gmail.com>: various patches (also for test suite)
Jonathan Yong (jon_y) <10walls@gmail.com>: win32 hacking
Malcolm Boczek <MBoczek@terraindustries.com>: Common language runtime wrapper
Elbert Pol (TeLLie) <elbert.pol@gmail.com>: OS/2 port fixup
Jeroen Valkonet <jvalkon@xs4all.nl>: motivate pitch control, suggestive patch for pitch command in generic control interface
Andy Hefner <ahefner@gmail.com>: patch for that second UTF16 issue
Taihei Monma <tmkk@mac.com>: A whole lot of new/improved assembler code, including Altivec!
Christian Weisgerber <naddy@openbsd.org>, Brad Smith: sndio output
Patrick Dehne (P4tr3ck) <patrick@steidle.net>: more MSVC++ porting, patch to handle missing bit reservoirs
Thorsten Glaser <tg@mirbsd.de>: icy2utf8, suggest utf8 locale stuff
Dan Smith <dan@algenta.com>: ABI fixes for ensuring stack alignment (esp. for MinGW-built DLL with MSVC)
Michael Ryzhykh <mclroy@gmail.com>: mpg123.spec.in
Stefan Lenselink <Stefan@lenselink.org>: initial aRts output
Sergej Kvachonok <ravenexp@gmail.com>: win32 audio rewrite
Winston: SunOS-4.1.4/gcc-2.7.0 testing and suggestions for fixes (legacy Makefile, integer type headers)
Mika Tiainen: pointing out the fix for the UTF to ASCII filtering of tags to actually work
Nick Kurshev <nickols_k@mail.ru>: extended 3dnow (from mplayer)
Zuxy Meng <zuxy.meng@gmail.com>: SSE (from mplayer)
Honza <cundrak@quick.cz>: idea and prototype patch for ICY meta data support
Petr Baudis <pasky@ucw.cz>: patches: term sigcont, id3 display unicode fallback and condensed output
Petr Salinger <Petr.Salinger@seznam.cz>: i486 enhancement
mpdavig@users.sourceforge.net: linux-ppc-nas Makefile.legacy entry
Adrian Bacon <adrian.bacon@xs4all.nl>: patched decode_i586_dither (noise shaped float/int rounding)
Cool Feet Audio project <nutcase@dtfm.org>: realtime equalizer control
Steve Grundell <www@grundell.u-net.com>: clean stdout in control mode with stdout decoding
Romain Dolbeau <romain@dolbeau.org>: Altivec support (taken from mplayer)
higway <higway@mednet.md>: MMX Patch
Clemens Ladisch <clemens@ladisch.de>: ALSA 0.9/1.0 support
Debian Daniel Kobras <kobras@debian.org> era:
Steve Kemp <skx@debian.org>
Dan Olson <theoddone33@icculus.org>
Syuuhei Kashiyama <squash@mb.kcom.ne.jp>
Rupert Levene <rupert.debian@hotpop.com>
Andreas Dilger <adilger@turbolinux.com>
Erik B. Andersen <andersee@debian.org>
Chris Butler <chrisb@debian.org>
Martin Sjogren <md9ms@mdstud.chalmers.se>
Chet Hosey <chosey@budapress.com>
Roland Rosenfeld <roland@spinnaker.de>
Debian Colin Watson <cjwatson@debian.org> era:
Helge Deller <deller@gmx.de>
Chet Hosey <chosey@budapress.com>
Christopher C. Chimelis <chris@debian.org>
Roland Rosenfeld <roland@spinnaker.de>
Marcelo E. Magallon <mmagallo@debian.org>
Initial Debianers:
Tommi Virtanen <tv@debian.org>
Paul Haggart <phaggart@debian.org>
Contributions/ideas Michael Hipp era:
Mikko Tommila: DCT9
Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
MPEG Software Simulation Group: reference decoder package
Tobias Bading: idea for DCT64 in subband synthesis from maplay package
Jeff Tsay and Mikko Tommila: MDCT36 from maplay package
Philipp Knirsch <phil@mpik-tueb.mpg.de>: DCT36/manual unroll idea
Thomas Woerner: SGI Audio
Damien Clermonte: HP-UX audio fixes
Niclas Lindstrom <nil@wineasy.se>: OS2 port
Stefan Bieschewski <stb@acm.org>: Pentium optimizations, decode_i586.s
Martin Denn <mdenn@unix-ag.uni-kl.de>: NAS port
Niklas Beisert <nbeisert@physik.tu-muenchen.de>: MPEG 2.5 tables
<mycroft@NetBSD.ORG> and <augustss@cs.chalmers.se>: NetBSD Patch(es)
Kevin Brintnall <kbrint@visi.com>: BSD patch
Tony Million: win32 port
Steven Tiger Lang: advanced shuffle
Eric B. Mitchell: esd port
Ryan R. Prosser <prosser@geocities.com>: esd port for Solaris
Andreas Neuhaus: initial generic control interface
(additionally fetched from changelog:)
Ralf Hildebrandt <R.Hildebrandt@TU-BS.DE>: audio_alib changes
<sms@moe.2bsd.com>: BSDOS 4.0 with gcc added to Makefile
Bertrand Petit <elrond@phoe.netdev.net>: frontend changes
Erik Mouw <J.A.K.Mouw@its.tudelft.nl>: SGI audio fix for non RAD machines
Daniel O'Connor <darius@guppy.dons.net.au>: freebsd-esd make-entry
D. Skarda <0rfelyus@atrey.karlin.mff.cuni.cz>: enhanced head_check
Wilson, Jeff D <jeff.wilson@wilcom.com>: xterm-title
Robert Bihlmeyer <robbe@orcus.priv.at>: esd changes
Hannu Napari's <Hannu.Napari@hut.fi>: SGI audio patches
<Juergen.Schoew@unix-ag.uni-siegen.de>: native AIX support
<psst@euskalnet.net>: playlist patch
Gilles Zunino <Gilles.Zunino@hei.fupl.asso.fr>: SGI audio patches
Matthew Parslow <roy@alpha.alphalink.com.au>: esdserver patch
<dlux@dlux.sch.bme.hu>: equalizer patch (equalfile setting)
Ducroquet Erwan <ducroque@ufr-info-p7.ibp.fr>: HPUX/ALib support
Shane Wegner <shane@CM.NU>: genrepatch
Samuel Audet <guardia@step.polymtl.ca>: wav-File patch
"J. Dean Brederson" <jdb@cs.utah.edu>: SGI-RAD support
Chou Ye-chi <is84002@cis.nctu.edu.tw>: sajberplay/FreeBSD patch
Fabrice Bellard <bellard@email.enst.fr>: 486 optimizations
A. Hermansen <ahermans@vf.telia.no> and J. Kysela <perex@jcu.cz>: ALSA output
KIMURA Takuhiro <kim@hannah.ipc.miyakyo-u.ac.jp>: K6-3DNow
Petr Stehlik <stehlik@cas3.zlin.vutbr.cz>: MINT
Andy <andy@snoogie.demon.co.uk>: float2int speed up proposal
Brian Foutz <foutz@anise.ee.cornell.edu>: TK3Play
Thomas Niederreiter <tn@tarantel.rz.fh-muenchen.de>: RIFF header fix
Stefan Gybas <cab@studbox.uni-stuttgart.de>: m68k patch
Grant Erickson <eric0139@tc.umn.edu>: Linux PPC patch
Peter Berger <peterb@hoopoe.psc.edu>: BSDi patch
Henrik P Johnson <king@one.se>: HTTP auth
Steven Tiger Lang <tiger@tyger.org>: advanced shuffle
"Brian J. Swetland" <swetland@uiuc.edu>: front-end (remote) patch
<leo@zycad.com>
Tillmann Steinbrecher <tst@gmx.de>: shuffle patch
M.Stekelenburg <m.stekelenburg@student.utwente.nl>: i386-getbits
Antti Andreimann <anttix@cyberix.edu.ee>: outburst patch
Hur TaeSung <saturn@arari.snu.ac.kr>: 'http accept' patch
(from post-0.59 changes that yet have to go into new trunk:)
Hans Schwengeler <schweng@astro.unibas.ch>: audio_dec additions
Wojciech Barañski's Mp3Play (check the tools folder): Mp3Play frontend
Daniel Koukola: audio_oss.c patch
Munechika SUMIKAWA <sumikawa@ebina.hitachi.co.jp>: IPv6
TEMNOTA <temnota@kmv.ru>: HTTP,FTP patch/playlist fix
Peter Surda <shurdeek@panorama.sth.ac.at>: VBR patch
Ben <ben@blaukopf.com>: ARM startup time improvements
Dave MacKenzie <djm@pix.net>: init_output() patch
pasky's <pasky@ju.cz>: close-on-stop patch

View File

@ -0,0 +1,773 @@
This is the file that contains the terms of use, copying, etc. for the mpg123 distribution package.
Main message:
Code is copyrighted by Michael Hipp, who made it free software under the terms of the LGPL 2.1.
But that is not all of it.
mpg123 is licensed under the GNU General Lesser Public License, version 2.1, and in parts under the GNU General Public License, version 2.
That means that _all_ of mpg123 is licensed under GPL and the major part also under the LGPL.
Actually, the "major part" currently is the whole distributed package of mpg123. There are some files (old alsa output, libao output) that you get from our svn repository and that do not fall under LGPL.
When the copyright marker in a source file says "the mpg123 project" that means that the file contains code copyrighted by contributors to mpg123, the "initially written by" naming the person(s) that created the file and thus may have the largest part of copyrights on it.
I am explaining this here to emphasize that the copyright always actually lies by the individual member (i.e. contributor to) of the mpg123 project who wrote a specific section of code.
Usage of a source code management system like Subversion should provide keeping track of individual copyright traces...
Please consider that any code that is contributed to the mpg123 project shall be licensed under LGPL 2.1 .
If you want to contribute, but don't agree to that (i.e. you want to have your code GPL only) please say so - then, we either you convince is to include your code under GPL, we convince you to make it LGPL instead or, as a last resort, you'll have to do you own GPLed fork.
But we should try to avoid the last option...
All files in the distribution that don't carry a license note on their own are licensed under the terms of the LGPL 2.1; all files that do carry either a LGPL or GPL note are licensed respectively under the LGPL or GPL as follows:
=======================
1. The LGPL version 2.1
=======================
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
====================
2. The GPL version 2
====================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 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.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
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 give any other recipients of the Program a copy of this License
along with the Program.
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 Program or any portion
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
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 Program, 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 Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) 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; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, 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 executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or 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 counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program 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.
5. 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 Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. 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 Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program 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 Program.
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.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program 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.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 Program
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 Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, 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
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View File

@ -1,66 +1,90 @@
CC=gcc
CPP=gcc -E
LIBRARY = libmpg123
CFLAGS= -c -combine -O2 -fomit-frame-pointer -ffast-math -mmmx -finline-functions
CC = gcc
CFLAGS= -c -O2 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math
CPPFLAGS = -DOPT_MULTI -DOPT_GENERIC -DOPT_GENERIC_DITHER -DOPT_I386 -DOPT_I586 -DOPT_I586_DITHER -DOPT_MMX -DOPT_3DNOW -DOPT_3DNOWEXT -DOPT_SSE -DREAL_IS_FLOAT -DNOXFERMEM -DNEWOLD_WRITE_SAMPLE
LDIMPORT:= -nostdlib --out-implib libmpg123imp.a --exclude-libs libamz.a
LD = ld
LDFLAGS = -shared -s -nostdlib -T ../newlib/dll.lds --entry _DllStartup --image-base=0 --out-implib $(LIBRARY).dll.a
LDFLAGS:= -shared -s -T../newlib/dll.lds --image-base 0
STRIP = $(PREFIX)strip
UDEF= -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -U_MSC_VER
DEFINES= -DHAVE_CONFIG_H
INCLUDES= -I../newlib/include
LIBPATH:= -L../newlib
LIBS:= -lamz -lgcc -lcimp
NAME:= libmpg123
DEFINES:= -DHAVE_CONFIG_H -DOPT_MMX -DOPT_MULTI -DREAL_IS_FLOAT -DNOXFERMEM
LIBS:= -ldll -lc.dll -lgcc
SRCS= \
libmpg123.c \
compat.c \
dct64.c \
dct64_i386.c \
dither.c \
equalizer.c \
optimize.c \
feature.c \
format.c \
frame.c \
icy.c \
icy2utf8.c \
id3.c \
index.c \
layer1.c \
layer2.c \
layer3.c \
synth.c \
tabinit.c \
lfs_alias.c \
libmpg123.c \
ntom.c \
optimize.c \
parse.c \
readers.c \
frame.c \
format.c
stringbuf.c \
synth.c \
tabinit.c
ASM= \
getcpuflags.S \
tabinit_mmx.S \
dct36_3dnow.S \
dct36_3dnowext.S \
dct64_3dnow.S \
dct64_3dnowext.S \
dct64_mmx.S \
synth_mmx.S
dct64_sse.S \
dct64_sse_float.S \
equalizer_3dnow.S \
getcpuflags.S \
synth_3dnow.S \
synth_3dnowext.S \
synth_i586.S \
synth_i586_dither.S \
synth_mmx.S \
synth_sse.S \
synth_sse_float.S \
synth_sse_s32.S \
synth_stereo_sse_float.S\
synth_stereo_sse_S32.S \
tabinit_mmx.S
ASM_OBJS = $(patsubst %.S, %.o, $(ASM))
SRCS_OBJ = $(patsubst %.c, %.o, $(SRCS))
all: $(NAME).dll
$(NAME).dll: $(SRCS_OBJ) $(ASM_OBJS) Makefile
ld $(LDIMPORT) $(LIBPATH) $(LDFLAGS) -o $@ $(SRCS_OBJ) $(ASM_OBJS) $(LIBS)
all: $(LIBRARY).dll
$(LIBRARY).dll: $(SRCS_OBJ) $(ASM_OBJS) Makefile
$(LD) $(LDFLAGS) $(LIBPATH) -o $@ libmpg123.dll.def $(SRCS_OBJ) $(ASM_OBJS) $(LIBS)
$(STRIP) $@
sed -f ../newlib/cmd1.sed libmpg123.dll.def > mem
sed -f ../newlib/cmd2.sed mem >$(LIBRARY).inc
%.o : %.S $(ASM) Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
$(CC) $(CFLAGS) $(CPPFLAGS) $(UDEF) $(DEFINES) $(INCLUDES) -o $@ $<
%.o: %.c Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
$(CC) $(CFLAGS) $(CPPFLAGS) $(UDEF) $(DEFINES) $(INCLUDES) -o $@ $<
clean:
-rm -f *.o

View File

@ -1,36 +0,0 @@
.global ___chkstk
.global __alloca
.section .text
___chkstk:
__alloca:
pushl %ecx /* save temp */
leal 8(%esp), %ecx /* point past return addr */
cmpl $0x1000, %eax /* > 4k ?*/
jb Ldone
Lprobe:
subl $0x1000, %ecx /* yes, move pointer down 4k*/
orl $0x0, (%ecx) /* probe there */
subl $0x1000, %eax /* decrement count */
cmpl $0x1000, %eax
ja Lprobe /* and do it again */
Ldone:
subl %eax, %ecx
orl $0x0, (%ecx) /* less than 4k, just peek here */
movl %esp, %eax /* save old stack pointer */
movl %ecx, %esp /* decrement stack */
movl (%eax), %ecx /* recover saved temp */
movl 4(%eax), %eax /* recover return address */
/* Push the return value back. Doing this instead of just
jumping to %eax preserves the cached call-return stack
used by most modern processors. */
pushl %eax
ret

View File

@ -1,16 +1,28 @@
/*
compat: Some compatibility functions. Basic standard C stuff, that may barely be above/around C89.
compat: Some compatibility functions.
The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
So anything possibly somewhat advanced should be considered to be put here, with proper #ifdef;-)
copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
initially written by Thomas Orgis, Windows Unicode stuff by JonY.
*/
#include "config.h"
#include "compat.h"
#ifdef _MSC_VER
#include <io.h>
#else
#include <fcntl.h>
#endif
#include <sys/stat.h>
#include "debug.h"
int _EXFUN(open, (const char *, int, ...));
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *safe_realloc(void *ptr, size_t size)
{
@ -39,3 +51,84 @@ char *strdup(const char *src)
return strcpy(dest, src);
}
#endif
int compat_open(const char *filename, int flags)
{
int ret;
#if defined (WANT_WIN32_UNICODE)
wchar_t *frag = NULL;
ret = win32_utf8_wide(filename, &frag, NULL);
if ((frag == NULL) || (ret == 0)) goto fallback; /* Fallback to plain open when ucs-2 conversion fails */
ret = _wopen(frag, flags); /*Try _wopen */
if (ret != -1 ) goto open_ok; /* msdn says -1 means failure */
fallback:
#endif
#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
ret = _open(filename, flags); /* Try plain old _open(), if it fails, do nothing */
#else
/* On UNIX, we always add a default permission mask in case flags|O_CREAT. */
ret = open(filename, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
#endif
#if defined (WANT_WIN32_UNICODE)
open_ok:
free ((void *)frag); /* Freeing a NULL should be OK */
#endif
return ret;
}
int compat_close(int infd)
{
#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
return _close(infd);
#else
return close(infd);
#endif
}
/* Windows Unicode stuff */
#ifdef WANT_WIN32_UNICODE
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen)
{
size_t len;
char *buf;
int ret = 0;
len = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, NULL, 0, NULL, NULL); /* Get utf-8 string length */
buf = calloc(len + 1, sizeof (char)); /* Can we assume sizeof char always = 1? */
if(!buf) len = 0;
else {
if (len != 0) ret = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, buf, len, NULL, NULL); /*Do actual conversion*/
buf[len] = '0'; /* Must terminate */
}
*mbptr = buf; /* Set string pointer to allocated buffer */
if(buflen != NULL) *buflen = (len) * sizeof (char); /* Give length of allocated memory if needed. */
return ret;
}
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen)
{
size_t len;
wchar_t *buf;
int ret = 0;
len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, NULL, 0); /* Get converted size */
buf = calloc(len + 1, sizeof (wchar_t)); /* Allocate memory accordingly */
if(!buf) len = 0;
else {
if (len != 0) ret = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, buf, len); /* Do conversion */
buf[len] = L'0'; /* Must terminate */
}
*wptr = buf; /* Set string pointer to allocated buffer */
if (buflen != NULL) *buflen = len * sizeof (wchar_t); /* Give length of allocated memory if needed. */
return ret; /* Number of characters written */
}
#endif

View File

@ -15,6 +15,7 @@
#define MPG123_COMPAT_H
#include "config.h"
#include "intsym.h"
#ifdef HAVE_STDLIB_H
/* realloc, size_t */
@ -121,4 +122,57 @@ typedef intmax_t ssize_p;
typedef long ssize_p;
#endif
/**
* Opening a file handle can be different.
* This function here is defined to take a path in native encoding (ISO8859 / UTF-8 / ...), or, when MS Windows Unicode support is enabled, an UTF-8 string that will be converted back to native UCS-2 (wide character) before calling the system's open function.
* @param[in] wptr Pointer to wide string.
* @param[in] mbptr Pointer to multibyte string.
* @return file descriptor (>=0) or error code.
*/
int compat_open(const char *filename, int flags);
/**
* Closing a file handle can be platform specific.
* This function takes a file descriptor that is to be closed.
* @param[in] infd File descriptor to be closed.
* @return 0 if the file was successfully closed. A return value of -1 indicates an error.
*/
int compat_close(int infd);
/* Those do make sense in a separate file, but I chose to include them in compat.c because that's the one source whose object is shared between mpg123 and libmpg123 -- and both need the functionality internally. */
#ifdef WANT_WIN32_UNICODE
/**
* win32_uni2mbc
* Converts a null terminated UCS-2 string to a multibyte (UTF-8) equivalent.
* Caller is supposed to free allocated buffer.
* @param[in] wptr Pointer to wide string.
* @param[out] mbptr Pointer to multibyte string.
* @param[out] buflen Optional parameter for length of allocated buffer.
* @return status of WideCharToMultiByte conversion.
*
* WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx
*/
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
/**
* win32_mbc2uni
* Converts a null terminated UTF-8 string to a UCS-2 equivalent.
* Caller is supposed to free allocated buffer.
* @param[out] mbptr Pointer to multibyte string.
* @param[in] wptr Pointer to wide string.
* @param[out] buflen Optional parameter for length of allocated buffer.
* @return status of WideCharToMultiByte conversion.
*
* MultiByteToWideChar - http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx
*/
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
#endif
/* That one comes from Tellie on OS/2, needed in resolver. */
#ifdef __KLIBC__
typedef int socklen_t;
#endif
#endif

View File

@ -2,32 +2,41 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Define if your architecture wants/needs/can use attribute_align_arg and
alignment checks. It's for 32bit x86... */
alignment checks. It is for 32bit x86... */
#define ABI_ALIGN_FUN 1
/* Define to use proper rounding. */
/* #undef ACCURATE_ROUNDING */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define if .balign is present. */
#define ASMALIGN_BALIGN 1
/* Define if .align just takes byte count. */
/* #undef ASMALIGN_BYTE */
/* Define if .align takes 3 for alignment of 2^3=8 bytes instead of 8. */
/* #undef ASMALIGN_EXP */
/* Define if __attribute__((aligned(16))) shall be used */
#define CCALIGN 1
/* Define if checking of stack alignment is wanted. */
#define CHECK_ALIGN 1
/* Define if debugging is enabled. */
/* #undef DEBUG */
/* The default audio output module(s) to use */
#define DEFAULT_OUTPUT_MODULE "win32"
#define DEFAULT_OUTPUT_MODULE "dummy"
/* Define if building with dynamcally linked libmpg123 */
#define DYNAMIC_BUILD 1
/* Use EFBIG as substitude for EOVERFLOW, mingw.org may lack the latter */
#define EOVERFLOW EFBIG
/* Define if FIFO support is enabled. */
/* #undef FIFO */
#define FIFO 1
/* Define if frame index should be used. */
#define FRAME_INDEX 1
@ -77,6 +86,9 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define if getaddrinfo accepts the AI_ADDRCONFIG flag */
/* #undef HAVE_GAI_ADDRCONFIG */
/* Define to 1 if you have the `getaddrinfo' function. */
/* #undef HAVE_GETADDRINFO */
@ -108,7 +120,7 @@
#define HAVE_LOCALE_H 1
/* Define if libltdl is available */
/* #undef HAVE_LTDL */
#define HAVE_LTDL 1
/* Define to 1 if you have the <machine/soundcard.h> header file. */
/* #undef HAVE_MACHINE_SOUNDCARD_H */
@ -150,7 +162,7 @@
/* #undef HAVE_RANDOM */
/* Define to 1 if you have the <sched.h> header file. */
/* #undef HAVE_SCHED_H */
#define HAVE_SCHED_H 1
/* Define to 1 if you have the `sched_setscheduler' function. */
/* #undef HAVE_SCHED_SETSCHEDULER */
@ -236,9 +248,6 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <windows.h> header file. */
#define HAVE_WINDOWS_H 1
/* Define to indicate that float storage follows IEEE754. */
#define IEEE_FLOAT 1
@ -246,42 +255,46 @@
#define INDEX_SIZE 1000
/* Define if IPV6 support is enabled. */
/* #undef IPV6 */
#define IPV6 1
/* Define this to the size of long type in bits, used for LFS small/native
alias functions. */
#define LFS_ALIAS_BITS 32
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define if network support is enabled. */
/* #undef NETWORK */
/* The suffix for module files. */
#define MODULE_FILE_SUFFIX ".la"
/* Define to disable 16 bit integer output. */
/* #undef NO_16BIT */
/* Define to disable 32 bit integer output. */
/* Define to disable 32 bit and 24 bit integer output. */
#define NO_32BIT 1
/* Define to disable 8 bit integer output. */
#define NO_8BIT 1
#define NO_8BIT 1
/* Define to disable downsampled decoding. */
/* #undef NO_DOWNSAMPLE */
/* Define to disable error messages in combination with a return value (the
return is left intact). */
#define NO_ERETURN 1
/* #undef NO_ERETURN */
/* Define to disable error messages. */
#define NO_ERROR 1
/* #undef NO_ERRORMSG */
/* Define to disable feeder and buffered readers. */
#define NO_FEEDER 1
/* #undef NO_FEEDER */
/* Define to disable ICY handling. */
#define NO_ICY 1
/* #undef NO_ICY */
/* Define to disable ID3v2 parsing. */
#define NO_ID3V2 1
/* #undef NO_ID3V2 */
/* Define to disable layer I. */
/* #undef NO_LAYER1 */
@ -293,16 +306,16 @@
/* #undef NO_LAYER3 */
/* Define to disable ntom resampling. */
#define NO_NTOM 1
/* #undef NO_NTOM */
/* Define to disable real output. */
#define NO_REAL 1
/* Define to disable string functions. */
#define NO_STRING
/* #undef NO_STRING */
/* Define to disable warning messages. */
#define NO_WARNING 1
/* #undef NO_WARNING */
/* Name of package */
#define PACKAGE "mpg123"
@ -314,13 +327,16 @@
#define PACKAGE_NAME "mpg123"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "mpg123 1.9.0"
#define PACKAGE_STRING "mpg123 1.15.4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "mpg123"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.9.0"
#define PACKAGE_VERSION "1.15.4"
/* Define if portaudio v18 API is wanted. */
/* #undef PORTAUDIO18 */
@ -344,10 +360,27 @@
#define STDC_HEADERS 1
/* Define if modules are enabled */
/* #undef USE_MODULES */
#define USE_MODULES 1
/* Version number of package */
#define VERSION "1.9.0"
#define VERSION "1.15.4"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
@ -384,3 +417,6 @@
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef uint32_t */
/* Define to `unsigned long' if <sys/types.h> does not define. */
/* #undef uintptr_t */

View File

@ -0,0 +1,505 @@
/*
dct64_3dnow.s: Replacement of dct36() with AMD's 3DNow! SIMD operations support
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Syuuhei Kashiyama
This code based 'dct36_3dnow.s' by Syuuhei Kashiyama
<squash@mb.kcom.ne.jp>,only two types of changes have been made:
- remove PREFETCH instruction for speedup
- change function name for support 3DNow! automatic detect
You can find Kashiyama's original 3dnow! support patch
(for mpg123-0.59o) at
http://user.ecc.u-tokyo.ac.jp/~g810370/linux-simd/ (Japanese).
by KIMURA Takuhiro <kim@hannah.ipc.miyakyo-u.ac.jp> - until 31.Mar.1999
<kim@comtec.co.jp> - after 1.Apr.1999
Replacement of dct36() with AMD's 3DNow! SIMD operations support
Syuuhei Kashiyama <squash@mb.kcom.ne.jp>
The author of this program disclaim whole expressed or implied
warranties with regard to this program, and in no event shall the
author of this program liable to whatever resulted from the use of
this program. Use it at your own risk.
*/
#include "mangle.h"
.globl ASM_NAME(dct36_3dnow)
/* .type ASM_NAME(dct36_3dnow),@function */
ASM_NAME(dct36_3dnow):
pushl %ebp
movl %esp,%ebp
subl $120,%esp
pushl %esi
pushl %ebx
movl 8(%ebp),%eax
movl 12(%ebp),%esi
movl 16(%ebp),%ecx
movl 20(%ebp),%edx
movl 24(%ebp),%ebx
leal -128(%ebp),%esp
femms
movq (%eax),%mm0
movq 4(%eax),%mm1
pfadd %mm1,%mm0
movq %mm0,4(%eax)
psrlq $32,%mm1
movq 12(%eax),%mm2
punpckldq %mm2,%mm1
pfadd %mm2,%mm1
movq %mm1,12(%eax)
psrlq $32,%mm2
movq 20(%eax),%mm3
punpckldq %mm3,%mm2
pfadd %mm3,%mm2
movq %mm2,20(%eax)
psrlq $32,%mm3
movq 28(%eax),%mm4
punpckldq %mm4,%mm3
pfadd %mm4,%mm3
movq %mm3,28(%eax)
psrlq $32,%mm4
movq 36(%eax),%mm5
punpckldq %mm5,%mm4
pfadd %mm5,%mm4
movq %mm4,36(%eax)
psrlq $32,%mm5
movq 44(%eax),%mm6
punpckldq %mm6,%mm5
pfadd %mm6,%mm5
movq %mm5,44(%eax)
psrlq $32,%mm6
movq 52(%eax),%mm7
punpckldq %mm7,%mm6
pfadd %mm7,%mm6
movq %mm6,52(%eax)
psrlq $32,%mm7
movq 60(%eax),%mm0
punpckldq %mm0,%mm7
pfadd %mm0,%mm7
movq %mm7,60(%eax)
psrlq $32,%mm0
movd 68(%eax),%mm1
pfadd %mm1,%mm0
movd %mm0,68(%eax)
movd 4(%eax),%mm0
movd 12(%eax),%mm1
punpckldq %mm1,%mm0
punpckldq 20(%eax),%mm1
pfadd %mm1,%mm0
movd %mm0,12(%eax)
psrlq $32,%mm0
movd %mm0,20(%eax)
psrlq $32,%mm1
movd 28(%eax),%mm2
punpckldq %mm2,%mm1
punpckldq 36(%eax),%mm2
pfadd %mm2,%mm1
movd %mm1,28(%eax)
psrlq $32,%mm1
movd %mm1,36(%eax)
psrlq $32,%mm2
movd 44(%eax),%mm3
punpckldq %mm3,%mm2
punpckldq 52(%eax),%mm3
pfadd %mm3,%mm2
movd %mm2,44(%eax)
psrlq $32,%mm2
movd %mm2,52(%eax)
psrlq $32,%mm3
movd 60(%eax),%mm4
punpckldq %mm4,%mm3
punpckldq 68(%eax),%mm4
pfadd %mm4,%mm3
movd %mm3,60(%eax)
psrlq $32,%mm3
movd %mm3,68(%eax)
movq 24(%eax),%mm0
movq 48(%eax),%mm1
movd ASM_NAME(COS9)+12,%mm2
punpckldq %mm2,%mm2
movd ASM_NAME(COS9)+24,%mm3
punpckldq %mm3,%mm3
pfmul %mm2,%mm0
pfmul %mm3,%mm1
pushl %eax
movl $1,%eax
movd %eax,%mm7
pi2fd %mm7,%mm7
popl %eax
movq 8(%eax),%mm2
movd ASM_NAME(COS9)+4,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfadd %mm0,%mm2
movq 40(%eax),%mm3
movd ASM_NAME(COS9)+20,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd ASM_NAME(COS9)+28,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd ASM_NAME(COS9)+8,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq 32(%eax),%mm4
movd ASM_NAME(COS9)+16,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd ASM_NAME(COS9)+32,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+0,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 108(%edx),%mm6
punpckldq 104(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,36(%ecx)
psrlq $32,%mm5
movd %mm5,32(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 32(%edx),%mm6
punpckldq 36(%edx),%mm6
pfmul %mm6,%mm5
movd 32(%esi),%mm6
punpckldq 36(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,1024(%ebx)
psrlq $32,%mm5
movd %mm5,1152(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+32,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 140(%edx),%mm6
punpckldq 72(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,68(%ecx)
psrlq $32,%mm5
movd %mm5,0(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 0(%edx),%mm6
punpckldq 68(%edx),%mm6
pfmul %mm6,%mm5
movd 0(%esi),%mm6
punpckldq 68(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,0(%ebx)
psrlq $32,%mm5
movd %mm5,2176(%ebx)
movq 8(%eax),%mm2
movq 40(%eax),%mm3
pfsub %mm3,%mm2
movq 56(%eax),%mm3
pfsub %mm3,%mm2
movd ASM_NAME(COS9)+12,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
movq 16(%eax),%mm3
movq 32(%eax),%mm4
pfsub %mm4,%mm3
movq 64(%eax),%mm4
pfsub %mm4,%mm3
movd ASM_NAME(COS9)+24,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
movq 48(%eax),%mm4
pfsub %mm4,%mm3
movq (%eax),%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+4,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 112(%edx),%mm6
punpckldq 100(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,40(%ecx)
psrlq $32,%mm5
movd %mm5,28(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 28(%edx),%mm6
punpckldq 40(%edx),%mm6
pfmul %mm6,%mm5
movd 28(%esi),%mm6
punpckldq 40(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,896(%ebx)
psrlq $32,%mm5
movd %mm5,1280(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+28,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 136(%edx),%mm6
punpckldq 76(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,64(%ecx)
psrlq $32,%mm5
movd %mm5,4(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 4(%edx),%mm6
punpckldq 64(%edx),%mm6
pfmul %mm6,%mm5
movd 4(%esi),%mm6
punpckldq 64(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,128(%ebx)
psrlq $32,%mm5
movd %mm5,2048(%ebx)
movq 8(%eax),%mm2
movd ASM_NAME(COS9)+20,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd ASM_NAME(COS9)+28,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq 56(%eax),%mm3
movd ASM_NAME(COS9)+4,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd ASM_NAME(COS9)+32,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd ASM_NAME(COS9)+8,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd ASM_NAME(COS9)+16,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+8,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 116(%edx),%mm6
punpckldq 96(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,44(%ecx)
psrlq $32,%mm5
movd %mm5,24(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 24(%edx),%mm6
punpckldq 44(%edx),%mm6
pfmul %mm6,%mm5
movd 24(%esi),%mm6
punpckldq 44(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,768(%ebx)
psrlq $32,%mm5
movd %mm5,1408(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+24,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 132(%edx),%mm6
punpckldq 80(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,60(%ecx)
psrlq $32,%mm5
movd %mm5,8(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 8(%edx),%mm6
punpckldq 60(%edx),%mm6
pfmul %mm6,%mm5
movd 8(%esi),%mm6
punpckldq 60(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,256(%ebx)
psrlq $32,%mm5
movd %mm5,1920(%ebx)
movq 8(%eax),%mm2
movd ASM_NAME(COS9)+28,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd ASM_NAME(COS9)+4,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd ASM_NAME(COS9)+20,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd ASM_NAME(COS9)+16,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd ASM_NAME(COS9)+32,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd ASM_NAME(COS9)+8,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+12,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 120(%edx),%mm6
punpckldq 92(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,48(%ecx)
psrlq $32,%mm5
movd %mm5,20(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 20(%edx),%mm6
punpckldq 48(%edx),%mm6
pfmul %mm6,%mm5
movd 20(%esi),%mm6
punpckldq 48(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,640(%ebx)
psrlq $32,%mm5
movd %mm5,1536(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+20,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 128(%edx),%mm6
punpckldq 84(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,56(%ecx)
psrlq $32,%mm5
movd %mm5,12(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 12(%edx),%mm6
punpckldq 56(%edx),%mm6
pfmul %mm6,%mm5
movd 12(%esi),%mm6
punpckldq 56(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,384(%ebx)
psrlq $32,%mm5
movd %mm5,1792(%ebx)
movq (%eax),%mm4
movq 16(%eax),%mm3
pfsub %mm3,%mm4
movq 32(%eax),%mm3
pfadd %mm3,%mm4
movq 48(%eax),%mm3
pfsub %mm3,%mm4
movq 64(%eax),%mm3
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+16,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 124(%edx),%mm6
punpckldq 88(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,52(%ecx)
psrlq $32,%mm5
movd %mm5,16(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 16(%edx),%mm6
punpckldq 52(%edx),%mm6
pfmul %mm6,%mm5
movd 16(%esi),%mm6
punpckldq 52(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,512(%ebx)
psrlq $32,%mm5
movd %mm5,1664(%ebx)
femms
popl %ebx
popl %esi
movl %ebp,%esp
popl %ebp
ret
NONEXEC_STACK

View File

@ -0,0 +1,512 @@
/*
dct36_3dnowext: extended 3DNow optimized DCT36
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
Transformed back into standalone asm, with help of
gcc -S -DHAVE_CONFIG_H -I. -march=k6-3 -O3 -Wall -pedantic -fno-strict-aliasing -DREAL_IS_FLOAT -c -o dct36_3dnowext.{S,c}
MPlayer comment follows.
*/
/*
* dct36_3dnow.c - 3DNow! optimized dct36()
*
* This code based 'dct36_3dnow.s' by Syuuhei Kashiyama
* <squash@mb.kcom.ne.jp>, only two types of changes have been made:
*
* - removed PREFETCH instruction for speedup
* - changed function name for support 3DNow! automatic detection
*
* You can find Kashiyama's original 3dnow! support patch
* (for mpg123-0.59o) at
* http://user.ecc.u-tokyo.ac.jp/~g810370/linux-simd/ (Japanese).
*
* by KIMURA Takuhiro <kim@hannah.ipc.miyakyo-u.ac.jp> - until 31.Mar.1999
* <kim@comtec.co.jp> - after 1.Apr.1999
*
* Modified for use with MPlayer, for details see the changelog at
* http://svn.mplayerhq.hu/mplayer/trunk/
* $Id: dct36_3dnow.c 18786 2006-06-22 13:34:00Z diego $
*
* Original disclaimer:
* The author of this program disclaim whole expressed or implied
* warranties with regard to this program, and in no event shall the
* author of this program liable to whatever resulted from the use of
* this program. Use it at your own risk.
*
* 2003/06/21: Moved to GCC inline assembly - Alex Beregszaszi
*/
#include "mangle.h"
.text
ALIGN32
.globl ASM_NAME(dct36_3dnowext)
/* .type ASM_NAME(dct36_3dnowext), @function */
ASM_NAME(dct36_3dnowext):
pushl %ebp
movl %esp, %ebp
pushl %esi
pushl %ebx
movl 8(%ebp), %eax
movl 12(%ebp), %esi
movl 16(%ebp), %ecx
movl 20(%ebp), %edx
movl 24(%ebp), %ebx
/* APP */
movq (%eax),%mm0
movq 4(%eax),%mm1
pfadd %mm1,%mm0
movq %mm0,4(%eax)
psrlq $32,%mm1
movq 12(%eax),%mm2
punpckldq %mm2,%mm1
pfadd %mm2,%mm1
movq %mm1,12(%eax)
psrlq $32,%mm2
movq 20(%eax),%mm3
punpckldq %mm3,%mm2
pfadd %mm3,%mm2
movq %mm2,20(%eax)
psrlq $32,%mm3
movq 28(%eax),%mm4
punpckldq %mm4,%mm3
pfadd %mm4,%mm3
movq %mm3,28(%eax)
psrlq $32,%mm4
movq 36(%eax),%mm5
punpckldq %mm5,%mm4
pfadd %mm5,%mm4
movq %mm4,36(%eax)
psrlq $32,%mm5
movq 44(%eax),%mm6
punpckldq %mm6,%mm5
pfadd %mm6,%mm5
movq %mm5,44(%eax)
psrlq $32,%mm6
movq 52(%eax),%mm7
punpckldq %mm7,%mm6
pfadd %mm7,%mm6
movq %mm6,52(%eax)
psrlq $32,%mm7
movq 60(%eax),%mm0
punpckldq %mm0,%mm7
pfadd %mm0,%mm7
movq %mm7,60(%eax)
psrlq $32,%mm0
movd 68(%eax),%mm1
pfadd %mm1,%mm0
movd %mm0,68(%eax)
movd 4(%eax),%mm0
movd 12(%eax),%mm1
punpckldq %mm1,%mm0
punpckldq 20(%eax),%mm1
pfadd %mm1,%mm0
movd %mm0,12(%eax)
psrlq $32,%mm0
movd %mm0,20(%eax)
psrlq $32,%mm1
movd 28(%eax),%mm2
punpckldq %mm2,%mm1
punpckldq 36(%eax),%mm2
pfadd %mm2,%mm1
movd %mm1,28(%eax)
psrlq $32,%mm1
movd %mm1,36(%eax)
psrlq $32,%mm2
movd 44(%eax),%mm3
punpckldq %mm3,%mm2
punpckldq 52(%eax),%mm3
pfadd %mm3,%mm2
movd %mm2,44(%eax)
psrlq $32,%mm2
movd %mm2,52(%eax)
psrlq $32,%mm3
movd 60(%eax),%mm4
punpckldq %mm4,%mm3
punpckldq 68(%eax),%mm4
pfadd %mm4,%mm3
movd %mm3,60(%eax)
psrlq $32,%mm3
movd %mm3,68(%eax)
movq 24(%eax),%mm0
movq 48(%eax),%mm1
movd ASM_NAME(COS9)+12,%mm2
punpckldq %mm2,%mm2
movd ASM_NAME(COS9)+24,%mm3
punpckldq %mm3,%mm3
pfmul %mm2,%mm0
pfmul %mm3,%mm1
pushl %eax
movl $1,%eax
movd %eax,%mm7
pi2fd %mm7,%mm7
popl %eax
movq 8(%eax),%mm2
movd ASM_NAME(COS9)+4,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfadd %mm0,%mm2
movq 40(%eax),%mm3
movd ASM_NAME(COS9)+20,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd ASM_NAME(COS9)+28,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd ASM_NAME(COS9)+8,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq 32(%eax),%mm4
movd ASM_NAME(COS9)+16,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd ASM_NAME(COS9)+32,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+0,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 108(%edx),%mm6
punpckldq 104(%edx),%mm6
pfmul %mm6,%mm5
pswapd %mm5,%mm5
movq %mm5,32(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 32(%edx),%mm6
punpckldq 36(%edx),%mm6
pfmul %mm6,%mm5
movd 32(%esi),%mm6
punpckldq 36(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,1024(%ebx)
psrlq $32,%mm5
movd %mm5,1152(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+32,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 140(%edx),%mm6
punpckldq 72(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,68(%ecx)
psrlq $32,%mm5
movd %mm5,0(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 0(%edx),%mm6
punpckldq 68(%edx),%mm6
pfmul %mm6,%mm5
movd 0(%esi),%mm6
punpckldq 68(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,0(%ebx)
psrlq $32,%mm5
movd %mm5,2176(%ebx)
movq 8(%eax),%mm2
movq 40(%eax),%mm3
pfsub %mm3,%mm2
movq 56(%eax),%mm3
pfsub %mm3,%mm2
movd ASM_NAME(COS9)+12,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
movq 16(%eax),%mm3
movq 32(%eax),%mm4
pfsub %mm4,%mm3
movq 64(%eax),%mm4
pfsub %mm4,%mm3
movd ASM_NAME(COS9)+24,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
movq 48(%eax),%mm4
pfsub %mm4,%mm3
movq (%eax),%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+4,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 112(%edx),%mm6
punpckldq 100(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,40(%ecx)
psrlq $32,%mm5
movd %mm5,28(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 28(%edx),%mm6
punpckldq 40(%edx),%mm6
pfmul %mm6,%mm5
movd 28(%esi),%mm6
punpckldq 40(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,896(%ebx)
psrlq $32,%mm5
movd %mm5,1280(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+28,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 136(%edx),%mm6
punpckldq 76(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,64(%ecx)
psrlq $32,%mm5
movd %mm5,4(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 4(%edx),%mm6
punpckldq 64(%edx),%mm6
pfmul %mm6,%mm5
movd 4(%esi),%mm6
punpckldq 64(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,128(%ebx)
psrlq $32,%mm5
movd %mm5,2048(%ebx)
movq 8(%eax),%mm2
movd ASM_NAME(COS9)+20,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd ASM_NAME(COS9)+28,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq 56(%eax),%mm3
movd ASM_NAME(COS9)+4,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd ASM_NAME(COS9)+32,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd ASM_NAME(COS9)+8,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd ASM_NAME(COS9)+16,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+8,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 116(%edx),%mm6
punpckldq 96(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,44(%ecx)
psrlq $32,%mm5
movd %mm5,24(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 24(%edx),%mm6
punpckldq 44(%edx),%mm6
pfmul %mm6,%mm5
movd 24(%esi),%mm6
punpckldq 44(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,768(%ebx)
psrlq $32,%mm5
movd %mm5,1408(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+24,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 132(%edx),%mm6
punpckldq 80(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,60(%ecx)
psrlq $32,%mm5
movd %mm5,8(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 8(%edx),%mm6
punpckldq 60(%edx),%mm6
pfmul %mm6,%mm5
movd 8(%esi),%mm6
punpckldq 60(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,256(%ebx)
psrlq $32,%mm5
movd %mm5,1920(%ebx)
movq 8(%eax),%mm2
movd ASM_NAME(COS9)+28,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd ASM_NAME(COS9)+4,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd ASM_NAME(COS9)+20,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd ASM_NAME(COS9)+16,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd ASM_NAME(COS9)+32,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd ASM_NAME(COS9)+8,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+12,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 120(%edx),%mm6
punpckldq 92(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,48(%ecx)
psrlq $32,%mm5
movd %mm5,20(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 20(%edx),%mm6
punpckldq 48(%edx),%mm6
pfmul %mm6,%mm5
movd 20(%esi),%mm6
punpckldq 48(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,640(%ebx)
psrlq $32,%mm5
movd %mm5,1536(%ebx)
movq %mm3,%mm4
pfsub %mm2,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+20,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 128(%edx),%mm6
punpckldq 84(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,56(%ecx)
psrlq $32,%mm5
movd %mm5,12(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 12(%edx),%mm6
punpckldq 56(%edx),%mm6
pfmul %mm6,%mm5
movd 12(%esi),%mm6
punpckldq 56(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,384(%ebx)
psrlq $32,%mm5
movd %mm5,1792(%ebx)
movq (%eax),%mm4
movq 16(%eax),%mm3
pfsub %mm3,%mm4
movq 32(%eax),%mm3
pfadd %mm3,%mm4
movq 48(%eax),%mm3
pfsub %mm3,%mm4
movq 64(%eax),%mm3
pfadd %mm3,%mm4
movq %mm7,%mm5
punpckldq ASM_NAME(tfcos36)+16,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 124(%edx),%mm6
punpckldq 88(%edx),%mm6
pfmul %mm6,%mm5
movd %mm5,52(%ecx)
psrlq $32,%mm5
movd %mm5,16(%ecx)
movq %mm4,%mm6
punpckldq %mm6,%mm5
pfsub %mm6,%mm5
punpckhdq %mm5,%mm5
movd 16(%edx),%mm6
punpckldq 52(%edx),%mm6
pfmul %mm6,%mm5
movd 16(%esi),%mm6
punpckldq 52(%esi),%mm6
pfadd %mm6,%mm5
movd %mm5,512(%ebx)
psrlq $32,%mm5
movd %mm5,1664(%ebx)
femms
/* NO_APP */
popl %ebx
popl %esi
leave
ret
/* .size ASM_NAME(dct36_3dnowext), .-ASM_NAME(dct36_3dnowext) */
NONEXEC_STACK

View File

@ -0,0 +1,712 @@
/*
dct64_3dnow.s: Replacement of dct64() with AMD's 3DNow! SIMD operations support
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Syuuhei Kashiyama
Original "license" statement:
The author of this program disclaim whole expressed or implied
warranties with regard to this program, and in no event shall the
author of this program liable to whatever resulted from the use of
this program. Use it at your own risk.
*/
#include "mangle.h"
.globl ASM_NAME(dct64_3dnow)
/* .type ASM_NAME(dct64_3dnow),@function */
ASM_NAME(dct64_3dnow):
subl $256,%esp
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
leal 16(%esp),%ebx
movl 284(%esp),%edi
movl 276(%esp),%ebp
movl 280(%esp),%edx
leal 128(%ebx),%esi
/* femms */
/* 1 */
movl ASM_NAME(pnts),%eax
movq 0(%edi),%mm0
movq %mm0,%mm1
movd 124(%edi),%mm2
punpckldq 120(%edi),%mm2
movq 0(%eax),%mm3
pfadd %mm2,%mm0
movq %mm0,0(%ebx)
pfsub %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,124(%ebx)
psrlq $32,%mm1
movd %mm1,120(%ebx)
movq 8(%edi),%mm4
movq %mm4,%mm5
movd 116(%edi),%mm6
punpckldq 112(%edi),%mm6
movq 8(%eax),%mm7
pfadd %mm6,%mm4
movq %mm4,8(%ebx)
pfsub %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,116(%ebx)
psrlq $32,%mm5
movd %mm5,112(%ebx)
movq 16(%edi),%mm0
movq %mm0,%mm1
movd 108(%edi),%mm2
punpckldq 104(%edi),%mm2
movq 16(%eax),%mm3
pfadd %mm2,%mm0
movq %mm0,16(%ebx)
pfsub %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,108(%ebx)
psrlq $32,%mm1
movd %mm1,104(%ebx)
movq 24(%edi),%mm4
movq %mm4,%mm5
movd 100(%edi),%mm6
punpckldq 96(%edi),%mm6
movq 24(%eax),%mm7
pfadd %mm6,%mm4
movq %mm4,24(%ebx)
pfsub %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,100(%ebx)
psrlq $32,%mm5
movd %mm5,96(%ebx)
movq 32(%edi),%mm0
movq %mm0,%mm1
movd 92(%edi),%mm2
punpckldq 88(%edi),%mm2
movq 32(%eax),%mm3
pfadd %mm2,%mm0
movq %mm0,32(%ebx)
pfsub %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,92(%ebx)
psrlq $32,%mm1
movd %mm1,88(%ebx)
movq 40(%edi),%mm4
movq %mm4,%mm5
movd 84(%edi),%mm6
punpckldq 80(%edi),%mm6
movq 40(%eax),%mm7
pfadd %mm6,%mm4
movq %mm4,40(%ebx)
pfsub %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,84(%ebx)
psrlq $32,%mm5
movd %mm5,80(%ebx)
movq 48(%edi),%mm0
movq %mm0,%mm1
movd 76(%edi),%mm2
punpckldq 72(%edi),%mm2
movq 48(%eax),%mm3
pfadd %mm2,%mm0
movq %mm0,48(%ebx)
pfsub %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,76(%ebx)
psrlq $32,%mm1
movd %mm1,72(%ebx)
movq 56(%edi),%mm4
movq %mm4,%mm5
movd 68(%edi),%mm6
punpckldq 64(%edi),%mm6
movq 56(%eax),%mm7
pfadd %mm6,%mm4
movq %mm4,56(%ebx)
pfsub %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,68(%ebx)
psrlq $32,%mm5
movd %mm5,64(%ebx)
/* 2 */
movl ASM_NAME(pnts)+4,%eax
/* 0,14 */
movq 0(%ebx),%mm0
movq %mm0,%mm1
movd 60(%ebx),%mm2
punpckldq 56(%ebx),%mm2
movq 0(%eax),%mm3
pfadd %mm2,%mm0
movq %mm0,0(%esi)
pfsub %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,60(%esi)
psrlq $32,%mm1
movd %mm1,56(%esi)
/* 16,30 */
movq 64(%ebx),%mm0
movq %mm0,%mm1
movd 124(%ebx),%mm2
punpckldq 120(%ebx),%mm2
pfadd %mm2,%mm0
movq %mm0,64(%esi)
pfsubr %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,124(%esi)
psrlq $32,%mm1
movd %mm1,120(%esi)
/* 2,12 */
movq 8(%ebx),%mm4
movq %mm4,%mm5
movd 52(%ebx),%mm6
punpckldq 48(%ebx),%mm6
movq 8(%eax),%mm7
pfadd %mm6,%mm4
movq %mm4,8(%esi)
pfsub %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,52(%esi)
psrlq $32,%mm5
movd %mm5,48(%esi)
/* 18,28 */
movq 72(%ebx),%mm4
movq %mm4,%mm5
movd 116(%ebx),%mm6
punpckldq 112(%ebx),%mm6
pfadd %mm6,%mm4
movq %mm4,72(%esi)
pfsubr %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,116(%esi)
psrlq $32,%mm5
movd %mm5,112(%esi)
/* 4,10 */
movq 16(%ebx),%mm0
movq %mm0,%mm1
movd 44(%ebx),%mm2
punpckldq 40(%ebx),%mm2
movq 16(%eax),%mm3
pfadd %mm2,%mm0
movq %mm0,16(%esi)
pfsub %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,44(%esi)
psrlq $32,%mm1
movd %mm1,40(%esi)
/* 20,26 */
movq 80(%ebx),%mm0
movq %mm0,%mm1
movd 108(%ebx),%mm2
punpckldq 104(%ebx),%mm2
pfadd %mm2,%mm0
movq %mm0,80(%esi)
pfsubr %mm2,%mm1
pfmul %mm3,%mm1
movd %mm1,108(%esi)
psrlq $32,%mm1
movd %mm1,104(%esi)
/* 6,8 */
movq 24(%ebx),%mm4
movq %mm4,%mm5
movd 36(%ebx),%mm6
punpckldq 32(%ebx),%mm6
movq 24(%eax),%mm7
pfadd %mm6,%mm4
movq %mm4,24(%esi)
pfsub %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,36(%esi)
psrlq $32,%mm5
movd %mm5,32(%esi)
/* 22,24 */
movq 88(%ebx),%mm4
movq %mm4,%mm5
movd 100(%ebx),%mm6
punpckldq 96(%ebx),%mm6
pfadd %mm6,%mm4
movq %mm4,88(%esi)
pfsubr %mm6,%mm5
pfmul %mm7,%mm5
movd %mm5,100(%esi)
psrlq $32,%mm5
movd %mm5,96(%esi)
/* 3 */
movl ASM_NAME(pnts)+8,%eax
movq 0(%eax),%mm0
movq 8(%eax),%mm1
/* 0,6 */
movq 0(%esi),%mm2
movq %mm2,%mm3
movd 28(%esi),%mm4
punpckldq 24(%esi),%mm4
pfadd %mm4,%mm2
pfsub %mm4,%mm3
pfmul %mm0,%mm3
movq %mm2,0(%ebx)
movd %mm3,28(%ebx)
psrlq $32,%mm3
movd %mm3,24(%ebx)
/* 2,4 */
movq 8(%esi),%mm5
movq %mm5,%mm6
movd 20(%esi),%mm7
punpckldq 16(%esi),%mm7
pfadd %mm7,%mm5
pfsub %mm7,%mm6
pfmul %mm1,%mm6
movq %mm5,8(%ebx)
movd %mm6,20(%ebx)
psrlq $32,%mm6
movd %mm6,16(%ebx)
/* 8,14 */
movq 32(%esi),%mm2
movq %mm2,%mm3
movd 60(%esi),%mm4
punpckldq 56(%esi),%mm4
pfadd %mm4,%mm2
pfsubr %mm4,%mm3
pfmul %mm0,%mm3
movq %mm2,32(%ebx)
movd %mm3,60(%ebx)
psrlq $32,%mm3
movd %mm3,56(%ebx)
/* 10,12 */
movq 40(%esi),%mm5
movq %mm5,%mm6
movd 52(%esi),%mm7
punpckldq 48(%esi),%mm7
pfadd %mm7,%mm5
pfsubr %mm7,%mm6
pfmul %mm1,%mm6
movq %mm5,40(%ebx)
movd %mm6,52(%ebx)
psrlq $32,%mm6
movd %mm6,48(%ebx)
/* 16,22 */
movq 64(%esi),%mm2
movq %mm2,%mm3
movd 92(%esi),%mm4
punpckldq 88(%esi),%mm4
pfadd %mm4,%mm2
pfsub %mm4,%mm3
pfmul %mm0,%mm3
movq %mm2,64(%ebx)
movd %mm3,92(%ebx)
psrlq $32,%mm3
movd %mm3,88(%ebx)
/* 18,20 */
movq 72(%esi),%mm5
movq %mm5,%mm6
movd 84(%esi),%mm7
punpckldq 80(%esi),%mm7
pfadd %mm7,%mm5
pfsub %mm7,%mm6
pfmul %mm1,%mm6
movq %mm5,72(%ebx)
movd %mm6,84(%ebx)
psrlq $32,%mm6
movd %mm6,80(%ebx)
/* 24,30 */
movq 96(%esi),%mm2
movq %mm2,%mm3
movd 124(%esi),%mm4
punpckldq 120(%esi),%mm4
pfadd %mm4,%mm2
pfsubr %mm4,%mm3
pfmul %mm0,%mm3
movq %mm2,96(%ebx)
movd %mm3,124(%ebx)
psrlq $32,%mm3
movd %mm3,120(%ebx)
/* 26,28 */
movq 104(%esi),%mm5
movq %mm5,%mm6
movd 116(%esi),%mm7
punpckldq 112(%esi),%mm7
pfadd %mm7,%mm5
pfsubr %mm7,%mm6
pfmul %mm1,%mm6
movq %mm5,104(%ebx)
movd %mm6,116(%ebx)
psrlq $32,%mm6
movd %mm6,112(%ebx)
/* 4 */
movl ASM_NAME(pnts)+12,%eax
movq 0(%eax),%mm0
/* 0 */
movq 0(%ebx),%mm1
movq %mm1,%mm2
movd 12(%ebx),%mm3
punpckldq 8(%ebx),%mm3
pfadd %mm3,%mm1
pfsub %mm3,%mm2
pfmul %mm0,%mm2
movq %mm1,0(%esi)
movd %mm2,12(%esi)
psrlq $32,%mm2
movd %mm2,8(%esi)
/* 4 */
movq 16(%ebx),%mm4
movq %mm4,%mm5
movd 28(%ebx),%mm6
punpckldq 24(%ebx),%mm6
pfadd %mm6,%mm4
pfsubr %mm6,%mm5
pfmul %mm0,%mm5
movq %mm4,16(%esi)
movd %mm5,28(%esi)
psrlq $32,%mm5
movd %mm5,24(%esi)
/* 8 */
movq 32(%ebx),%mm1
movq %mm1,%mm2
movd 44(%ebx),%mm3
punpckldq 40(%ebx),%mm3
pfadd %mm3,%mm1
pfsub %mm3,%mm2
pfmul %mm0,%mm2
movq %mm1,32(%esi)
movd %mm2,44(%esi)
psrlq $32,%mm2
movd %mm2,40(%esi)
/* 12 */
movq 48(%ebx),%mm4
movq %mm4,%mm5
movd 60(%ebx),%mm6
punpckldq 56(%ebx),%mm6
pfadd %mm6,%mm4
pfsubr %mm6,%mm5
pfmul %mm0,%mm5
movq %mm4,48(%esi)
movd %mm5,60(%esi)
psrlq $32,%mm5
movd %mm5,56(%esi)
/* 16 */
movq 64(%ebx),%mm1
movq %mm1,%mm2
movd 76(%ebx),%mm3
punpckldq 72(%ebx),%mm3
pfadd %mm3,%mm1
pfsub %mm3,%mm2
pfmul %mm0,%mm2
movq %mm1,64(%esi)
movd %mm2,76(%esi)
psrlq $32,%mm2
movd %mm2,72(%esi)
/* 20 */
movq 80(%ebx),%mm4
movq %mm4,%mm5
movd 92(%ebx),%mm6
punpckldq 88(%ebx),%mm6
pfadd %mm6,%mm4
pfsubr %mm6,%mm5
pfmul %mm0,%mm5
movq %mm4,80(%esi)
movd %mm5,92(%esi)
psrlq $32,%mm5
movd %mm5,88(%esi)
/* 24 */
movq 96(%ebx),%mm1
movq %mm1,%mm2
movd 108(%ebx),%mm3
punpckldq 104(%ebx),%mm3
pfadd %mm3,%mm1
pfsub %mm3,%mm2
pfmul %mm0,%mm2
movq %mm1,96(%esi)
movd %mm2,108(%esi)
psrlq $32,%mm2
movd %mm2,104(%esi)
/* 28 */
movq 112(%ebx),%mm4
movq %mm4,%mm5
movd 124(%ebx),%mm6
punpckldq 120(%ebx),%mm6
pfadd %mm6,%mm4
pfsubr %mm6,%mm5
pfmul %mm0,%mm5
movq %mm4,112(%esi)
movd %mm5,124(%esi)
psrlq $32,%mm5
movd %mm5,120(%esi)
/* 5 */
movl $-1,%eax
movd %eax,%mm1
movl $1,%eax
/* L | H */
movd %eax,%mm0
punpckldq %mm1,%mm0
/* 1.0 | -1.0 */
pi2fd %mm0,%mm0
movd %eax,%mm1
pi2fd %mm1,%mm1
movl ASM_NAME(pnts)+16,%eax
movd 0(%eax),%mm2
/* 1.0 | cos0 */
punpckldq %mm2,%mm1
/* 0 */
movq 0(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq %mm2,0(%ebx)
movq 8(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm4,8(%ebx)
/* 4 */
movq 16(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq 24(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm2,%mm3
psrlq $32,%mm3
pfadd %mm4,%mm2
pfadd %mm3,%mm4
movq %mm2,16(%ebx)
movq %mm4,24(%ebx)
/* 8 */
movq 32(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq %mm2,32(%ebx)
movq 40(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm4,40(%ebx)
/* 12 */
movq 48(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq 56(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm2,%mm3
psrlq $32,%mm3
pfadd %mm4,%mm2
pfadd %mm3,%mm4
movq %mm2,48(%ebx)
movq %mm4,56(%ebx)
/* 16 */
movq 64(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq %mm2,64(%ebx)
movq 72(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm4,72(%ebx)
/* 20 */
movq 80(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq 88(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm2,%mm3
psrlq $32,%mm3
pfadd %mm4,%mm2
pfadd %mm3,%mm4
movq %mm2,80(%ebx)
movq %mm4,88(%ebx)
/* 24 */
movq 96(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq %mm2,96(%ebx)
movq 104(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm4,104(%ebx)
/* 28 */
movq 112(%esi),%mm2
movq %mm2,%mm3
pfmul %mm0,%mm3
pfacc %mm3,%mm2
pfmul %mm1,%mm2
movq 120(%esi),%mm4
movq %mm4,%mm5
pfmul %mm0,%mm5
pfacc %mm5,%mm4
pfmul %mm0,%mm4
pfmul %mm1,%mm4
movq %mm4,%mm5
psrlq $32,%mm5
pfacc %mm5,%mm4
movq %mm2,%mm3
psrlq $32,%mm3
pfadd %mm4,%mm2
pfadd %mm3,%mm4
movq %mm2,112(%ebx)
movq %mm4,120(%ebx)
/* Phase6 */
movl 0(%ebx),%eax
movl %eax,1024(%ebp)
movl 4(%ebx),%eax
movl %eax,0(%ebp)
movl %eax,0(%edx)
movl 8(%ebx),%eax
movl %eax,512(%ebp)
movl 12(%ebx),%eax
movl %eax,512(%edx)
movl 16(%ebx),%eax
movl %eax,768(%ebp)
movl 20(%ebx),%eax
movl %eax,256(%edx)
movl 24(%ebx),%eax
movl %eax,256(%ebp)
movl 28(%ebx),%eax
movl %eax,768(%edx)
movq 32(%ebx),%mm0
movq 48(%ebx),%mm1
pfadd %mm1,%mm0
movd %mm0,896(%ebp)
psrlq $32,%mm0
movd %mm0,128(%edx)
movq 40(%ebx),%mm2
pfadd %mm2,%mm1
movd %mm1,640(%ebp)
psrlq $32,%mm1
movd %mm1,384(%edx)
movq 56(%ebx),%mm3
pfadd %mm3,%mm2
movd %mm2,384(%ebp)
psrlq $32,%mm2
movd %mm2,640(%edx)
movd 36(%ebx),%mm4
pfadd %mm4,%mm3
movd %mm3,128(%ebp)
psrlq $32,%mm3
movd %mm3,896(%edx)
movq 96(%ebx),%mm0
movq 64(%ebx),%mm1
movq 112(%ebx),%mm2
pfadd %mm2,%mm0
movq %mm0,%mm3
pfadd %mm1,%mm3
movd %mm3,960(%ebp)
psrlq $32,%mm3
movd %mm3,64(%edx)
movq 80(%ebx),%mm1
pfadd %mm1,%mm0
movd %mm0,832(%ebp)
psrlq $32,%mm0
movd %mm0,192(%edx)
movq 104(%ebx),%mm3
pfadd %mm3,%mm2
movq %mm2,%mm4
pfadd %mm1,%mm4
movd %mm4,704(%ebp)
psrlq $32,%mm4
movd %mm4,320(%edx)
movq 72(%ebx),%mm1
pfadd %mm1,%mm2
movd %mm2,576(%ebp)
psrlq $32,%mm2
movd %mm2,448(%edx)
movq 120(%ebx),%mm4
pfadd %mm4,%mm3
movq %mm3,%mm5
pfadd %mm1,%mm5
movd %mm5,448(%ebp)
psrlq $32,%mm5
movd %mm5,576(%edx)
movq 88(%ebx),%mm1
pfadd %mm1,%mm3
movd %mm3,320(%ebp)
psrlq $32,%mm3
movd %mm3,704(%edx)
movd 100(%ebx),%mm5
pfadd %mm5,%mm4
movq %mm4,%mm6
pfadd %mm1,%mm6
movd %mm6,192(%ebp)
psrlq $32,%mm6
movd %mm6,832(%edx)
movd 68(%ebx),%mm1
pfadd %mm1,%mm4
movd %mm4,64(%ebp)
psrlq $32,%mm4
movd %mm4,960(%edx)
/* femms */
popl %ebx
popl %esi
popl %edi
popl %ebp
addl $256,%esp
ret
NONEXEC_STACK

View File

@ -0,0 +1,714 @@
/*
dct64_3dnowext: extended 3DNow optimized DCT64
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
Transformed back into standalone asm, with help of
gcc -S -DHAVE_CONFIG_H -I. -march=k6-3 -O3 -Wall -pedantic -fno-strict-aliasing -DREAL_IS_FLOAT -c -o dct64_3dnowext.{S,c}
MPlayer comment follows.
*/
/*
* This code was taken from http://www.mpg123.org
* See ChangeLog of mpg123-0.59s-pre.1 for detail
* Applied to mplayer by Nick Kurshev <nickols_k@mail.ru>
* Partial 3dnowex-DSP! optimization by Nick Kurshev
*
* TODO: optimize scalar 3dnow! code
* Warning: Phases 7 & 8 are not tested
*/
#include "mangle.h"
.data
ALIGN4
/* .type plus_1f, @object
.size plus_1f, 4 */
plus_1f:
.long 1065353216
ALIGN8
/* .type x_plus_minus_3dnow, @object
.size x_plus_minus_3dnow, 8 */
x_plus_minus_3dnow:
.long 0
.long -2147483648
.text
ALIGN32
.globl ASM_NAME(dct64_3dnowext)
/* .type ASM_NAME(dct64_3dnowext), @function */
ASM_NAME(dct64_3dnowext):
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $256, %esp
/* APP */
movl 16(%ebp),%eax
leal 128+-268(%ebp),%edx
movl 8(%ebp),%esi
movl 12(%ebp),%edi
movl ASM_VALUE(costab_mmxsse),%ebx
leal -268(%ebp),%ecx
movq (%eax), %mm0
movq 8(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 120(%eax), %mm1
pswapd 112(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%edx)
movq %mm4, 8(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul (%ebx), %mm3
pfmul 8(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 120(%edx)
movq %mm7, 112(%edx)
movq 16(%eax), %mm0
movq 24(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 104(%eax), %mm1
pswapd 96(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 16(%edx)
movq %mm4, 24(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 16(%ebx), %mm3
pfmul 24(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 104(%edx)
movq %mm7, 96(%edx)
movq 32(%eax), %mm0
movq 40(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 88(%eax), %mm1
pswapd 80(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 32(%edx)
movq %mm4, 40(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 32(%ebx), %mm3
pfmul 40(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 88(%edx)
movq %mm7, 80(%edx)
movq 48(%eax), %mm0
movq 56(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 72(%eax), %mm1
pswapd 64(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 48(%edx)
movq %mm4, 56(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 48(%ebx), %mm3
pfmul 56(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 72(%edx)
movq %mm7, 64(%edx)
movq (%edx), %mm0
movq 8(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 56(%edx), %mm1
pswapd 48(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%ecx)
movq %mm4, 8(%ecx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 64(%ebx), %mm3
pfmul 72(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 56(%ecx)
movq %mm7, 48(%ecx)
movq 16(%edx), %mm0
movq 24(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 40(%edx), %mm1
pswapd 32(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 16(%ecx)
movq %mm4, 24(%ecx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 80(%ebx), %mm3
pfmul 88(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 40(%ecx)
movq %mm7, 32(%ecx)
movq 64(%edx), %mm0
movq 72(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 120(%edx), %mm1
pswapd 112(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 64(%ecx)
movq %mm4, 72(%ecx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul 64(%ebx), %mm3
pfmul 72(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 120(%ecx)
movq %mm7, 112(%ecx)
movq 80(%edx), %mm0
movq 88(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 104(%edx), %mm1
pswapd 96(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 80(%ecx)
movq %mm4, 88(%ecx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul 80(%ebx), %mm3
pfmul 88(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 104(%ecx)
movq %mm7, 96(%ecx)
movq 96(%ebx), %mm2
movq 104(%ebx), %mm6
movq (%ecx), %mm0
movq 8(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 24(%ecx), %mm1
pswapd 16(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%edx)
movq %mm4, 8(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 24(%edx)
movq %mm7, 16(%edx)
movq 32(%ecx), %mm0
movq 40(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 56(%ecx), %mm1
pswapd 48(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 32(%edx)
movq %mm4, 40(%edx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 56(%edx)
movq %mm7, 48(%edx)
movq 64(%ecx), %mm0
movq 72(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 88(%ecx), %mm1
pswapd 80(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 64(%edx)
movq %mm4, 72(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 88(%edx)
movq %mm7, 80(%edx)
movq 96(%ecx), %mm0
movq 104(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 120(%ecx), %mm1
pswapd 112(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 96(%edx)
movq %mm4, 104(%edx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 120(%edx)
movq %mm7, 112(%edx)
movq 112(%ebx), %mm2
movq (%edx), %mm0
movq 16(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 8(%edx), %mm1
pswapd 24(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%ecx)
movq %mm4, 16(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 8(%ecx)
movq %mm7, 24(%ecx)
movq 32(%edx), %mm0
movq 48(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 40(%edx), %mm1
pswapd 56(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 32(%ecx)
movq %mm4, 48(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 40(%ecx)
movq %mm7, 56(%ecx)
movq 64(%edx), %mm0
movq 80(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 72(%edx), %mm1
pswapd 88(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 64(%ecx)
movq %mm4, 80(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 72(%ecx)
movq %mm7, 88(%ecx)
movq 96(%edx), %mm0
movq 112(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 104(%edx), %mm1
pswapd 120(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 96(%ecx)
movq %mm4, 112(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 104(%ecx)
movq %mm7, 120(%ecx)
movd plus_1f, %mm6
punpckldq 120(%ebx), %mm6
movq x_plus_minus_3dnow, %mm7
movq 32(%ecx), %mm0
movq 64(%ecx), %mm2
movq %mm0, %mm1
movq %mm2, %mm3
pxor %mm7, %mm1
pxor %mm7, %mm3
pfacc %mm1, %mm0
pfacc %mm3, %mm2
pfmul %mm6, %mm0
pfmul %mm6, %mm2
movq %mm0, 32(%edx)
movq %mm2, 64(%edx)
movd 44(%ecx), %mm0
movd 40(%ecx), %mm2
movd 120(%ebx), %mm3
punpckldq 76(%ecx), %mm0
punpckldq 72(%ecx), %mm2
punpckldq %mm3, %mm3
movq %mm0, %mm4
movq %mm2, %mm5
pfsub %mm2, %mm0
pfmul %mm3, %mm0
movq %mm0, %mm1
pfadd %mm5, %mm0
pfadd %mm4, %mm0
movq %mm0, %mm2
punpckldq %mm1, %mm0
punpckhdq %mm1, %mm2
movq %mm0, 40(%edx)
movq %mm2, 72(%edx)
movd 48(%ecx), %mm3
movd 60(%ecx), %mm2
pfsub 52(%ecx), %mm3
pfsub 56(%ecx), %mm2
pfmul 120(%ebx), %mm3
pfmul 120(%ebx), %mm2
movq %mm2, %mm1
pfadd 56(%ecx), %mm1
pfadd 60(%ecx), %mm1
movq %mm1, %mm0
pfadd 48(%ecx), %mm0
pfadd 52(%ecx), %mm0
pfadd %mm3, %mm1
punpckldq %mm2, %mm1
pfadd %mm3, %mm2
punpckldq %mm2, %mm0
movq %mm1, 56(%edx)
movq %mm0, 48(%edx)
movd 92(%ecx), %mm1
pfsub 88(%ecx), %mm1
pfmul 120(%ebx), %mm1
movd %mm1, 92(%edx)
pfadd 92(%ecx), %mm1
pfadd 88(%ecx), %mm1
movq %mm1, %mm0
pfadd 80(%ecx), %mm0
pfadd 84(%ecx), %mm0
movd %mm0, 80(%edx)
movd 80(%ecx), %mm0
pfsub 84(%ecx), %mm0
pfmul 120(%ebx), %mm0
pfadd %mm0, %mm1
pfadd 92(%edx), %mm0
punpckldq %mm1, %mm0
movq %mm0, 84(%edx)
movq 96(%ecx), %mm0
movq %mm0, %mm1
pxor %mm7, %mm1
pfacc %mm1, %mm0
pfmul %mm6, %mm0
movq %mm0, 96(%edx)
movd 108(%ecx), %mm0
pfsub 104(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, 108(%edx)
pfadd 104(%ecx), %mm0
pfadd 108(%ecx), %mm0
movd %mm0, 104(%edx)
movd 124(%ecx), %mm1
pfsub 120(%ecx), %mm1
pfmul 120(%ebx), %mm1
movd %mm1, 124(%edx)
pfadd 120(%ecx), %mm1
pfadd 124(%ecx), %mm1
movq %mm1, %mm0
pfadd 112(%ecx), %mm0
pfadd 116(%ecx), %mm0
movd %mm0, 112(%edx)
movd 112(%ecx), %mm0
pfsub 116(%ecx), %mm0
pfmul 120(%ebx), %mm0
pfadd %mm0,%mm1
pfadd 124(%edx), %mm0
punpckldq %mm1, %mm0
movq %mm0, 116(%edx)
jnz .L01
movd (%ecx), %mm0
pfadd 4(%ecx), %mm0
movd %mm0, 1024(%esi)
movd (%ecx), %mm0
pfsub 4(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, (%esi)
movd %mm0, (%edi)
movd 12(%ecx), %mm0
pfsub 8(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, 512(%edi)
pfadd 12(%ecx), %mm0
pfadd 8(%ecx), %mm0
movd %mm0, 512(%esi)
movd 16(%ecx), %mm0
pfsub 20(%ecx), %mm0
pfmul 120(%ebx), %mm0
movq %mm0, %mm3
movd 28(%ecx), %mm0
pfsub 24(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, 768(%edi)
movq %mm0, %mm2
pfadd 24(%ecx), %mm0
pfadd 28(%ecx), %mm0
movq %mm0, %mm1
pfadd 16(%ecx), %mm0
pfadd 20(%ecx), %mm0
movd %mm0, 768(%esi)
pfadd %mm3, %mm1
movd %mm1, 256(%esi)
pfadd %mm3, %mm2
movd %mm2, 256(%edi)
movq 32(%edx), %mm0
movq 48(%edx), %mm1
pfadd 48(%edx), %mm0
pfadd 40(%edx), %mm1
movd %mm0, 896(%esi)
movd %mm1, 640(%esi)
psrlq $32, %mm0
psrlq $32, %mm1
movd %mm0, 128(%edi)
movd %mm1, 384(%edi)
movd 40(%edx), %mm0
pfadd 56(%edx), %mm0
movd %mm0, 384(%esi)
movd 56(%edx), %mm0
pfadd 36(%edx), %mm0
movd %mm0, 128(%esi)
movd 60(%edx), %mm0
movd %mm0, 896(%edi)
pfadd 44(%edx), %mm0
movd %mm0, 640(%edi)
movq 96(%edx), %mm0
movq 112(%edx), %mm2
movq 104(%edx), %mm4
pfadd 112(%edx), %mm0
pfadd 104(%edx), %mm2
pfadd 120(%edx), %mm4
movq %mm0, %mm1
movq %mm2, %mm3
movq %mm4, %mm5
pfadd 64(%edx), %mm0
pfadd 80(%edx), %mm2
pfadd 72(%edx), %mm4
movd %mm0, 960(%esi)
movd %mm2, 704(%esi)
movd %mm4, 448(%esi)
psrlq $32, %mm0
psrlq $32, %mm2
psrlq $32, %mm4
movd %mm0, 64(%edi)
movd %mm2, 320(%edi)
movd %mm4, 576(%edi)
pfadd 80(%edx), %mm1
pfadd 72(%edx), %mm3
pfadd 88(%edx), %mm5
movd %mm1, 832(%esi)
movd %mm3, 576(%esi)
movd %mm5, 320(%esi)
psrlq $32, %mm1
psrlq $32, %mm3
psrlq $32, %mm5
movd %mm1, 192(%edi)
movd %mm3, 448(%edi)
movd %mm5, 704(%edi)
movd 120(%edx), %mm0
pfadd 100(%edx), %mm0
movq %mm0, %mm1
pfadd 88(%edx), %mm0
movd %mm0, 192(%esi)
pfadd 68(%edx), %mm1
movd %mm1, 64(%esi)
movd 124(%edx), %mm0
movd %mm0, 960(%edi)
pfadd 92(%edx), %mm0
movd %mm0, 832(%edi)
jmp .L_bye
.L01:
movq (%ecx), %mm0
movq %mm0, %mm1
pxor %mm7, %mm1
pfacc %mm1, %mm0
pfmul %mm6, %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
movw %ax, 512(%esi)
psrlq $32, %mm0
movd %mm0, %eax
movw %ax, (%esi)
movd 12(%ecx), %mm0
pfsub 8(%ecx), %mm0
pfmul 120(%ebx), %mm0
pf2iw %mm0, %mm7
movd %mm7, %eax
movw %ax, 256(%edi)
pfadd 12(%ecx), %mm0
pfadd 8(%ecx), %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
movw %ax, 256(%esi)
movd 16(%ecx), %mm3
pfsub 20(%ecx), %mm3
pfmul 120(%ebx), %mm3
movq %mm3, %mm2
movd 28(%ecx), %mm2
pfsub 24(%ecx), %mm2
pfmul 120(%ebx), %mm2
movq %mm2, %mm1
pf2iw %mm2, %mm7
movd %mm7, %eax
movw %ax, 384(%edi)
pfadd 24(%ecx), %mm1
pfadd 28(%ecx), %mm1
movq %mm1, %mm0
pfadd 16(%ecx), %mm0
pfadd 20(%ecx), %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
movw %ax, 384(%esi)
pfadd %mm3, %mm1
pf2iw %mm1, %mm1
movd %mm1, %eax
movw %ax, 128(%esi)
pfadd %mm3, %mm2
pf2iw %mm2, %mm2
movd %mm2, %eax
movw %ax, 128(%edi)
movq 32(%edx), %mm0
movq 48(%edx), %mm1
pfadd 48(%edx), %mm0
pfadd 40(%edx), %mm1
pf2iw %mm0, %mm0
pf2iw %mm1, %mm1
movd %mm0, %eax
movd %mm1, %ecx
movw %ax, 448(%esi)
movw %cx, 320(%esi)
psrlq $32, %mm0
psrlq $32, %mm1
movd %mm0, %eax
movd %mm1, %ecx
movw %ax, 64(%edi)
movw %cx, 192(%edi)
movd 40(%edx), %mm3
movd 56(%edx), %mm4
movd 60(%edx), %mm0
movd 44(%edx), %mm2
movd 120(%edx), %mm5
punpckldq %mm4, %mm3
punpckldq 124(%edx), %mm0
pfadd 100(%edx), %mm5
punpckldq 36(%edx), %mm4
punpckldq 92(%edx), %mm2
movq %mm5, %mm6
pfadd %mm4, %mm3
pf2iw %mm0, %mm1
pf2iw %mm3, %mm3
pfadd 88(%edx), %mm5
movd %mm1, %eax
movd %mm3, %ecx
movw %ax, 448(%edi)
movw %cx, 192(%esi)
pf2iw %mm5, %mm5
psrlq $32, %mm1
psrlq $32, %mm3
movd %mm5, %ebx
movd %mm1, %eax
movd %mm3, %ecx
movw %bx, 96(%esi)
movw %ax, 480(%edi)
movw %cx, 64(%esi)
pfadd %mm2, %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
pfadd 68(%edx), %mm6
movw %ax, 320(%edi)
psrlq $32, %mm0
pf2iw %mm6, %mm6
movd %mm0, %eax
movd %mm6, %ebx
movw %ax, 416(%edi)
movw %bx, 32(%esi)
movq 96(%edx), %mm0
movq 112(%edx), %mm2
movq 104(%edx), %mm4
pfadd %mm2, %mm0
pfadd %mm4, %mm2
pfadd 120(%edx), %mm4
movq %mm0, %mm1
movq %mm2, %mm3
movq %mm4, %mm5
pfadd 64(%edx), %mm0
pfadd 80(%edx), %mm2
pfadd 72(%edx), %mm4
pf2iw %mm0, %mm0
pf2iw %mm2, %mm2
pf2iw %mm4, %mm4
movd %mm0, %eax
movd %mm2, %ecx
movd %mm4, %ebx
movw %ax, 480(%esi)
movw %cx, 352(%esi)
movw %bx, 224(%esi)
psrlq $32, %mm0
psrlq $32, %mm2
psrlq $32, %mm4
movd %mm0, %eax
movd %mm2, %ecx
movd %mm4, %ebx
movw %ax, 32(%edi)
movw %cx, 160(%edi)
movw %bx, 288(%edi)
pfadd 80(%edx), %mm1
pfadd 72(%edx), %mm3
pfadd 88(%edx), %mm5
pf2iw %mm1, %mm1
pf2iw %mm3, %mm3
pf2iw %mm5, %mm5
movd %mm1, %eax
movd %mm3, %ecx
movd %mm5, %ebx
movw %ax, 416(%esi)
movw %cx, 288(%esi)
movw %bx, 160(%esi)
psrlq $32, %mm1
psrlq $32, %mm3
psrlq $32, %mm5
movd %mm1, %eax
movd %mm3, %ecx
movd %mm5, %ebx
movw %ax, 96(%edi)
movw %cx, 224(%edi)
movw %bx, 352(%edi)
movsw
.L_bye:
femms
/* NO_APP */
addl $256, %esp
popl %ebx
popl %esi
popl %edi
leave
ret
/* .size ASM_NAME(dct64_3dnowext), .-ASM_NAME(dct64_3dnowext) */
NONEXEC_STACK

View File

@ -808,8 +808,4 @@ ASM_NAME(dct64_MMX):
popl %ebx
ret
/* Mark non-executable stack. */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
NONEXEC_STACK

View File

@ -0,0 +1,454 @@
/*
dct64_sse: MMX/SSE optimized dct64
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#define ARG(n) (8+n*4)(%ebp)
#define TEMP(n) (4+n*16)(%esp)
#define TEMP_BYTE(n) (4+n)(%esp)
/*
void dct64_sse(short *out0, short *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
pnpn:
.long 0
.long -2147483648
.long 0
.long -2147483648
ALIGN16
mask:
.long -1
.long -1
.long -1
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_sse)
ASM_NAME(dct64_sse):
pushl %ebp
movl %esp, %ebp
andl $-16, %esp /* align the stack at 16 bytes */
subl $128, %esp /* reserve space for temporal store */
pushl %ebx
movl ARG(0), %ecx
movl ARG(1), %ebx
movl ARG(2), %eax
MOVUAPS (%eax), %xmm7
MOVUAPS 16(%eax), %xmm6
MOVUAPS 112(%eax), %xmm0
MOVUAPS 96(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm7, %xmm4
movaps %xmm6, %xmm5
addps %xmm0, %xmm4
addps %xmm1, %xmm5
subps %xmm0, %xmm7
subps %xmm1, %xmm6
movaps %xmm4, TEMP(0)
movaps %xmm5, TEMP(1)
MOVUAPS 32(%eax), %xmm2
MOVUAPS 48(%eax), %xmm3
MOVUAPS 80(%eax), %xmm0
MOVUAPS 64(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm2, %xmm5
movaps %xmm3, %xmm4
addps %xmm0, %xmm2
addps %xmm1, %xmm3
subps %xmm0, %xmm5
subps %xmm1, %xmm4
mulps ASM_NAME(costab_mmxsse), %xmm7
mulps ASM_NAME(costab_mmxsse)+16, %xmm6
mulps ASM_NAME(costab_mmxsse)+32, %xmm5
mulps ASM_NAME(costab_mmxsse)+48, %xmm4
shufps $0x1b, %xmm2, %xmm2
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm4, %xmm4
shufps $0x1b, %xmm5, %xmm5
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
subps %xmm3, %xmm0
subps %xmm2, %xmm1
addps TEMP(0), %xmm3
addps TEMP(1), %xmm2
movaps %xmm3, TEMP(0)
movaps %xmm2, TEMP(1)
movaps %xmm6, %xmm2
movaps %xmm7, %xmm3
subps %xmm5, %xmm6
subps %xmm4, %xmm7
addps %xmm3, %xmm4
addps %xmm2, %xmm5
mulps ASM_NAME(costab_mmxsse)+64, %xmm0
mulps ASM_NAME(costab_mmxsse)+80, %xmm1
mulps ASM_NAME(costab_mmxsse)+80, %xmm6
mulps ASM_NAME(costab_mmxsse)+64, %xmm7
movaps TEMP(0), %xmm2
movaps TEMP(1), %xmm3
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm5, %xmm5
shufps $0x1b, %xmm1, %xmm1
shufps $0x1b, %xmm6, %xmm6
movaps %xmm0, TEMP(1)
subps %xmm3, %xmm2
subps %xmm1, %xmm0
addps TEMP(0), %xmm3
addps TEMP(1), %xmm1
movaps %xmm3, TEMP(0)
movaps %xmm1, TEMP(2)
movaps %xmm5, %xmm1
movaps %xmm4, %xmm5
movaps %xmm7, %xmm3
subps %xmm1, %xmm5
subps %xmm6, %xmm7
addps %xmm1, %xmm4
addps %xmm3, %xmm6
mulps ASM_NAME(costab_mmxsse)+96, %xmm2
mulps ASM_NAME(costab_mmxsse)+96, %xmm0
mulps ASM_NAME(costab_mmxsse)+96, %xmm5
mulps ASM_NAME(costab_mmxsse)+96, %xmm7
movaps %xmm2, TEMP(1)
movaps %xmm0, TEMP(3)
movaps %xmm4, %xmm2
movaps %xmm5, %xmm3
shufps $0x44, %xmm6, %xmm2
shufps $0xbb, %xmm7, %xmm5
shufps $0xbb, %xmm6, %xmm4
shufps $0x44, %xmm7, %xmm3
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
subps %xmm4, %xmm2
subps %xmm5, %xmm3
addps %xmm6, %xmm4
addps %xmm7, %xmm5
movaps ASM_NAME(costab_mmxsse)+112, %xmm0
movlhps %xmm0, %xmm0
mulps %xmm0, %xmm2
mulps %xmm0, %xmm3
movaps %xmm0, TEMP(4)
movaps %xmm4, %xmm6
movaps %xmm5, %xmm7
shufps $0x14, %xmm2, %xmm4
shufps $0xbe, %xmm2, %xmm6
shufps $0x14, %xmm3, %xmm5
shufps $0xbe, %xmm3, %xmm7
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
movaps %xmm0, %xmm2
movaps %xmm1, %xmm3
shufps $0x44, TEMP(2), %xmm2
shufps $0xbb, TEMP(3), %xmm1
shufps $0xbb, TEMP(2), %xmm0
shufps $0x44, TEMP(3), %xmm3
movaps %xmm2, %xmm5
movaps %xmm3, %xmm7
subps %xmm0, %xmm2
subps %xmm1, %xmm3
addps %xmm5, %xmm0
addps %xmm7, %xmm1
mulps TEMP(4), %xmm2
mulps TEMP(4), %xmm3
movaps %xmm0, %xmm5
movaps %xmm1, %xmm7
shufps $0x14, %xmm2, %xmm0
shufps $0xbe, %xmm2, %xmm5
shufps $0x14, %xmm3, %xmm1
shufps $0xbe, %xmm3, %xmm7
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm5, TEMP(2)
movaps %xmm7, TEMP(3)
movss ASM_NAME(costab_mmxsse)+120, %xmm5
shufps $0x00, %xmm5, %xmm5
xorps pnpn, %xmm5
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps TEMP(5), %xmm4
unpckhps TEMP(5), %xmm0
unpcklps TEMP(7), %xmm6
unpckhps TEMP(7), %xmm1
movaps %xmm4, %xmm2
movaps %xmm6, %xmm3
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm2
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm3
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
subps %xmm2, %xmm0
subps %xmm3, %xmm1
addps %xmm2, %xmm4
addps %xmm3, %xmm6
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
movaps %xmm5, TEMP(5)
movaps %xmm4, %xmm5
movaps %xmm6, %xmm7
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm5
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm7
movaps TEMP(0), %xmm0
movaps TEMP(2), %xmm2
movaps %xmm4, TEMP(4)
movaps %xmm6, TEMP(6)
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
unpcklps TEMP(1), %xmm0
unpckhps TEMP(1), %xmm4
unpcklps TEMP(3), %xmm2
unpckhps TEMP(3), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
subps %xmm1, %xmm4
subps %xmm3, %xmm6
addps %xmm1, %xmm0
addps %xmm3, %xmm2
mulps TEMP(5), %xmm4
mulps TEMP(5), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm2, TEMP(2)
movaps %xmm3, TEMP(3)
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movss TEMP_BYTE(12), %xmm0
movss TEMP_BYTE(28), %xmm1
movss TEMP_BYTE(44), %xmm2
movss TEMP_BYTE(60), %xmm3
addss TEMP_BYTE(8), %xmm0
addss TEMP_BYTE(24), %xmm1
addss TEMP_BYTE(40), %xmm2
addss TEMP_BYTE(56), %xmm3
movss %xmm0, TEMP_BYTE(8)
movss %xmm1, TEMP_BYTE(24)
movss %xmm2, TEMP_BYTE(40)
movss %xmm3, TEMP_BYTE(56)
movss TEMP_BYTE(76), %xmm0
movss TEMP_BYTE(92), %xmm1
movss TEMP_BYTE(108), %xmm2
movss TEMP_BYTE(124), %xmm3
addss TEMP_BYTE(72), %xmm0
addss TEMP_BYTE(88), %xmm1
addss TEMP_BYTE(104), %xmm2
addss TEMP_BYTE(120), %xmm3
movss %xmm0, TEMP_BYTE(72)
movss %xmm1, TEMP_BYTE(88)
movss %xmm2, TEMP_BYTE(104)
movss %xmm3, TEMP_BYTE(120)
movaps TEMP_BYTE(16), %xmm1
movaps TEMP_BYTE(48), %xmm3
movaps TEMP_BYTE(80), %xmm5
movaps TEMP_BYTE(112), %xmm7
movaps %xmm1, %xmm0
movaps %xmm3, %xmm2
movaps %xmm5, %xmm4
movaps %xmm7, %xmm6
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm2, %xmm2
shufps $0x1e, %xmm4, %xmm4
shufps $0x1e, %xmm6, %xmm6
andps mask, %xmm0
andps mask, %xmm2
andps mask, %xmm4
andps mask, %xmm6
addps %xmm0, %xmm1
addps %xmm2, %xmm3
addps %xmm4, %xmm5
addps %xmm6, %xmm7
movaps TEMP_BYTE(32), %xmm2
movaps TEMP_BYTE(96), %xmm6
movaps %xmm2, %xmm0
movaps %xmm6, %xmm4
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm4, %xmm4
andps mask, %xmm0
andps mask, %xmm4
addps %xmm3, %xmm2
addps %xmm0, %xmm3
addps %xmm7, %xmm6
addps %xmm4, %xmm7
movaps TEMP_BYTE(0), %xmm0
movaps TEMP_BYTE(64), %xmm4
cvtps2pi %xmm0, %mm0
cvtps2pi %xmm1, %mm1
movhlps %xmm0, %xmm0
movhlps %xmm1, %xmm1
cvtps2pi %xmm0, %mm2
cvtps2pi %xmm1, %mm3
packssdw %mm2, %mm0
packssdw %mm3, %mm1
cvtps2pi %xmm2, %mm2
cvtps2pi %xmm3, %mm3
movhlps %xmm2, %xmm2
movhlps %xmm3, %xmm3
cvtps2pi %xmm2, %mm4
cvtps2pi %xmm3, %mm5
packssdw %mm4, %mm2
packssdw %mm5, %mm3
movd %mm0, %eax
movd %mm1, %edx
movw %ax, 512(%ecx)
movw %dx, 384(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, (%ecx)
movw %ax, (%ebx)
movw %dx, 128(%ebx)
movd %mm2, %eax
movd %mm3, %edx
movw %ax, 448(%ecx)
movw %dx, 320(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 64(%ebx)
movw %dx, 192(%ebx)
psrlq $32, %mm0
psrlq $32, %mm1
movd %mm0, %eax
movd %mm1, %edx
movw %ax, 256(%ecx)
movw %dx, 128(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 256(%ebx)
movw %dx, 384(%ebx)
psrlq $32, %mm2
psrlq $32, %mm3
movd %mm2, %eax
movd %mm3, %edx
movw %ax, 192(%ecx)
movw %dx, 64(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 320(%ebx)
movw %dx, 448(%ebx)
movaps %xmm4, %xmm0
shufps $0x1e, %xmm0, %xmm0
movaps %xmm5, %xmm1
andps mask, %xmm0
addps %xmm6, %xmm4
addps %xmm7, %xmm5
addps %xmm1, %xmm6
addps %xmm0, %xmm7
cvtps2pi %xmm4, %mm0
cvtps2pi %xmm5, %mm1
movhlps %xmm4, %xmm4
movhlps %xmm5, %xmm5
cvtps2pi %xmm4, %mm2
cvtps2pi %xmm5, %mm3
packssdw %mm2, %mm0
packssdw %mm3, %mm1
cvtps2pi %xmm6, %mm2
cvtps2pi %xmm7, %mm3
movhlps %xmm6, %xmm6
movhlps %xmm7, %xmm7
cvtps2pi %xmm6, %mm4
cvtps2pi %xmm7, %mm5
packssdw %mm4, %mm2
packssdw %mm5, %mm3
movd %mm0, %eax
movd %mm2, %edx
movw %ax, 480(%ecx)
movw %dx, 416(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 32(%ebx)
movw %dx, 96(%ebx)
psrlq $32, %mm0
psrlq $32, %mm2
movd %mm0, %eax
movd %mm2, %edx
movw %ax, 224(%ecx)
movw %dx, 160(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 288(%ebx)
movw %dx, 352(%ebx)
movd %mm1, %eax
movd %mm3, %edx
movw %ax, 352(%ecx)
movw %dx, 288(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 160(%ebx)
movw %dx, 224(%ebx)
psrlq $32, %mm1
psrlq $32, %mm3
movd %mm1, %eax
movd %mm3, %edx
movw %ax, 96(%ecx)
movw %dx, 32(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 416(%ebx)
movw %dx, 480(%ebx)
popl %ebx
movl %ebp, %esp
popl %ebp
ret
NONEXEC_STACK

View File

@ -0,0 +1,401 @@
/*
dct64_sse_float: SSE optimized dct64 (float output version)
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#define ARG(n) (8+n*4)(%ebp)
#define TEMP(n) (4+n*16)(%esp)
#define TEMP_BYTE(n) (4+n)(%esp)
/*
void dct64_real_sse(real *out0, real *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
pnpn:
.long 0
.long -2147483648
.long 0
.long -2147483648
ALIGN16
mask:
.long -1
.long -1
.long -1
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_real_sse)
ASM_NAME(dct64_real_sse):
pushl %ebp
movl %esp, %ebp
andl $-16, %esp /* align the stack at 16 bytes */
subl $128, %esp /* reserve space for temporal store */
pushl %ebx
movl ARG(0), %ecx
movl ARG(1), %ebx
movl ARG(2), %eax
MOVUAPS (%eax), %xmm7
MOVUAPS 16(%eax), %xmm6
MOVUAPS 112(%eax), %xmm0
MOVUAPS 96(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm7, %xmm4
movaps %xmm6, %xmm5
addps %xmm0, %xmm4
addps %xmm1, %xmm5
subps %xmm0, %xmm7
subps %xmm1, %xmm6
movaps %xmm4, TEMP(0)
movaps %xmm5, TEMP(1)
MOVUAPS 32(%eax), %xmm2
MOVUAPS 48(%eax), %xmm3
MOVUAPS 80(%eax), %xmm0
MOVUAPS 64(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm2, %xmm5
movaps %xmm3, %xmm4
addps %xmm0, %xmm2
addps %xmm1, %xmm3
subps %xmm0, %xmm5
subps %xmm1, %xmm4
mulps ASM_NAME(costab_mmxsse), %xmm7
mulps ASM_NAME(costab_mmxsse)+16, %xmm6
mulps ASM_NAME(costab_mmxsse)+32, %xmm5
mulps ASM_NAME(costab_mmxsse)+48, %xmm4
shufps $0x1b, %xmm2, %xmm2
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm4, %xmm4
shufps $0x1b, %xmm5, %xmm5
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
subps %xmm3, %xmm0
subps %xmm2, %xmm1
addps TEMP(0), %xmm3
addps TEMP(1), %xmm2
movaps %xmm3, TEMP(0)
movaps %xmm2, TEMP(1)
movaps %xmm6, %xmm2
movaps %xmm7, %xmm3
subps %xmm5, %xmm6
subps %xmm4, %xmm7
addps %xmm3, %xmm4
addps %xmm2, %xmm5
mulps ASM_NAME(costab_mmxsse)+64, %xmm0
mulps ASM_NAME(costab_mmxsse)+80, %xmm1
mulps ASM_NAME(costab_mmxsse)+80, %xmm6
mulps ASM_NAME(costab_mmxsse)+64, %xmm7
movaps TEMP(0), %xmm2
movaps TEMP(1), %xmm3
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm5, %xmm5
shufps $0x1b, %xmm1, %xmm1
shufps $0x1b, %xmm6, %xmm6
movaps %xmm0, TEMP(1)
subps %xmm3, %xmm2
subps %xmm1, %xmm0
addps TEMP(0), %xmm3
addps TEMP(1), %xmm1
movaps %xmm3, TEMP(0)
movaps %xmm1, TEMP(2)
movaps %xmm5, %xmm1
movaps %xmm4, %xmm5
movaps %xmm7, %xmm3
subps %xmm1, %xmm5
subps %xmm6, %xmm7
addps %xmm1, %xmm4
addps %xmm3, %xmm6
mulps ASM_NAME(costab_mmxsse)+96, %xmm2
mulps ASM_NAME(costab_mmxsse)+96, %xmm0
mulps ASM_NAME(costab_mmxsse)+96, %xmm5
mulps ASM_NAME(costab_mmxsse)+96, %xmm7
movaps %xmm2, TEMP(1)
movaps %xmm0, TEMP(3)
movaps %xmm4, %xmm2
movaps %xmm5, %xmm3
shufps $0x44, %xmm6, %xmm2
shufps $0xbb, %xmm7, %xmm5
shufps $0xbb, %xmm6, %xmm4
shufps $0x44, %xmm7, %xmm3
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
subps %xmm4, %xmm2
subps %xmm5, %xmm3
addps %xmm6, %xmm4
addps %xmm7, %xmm5
movaps ASM_NAME(costab_mmxsse)+112, %xmm0
movlhps %xmm0, %xmm0
mulps %xmm0, %xmm2
mulps %xmm0, %xmm3
movaps %xmm0, TEMP(4)
movaps %xmm4, %xmm6
movaps %xmm5, %xmm7
shufps $0x14, %xmm2, %xmm4
shufps $0xbe, %xmm2, %xmm6
shufps $0x14, %xmm3, %xmm5
shufps $0xbe, %xmm3, %xmm7
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
movaps %xmm0, %xmm2
movaps %xmm1, %xmm3
shufps $0x44, TEMP(2), %xmm2
shufps $0xbb, TEMP(3), %xmm1
shufps $0xbb, TEMP(2), %xmm0
shufps $0x44, TEMP(3), %xmm3
movaps %xmm2, %xmm5
movaps %xmm3, %xmm7
subps %xmm0, %xmm2
subps %xmm1, %xmm3
addps %xmm5, %xmm0
addps %xmm7, %xmm1
mulps TEMP(4), %xmm2
mulps TEMP(4), %xmm3
movaps %xmm0, %xmm5
movaps %xmm1, %xmm7
shufps $0x14, %xmm2, %xmm0
shufps $0xbe, %xmm2, %xmm5
shufps $0x14, %xmm3, %xmm1
shufps $0xbe, %xmm3, %xmm7
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm5, TEMP(2)
movaps %xmm7, TEMP(3)
movss ASM_NAME(costab_mmxsse)+120, %xmm5
shufps $0x00, %xmm5, %xmm5
xorps pnpn, %xmm5
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps TEMP(5), %xmm4
unpckhps TEMP(5), %xmm0
unpcklps TEMP(7), %xmm6
unpckhps TEMP(7), %xmm1
movaps %xmm4, %xmm2
movaps %xmm6, %xmm3
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm2
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm3
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
subps %xmm2, %xmm0
subps %xmm3, %xmm1
addps %xmm2, %xmm4
addps %xmm3, %xmm6
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
movaps %xmm5, TEMP(5)
movaps %xmm4, %xmm5
movaps %xmm6, %xmm7
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm5
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm7
movaps TEMP(0), %xmm0
movaps TEMP(2), %xmm2
movaps %xmm4, TEMP(4)
movaps %xmm6, TEMP(6)
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
unpcklps TEMP(1), %xmm0
unpckhps TEMP(1), %xmm4
unpcklps TEMP(3), %xmm2
unpckhps TEMP(3), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
subps %xmm1, %xmm4
subps %xmm3, %xmm6
addps %xmm1, %xmm0
addps %xmm3, %xmm2
mulps TEMP(5), %xmm4
mulps TEMP(5), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm2, TEMP(2)
movaps %xmm3, TEMP(3)
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movss TEMP_BYTE(12), %xmm0
movss TEMP_BYTE(28), %xmm1
movss TEMP_BYTE(44), %xmm2
movss TEMP_BYTE(60), %xmm3
addss TEMP_BYTE(8), %xmm0
addss TEMP_BYTE(24), %xmm1
addss TEMP_BYTE(40), %xmm2
addss TEMP_BYTE(56), %xmm3
movss %xmm0, TEMP_BYTE(8)
movss %xmm1, TEMP_BYTE(24)
movss %xmm2, TEMP_BYTE(40)
movss %xmm3, TEMP_BYTE(56)
movss TEMP_BYTE(76), %xmm0
movss TEMP_BYTE(92), %xmm1
movss TEMP_BYTE(108), %xmm2
movss TEMP_BYTE(124), %xmm3
addss TEMP_BYTE(72), %xmm0
addss TEMP_BYTE(88), %xmm1
addss TEMP_BYTE(104), %xmm2
addss TEMP_BYTE(120), %xmm3
movss %xmm0, TEMP_BYTE(72)
movss %xmm1, TEMP_BYTE(88)
movss %xmm2, TEMP_BYTE(104)
movss %xmm3, TEMP_BYTE(120)
movaps TEMP_BYTE(16), %xmm1
movaps TEMP_BYTE(48), %xmm3
movaps TEMP_BYTE(80), %xmm5
movaps TEMP_BYTE(112), %xmm7
movaps %xmm1, %xmm0
movaps %xmm3, %xmm2
movaps %xmm5, %xmm4
movaps %xmm7, %xmm6
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm2, %xmm2
shufps $0x1e, %xmm4, %xmm4
shufps $0x1e, %xmm6, %xmm6
andps mask, %xmm0
andps mask, %xmm2
andps mask, %xmm4
andps mask, %xmm6
addps %xmm0, %xmm1
addps %xmm2, %xmm3
addps %xmm4, %xmm5
addps %xmm6, %xmm7
movaps TEMP_BYTE(32), %xmm2
movaps TEMP_BYTE(96), %xmm6
movaps %xmm2, %xmm0
movaps %xmm6, %xmm4
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm4, %xmm4
andps mask, %xmm0
andps mask, %xmm4
addps %xmm3, %xmm2
addps %xmm0, %xmm3
addps %xmm7, %xmm6
addps %xmm4, %xmm7
movaps TEMP_BYTE(0), %xmm0
movaps TEMP_BYTE(64), %xmm4
movss %xmm0, 1024(%ecx)
movss %xmm2, 896(%ecx)
movss %xmm1, 768(%ecx)
movss %xmm3, 640(%ecx)
shufps $0xe1, %xmm0, %xmm0
shufps $0xe1, %xmm2, %xmm2
shufps $0xe1, %xmm1, %xmm1
shufps $0xe1, %xmm3, %xmm3
movss %xmm0, (%ecx)
movss %xmm0, (%ebx)
movss %xmm2, 128(%ebx)
movss %xmm1, 256(%ebx)
movss %xmm3, 384(%ebx)
movhlps %xmm0, %xmm0
movhlps %xmm2, %xmm2
movhlps %xmm1, %xmm1
movhlps %xmm3, %xmm3
movss %xmm0, 512(%ecx)
movss %xmm2, 384(%ecx)
movss %xmm1, 256(%ecx)
movss %xmm3, 128(%ecx)
shufps $0xe1, %xmm0, %xmm0
shufps $0xe1, %xmm2, %xmm2
shufps $0xe1, %xmm1, %xmm1
shufps $0xe1, %xmm3, %xmm3
movss %xmm0, 512(%ebx)
movss %xmm2, 640(%ebx)
movss %xmm1, 768(%ebx)
movss %xmm3, 896(%ebx)
movaps %xmm4, %xmm0
shufps $0x1e, %xmm0, %xmm0
movaps %xmm5, %xmm1
andps mask, %xmm0
addps %xmm6, %xmm4
addps %xmm7, %xmm5
addps %xmm1, %xmm6
addps %xmm0, %xmm7
movss %xmm4, 960(%ecx)
movss %xmm6, 832(%ecx)
movss %xmm5, 704(%ecx)
movss %xmm7, 576(%ecx)
movhlps %xmm4, %xmm0
movhlps %xmm6, %xmm1
movhlps %xmm5, %xmm2
movhlps %xmm7, %xmm3
movss %xmm0, 448(%ecx)
movss %xmm1, 320(%ecx)
movss %xmm2, 192(%ecx)
movss %xmm3, 64(%ecx)
shufps $0xe1, %xmm4, %xmm4
shufps $0xe1, %xmm6, %xmm6
shufps $0xe1, %xmm5, %xmm5
shufps $0xe1, %xmm7, %xmm7
movss %xmm4, 64(%ebx)
movss %xmm6, 192(%ebx)
movss %xmm5, 320(%ebx)
movss %xmm7, 448(%ebx)
shufps $0xe1, %xmm0, %xmm0
shufps $0xe1, %xmm1, %xmm1
shufps $0xe1, %xmm2, %xmm2
shufps $0xe1, %xmm3, %xmm3
movss %xmm0, 576(%ebx)
movss %xmm1, 704(%ebx)
movss %xmm2, 832(%ebx)
movss %xmm3, 960(%ebx)
popl %ebx
movl %ebp, %esp
popl %ebp
ret
NONEXEC_STACK

View File

@ -97,7 +97,7 @@
#endif
/* error macros also here... */
#ifndef NO_ERROR
#ifndef NO_ERRORMSG
#define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__)
#define error1(s, a) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a)
#define error2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b)

View File

@ -30,16 +30,13 @@
#define NTOM_MAX 8 /* maximum allowed factor for upsampling */
#define NTOM_MAX_FREQ 96000 /* maximum frequency to upsample to / downsample from */
#define NTOM_MUL (32768)
void ntom_set_ntom(mpg123_handle *fr, off_t num);
#endif
/* Let's collect all possible synth functions here, for an overview.
If they are actually defined and used depends on preprocessor machinery.
See synth.c and optimize.h for that, also some special C and assembler files. */
/* The call of left and right plain synth, wrapped.
This may be replaced by a direct stereo optimized synth. */
int synth_stereo_wrap(real*, real*, mpg123_handle*);
#ifndef NO_16BIT
/* The signed-16bit-producing variants. */
int synth_1to1 (real*, int, mpg123_handle*, int);
@ -57,13 +54,15 @@ int synth_1to1_stereo_altivec(real*, real*, mpg123_handle*);
int synth_1to1_x86_64 (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_x86_64(real*, real*, mpg123_handle*);
int synth_1to1_arm (real*, int, mpg123_handle*, int);
int synth_1to1_neon (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_neon(real*, real*, mpg123_handle*);
/* This is different, special usage in layer3.c only.
Hence, the name... and now forget about it.
Never use it outside that special portion of code inside layer3.c! */
int absynth_1to1_i486(real*, int, mpg123_handle*, int);
/* These mono/stereo converters use one of the above for the grunt work. */
int synth_1to1_mono (real*, mpg123_handle*);
int synth_1to1_mono2stereo(real*, mpg123_handle*);
int synth_1to1_m2s(real*, mpg123_handle*);
/* Sample rate decimation comes in less flavours. */
#ifndef NO_DOWNSAMPLE
@ -71,18 +70,18 @@ int synth_2to1 (real*, int, mpg123_handle*, int);
int synth_2to1_dither (real*, int, mpg123_handle*, int);
int synth_2to1_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_mono (real*, mpg123_handle*);
int synth_2to1_mono2stereo(real*, mpg123_handle*);
int synth_2to1_m2s(real*, mpg123_handle*);
int synth_4to1 (real *,int, mpg123_handle*, int);
int synth_4to1_dither (real *,int, mpg123_handle*, int);
int synth_4to1_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_mono (real*, mpg123_handle*);
int synth_4to1_mono2stereo(real*, mpg123_handle*);
int synth_4to1_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
/* NtoM is really just one implementation. */
int synth_ntom (real *,int, mpg123_handle*, int);
int synth_ntom_mono (real *, mpg123_handle *);
int synth_ntom_mono2stereo (real *, mpg123_handle *);
int synth_ntom_m2s (real *, mpg123_handle *);
#endif
#endif
@ -95,26 +94,25 @@ int synth_1to1_8bit_i386 (real*, int, mpg123_handle*, int);
int synth_1to1_8bit_wrap (real*, int, mpg123_handle*, int);
int synth_1to1_8bit_mono (real*, mpg123_handle*);
#endif
int synth_1to1_8bit_mono2stereo(real*, mpg123_handle*);
int synth_1to1_8bit_m2s(real*, mpg123_handle*);
#ifndef NO_16BIT
int synth_1to1_8bit_wrap_mono (real*, mpg123_handle*);
int synth_1to1_8bit_wrap_mono2stereo(real*, mpg123_handle*);
int synth_1to1_8bit_wrap_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_DOWNSAMPLE
int synth_2to1_8bit (real*, int, mpg123_handle*, int);
int synth_2to1_8bit_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_8bit_mono (real*, mpg123_handle*);
int synth_2to1_8bit_mono2stereo(real*, mpg123_handle*);
int synth_2to1_8bit_m2s(real*, mpg123_handle*);
int synth_4to1_8bit (real*, int, mpg123_handle*, int);
int synth_4to1_8bit_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_8bit_mono (real*, mpg123_handle*);
int synth_4to1_8bit_mono2stereo(real*, mpg123_handle*);
int synth_4to1_8bit_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
int synth_ntom_8bit (real*, int, mpg123_handle*, int);
int synth_ntom_8bit_mono (real*, mpg123_handle*);
int synth_ntom_8bit_mono2stereo(real*, mpg123_handle*);
void ntom_set_ntom(mpg123_handle *fr, off_t num);
int synth_ntom_8bit_m2s(real*, mpg123_handle*);
#endif
#endif
@ -130,22 +128,24 @@ int synth_1to1_real_x86_64 (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_x86_64(real*, real*, mpg123_handle*);
int synth_1to1_real_altivec (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_altivec(real*, real*, mpg123_handle*);
int synth_1to1_real_neon (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_neon(real*, real*, mpg123_handle*);
int synth_1to1_real_mono (real*, mpg123_handle*);
int synth_1to1_real_mono2stereo(real*, mpg123_handle*);
int synth_1to1_real_m2s(real*, mpg123_handle*);
#ifndef NO_DOWNSAMPLE
int synth_2to1_real (real*, int, mpg123_handle*, int);
int synth_2to1_real_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_real_mono (real*, mpg123_handle*);
int synth_2to1_real_mono2stereo(real*, mpg123_handle*);
int synth_2to1_real_m2s(real*, mpg123_handle*);
int synth_4to1_real (real*, int, mpg123_handle*, int);
int synth_4to1_real_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_real_mono (real*, mpg123_handle*);
int synth_4to1_real_mono2stereo(real*, mpg123_handle*);
int synth_4to1_real_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
int synth_ntom_real (real*, int, mpg123_handle*, int);
int synth_ntom_real_mono (real*, mpg123_handle*);
int synth_ntom_real_mono2stereo(real*, mpg123_handle*);
int synth_ntom_real_m2s(real*, mpg123_handle*);
#endif
#endif
@ -159,22 +159,24 @@ int synth_1to1_s32_x86_64 (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_x86_64(real*, real*, mpg123_handle*);
int synth_1to1_s32_altivec (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_altivec(real*, real*, mpg123_handle*);
int synth_1to1_s32_neon (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_neon(real*, real*, mpg123_handle*);
int synth_1to1_s32_mono (real*, mpg123_handle*);
int synth_1to1_s32_mono2stereo(real*, mpg123_handle*);
int synth_1to1_s32_m2s(real*, mpg123_handle*);
#ifndef NO_DOWNSAMPLE
int synth_2to1_s32 (real*, int, mpg123_handle*, int);
int synth_2to1_s32_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_s32_mono (real*, mpg123_handle*);
int synth_2to1_s32_mono2stereo(real*, mpg123_handle*);
int synth_2to1_s32_m2s(real*, mpg123_handle*);
int synth_4to1_s32 (real*, int, mpg123_handle*, int);
int synth_4to1_s32_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_s32_mono (real*, mpg123_handle*);
int synth_4to1_s32_mono2stereo(real*, mpg123_handle*);
int synth_4to1_s32_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
int synth_ntom_s32 (real*, int, mpg123_handle*, int);
int synth_ntom_s32_mono (real*, mpg123_handle*);
int synth_ntom_s32_mono2stereo(real*, mpg123_handle*);
int synth_ntom_s32_m2s(real*, mpg123_handle*);
#endif
#endif
@ -199,6 +201,12 @@ int synth_ntom_set_step(mpg123_handle *fr); /* prepare ntom decoding */
unsigned long ntom_val(mpg123_handle *fr, off_t frame); /* compute ntom_val for frame offset */
/* Frame and sample offsets. */
#ifndef NO_NTOM
/*
Outsamples of _this_ frame.
To be exact: The samples to be expected from the next frame decode (using the current ntom_val). When you already decoded _this_ frame, this is the number of samples to be expected from the next one.
*/
off_t ntom_frame_outsamples(mpg123_handle *fr);
/* Total out/insample offset. */
off_t ntom_frmouts(mpg123_handle *fr, off_t frame);
off_t ntom_ins2outs(mpg123_handle *fr, off_t ins);
off_t ntom_frameoff(mpg123_handle *fr, off_t soff);

View File

@ -0,0 +1,119 @@
/*
dither: Generate shaped noise for dithering
copyright 2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "config.h"
#include "compat.h"
#include "dither.h"
static const uint32_t init_seed = 2463534242UL;
#define LAP 100
/*
xorshift random number generator, with output scaling to [-0.5, 0.5]
This is the white noise...
See http://www.jstatsoft.org/v08/i14/paper on XOR shift random number generators.
*/
static float rand_xorshift32(uint32_t *seed)
{
union
{
uint32_t i;
float f;
} fi;
fi.i = *seed;
fi.i ^= (fi.i<<13);
fi.i ^= (fi.i>>17);
fi.i ^= (fi.i<<5);
*seed = fi.i;
/* scale the number to [-0.5, 0.5] */
#ifdef IEEE_FLOAT
fi.i = (fi.i>>9)|0x3f800000;
fi.f -= 1.5f;
#else
fi.f = (double)fi.i / 4294967295.0;
fi.f -= 0.5f;
#endif
return fi.f;
}
static void white_noise(float *table, size_t count)
{
size_t i;
uint32_t seed = init_seed;
for(i=0; i<count; ++i)
table[i] = rand_xorshift32(&seed);
}
static void tpdf_noise(float *table, size_t count)
{
size_t i;
uint32_t seed = init_seed;
for(i=0; i<count; ++i)
table[i] = rand_xorshift32(&seed) + rand_xorshift32(&seed);
}
static void highpass_tpdf_noise(float *table, size_t count)
{
size_t i;
uint32_t seed = init_seed;
/* Ensure some minimum lap for keeping the high-pass filter circular. */
size_t lap = count > 2*LAP ? LAP : count/2;
float input_noise;
float xv[9], yv[9];
for(i=0;i<9;i++)
{
xv[i] = yv[i] = 0.0f;
}
for(i=0;i<count+lap;i++)
{
if(i==count) seed=init_seed;
/* generate and add 2 random numbers, to make a TPDF noise distribution */
input_noise = rand_xorshift32(&seed) + rand_xorshift32(&seed);
/* apply 8th order Chebyshev high-pass IIR filter */
/* Coefficients are from http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
Given parameters are: Chebyshev, Highpass, ripple=-1, order=8, samplerate=44100, corner1=19000 */
xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8];
xv[8] = input_noise / 1.382814179e+07;
yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8];
yv[8] = (xv[0] + xv[8]) - 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6])
- 56 * (xv[3] + xv[5]) + 70 * xv[4]
+ ( -0.6706204984 * yv[0]) + ( -5.3720827038 * yv[1])
+ (-19.0865382480 * yv[2]) + (-39.2831607860 * yv[3])
+ (-51.2308985070 * yv[4]) + (-43.3590135780 * yv[5])
+ (-23.2632305320 * yv[6]) + ( -7.2370122050 * yv[7]);
if(i>=lap) table[i-lap] = yv[8] * 3.0f;
}
}
void mpg123_noise(float* table, size_t count, enum mpg123_noise_type noisetype)
{
switch(noisetype)
{
case mpg123_white_noise: white_noise(table, count); break;
case mpg123_tpdf_noise: tpdf_noise(table, count); break;
case mpg123_highpass_tpdf_noise:
highpass_tpdf_noise(table, count);
break;
}
}
/* Generate white noise and shape it with a high pass filter. */
void dither_table_init(float *dithertable)
{
highpass_tpdf_noise(dithertable, DITHERSIZE);
}

View File

@ -0,0 +1,70 @@
/*
equalizer_3dnow: 3DNow! optimized do_equalizer()
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by KIMURA Takuhiro
*/
#include "mangle.h"
.text
ALIGN4
.globl ASM_NAME(do_equalizer_3dnow)
/* .type ASM_NAME(do_equalizer_3dnow),@function */
/* void do_equalizer(real *bandPtr,int channel, real equalizer[2][32]); */
ASM_NAME(do_equalizer_3dnow):
pushl %esi
pushl %ebx
/* bandPtr */
movl 12(%esp),%ebx
/* channel */
movl 16(%esp),%ecx
xorl %edx,%edx
/* equalizer */
movl 20(%esp),%esi
sall $7,%ecx
ALIGN4
.L9:
movq (%ebx,%edx),%mm0
pfmul (%esi,%ecx),%mm0
movq 8(%ebx,%edx),%mm1
pfmul 8(%esi,%ecx),%mm1
movq %mm0,(%ebx,%edx)
movq 16(%ebx,%edx),%mm0
pfmul 16(%esi,%ecx),%mm0
movq %mm1,8(%ebx,%edx)
movq 24(%ebx,%edx),%mm1
pfmul 24(%esi,%ecx),%mm1
movq %mm0,16(%ebx,%edx)
movq 32(%ebx,%edx),%mm0
pfmul 32(%esi,%ecx),%mm0
movq %mm1,24(%ebx,%edx)
movq 40(%ebx,%edx),%mm1
pfmul 40(%esi,%ecx),%mm1
movq %mm0,32(%ebx,%edx)
movq 48(%ebx,%edx),%mm0
pfmul 48(%esi,%ecx),%mm0
movq %mm1,40(%ebx,%edx)
movq 56(%ebx,%edx),%mm1
pfmul 56(%esi,%ecx),%mm1
movq %mm0,48(%ebx,%edx)
movq %mm1,56(%ebx,%edx)
addl $64,%edx
addl $32,%ecx
cmpl $124,%edx
jle .L9
ALIGN4
popl %ebx
popl %esi
ret
NONEXEC_STACK

View File

@ -0,0 +1,106 @@
#include "mpg123lib_intern.h"
int mpg123_feature(const enum mpg123_feature_set key)
{
switch(key)
{
case MPG123_FEATURE_ABI_UTF8OPEN:
#ifdef WANT_WIN32_UNICODE
return 1;
#else
return 0;
#endif /* WANT_WIN32_UNICODE */
case MPG123_FEATURE_OUTPUT_8BIT:
#ifdef NO_8BIT
return 0;
#else
return 1;
#endif /* mpg123_output_8bit */
case MPG123_FEATURE_OUTPUT_16BIT:
#ifdef NO_16BIT
return 0;
#else
return 1;
#endif /* mpg123_output_16bit */
case MPG123_FEATURE_OUTPUT_32BIT:
#ifdef NO_32BIT
return 0;
#else
return 1;
#endif /* mpg123_output_32bit */
case MPG123_FEATURE_PARSE_ID3V2:
#ifdef NO_ID3V2
return 0;
#else
return 1;
#endif /* NO_ID3V2 */
case MPG123_FEATURE_DECODE_LAYER1:
#ifdef NO_LAYER1
return 0;
#else
return 1;
#endif /* NO_LAYER1 */
case MPG123_FEATURE_DECODE_LAYER2:
#ifdef NO_LAYER2
return 0;
#else
return 1;
#endif /* NO_LAYER2 */
case MPG123_FEATURE_DECODE_LAYER3:
#ifdef NO_LAYER3
return 0;
#else
return 1;
#endif /* NO_LAYER3 */
case MPG123_FEATURE_DECODE_ACCURATE:
#ifdef ACCURATE_ROUNDING
return 1;
#else
return 0;
#endif /* ACCURATE_ROUNDING */
case MPG123_FEATURE_DECODE_DOWNSAMPLE:
#ifdef NO_DOWNSAMPLE
return 0;
#else
return 1;
#endif /* NO_DOWNSAMPLE */
case MPG123_FEATURE_DECODE_NTOM:
#ifdef NO_NTOM
return 0;
#else
return 1;
#endif /* NO_NTOM */
case MPG123_FEATURE_PARSE_ICY:
#ifdef NO_ICY
return 0;
#else
return 1;
#endif /* NO_ICY */
case MPG123_FEATURE_INDEX:
#ifdef FRAME_INDEX
return 1;
#else
return 0;
#endif /* FRAME_INDEX */
case MPG123_FEATURE_TIMEOUT_READ:
#ifdef TIMEOUT_READ
return 1;
#else
return 0;
#endif
default: return 0;
}
}

View File

@ -23,14 +23,25 @@ static const int my_encodings[MPG123_ENCODINGS] =
MPG123_ENC_UNSIGNED_16,
MPG123_ENC_SIGNED_32,
MPG123_ENC_UNSIGNED_32,
MPG123_ENC_SIGNED_24,
MPG123_ENC_UNSIGNED_24,
/* Floating point range, see below. */
MPG123_ENC_FLOAT_32,
MPG123_ENC_FLOAT_64,
/* 8 bit range, see below. */
MPG123_ENC_SIGNED_8,
MPG123_ENC_UNSIGNED_8,
MPG123_ENC_ULAW_8,
MPG123_ENC_ALAW_8
};
/* Make that match the above table.
And yes, I still don't like this kludgy stuff. */
/* range[0] <= i < range[1] for forced floating point */
static const int enc_float_range[2] = { 6, 8 };
/* same for 8 bit encodings */
static const int enc_8bit_range[2] = { 8, 12 };
/* Only one type of float is supported. */
# ifdef REAL_IS_FLOAT
# define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32
@ -48,6 +59,8 @@ static const int good_encodings[] =
#ifndef NO_32BIT
MPG123_ENC_SIGNED_32,
MPG123_ENC_UNSIGNED_32,
MPG123_ENC_SIGNED_24,
MPG123_ENC_UNSIGNED_24,
#endif
#ifndef NO_REAL
MPG123_FLOAT_ENC,
@ -84,6 +97,22 @@ void attribute_align_arg mpg123_encodings(const int **list, size_t *number)
if(number != NULL) *number = sizeof(good_encodings)/sizeof(int);
}
int attribute_align_arg mpg123_encsize(int encoding)
{
if(encoding & MPG123_ENC_8)
return 1;
else if(encoding & MPG123_ENC_16)
return 2;
else if(encoding & MPG123_ENC_24)
return 3;
else if(encoding & MPG123_ENC_32 || encoding == MPG123_ENC_FLOAT_32)
return 4;
else if(encoding == MPG123_ENC_FLOAT_64)
return 8;
else
return 0;
}
/* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */
static int rate2num(mpg123_pars *mp, long r)
@ -126,14 +155,18 @@ static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
{
nf->rate = frame_freq(fr)>>fr->p.down_sample;
if(cap_fit(fr,nf,f0,f2)) return 1;
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
if(fr->p.flags & MPG123_AUTO_RESAMPLE)
{
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
}
#ifndef NO_NTOM
/* If nothing worked, try the other rates, only without constrains from user.
In case you didn't guess: We enable flexible resampling if we find a working rate. */
if(!fr->p.force_rate && fr->p.down_sample == 0)
if( fr->p.flags & MPG123_AUTO_RESAMPLE &&
!fr->p.force_rate && fr->p.down_sample == 0)
{
int i;
int c = nf->channels-1;
@ -176,13 +209,13 @@ int frame_output_format(mpg123_handle *fr)
/* All this forcing should be removed in favour of the capabilities table... */
if(p->flags & MPG123_FORCE_8BIT)
{
f0 = 6;
f2 = 10;
f0 = enc_8bit_range[0];
f2 = enc_8bit_range[1];
}
if(p->flags & MPG123_FORCE_FLOAT)
{
f0 = 4;
f2 = 6;
f0 = enc_float_range[0];
f2 = enc_float_range[1];
}
/* force stereo is stronger */
@ -254,15 +287,8 @@ end: /* Here is the _good_ end. */
fr->af.channels = nf.channels;
fr->af.encoding = nf.encoding;
/* Cache the size of one sample in bytes, for ease of use. */
if(fr->af.encoding & MPG123_ENC_8)
fr->af.encsize = 1;
else if(fr->af.encoding & MPG123_ENC_16)
fr->af.encsize = 2;
else if(fr->af.encoding & MPG123_ENC_32 || fr->af.encoding == MPG123_ENC_FLOAT_32)
fr->af.encsize = 4;
else if(fr->af.encoding == MPG123_ENC_FLOAT_64)
fr->af.encsize = 8;
else
fr->af.encsize = mpg123_encsize(fr->af.encoding);
if(fr->af.encsize < 1)
{
if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding);
@ -383,6 +409,15 @@ void invalidate_format(struct audioformat *af)
af->channels = 0;
}
/* Consider 24bit output needing 32bit output as temporary storage. */
off_t samples_to_storage(mpg123_handle *fr, off_t s)
{
if(fr->af.encoding & MPG123_ENC_24)
return s*4*fr->af.channels; /* 4 bytes per sample */
else
return samples_to_bytes(fr, s);
}
/* take into account: channels, bytes per sample -- NOT resampling!*/
off_t samples_to_bytes(mpg123_handle *fr , off_t s)
{
@ -393,3 +428,94 @@ off_t bytes_to_samples(mpg123_handle *fr , off_t b)
{
return b / fr->af.encsize / fr->af.channels;
}
#ifndef NO_32BIT
/* Remove every fourth byte, facilitating conversion from 32 bit to 24 bit integers.
This has to be aware of endianness, of course. */
static void chop_fourth_byte(struct outbuffer *buf)
{
unsigned char *wpos = buf->data;
unsigned char *rpos = buf->data;
#ifdef WORDS_BIGENDIAN
while((size_t) (rpos - buf->data + 4) <= buf->fill)
{
/* Really stupid: Copy, increment. Byte per byte. */
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
rpos++; /* Skip the lowest byte (last). */
}
#else
while((size_t) (rpos - buf->data + 4) <= buf->fill)
{
/* Really stupid: Copy, increment. Byte per byte. */
rpos++; /* Skip the lowest byte (first). */
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
}
#endif
buf->fill = wpos-buf->data;
}
#endif
void postprocess_buffer(mpg123_handle *fr)
{
/* Handle unsigned output formats via reshifting after decode here.
Also handle conversion to 24 bit. */
#ifndef NO_32BIT
if(fr->af.encoding == MPG123_ENC_UNSIGNED_32 || fr->af.encoding == MPG123_ENC_UNSIGNED_24)
{ /* 32bit signed -> unsigned */
size_t i;
int32_t *ssamples;
uint32_t *usamples;
ssamples = (int32_t*)fr->buffer.data;
usamples = (uint32_t*)fr->buffer.data;
debug("converting output to unsigned 32 bit integer");
for(i=0; i<fr->buffer.fill/sizeof(int32_t); ++i)
{
/* Different strategy since we don't have a larger type at hand.
Also watch out for silly +-1 fun because integer constants are signed in C90! */
if(ssamples[i] >= 0)
usamples[i] = (uint32_t)ssamples[i] + 2147483647+1;
/* The smalles value goes zero. */
else if(ssamples[i] == ((int32_t)-2147483647-1))
usamples[i] = 0;
/* Now -value is in the positive range of signed int ... so it's a possible value at all. */
else
usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]);
}
/* Dumb brute force: A second pass for hacking off the last byte. */
if(fr->af.encoding == MPG123_ENC_UNSIGNED_24)
chop_fourth_byte(&fr->buffer);
}
else if(fr->af.encoding == MPG123_ENC_SIGNED_24)
{
/* We got 32 bit signed ... chop off for 24 bit signed. */
chop_fourth_byte(&fr->buffer);
}
#endif
#ifndef NO_16BIT
if(fr->af.encoding == MPG123_ENC_UNSIGNED_16)
{
size_t i;
short *ssamples;
unsigned short *usamples;
ssamples = (short*)fr->buffer.data;
usamples = (unsigned short*)fr->buffer.data;
debug("converting output to unsigned 16 bit integer");
for(i=0; i<fr->buffer.fill/sizeof(short); ++i)
{
long tmp = (long)ssamples[i]+32768;
usamples[i] = (unsigned short)tmp;
}
}
#endif
}

View File

@ -1,7 +1,7 @@
/*
frame: Heap of routines dealing with the core mpg123 data structure.
copyright 2008-9 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 2008-2010 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
@ -14,18 +14,33 @@ static void frame_fixed_reset(mpg123_handle *fr);
/* that's doubled in decode_ntom.c */
#define NTOM_MUL (32768)
#define aligned_pointer(p,type,alignment) \
(((char*)(p)-(char*)NULL) % (alignment)) \
? (type*)((char*)(p) + (alignment) - (((char*)(p)-(char*)NULL) % (alignment))) \
: (type*)(p)
void frame_default_pars(mpg123_pars *mp)
#define aligned_pointer(p, type, alignment) align_the_pointer(p, alignment)
static void *align_the_pointer(void *base, unsigned int alignment)
{
/*
Work in unsigned integer realm, explicitly.
Tricking the compiler into integer operations like % by invoking base-NULL is dangerous: It results into ptrdiff_t, which gets negative on big addresses. Big screw up, that.
I try to do it "properly" here: Casting only to uintptr_t and no artihmethic with void*.
*/
uintptr_t baseval = (uintptr_t)(char*)base;
uintptr_t aoff = baseval % alignment;
debug3("align_the_pointer: pointer %p is off by %u from %u",
base, (unsigned int)aoff, alignment);
if(aoff) return (char*)base+alignment-aoff;
else return base;
}
static void frame_default_pars(mpg123_pars *mp)
{
mp->outscale = 1.0;
#ifdef GAPLESS
mp->flags = MPG123_GAPLESS;
#else
mp->flags = 0;
#ifdef GAPLESS
mp->flags |= MPG123_GAPLESS;
#endif
mp->flags |= MPG123_AUTO_RESAMPLE;
#ifndef NO_NTOM
mp->force_rate = 0;
#endif
@ -37,15 +52,18 @@ void frame_default_pars(mpg123_pars *mp)
#ifndef NO_ICY
mp->icy_interval = 0;
#endif
#ifndef WIN32
mp->timeout = 0;
#endif
mp->resync_limit = 1024;
#ifdef FRAME_INDEX
mp->index_size = INDEX_SIZE;
#endif
mp->preframes = 4; /* That's good for layer 3 ISO compliance bitstream. */
mpg123_fmt_all(mp);
/* Default of keeping some 4K buffers at hand, should cover the "usual" use case (using 16K pipe buffers as role model). */
#ifndef NO_FEEDER
mp->feedpool = 5;
mp->feedbuffer = 4096;
#endif
}
void frame_init(mpg123_handle *fr)
@ -55,8 +73,11 @@ void frame_init(mpg123_handle *fr)
void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
{
fr->own_buffer = FALSE;
fr->own_buffer = TRUE;
fr->buffer.data = NULL;
fr->buffer.rdata = NULL;
fr->buffer.fill = 0;
fr->buffer.size = 0;
fr->rawbuffs = NULL;
fr->rawbuffss = 0;
fr->rawdecwin = NULL;
@ -67,6 +88,7 @@ void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
#ifdef OPT_DITHER
fr->dithernoise = NULL;
#endif
fr->layerscratch = NULL;
fr->xing_toc = NULL;
fr->cpu_opts.type = defdec();
fr->cpu_opts.class = decclass(fr->cpu_opts.type);
@ -86,11 +108,21 @@ void frame_init_par(mpg123_handle *fr, mpg123_pars *mp)
invalidate_format(&fr->af);
fr->rdat.r_read = NULL;
fr->rdat.r_lseek = NULL;
fr->rdat.iohandle = NULL;
fr->rdat.r_read_handle = NULL;
fr->rdat.r_lseek_handle = NULL;
fr->rdat.cleanup_handle = NULL;
fr->wrapperdata = NULL;
fr->wrapperclean = NULL;
fr->decoder_change = 1;
fr->err = MPG123_OK;
if(mp == NULL) frame_default_pars(&fr->p);
else memcpy(&fr->p, mp, sizeof(struct mpg123_pars_struct));
#ifndef NO_FEEDER
bc_prepare(&fr->rdat.buffer, fr->p.feedpool, fr->p.feedbuffer);
#endif
fr->down_sample = 0; /* Initialize to silence harmless errors when debugging. */
frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */
fr->synth = NULL;
@ -143,34 +175,51 @@ int attribute_align_arg mpg123_reset_eq(mpg123_handle *mh)
int frame_outbuffer(mpg123_handle *fr)
{
size_t size = mpg123_safe_buffer()*AUDIOBUFSIZE;
if(!fr->own_buffer) fr->buffer.data = NULL;
if(fr->buffer.data != NULL && fr->buffer.size != size)
size_t size = fr->outblock;
if(!fr->own_buffer)
{
free(fr->buffer.data);
fr->buffer.data = NULL;
if(fr->buffer.size < size)
{
fr->err = MPG123_BAD_BUFFER;
if(NOQUIET) error2("have external buffer of size %"SIZE_P", need %"SIZE_P, (size_p)fr->buffer.size, size);
return MPG123_ERR;
}
}
debug1("need frame buffer of %"SIZE_P, (size_p)size);
if(fr->buffer.rdata != NULL && fr->buffer.size != size)
{
free(fr->buffer.rdata);
fr->buffer.rdata = NULL;
}
fr->buffer.size = size;
if(fr->buffer.data == NULL) fr->buffer.data = (unsigned char*) malloc(fr->buffer.size);
if(fr->buffer.data == NULL)
fr->buffer.data = NULL;
/* be generous: use 16 byte alignment */
if(fr->buffer.rdata == NULL) fr->buffer.rdata = (unsigned char*) malloc(fr->buffer.size+15);
if(fr->buffer.rdata == NULL)
{
fr->err = MPG123_OUT_OF_MEM;
return -1;
return MPG123_ERR;
}
fr->buffer.data = aligned_pointer(fr->buffer.rdata, unsigned char*, 16);
fr->own_buffer = TRUE;
fr->buffer.fill = 0;
return 0;
return MPG123_OK;
}
int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size)
{
if(data == NULL || size < mpg123_safe_buffer())
debug2("replace buffer with %p size %"SIZE_P, data, (size_p)size);
/* Will accept any size, the error comes later... */
if(data == NULL)
{
mh->err = MPG123_BAD_BUFFER;
return MPG123_ERR;
}
if(mh->own_buffer && mh->buffer.data != NULL) free(mh->buffer.data);
if(mh->buffer.rdata != NULL) free(mh->buffer.rdata);
mh->own_buffer = FALSE;
mh->buffer.rdata = NULL;
mh->buffer.data = data;
mh->buffer.size = size;
mh->buffer.fill = 0;
@ -293,8 +342,9 @@ int frame_buffers(mpg123_handle *fr)
#endif
#endif
#if defined(OPT_ALTIVEC) || defined(OPT_ARM)
if(decwin_size < (512+32)*4) decwin_size = (512+32)*4;
decwin_size += 512*4;
/* sizeof(real) >= 4 ... yes, it could be 8, for example.
We got it intialized to at least (512+32)*sizeof(real).*/
decwin_size += 512*sizeof(real);
#endif
/* Hm, that's basically realloc() ... */
if(fr->rawdecwin != NULL && fr->rawdecwins != decwin_size)
@ -327,6 +377,51 @@ int frame_buffers(mpg123_handle *fr)
#endif
#endif
}
/* Layer scratch buffers are of compile-time fixed size, so allocate only once. */
if(fr->layerscratch == NULL)
{
/* Allocate specific layer1/2/3 buffers, so that we know they'll work for SSE. */
size_t scratchsize = 0;
real *scratcher;
#ifndef NO_LAYER1
scratchsize += sizeof(real) * 2 * SBLIMIT;
#endif
#ifndef NO_LAYER2
scratchsize += sizeof(real) * 2 * 4 * SBLIMIT;
#endif
#ifndef NO_LAYER3
scratchsize += sizeof(real) * 2 * SBLIMIT * SSLIMIT; /* hybrid_in */
scratchsize += sizeof(real) * 2 * SSLIMIT * SBLIMIT; /* hybrid_out */
#endif
/*
Now figure out correct alignment:
We need 16 byte minimum, smallest unit of the blocks is 2*SBLIMIT*sizeof(real), which is 64*4=256. Let's do 64bytes as heuristic for cache line (as proven useful in buffs above).
*/
fr->layerscratch = malloc(scratchsize+63);
if(fr->layerscratch == NULL) return -1;
/* Get aligned part of the memory, then divide it up. */
scratcher = aligned_pointer(fr->layerscratch,real,64);
/* Those funky pointer casts silence compilers...
One might change the code at hand to really just use 1D arrays, but in practice, that would not make a (positive) difference. */
#ifndef NO_LAYER1
fr->layer1.fraction = (real(*)[SBLIMIT])scratcher;
scratcher += 2 * SBLIMIT;
#endif
#ifndef NO_LAYER2
fr->layer2.fraction = (real(*)[4][SBLIMIT])scratcher;
scratcher += 2 * 4 * SBLIMIT;
#endif
#ifndef NO_LAYER3
fr->layer3.hybrid_in = (real(*)[SBLIMIT][SSLIMIT])scratcher;
scratcher += 2 * SBLIMIT * SSLIMIT;
fr->layer3.hybrid_out = (real(*)[SSLIMIT][SBLIMIT])scratcher;
scratcher += 2 * SSLIMIT * SBLIMIT;
#endif
/* Note: These buffers don't need resetting here. */
}
/* Only reset the buffers we created just now. */
frame_decode_buffers_reset(fr);
@ -341,7 +436,7 @@ int frame_buffers_reset(mpg123_handle *fr)
/* Wondering: could it be actually _wanted_ to retain buffer contents over different files? (special gapless / cut stuff) */
fr->bsbuf = fr->bsspace[1];
fr->bsbufold = fr->bsbuf;
fr->bitreservoir = 0; /* Not entirely sure if this is the right place for that counter. */
fr->bitreservoir = 0;
frame_decode_buffers_reset(fr);
memset(fr->bsspace, 0, 2*(MAXFRAMESIZE+512));
memset(fr->ssave, 0, 34);
@ -350,7 +445,7 @@ int frame_buffers_reset(mpg123_handle *fr)
return 0;
}
void frame_icy_reset(mpg123_handle* fr)
static void frame_icy_reset(mpg123_handle* fr)
{
#ifndef NO_ICY
if(fr->icy.data != NULL) free(fr->icy.data);
@ -360,7 +455,7 @@ void frame_icy_reset(mpg123_handle* fr)
#endif
}
void frame_free_toc(mpg123_handle *fr)
static void frame_free_toc(mpg123_handle *fr)
{
if(fr->xing_toc != NULL){ free(fr->xing_toc); fr->xing_toc = NULL; }
}
@ -407,10 +502,11 @@ static void frame_fixed_reset(mpg123_handle *fr)
fr->to_decode = FALSE;
fr->to_ignore = FALSE;
fr->metaflags = 0;
fr->outblock = mpg123_safe_buffer();
fr->outblock = 0; /* This will be set before decoding! */
fr->num = -1;
fr->input_offset = -1;
fr->playnum = -1;
fr->accurate = TRUE;
fr->state_flags = FRAME_ACCURATE;
fr->silent_resync = 0;
fr->audio_start = 0;
fr->clip = 0;
@ -438,7 +534,7 @@ static void frame_fixed_reset(mpg123_handle *fr)
fr->fresh = 1;
fr->new_format = 0;
#ifdef GAPLESS
frame_gapless_init(fr,0,0);
frame_gapless_init(fr,-1,0,0);
fr->lastoff = 0;
fr->firstoff = 0;
#endif
@ -461,7 +557,7 @@ static void frame_fixed_reset(mpg123_handle *fr)
fr->freeformat_framesize = -1;
}
void frame_free_buffers(mpg123_handle *fr)
static void frame_free_buffers(mpg123_handle *fr)
{
if(fr->rawbuffs != NULL) free(fr->rawbuffs);
fr->rawbuffs = NULL;
@ -473,16 +569,17 @@ void frame_free_buffers(mpg123_handle *fr)
if(fr->conv16to8_buf != NULL) free(fr->conv16to8_buf);
fr->conv16to8_buf = NULL;
#endif
if(fr->layerscratch != NULL) free(fr->layerscratch);
}
void frame_exit(mpg123_handle *fr)
{
if(fr->own_buffer && fr->buffer.data != NULL)
if(fr->buffer.rdata != NULL)
{
debug1("freeing buffer at %p", (void*)fr->buffer.data);
free(fr->buffer.data);
debug1("freeing buffer at %p", (void*)fr->buffer.rdata);
free(fr->buffer.rdata);
}
fr->buffer.data = NULL;
fr->buffer.rdata = NULL;
frame_free_buffers(fr);
frame_free_toc(fr);
#ifdef FRAME_INDEX
@ -497,6 +594,15 @@ void frame_exit(mpg123_handle *fr)
#endif
exit_id3(fr);
clear_icy(&fr->icy);
/* Clean up possible mess from LFS wrapper. */
if(fr->wrapperclean != NULL)
{
fr->wrapperclean(fr->wrapperdata);
fr->wrapperdata = NULL;
}
#ifndef NO_FEEDER
bc_cleanup(&fr->rdat.buffer);
#endif
}
int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi)
@ -532,6 +638,17 @@ int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *
return MPG123_OK;
}
int attribute_align_arg mpg123_framedata(mpg123_handle *mh, unsigned long *header, unsigned char **bodydata, size_t *bodybytes)
{
if(mh == NULL) return MPG123_ERR;
if(!mh->to_decode) return MPG123_ERR;
if(header != NULL) *header = mh->oldhead;
if(bodydata != NULL) *bodydata = mh->bsbuf;
if(bodybytes != NULL) *bodybytes = mh->framesize;
return MPG123_OK;
}
/*
Fuzzy frame offset searching (guessing).
@ -541,7 +658,7 @@ int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *
- guess wildly from mean framesize and offset of first frame / beginning of file.
*/
off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
static off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
{
/* Default is to go to the beginning. */
off_t ret = fr->audio_start;
@ -561,7 +678,7 @@ off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
/* Now estimate back what frame we get. */
*get_frame = (off_t) ((double)toc_entry/100. * fr->track_frames);
fr->accurate = FALSE;
fr->state_flags &= ~FRAME_ACCURATE;
fr->silent_resync = 1;
/* Question: Is the TOC for whole file size (with/without ID3) or the "real" audio data only?
ID3v1 info could also matter. */
@ -570,7 +687,7 @@ off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
else if(fr->mean_framesize > 0)
{ /* Just guess with mean framesize (may be exact with CBR files). */
/* Query filelen here or not? */
fr->accurate = FALSE; /* Fuzzy! */
fr->state_flags &= ~FRAME_ACCURATE; /* Fuzzy! */
fr->silent_resync = 1;
*get_frame = want_frame;
ret = (off_t) (fr->audio_start+fr->mean_framesize*want_frame);
@ -617,7 +734,7 @@ off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame)
/* We have index position, that yields frame and byte offsets. */
*get_frame = fi*fr->index.step;
gopos = fr->index.data[fi];
fr->accurate = TRUE; /* When using the frame index, we are accurate. */
fr->state_flags |= FRAME_ACCURATE; /* When using the frame index, we are accurate. */
}
else
{
@ -674,6 +791,28 @@ off_t frame_outs(mpg123_handle *fr, off_t num)
return outs;
}
/* Compute the number of output samples we expect from this frame.
This is either simple spf() or a tad more elaborate for ntom. */
off_t frame_expect_outsamples(mpg123_handle *fr)
{
off_t outs = 0;
switch(fr->down_sample)
{
case 0:
# ifndef NO_DOWNSAMPLE
case 1:
case 2:
# endif
outs = spf(fr)>>fr->down_sample;
break;
#ifndef NO_NTOM
case 3: outs = ntom_frame_outsamples(fr); break;
#endif
default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample);
}
return outs;
}
off_t frame_offset(mpg123_handle *fr, off_t outs)
{
off_t num = 0;
@ -696,35 +835,47 @@ off_t frame_offset(mpg123_handle *fr, off_t outs)
#ifdef GAPLESS
/* input in _input_ samples */
void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e)
void frame_gapless_init(mpg123_handle *fr, off_t framecount, off_t bskip, off_t eskip)
{
fr->begin_s = b;
fr->end_s = e;
debug3("frame_gaples_init: given %"OFF_P" frames, skip %"OFF_P" and %"OFF_P, (off_p)framecount, (off_p)bskip, (off_p)eskip);
fr->gapless_frames = framecount;
if(fr->gapless_frames > 0)
{
fr->begin_s = bskip+GAPLESS_DELAY;
fr->end_s = framecount*spf(fr)-eskip+GAPLESS_DELAY;
}
else fr->begin_s = fr->end_s = 0;
/* These will get proper values later, from above plus resampling info. */
fr->begin_os = 0;
fr->end_os = 0;
debug2("frame_gapless_init: from %lu to %lu samples", (long unsigned)fr->begin_s, (long unsigned)fr->end_s);
fr->fullend_os = 0;
debug2("frame_gapless_init: from %"OFF_P" to %"OFF_P" samples", (off_p)fr->begin_s, (off_p)fr->end_s);
}
void frame_gapless_realinit(mpg123_handle *fr)
{
fr->begin_os = frame_ins2outs(fr, fr->begin_s);
fr->end_os = frame_ins2outs(fr, fr->end_s);
debug2("frame_gapless_realinit: from %lu to %lu samples", (long unsigned)fr->begin_os, (long unsigned)fr->end_os);
fr->fullend_os = frame_ins2outs(fr, fr->gapless_frames*spf(fr));
debug2("frame_gapless_realinit: from %"OFF_P" to %"OFF_P" samples", (off_p)fr->begin_os, (off_p)fr->end_os);
}
/* When we got a new sample count, update the gaplessness. */
/* At least note when there is trouble... */
void frame_gapless_update(mpg123_handle *fr, off_t total_samples)
{
if(fr->end_s < 1)
off_t gapless_samples = fr->gapless_frames*spf(fr);
debug2("gapless update with new sample count %"OFF_P" as opposed to known %"OFF_P, total_samples, gapless_samples);
if(NOQUIET && total_samples != gapless_samples)
fprintf(stderr, "\nWarning: Real sample count differs from given gapless sample count. Frankenstein stream?\n");
if(gapless_samples > total_samples)
{
fr->end_s = total_samples;
if(NOQUIET) error2("End sample count smaller than gapless end! (%"OFF_P" < %"OFF_P"). Disabling gapless mode from now on.", (off_p)total_samples, (off_p)fr->end_s);
/* This invalidates the current position... but what should I do? */
frame_gapless_init(fr, -1, 0, 0);
frame_gapless_realinit(fr);
}
else if(fr->end_s > total_samples)
{
if(NOQUIET) error2("end sample count smaller than gapless end! (%"OFF_P" < %"OFF_P").", (off_p)total_samples, (off_p)fr->end_s);
fr->end_s = total_samples;
fr->lastframe = -1;
fr->lastoff = 0;
}
}
@ -750,7 +901,7 @@ void frame_set_frameseek(mpg123_handle *fr, off_t fe)
{
fr->firstframe = fe;
#ifdef GAPLESS
if(fr->p.flags & MPG123_GAPLESS)
if(fr->p.flags & MPG123_GAPLESS && fr->gapless_frames > 0)
{
/* Take care of the beginning... */
off_t beg_f = frame_offset(fr, fr->begin_os);
@ -765,7 +916,7 @@ void frame_set_frameseek(mpg123_handle *fr, off_t fe)
{
fr->lastframe = frame_offset(fr,fr->end_os);
fr->lastoff = fr->end_os - frame_outs(fr, fr->lastframe);
} else fr->lastoff = 0;
} else {fr->lastframe = -1; fr->lastoff = 0; }
} else { fr->firstoff = fr->lastoff = 0; fr->lastframe = -1; }
#endif
fr->ignoreframe = ignoreframe(fr);
@ -791,6 +942,7 @@ void frame_skip(mpg123_handle *fr)
void frame_set_seek(mpg123_handle *fr, off_t sp)
{
fr->firstframe = frame_offset(fr, sp);
debug1("frame_set_seek: from %"OFF_P, fr->num);
#ifndef NO_NTOM
if(fr->down_sample == 3) ntom_set_ntom(fr, fr->firstframe);
#endif
@ -886,3 +1038,9 @@ int attribute_align_arg mpg123_getvolume(mpg123_handle *mh, double *base, double
return MPG123_OK;
}
off_t attribute_align_arg mpg123_framepos(mpg123_handle *mh)
{
if(mh == NULL) return MPG123_ERR;
return mh->input_offset;
}

View File

@ -38,10 +38,11 @@ struct al_table
/* the output buffer, used to be pcm_sample, pcm_point and audiobufsize */
struct outbuffer
{
unsigned char *data;
unsigned char *data; /* main data pointer, aligned */
unsigned char *p; /* read pointer */
size_t fill; /* fill from read pointer */
size_t size; /* that's actually more like a safe size, after we have more than that, flush it */
size_t size;
unsigned char *rdata; /* unaligned base pointer */
};
struct audioformat
@ -65,9 +66,7 @@ struct mpg123_pars_struct
int rva; /* (which) rva to do: 0: nothing, 1: radio/mix/track 2: album/audiophile */
long halfspeed;
long doublespeed;
#ifndef WIN32
long timeout;
#endif
#define NUM_CHANNELS 2
char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS];
/* long start_frame; */ /* frame offset to begin with */
@ -79,9 +78,17 @@ struct mpg123_pars_struct
long resync_limit;
long index_size; /* Long, because: negative values have a meaning. */
long preframes;
#ifndef NO_FEEDER
long feedpool;
long feedbuffer;
#endif
};
enum frame_state_flags
{
FRAME_ACCURATE = 0x1 /**< 0001 Positions are considered accurate. */
,FRAME_FRANKENSTEIN = 0x2 /**< 0010 This stream is concatenated. */
};
/* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */
struct mpg123_handle_struct
@ -152,7 +159,7 @@ struct mpg123_handle_struct
#ifndef NO_LAYER3
#if (defined OPT_3DNOW || defined OPT_3DNOWEXT)
void (*dct36)(real *,real *,real *,real *,real *);
void (*the_dct36)(real *,real *,real *,real *,real *);
#endif
#endif
@ -201,9 +208,10 @@ struct mpg123_handle_struct
int freesize; /* free format frame size */
enum mpg123_vbr vbr; /* 1 if variable bitrate was detected */
off_t num; /* frame offset ... */
off_t input_offset; /* byte offset of this frame in input stream */
off_t playnum; /* playback offset... includes repetitions, reset at seeks */
off_t audio_start; /* The byte offset in the file where audio data begins. */
char accurate; /* Flag to see if we trust the frame number. */
int state_flags;
char silent_resync; /* Do not complain for the next n resyncs. */
unsigned char* xing_toc; /* The seek TOC from Xing header. */
int freeformat;
@ -239,7 +247,9 @@ struct mpg123_handle_struct
unsigned char *bsbuf;
unsigned char *bsbufold;
int bsnum;
/* That is the header matching the last read frame body. */
unsigned long oldhead;
/* That is the header that is supposedly the first of the stream. */
unsigned long firsthead;
int abr_rate;
#ifdef FRAME_INDEX
@ -257,12 +267,14 @@ struct mpg123_handle_struct
off_t lastframe; /* last frame to decode (for gapless or num_frames limit) */
off_t ignoreframe; /* frames to decode but discard before firstframe */
#ifdef GAPLESS
off_t gapless_frames; /* frame count for the gapless part */
off_t firstoff; /* number of samples to ignore from firstframe */
off_t lastoff; /* number of samples to use from lastframe */
off_t begin_s; /* overall begin offset in samples */
off_t begin_os;
off_t end_s; /* overall end offset in samples */
off_t end_os;
off_t fullend_os; /* gapless_frames translated to output samples */
#endif
unsigned int crc; /* Well, I need a safe 16bit type, actually. But wider doesn't hurt. */
struct reader *rd; /* pointer to the reading functions */
@ -281,6 +293,41 @@ struct mpg123_handle_struct
#ifndef NO_ICY
struct icy_meta icy;
#endif
/*
More variables needed for decoders, layerX.c.
This time it is not about static variables but about the need for alignment which cannot be guaranteed on the stack by certain compilers (Sun Studio).
We do not require the compiler to align stuff for our hand-written assembly. We only hope that it's able to align stuff for SSE and similar ops it generates itself.
*/
/*
Those layer-specific structs could actually share memory, as they are not in use simultaneously. One might allocate on decoder switch, too.
They all reside in one lump of memory (after each other), allocated to layerscratch.
*/
real *layerscratch;
#ifndef NO_LAYER1
struct
{
real (*fraction)[SBLIMIT]; /* ALIGNED(16) real fraction[2][SBLIMIT]; */
} layer1;
#endif
#ifndef NO_LAYER2
struct
{
real (*fraction)[4][SBLIMIT]; /* ALIGNED(16) real fraction[2][4][SBLIMIT] */
} layer2;
#endif
#ifndef NO_LAYER3
/* These are significant chunks of memory already... */
struct
{
real (*hybrid_in)[SBLIMIT][SSLIMIT]; /* ALIGNED(16) real hybridIn[2][SBLIMIT][SSLIMIT]; */
real (*hybrid_out)[SSLIMIT][SBLIMIT]; /* ALIGNED(16) real hybridOut[2][SSLIMIT][SBLIMIT]; */
} layer3;
#endif
/* A place for storing additional data for the large file wrapper.
This is cruft! */
void *wrapperdata;
/* A callback used to properly destruct the wrapper data. */
void (*wrapperclean)(void*);
};
/* generic init, does not include dynamic buffers */
@ -328,8 +375,7 @@ MPEG 2.5
#ifdef GAPLESS
/* well, I take that one for granted... at least layer3 */
#define GAPLESS_DELAY 529
/* still fine-tuning the "real music" window... see read_frame */
void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e);
void frame_gapless_init(mpg123_handle *fr, off_t framecount, off_t bskip, off_t eskip);
void frame_gapless_realinit(mpg123_handle *fr);
void frame_gapless_update(mpg123_handle *mh, off_t total_samples);
/*void frame_gapless_position(mpg123_handle* fr);
@ -338,6 +384,9 @@ void frame_gapless_ignore(mpg123_handle *fr, off_t frames);*/
/* void frame_gapless_buffercheck(mpg123_handle *fr); */
#endif
/* Number of samples the decoding of the current frame should yield. */
off_t frame_expect_outsamples(mpg123_handle *fr);
/* Skip this frame... do some fake action to get away without actually decoding it. */
void frame_skip(mpg123_handle *fr);
@ -350,14 +399,12 @@ void frame_skip(mpg123_handle *fr);
*/
off_t frame_ins2outs(mpg123_handle *fr, off_t ins);
off_t frame_outs(mpg123_handle *fr, off_t num);
/* This one just computes the expected sample count for _this_ frame. */
off_t frame_expect_outsampels(mpg123_handle *fr);
off_t frame_offset(mpg123_handle *fr, off_t outs);
void frame_set_frameseek(mpg123_handle *fr, off_t fe);
void frame_set_seek(mpg123_handle *fr, off_t sp);
off_t frame_tell_seek(mpg123_handle *fr);
/* Take a copy of the Xing VBR TOC for fuzzy seeking. */
int frame_fill_toc(mpg123_handle *fr, unsigned char* in);
/* adjust volume to current outscale and rva values if wanted */
void do_rva(mpg123_handle *fr);
#endif

View File

@ -0,0 +1,119 @@
/*
sampleadjust: gapless sample offset math
copyright 1995-2012 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
This is no stand-alone header, precisely to be able to fool it into using fake handle types for testing the math.
*/
#include "debug.h"
#ifdef GAPLESS
/* From internal sample number to external. */
static off_t sample_adjust(mpg123_handle *mh, off_t x)
{
off_t s;
if(mh->p.flags & MPG123_GAPLESS)
{
/* It's a bit tricky to do this computation for the padding samples.
They are not there on the outside. */
if(x > mh->end_os)
{
if(x < mh->fullend_os)
s = mh->end_os - mh->begin_os;
else
s = x - (mh->fullend_os - mh->end_os + mh->begin_os);
}
else
s = x - mh->begin_os;
}
else
s = x;
return s;
}
/* from external samples to internal */
static off_t sample_unadjust(mpg123_handle *mh, off_t x)
{
off_t s;
if(mh->p.flags & MPG123_GAPLESS)
{
s = x + mh->begin_os;
/* There is a hole; we don't create sample positions in there.
Jump from the end of the gapless track directly to after the padding. */
if(s >= mh->end_os)
s += mh->fullend_os - mh->end_os;
}
else s = x;
return s;
}
/*
Take the buffer after a frame decode (strictly: it is the data from frame fr->num!) and cut samples out.
fr->buffer.fill may then be smaller than before...
*/
static void frame_buffercheck(mpg123_handle *fr)
{
/* When we have no accurate position, gapless code does not make sense. */
if(!(fr->state_flags & FRAME_ACCURATE)) return;
/* Get a grip on dirty streams that start with a gapless header.
Simply accept all data from frames that are too much,
they are supposedly attached to the stream after the fact. */
if(fr->gapless_frames > 0 && fr->num >= fr->gapless_frames) return;
/* Important: We first cut samples from the end, then cut from beginning (including left-shift of the buffer).
This order works also for the case where firstframe == lastframe. */
/* The last interesting (planned) frame: Only use some leading samples.
Note a difference from the below: The last frame and offset are unchanges by seeks.
The lastoff keeps being valid. */
if(fr->lastframe > -1 && fr->num >= fr->lastframe)
{
/* There can be more than one frame of padding at the end, so we ignore the whole frame if we are beyond lastframe. */
off_t byteoff = (fr->num == fr->lastframe) ? samples_to_bytes(fr, fr->lastoff) : 0;
if((off_t)fr->buffer.fill > byteoff)
{
fr->buffer.fill = byteoff;
}
if(VERBOSE3) fprintf(stderr, "\nNote: Cut frame %"OFF_P" buffer on end of stream to %"OFF_P" samples, fill now %"SIZE_P" bytes.\n", (off_p)fr->num, (off_p)(fr->num == fr->lastframe ? fr->lastoff : 0), (size_p)fr->buffer.fill);
}
/* The first interesting frame: Skip some leading samples. */
if(fr->firstoff && fr->num == fr->firstframe)
{
off_t byteoff = samples_to_bytes(fr, fr->firstoff);
if((off_t)fr->buffer.fill > byteoff)
{
fr->buffer.fill -= byteoff;
/* buffer.p != buffer.data only for own buffer */
debug6("cutting %li samples/%li bytes on begin, own_buffer=%i at %p=%p, buf[1]=%i",
(long)fr->firstoff, (long)byteoff, fr->own_buffer, (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
if(fr->own_buffer) fr->buffer.p = fr->buffer.data + byteoff;
else memmove(fr->buffer.data, fr->buffer.data + byteoff, fr->buffer.fill);
debug3("done cutting, buffer at %p =? %p, buf[1]=%i",
(void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
}
else fr->buffer.fill = 0;
if(VERBOSE3) fprintf(stderr, "\nNote: Cut frame %"OFF_P" buffer on beginning of stream by %"OFF_P" samples, fill now %"SIZE_P" bytes.\n", (off_p)fr->num, (off_p)fr->firstoff, (size_p)fr->buffer.fill);
/* We can only reach this frame again by seeking. And on seeking, firstoff will be recomputed.
So it is safe to null it here (and it makes the if() decision abort earlier). */
fr->firstoff = 0;
}
}
#define SAMPLE_ADJUST(mh,x) sample_adjust(mh,x)
#define SAMPLE_UNADJUST(mh,x) sample_unadjust(mh,x)
#define FRAME_BUFFERCHECK(mh) frame_buffercheck(mh)
#else /* no gapless code included */
#define SAMPLE_ADJUST(mh,x) (x)
#define SAMPLE_UNADJUST(mh,x) (x)
#define FRAME_BUFFERCHECK(mh)
#endif

View File

@ -88,7 +88,4 @@ ASM_NAME(getcpuflags):
popl %ebp
ret
/* Mark non-executable stack. */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
NONEXEC_STACK

View File

@ -31,8 +31,6 @@ struct cpuflags
unsigned int ext;
};
extern struct cpuflags cpu_flags;
unsigned int getcpuflags(struct cpuflags* cf);
/* checks the family */

View File

@ -1,5 +1,5 @@
/*
huffman.h: huffman tables ... recalcualted to work with optimzed decoder scheme (MH)
huffman.h: huffman tables ... recalcualted to work with optimized decoder scheme (MH)
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
@ -16,46 +16,46 @@
struct newhuff
{
unsigned int linbits;
short *table;
const short *table;
};
static short tab0[] =
static const short tab0[] =
{
0
};
static short tab1[] =
static const short tab1[] =
{
-5, -3, -1, 17, 1, 16, 0
};
static short tab2[] =
static const short tab2[] =
{
-15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
16, 0
};
static short tab3[] =
static const short tab3[] =
{
-13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
1, 0
};
static short tab5[] =
static const short tab5[] =
{
-29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19,
3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16,
0
};
static short tab6[] =
static const short tab6[] =
{
-25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19,
49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16,
0
};
static short tab7[] =
static const short tab7[] =
{
-69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83,
-1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1,
@ -64,7 +64,7 @@ static short tab7[] =
-5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0
};
static short tab8[] =
static const short tab8[] =
{
-65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83,
-3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52,
@ -73,7 +73,7 @@ static short tab8[] =
2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0
};
static short tab9[] =
static const short tab9[] =
{
-63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1,
84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67,
@ -82,7 +82,7 @@ static short tab9[] =
18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0
};
static short tab10[] =
static const short tab10[] =
{
-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118,
87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3,
@ -95,7 +95,7 @@ static short tab10[] =
2, 32, 17, -1, 1, 16, 0
};
static short tab11[] =
static const short tab11[] =
{
-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117,
-3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55,
@ -108,7 +108,7 @@ static short tab11[] =
32, 17, -3, -1, 1, 16, 0
};
static short tab12[] =
static const short tab12[] =
{
-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87,
117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115,
@ -121,7 +121,7 @@ static short tab12[] =
2, 32, 0, 17, -1, 1, 16
};
static short tab13[] =
static const short tab13[] =
{
-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9,
-7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238,
@ -160,7 +160,7 @@ static short tab13[] =
0
};
static short tab15[] =
static const short tab15[] =
{
-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239,
-1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237,
@ -199,7 +199,7 @@ static short tab15[] =
0
};
static short tab16[] =
static const short tab16[] =
{
-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223,
253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3,
@ -238,7 +238,7 @@ static short tab16[] =
0
};
static short tab24[] =
static const short tab24[] =
{
-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1,
207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9,
@ -277,14 +277,14 @@ static short tab24[] =
0
};
static short tab_c0[] =
static const short tab_c0[] =
{
-29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5,
9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8,
0
};
static short tab_c1[] =
static const short tab_c1[] =
{
-15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9,
8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1,
@ -293,7 +293,7 @@ static short tab_c1[] =
static struct newhuff ht[] =
static const struct newhuff ht[] =
{
{ /* 0 */ 0 , tab0 } ,
{ /* 2 */ 0 , tab1 } ,
@ -330,7 +330,7 @@ static struct newhuff ht[] =
{ /* 16 */ 13, tab24 }
};
static struct newhuff htc[] =
static const struct newhuff htc[] =
{
{ /* 1 , 1 , */ 0 , tab_c0 } ,
{ /* 1 , 1 , */ 0 , tab_c1 }

View File

@ -26,8 +26,11 @@ void reset_icy(struct icy_meta *);
#else
#undef init_icy
#define init_icy(a)
#undef clear_icy
#define clear_icy(a)
#undef reset_icy
#define reset_icy(a)
#endif /* NO_ICY */

View File

@ -0,0 +1,438 @@
/* mpg123 note: This is BSD-licensed code that is no problem for mpg123 usage under LGPL.
It's Free, understood? ;-) */
/* Another note: This code is basically written by Thorsten Glaser,
Thomas Orgis did just some rearrangements and comments. */
/*-
* Copyright (c) 2008
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission
* is granted to deal in this work without restriction, including un-
* limited rights to use, publicly perform, distribute, sell, modify,
* merge, give away, or sublicence.
*
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
* the utmost extent permitted by applicable law, neither express nor
* implied; without malicious intent or gross negligence. In no event
* may a licensor, author or contributor be held liable for indirect,
* direct, other damage, loss, or other issues arising in any way out
* of dealing in the work, even if advised of the possibility of such
* damage or existence of a defect, except proven that it results out
* of said person's immediate fault when using the work as intended.
*-
* Convert from ICY encoding (windows-1252 codepage) to UTF-8
*/
/* Includes string and stdlib headers... */
#include "compat.h"
/* ThOr: too lazy for this type check; also we use char/short all around anyway.
Of cource, it would be the proper way to use _these_ kind of types all around. */
#define uint8_t unsigned char
#define uint16_t unsigned short
static const uint8_t cp1252_utf8[] = {
/* 0x00 @ 0 */ 0x00,
/* 0x01 @ 1 */ 0x01,
/* 0x02 @ 2 */ 0x02,
/* 0x03 @ 3 */ 0x03,
/* 0x04 @ 4 */ 0x04,
/* 0x05 @ 5 */ 0x05,
/* 0x06 @ 6 */ 0x06,
/* 0x07 @ 7 */ 0x07,
/* 0x08 @ 8 */ 0x08,
/* 0x09 @ 9 */ 0x09,
/* 0x0A @ 10 */ 0x0A,
/* 0x0B @ 11 */ 0x0B,
/* 0x0C @ 12 */ 0x0C,
/* 0x0D @ 13 */ 0x0D,
/* 0x0E @ 14 */ 0x0E,
/* 0x0F @ 15 */ 0x0F,
/* 0x10 @ 16 */ 0x10,
/* 0x11 @ 17 */ 0x11,
/* 0x12 @ 18 */ 0x12,
/* 0x13 @ 19 */ 0x13,
/* 0x14 @ 20 */ 0x14,
/* 0x15 @ 21 */ 0x15,
/* 0x16 @ 22 */ 0x16,
/* 0x17 @ 23 */ 0x17,
/* 0x18 @ 24 */ 0x18,
/* 0x19 @ 25 */ 0x19,
/* 0x1A @ 26 */ 0x1A,
/* 0x1B @ 27 */ 0x1B,
/* 0x1C @ 28 */ 0x1C,
/* 0x1D @ 29 */ 0x1D,
/* 0x1E @ 30 */ 0x1E,
/* 0x1F @ 31 */ 0x1F,
/* 0x20 @ 32 */ 0x20,
/* 0x21 @ 33 */ 0x21,
/* 0x22 @ 34 */ 0x22,
/* 0x23 @ 35 */ 0x23,
/* 0x24 @ 36 */ 0x24,
/* 0x25 @ 37 */ 0x25,
/* 0x26 @ 38 */ 0x26,
/* 0x27 @ 39 */ 0x27,
/* 0x28 @ 40 */ 0x28,
/* 0x29 @ 41 */ 0x29,
/* 0x2A @ 42 */ 0x2A,
/* 0x2B @ 43 */ 0x2B,
/* 0x2C @ 44 */ 0x2C,
/* 0x2D @ 45 */ 0x2D,
/* 0x2E @ 46 */ 0x2E,
/* 0x2F @ 47 */ 0x2F,
/* 0x30 @ 48 */ 0x30,
/* 0x31 @ 49 */ 0x31,
/* 0x32 @ 50 */ 0x32,
/* 0x33 @ 51 */ 0x33,
/* 0x34 @ 52 */ 0x34,
/* 0x35 @ 53 */ 0x35,
/* 0x36 @ 54 */ 0x36,
/* 0x37 @ 55 */ 0x37,
/* 0x38 @ 56 */ 0x38,
/* 0x39 @ 57 */ 0x39,
/* 0x3A @ 58 */ 0x3A,
/* 0x3B @ 59 */ 0x3B,
/* 0x3C @ 60 */ 0x3C,
/* 0x3D @ 61 */ 0x3D,
/* 0x3E @ 62 */ 0x3E,
/* 0x3F @ 63 */ 0x3F,
/* 0x40 @ 64 */ 0x40,
/* 0x41 @ 65 */ 0x41,
/* 0x42 @ 66 */ 0x42,
/* 0x43 @ 67 */ 0x43,
/* 0x44 @ 68 */ 0x44,
/* 0x45 @ 69 */ 0x45,
/* 0x46 @ 70 */ 0x46,
/* 0x47 @ 71 */ 0x47,
/* 0x48 @ 72 */ 0x48,
/* 0x49 @ 73 */ 0x49,
/* 0x4A @ 74 */ 0x4A,
/* 0x4B @ 75 */ 0x4B,
/* 0x4C @ 76 */ 0x4C,
/* 0x4D @ 77 */ 0x4D,
/* 0x4E @ 78 */ 0x4E,
/* 0x4F @ 79 */ 0x4F,
/* 0x50 @ 80 */ 0x50,
/* 0x51 @ 81 */ 0x51,
/* 0x52 @ 82 */ 0x52,
/* 0x53 @ 83 */ 0x53,
/* 0x54 @ 84 */ 0x54,
/* 0x55 @ 85 */ 0x55,
/* 0x56 @ 86 */ 0x56,
/* 0x57 @ 87 */ 0x57,
/* 0x58 @ 88 */ 0x58,
/* 0x59 @ 89 */ 0x59,
/* 0x5A @ 90 */ 0x5A,
/* 0x5B @ 91 */ 0x5B,
/* 0x5C @ 92 */ 0x5C,
/* 0x5D @ 93 */ 0x5D,
/* 0x5E @ 94 */ 0x5E,
/* 0x5F @ 95 */ 0x5F,
/* 0x60 @ 96 */ 0x60,
/* 0x61 @ 97 */ 0x61,
/* 0x62 @ 98 */ 0x62,
/* 0x63 @ 99 */ 0x63,
/* 0x64 @ 100 */ 0x64,
/* 0x65 @ 101 */ 0x65,
/* 0x66 @ 102 */ 0x66,
/* 0x67 @ 103 */ 0x67,
/* 0x68 @ 104 */ 0x68,
/* 0x69 @ 105 */ 0x69,
/* 0x6A @ 106 */ 0x6A,
/* 0x6B @ 107 */ 0x6B,
/* 0x6C @ 108 */ 0x6C,
/* 0x6D @ 109 */ 0x6D,
/* 0x6E @ 110 */ 0x6E,
/* 0x6F @ 111 */ 0x6F,
/* 0x70 @ 112 */ 0x70,
/* 0x71 @ 113 */ 0x71,
/* 0x72 @ 114 */ 0x72,
/* 0x73 @ 115 */ 0x73,
/* 0x74 @ 116 */ 0x74,
/* 0x75 @ 117 */ 0x75,
/* 0x76 @ 118 */ 0x76,
/* 0x77 @ 119 */ 0x77,
/* 0x78 @ 120 */ 0x78,
/* 0x79 @ 121 */ 0x79,
/* 0x7A @ 122 */ 0x7A,
/* 0x7B @ 123 */ 0x7B,
/* 0x7C @ 124 */ 0x7C,
/* 0x7D @ 125 */ 0x7D,
/* 0x7E @ 126 */ 0x7E,
/* 0x7F @ 127 */ 0x7F,
/* 0x80 @ 128 */ 0xE2, 0x82, 0xAC,
/* 0x81 @ 131 */ 0xEF, 0xBF, 0xBD,
/* 0x82 @ 134 */ 0xE2, 0x80, 0x9A,
/* 0x83 @ 137 */ 0xC6, 0x92,
/* 0x84 @ 139 */ 0xE2, 0x80, 0x9E,
/* 0x85 @ 142 */ 0xE2, 0x80, 0xA6,
/* 0x86 @ 145 */ 0xE2, 0x80, 0xA0,
/* 0x87 @ 148 */ 0xE2, 0x80, 0xA1,
/* 0x88 @ 151 */ 0xCB, 0x86,
/* 0x89 @ 153 */ 0xE2, 0x80, 0xB0,
/* 0x8A @ 156 */ 0xC5, 0xA0,
/* 0x8B @ 158 */ 0xE2, 0x80, 0xB9,
/* 0x8C @ 161 */ 0xC5, 0x92,
/* 0x8D @ 163 */ 0xEF, 0xBF, 0xBD,
/* 0x8E @ 166 */ 0xC5, 0xBD,
/* 0x8F @ 168 */ 0xEF, 0xBF, 0xBD,
/* 0x90 @ 171 */ 0xEF, 0xBF, 0xBD,
/* 0x91 @ 174 */ 0xE2, 0x80, 0x98,
/* 0x92 @ 177 */ 0xE2, 0x80, 0x99,
/* 0x93 @ 180 */ 0xE2, 0x80, 0x9C,
/* 0x94 @ 183 */ 0xE2, 0x80, 0x9D,
/* 0x95 @ 186 */ 0xE2, 0x80, 0xA2,
/* 0x96 @ 189 */ 0xE2, 0x80, 0x93,
/* 0x97 @ 192 */ 0xE2, 0x80, 0x94,
/* 0x98 @ 195 */ 0xCB, 0x9C,
/* 0x99 @ 197 */ 0xE2, 0x84, 0xA2,
/* 0x9A @ 200 */ 0xC5, 0xA1,
/* 0x9B @ 202 */ 0xE2, 0x80, 0xBA,
/* 0x9C @ 205 */ 0xC5, 0x93,
/* 0x9D @ 207 */ 0xEF, 0xBF, 0xBD,
/* 0x9E @ 210 */ 0xC5, 0xBE,
/* 0x9F @ 212 */ 0xC5, 0xB8,
/* 0xA0 @ 214 */ 0xC2, 0xA0,
/* 0xA1 @ 216 */ 0xC2, 0xA1,
/* 0xA2 @ 218 */ 0xC2, 0xA2,
/* 0xA3 @ 220 */ 0xC2, 0xA3,
/* 0xA4 @ 222 */ 0xC2, 0xA4,
/* 0xA5 @ 224 */ 0xC2, 0xA5,
/* 0xA6 @ 226 */ 0xC2, 0xA6,
/* 0xA7 @ 228 */ 0xC2, 0xA7,
/* 0xA8 @ 230 */ 0xC2, 0xA8,
/* 0xA9 @ 232 */ 0xC2, 0xA9,
/* 0xAA @ 234 */ 0xC2, 0xAA,
/* 0xAB @ 236 */ 0xC2, 0xAB,
/* 0xAC @ 238 */ 0xC2, 0xAC,
/* 0xAD @ 240 */ 0xC2, 0xAD,
/* 0xAE @ 242 */ 0xC2, 0xAE,
/* 0xAF @ 244 */ 0xC2, 0xAF,
/* 0xB0 @ 246 */ 0xC2, 0xB0,
/* 0xB1 @ 248 */ 0xC2, 0xB1,
/* 0xB2 @ 250 */ 0xC2, 0xB2,
/* 0xB3 @ 252 */ 0xC2, 0xB3,
/* 0xB4 @ 254 */ 0xC2, 0xB4,
/* 0xB5 @ 256 */ 0xC2, 0xB5,
/* 0xB6 @ 258 */ 0xC2, 0xB6,
/* 0xB7 @ 260 */ 0xC2, 0xB7,
/* 0xB8 @ 262 */ 0xC2, 0xB8,
/* 0xB9 @ 264 */ 0xC2, 0xB9,
/* 0xBA @ 266 */ 0xC2, 0xBA,
/* 0xBB @ 268 */ 0xC2, 0xBB,
/* 0xBC @ 270 */ 0xC2, 0xBC,
/* 0xBD @ 272 */ 0xC2, 0xBD,
/* 0xBE @ 274 */ 0xC2, 0xBE,
/* 0xBF @ 276 */ 0xC2, 0xBF,
/* 0xC0 @ 278 */ 0xC3, 0x80,
/* 0xC1 @ 280 */ 0xC3, 0x81,
/* 0xC2 @ 282 */ 0xC3, 0x82,
/* 0xC3 @ 284 */ 0xC3, 0x83,
/* 0xC4 @ 286 */ 0xC3, 0x84,
/* 0xC5 @ 288 */ 0xC3, 0x85,
/* 0xC6 @ 290 */ 0xC3, 0x86,
/* 0xC7 @ 292 */ 0xC3, 0x87,
/* 0xC8 @ 294 */ 0xC3, 0x88,
/* 0xC9 @ 296 */ 0xC3, 0x89,
/* 0xCA @ 298 */ 0xC3, 0x8A,
/* 0xCB @ 300 */ 0xC3, 0x8B,
/* 0xCC @ 302 */ 0xC3, 0x8C,
/* 0xCD @ 304 */ 0xC3, 0x8D,
/* 0xCE @ 306 */ 0xC3, 0x8E,
/* 0xCF @ 308 */ 0xC3, 0x8F,
/* 0xD0 @ 310 */ 0xC3, 0x90,
/* 0xD1 @ 312 */ 0xC3, 0x91,
/* 0xD2 @ 314 */ 0xC3, 0x92,
/* 0xD3 @ 316 */ 0xC3, 0x93,
/* 0xD4 @ 318 */ 0xC3, 0x94,
/* 0xD5 @ 320 */ 0xC3, 0x95,
/* 0xD6 @ 322 */ 0xC3, 0x96,
/* 0xD7 @ 324 */ 0xC3, 0x97,
/* 0xD8 @ 326 */ 0xC3, 0x98,
/* 0xD9 @ 328 */ 0xC3, 0x99,
/* 0xDA @ 330 */ 0xC3, 0x9A,
/* 0xDB @ 332 */ 0xC3, 0x9B,
/* 0xDC @ 334 */ 0xC3, 0x9C,
/* 0xDD @ 336 */ 0xC3, 0x9D,
/* 0xDE @ 338 */ 0xC3, 0x9E,
/* 0xDF @ 340 */ 0xC3, 0x9F,
/* 0xE0 @ 342 */ 0xC3, 0xA0,
/* 0xE1 @ 344 */ 0xC3, 0xA1,
/* 0xE2 @ 346 */ 0xC3, 0xA2,
/* 0xE3 @ 348 */ 0xC3, 0xA3,
/* 0xE4 @ 350 */ 0xC3, 0xA4,
/* 0xE5 @ 352 */ 0xC3, 0xA5,
/* 0xE6 @ 354 */ 0xC3, 0xA6,
/* 0xE7 @ 356 */ 0xC3, 0xA7,
/* 0xE8 @ 358 */ 0xC3, 0xA8,
/* 0xE9 @ 360 */ 0xC3, 0xA9,
/* 0xEA @ 362 */ 0xC3, 0xAA,
/* 0xEB @ 364 */ 0xC3, 0xAB,
/* 0xEC @ 366 */ 0xC3, 0xAC,
/* 0xED @ 368 */ 0xC3, 0xAD,
/* 0xEE @ 370 */ 0xC3, 0xAE,
/* 0xEF @ 372 */ 0xC3, 0xAF,
/* 0xF0 @ 374 */ 0xC3, 0xB0,
/* 0xF1 @ 376 */ 0xC3, 0xB1,
/* 0xF2 @ 378 */ 0xC3, 0xB2,
/* 0xF3 @ 380 */ 0xC3, 0xB3,
/* 0xF4 @ 382 */ 0xC3, 0xB4,
/* 0xF5 @ 384 */ 0xC3, 0xB5,
/* 0xF6 @ 386 */ 0xC3, 0xB6,
/* 0xF7 @ 388 */ 0xC3, 0xB7,
/* 0xF8 @ 390 */ 0xC3, 0xB8,
/* 0xF9 @ 392 */ 0xC3, 0xB9,
/* 0xFA @ 394 */ 0xC3, 0xBA,
/* 0xFB @ 396 */ 0xC3, 0xBB,
/* 0xFC @ 398 */ 0xC3, 0xBC,
/* 0xFD @ 400 */ 0xC3, 0xBD,
/* 0xFE @ 402 */ 0xC3, 0xBE,
/* 0xFF @ 404 */ 0xC3, 0xBF,
};
static const uint16_t tblofs[257] = {
/* 0x00 */ 0, 1, 2, 3, 4, 5, 6, 7,
/* 0x08 */ 8, 9, 10, 11, 12, 13, 14, 15,
/* 0x10 */ 16, 17, 18, 19, 20, 21, 22, 23,
/* 0x18 */ 24, 25, 26, 27, 28, 29, 30, 31,
/* 0x20 */ 32, 33, 34, 35, 36, 37, 38, 39,
/* 0x28 */ 40, 41, 42, 43, 44, 45, 46, 47,
/* 0x30 */ 48, 49, 50, 51, 52, 53, 54, 55,
/* 0x38 */ 56, 57, 58, 59, 60, 61, 62, 63,
/* 0x40 */ 64, 65, 66, 67, 68, 69, 70, 71,
/* 0x48 */ 72, 73, 74, 75, 76, 77, 78, 79,
/* 0x50 */ 80, 81, 82, 83, 84, 85, 86, 87,
/* 0x58 */ 88, 89, 90, 91, 92, 93, 94, 95,
/* 0x60 */ 96, 97, 98, 99, 100, 101, 102, 103,
/* 0x68 */ 104, 105, 106, 107, 108, 109, 110, 111,
/* 0x70 */ 112, 113, 114, 115, 116, 117, 118, 119,
/* 0x78 */ 120, 121, 122, 123, 124, 125, 126, 127,
/* 0x80 */ 128, 131, 134, 137, 139, 142, 145, 148,
/* 0x88 */ 151, 153, 156, 158, 161, 163, 166, 168,
/* 0x90 */ 171, 174, 177, 180, 183, 186, 189, 192,
/* 0x98 */ 195, 197, 200, 202, 205, 207, 210, 212,
/* 0xA0 */ 214, 216, 218, 220, 222, 224, 226, 228,
/* 0xA8 */ 230, 232, 234, 236, 238, 240, 242, 244,
/* 0xB0 */ 246, 248, 250, 252, 254, 256, 258, 260,
/* 0xB8 */ 262, 264, 266, 268, 270, 272, 274, 276,
/* 0xC0 */ 278, 280, 282, 284, 286, 288, 290, 292,
/* 0xC8 */ 294, 296, 298, 300, 302, 304, 306, 308,
/* 0xD0 */ 310, 312, 314, 316, 318, 320, 322, 324,
/* 0xD8 */ 326, 328, 330, 332, 334, 336, 338, 340,
/* 0xE0 */ 342, 344, 346, 348, 350, 352, 354, 356,
/* 0xE8 */ 358, 360, 362, 364, 366, 368, 370, 372,
/* 0xF0 */ 374, 376, 378, 380, 382, 384, 386, 388,
/* 0xF8 */ 390, 392, 394, 396, 398, 400, 402, 404,
/* sizeof (cp1252_utf8) */ 406
};
/* Check if a string qualifies as UTF-8. */
static int
is_utf8(const char* src)
{
uint8_t ch;
size_t i;
const uint8_t* s = (const uint8_t*) src;
/* We make a loop over every character, until we find a null one.
Remember: The string is supposed to end with a NUL, so ahead checks are safe. */
while ((ch = *s++)) {
/* Ye olde 7bit ASCII chars 'rr fine for anything */
if(ch < 0x80) continue;
/* Now, we watch out for non-UTF conform sequences. */
else if ((ch < 0xC2) || (ch > 0xFD))
return 0;
/* check for some misformed sequences */
if (((ch == 0xC2) && (s[0] < 0xA0)) ||
((ch == 0xEF) && (s[0] == 0xBF) && (s[1] > 0xBD)))
/* XXX add more for outside the BMP */
return 0;
/* Check the continuation bytes. */
if (ch < 0xE0) i = 1;
else if (ch < 0xF0) i = 2;
else if (ch < 0xF8) i = 3;
else if (ch < 0xFC) i = 4;
else
i = 5;
while (i--)
if ((*s++ & 0xC0) != 0x80)
return 0;
}
/* If no check failed, the string indeed looks like valid UTF-8. */
return 1;
}
/* The main conversion routine.
ICY in CP-1252 (or UTF-8 alreay) to UTF-8 encoded string.
If force is applied, it will always encode to UTF-8, without checking. */
char *
icy2utf8(const char *src, int force)
{
const uint8_t *s = (const uint8_t *)src;
size_t srclen, dstlen, i, k;
uint8_t ch, *d;
char *dst;
/* Some funny streams from Apple/iTunes give ICY info in UTF-8 already.
So, be prepared and don't try to re-encode such. Unless forced. */
if(!force && is_utf8(src)) return (strdup(src));
srclen = strlen(src) + 1;
/* allocate conservatively */
if ((d = malloc(srclen * 3)) == NULL)
return (NULL);
i = 0;
dstlen = 0;
while (i < srclen) {
ch = s[i++];
k = tblofs[ch];
while (k < tblofs[ch + 1])
d[dstlen++] = cp1252_utf8[k++];
}
/* dstlen includes trailing NUL since srclen also does */
if ((dst = realloc(d, dstlen)) == NULL) {
free(d);
return (NULL);
}
return (dst);
}
/* This stuff is for testing only. */
#ifdef TEST
static const char intext[] = "\225 Gr\374\337e kosten 0,55 \200\205";
#include <stdio.h>
int
main(void)
{
char *t, *t2;
if ((t = icy2utf8(intext, 0)) == NULL) {
fprintf(stderr, "out of memory\n");
return (1);
}
/* make sure it won't be converted twice */
if ((t2 = icy2utf8(t), 0) == NULL) {
fprintf(stderr, "out of memory\n");
return (1);
}
printf("Result is:\t\343\200\214%s\343\200\215\n"
"\t\t\343\200\214%s\343\200\215\n", t, t2);
free(t);
free(t2);
return (0);
}
#endif

View File

@ -35,7 +35,7 @@ static const text_converter text_converters[4] =
convert_utf8
};
const unsigned int encoding_widths[4] = { 1, 2, 2, 1 };
static const unsigned int encoding_widths[4] = { 1, 2, 2, 1 };
/* the code starts here... */
@ -186,7 +186,7 @@ void id3_link(mpg123_handle *fr)
ID3v2 standard says that there should be one text frame of specific type per tag, and subsequent tags overwrite old values.
So, I always replace the text that may be stored already (perhaps with a list of zero-separated strings, though).
*/
void store_id3_text(mpg123_string *sb, char *source, size_t source_size, const int noquiet, const int notranslate)
static void store_id3_text(mpg123_string *sb, char *source, size_t source_size, const int noquiet, const int notranslate)
{
if(!source_size)
{
@ -247,7 +247,7 @@ void id3_to_utf8(mpg123_string *sb, unsigned char encoding, const unsigned char
text_converters[encoding](sb, source, source_size, noquiet);
}
char *next_text(char* prev, int encoding, size_t limit)
static char *next_text(char* prev, int encoding, size_t limit)
{
char *text = prev;
size_t width = encoding_widths[encoding];
@ -274,7 +274,7 @@ char *next_text(char* prev, int encoding, size_t limit)
text += width;
}
if(text-prev >= limit) text = NULL;
if((size_t)(text-prev) >= limit) text = NULL;
return text;
}
@ -352,7 +352,7 @@ static void process_comment(mpg123_handle *fr, enum frame_types tt, char *realda
Reminder: No bailing out from here on without freeing the local comment data! */
store_id3_text(&xcom->description, descr-1, text-descr+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
if(tt == comment)
store_id3_text(&localcom.description, descr-1, text-descr+1, NOQUIET, 1);
store_id3_text(&localcom.description, descr-1, text-descr+1, NOQUIET, 0);
text[-1] = encoding; /* Byte abusal for encoding... */
store_id3_text(&xcom->text, text-1, realsize+1-(text-realdata), NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
@ -379,7 +379,7 @@ static void process_comment(mpg123_handle *fr, enum frame_types tt, char *realda
if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
{
/* Only translate the contents in here where we really need them. */
store_id3_text(&localcom.text, text-1, realsize+1-(text-realdata), NOQUIET, 1);
store_id3_text(&localcom.text, text-1, realsize+1-(text-realdata), NOQUIET, 0);
if(localcom.text.fill > 0)
{
fr->rva.gain[rva_mode] = (float) atof(localcom.text.p);
@ -393,7 +393,7 @@ static void process_comment(mpg123_handle *fr, enum frame_types tt, char *realda
free_mpg123_text(&localcom);
}
void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_level, char *id)
static void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_level, char *id)
{
/* Text encoding $xx */
/* Description ... $00 (00) */
@ -424,10 +424,16 @@ void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_l
}
memcpy(xex->id, id, 4);
init_mpg123_text(&localex); /* For our local copy. */
/* The outside storage gets reencoded to UTF-8 only if not requested otherwise.
Remember that we really need the -1 here to hand in the encoding byte!*/
store_id3_text(&xex->description, descr-1, text-descr+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
store_id3_text(&localex.description, descr-1, text-descr+1, NOQUIET, 1);
/* Our local copy is always stored in UTF-8! */
store_id3_text(&localex.description, descr-1, text-descr+1, NOQUIET, 0);
/* At first, only store the outside copy of the payload. We may not need the local copy. */
text[-1] = encoding;
store_id3_text(&xex->text, text-1, realsize-(text-realdata)+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
/* Now check if we would like to interpret this extra info for RVA. */
if(localex.description.fill > 0)
{
@ -454,7 +460,7 @@ void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_l
if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
{
/* Now we need the translated copy of the data. */
store_id3_text(&localex.text, text-1, realsize-(text-realdata)+1, NOQUIET, 1);
store_id3_text(&localex.text, text-1, realsize-(text-realdata)+1, NOQUIET, 0);
if(localex.text.fill > 0)
{
if(is_peak)
@ -479,7 +485,7 @@ void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_l
Note that not all frames survived to 2.4; the mapping goes to 2.3 .
A notable miss is the old RVA frame, which is very unspecific anyway.
This function returns -1 when a not known 3 char ID was encountered, 0 otherwise. */
int promote_framename(mpg123_handle *fr, char *id) /* fr because of VERBOSE macros */
static int promote_framename(mpg123_handle *fr, char *id) /* fr because of VERBOSE macros */
{
size_t i;
char *old[] =
@ -530,7 +536,6 @@ int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
unsigned char flags = 0;
int ret = 1;
int ret2;
unsigned char* tagdata = NULL;
unsigned char major = first4bytes & 0xff;
debug1("ID3v2: major tag version: %i", major);
if(major == 0xff) return 0; /* Invalid... */
@ -582,10 +587,17 @@ int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
#ifndef NO_ID3V2
if(VERBOSE2) fprintf(stderr,"Note: ID3v2.%i rev %i tag of %lu bytes\n", major, buf[0], length);
/* skip if unknown version/scary flags, parse otherwise */
if((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2))
if(fr->p.flags & MPG123_SKIP_ID3V2 || ((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2)))
{
/* going to skip because there are unknown flags set */
if(NOQUIET) warning2("ID3v2: Won't parse the ID3v2 tag with major version %u and flags 0x%xu - some extra code may be needed", major, flags);
if(NOQUIET)
{
if(fr->p.flags & MPG123_SKIP_ID3V2)
{
if(VERBOSE3) fprintf(stderr, "Note: Skipping ID3v2 tag per user request.\n");
}
else /* Must be because of scary Tag properties. */
warning2("ID3v2: Won't parse the ID3v2 tag with major version %u and flags 0x%xu - some extra code may be needed", major, flags);
}
#endif
if((ret2 = fr->rd->skip_bytes(fr,length)) < 0) /* will not store data in backbuff! */
ret = ret2;
@ -593,6 +605,7 @@ int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
}
else
{
unsigned char* tagdata = NULL;
fr->id3v2.version = major;
/* try to interpret that beast */
if((tagdata = (unsigned char*) malloc(length+1)) != NULL)
@ -641,6 +654,7 @@ int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
{
/* 4 or 3 bytes id */
strncpy(id, (char*) tagdata+pos, head_part);
id[head_part] = 0; /* terminate for 3 or 4 bytes */
pos += head_part;
tagpos += head_part;
/* size as 32 bits or 28 bits */
@ -790,7 +804,8 @@ int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
}
else
{
if(NOQUIET) error("ID3v2: Duh, not able to read ID3v2 tag data.");
/* There are tags with zero length. Strictly not an error, then. */
if(length > 0 && NOQUIET && ret2 != MPG123_NEED_MORE) error("ID3v2: Duh, not able to read ID3v2 tag data.");
ret = ret2;
}
tagparse_cleanup:
@ -851,7 +866,7 @@ static void convert_latin1(mpg123_string *sb, const unsigned char* s, size_t l,
1: big endian
This modifies source and len to indicate the data _after_ the BOM(s).
Note on nasty data: The last encountered BOM determines the endianess.
Note on nasty data: The last encountered BOM determines the endianness.
I have seen data with multiple BOMS, namely from "the" id3v2 program.
Not nice, but what should I do?
*/
@ -898,7 +913,7 @@ static void convert_utf16bom(mpg123_string *sb, const unsigned char* s, size_t l
debug1("convert_utf16 with length %lu", (unsigned long)l);
bom_endian = check_bom(&s, &l);
debug1("UTF16 endianess check: %i", bom_endian);
debug1("UTF16 endianness check: %i", bom_endian);
if(bom_endian == -1) /* little-endian */
{

View File

@ -13,9 +13,21 @@
#include "frame.h"
#ifdef NO_ID3V2
# ifdef init_id3
# undef init_id3
# endif
# define init_id3(fr)
# ifdef exit_id3
# undef exit_id3
# endif
# define exit_id3(fr)
# ifdef reset_id3
# undef reset_id3
# endif
# define reset_id3(fr)
# ifdef id3_link
# undef id3_link
# endif
# define id3_link(fr)
#else
void init_id3(mpg123_handle *fr);

View File

@ -105,6 +105,26 @@ void fi_add(struct frame_index *fi, off_t pos)
}
}
int fi_set(struct frame_index *fi, off_t *offsets, off_t step, size_t fill)
{
if(fi_resize(fi, fill) == -1) return -1;
fi->step = step;
if(offsets != NULL)
{
memcpy(fi->data, offsets, fill*sizeof(off_t));
fi->fill = fill;
}
else
{
/* allocation only, no entries in index yet */
fi->fill = 0;
}
fi->next = fi_next(fi);
debug3("set new index of fill %lu, size %lu at %p",
(unsigned long)fi->fill, (unsigned long)fi->size, (void*)fi->data);
return 0;
}
void fi_reset(struct frame_index *fi)
{
debug1("reset with size %"SIZE_P, (size_p)fi->size);

View File

@ -50,6 +50,9 @@ int fi_resize(struct frame_index *fi, size_t newsize);
/* Append a frame position, reducing index density if needed. */
void fi_add(struct frame_index *fi, off_t pos);
/* Replace the frame index */
int fi_set(struct frame_index *fi, off_t *offsets, off_t step, size_t fill);
/* Empty the index (setting fill=0 and step=1), but keep current size. */
void fi_reset(struct frame_index *fi);

View File

@ -0,0 +1,256 @@
#ifndef MPG123_INTMAP_H
#define MPG123_INTMAP_H
/* Mapping of internal mpg123 symbols to something that is less likely to conflict in case of static linking. */
#define COS9 INT123_COS9
#define tfcos36 INT123_tfcos36
#define pnts INT123_pnts
#define safe_realloc INT123_safe_realloc
#define compat_open INT123_compat_open
#define compat_close INT123_compat_close
#define win32_wide_utf8 INT123_win32_wide_utf8
#define win32_utf8_wide INT123_win32_utf8_wide
#define ntom_set_ntom INT123_ntom_set_ntom
#define synth_1to1 INT123_synth_1to1
#define synth_1to1_dither INT123_synth_1to1_dither
#define synth_1to1_i386 INT123_synth_1to1_i386
#define synth_1to1_i586 INT123_synth_1to1_i586
#define synth_1to1_i586_dither INT123_synth_1to1_i586_dither
#define synth_1to1_mmx INT123_synth_1to1_mmx
#define synth_1to1_3dnow INT123_synth_1to1_3dnow
#define synth_1to1_sse INT123_synth_1to1_sse
#define synth_1to1_stereo_sse INT123_synth_1to1_stereo_sse
#define synth_1to1_3dnowext INT123_synth_1to1_3dnowext
#define synth_1to1_altivec INT123_synth_1to1_altivec
#define synth_1to1_stereo_altivec INT123_synth_1to1_stereo_altivec
#define synth_1to1_x86_64 INT123_synth_1to1_x86_64
#define synth_1to1_stereo_x86_64 INT123_synth_1to1_stereo_x86_64
#define synth_1to1_arm INT123_synth_1to1_arm
#define synth_1to1_neon INT123_synth_1to1_neon
#define synth_1to1_stereo_neon INT123_synth_1to1_stereo_neon
#define absynth_1to1_i486 INT123_absynth_1to1_i486
#define synth_1to1_mono INT123_synth_1to1_mono
#define synth_1to1_m2s INT123_synth_1to1_m2s
#define synth_2to1 INT123_synth_2to1
#define synth_2to1_dither INT123_synth_2to1_dither
#define synth_2to1_i386 INT123_synth_2to1_i386
#define synth_2to1_mono INT123_synth_2to1_mono
#define synth_2to1_m2s INT123_synth_2to1_m2s
#define synth_4to1 INT123_synth_4to1
#define synth_4to1_dither INT123_synth_4to1_dither
#define synth_4to1_i386 INT123_synth_4to1_i386
#define synth_4to1_mono INT123_synth_4to1_mono
#define synth_4to1_m2s INT123_synth_4to1_m2s
#define synth_ntom INT123_synth_ntom
#define synth_ntom_mono INT123_synth_ntom_mono
#define synth_ntom_m2s INT123_synth_ntom_m2s
#define synth_1to1_8bit INT123_synth_1to1_8bit
#define synth_1to1_8bit_i386 INT123_synth_1to1_8bit_i386
#define synth_1to1_8bit_wrap INT123_synth_1to1_8bit_wrap
#define synth_1to1_8bit_mono INT123_synth_1to1_8bit_mono
#define synth_1to1_8bit_m2s INT123_synth_1to1_8bit_m2s
#define synth_1to1_8bit_wrap_mono INT123_synth_1to1_8bit_wrap_mono
#define synth_1to1_8bit_wrap_m2s INT123_synth_1to1_8bit_wrap_m2s
#define synth_2to1_8bit INT123_synth_2to1_8bit
#define synth_2to1_8bit_i386 INT123_synth_2to1_8bit_i386
#define synth_2to1_8bit_mono INT123_synth_2to1_8bit_mono
#define synth_2to1_8bit_m2s INT123_synth_2to1_8bit_m2s
#define synth_4to1_8bit INT123_synth_4to1_8bit
#define synth_4to1_8bit_i386 INT123_synth_4to1_8bit_i386
#define synth_4to1_8bit_mono INT123_synth_4to1_8bit_mono
#define synth_4to1_8bit_m2s INT123_synth_4to1_8bit_m2s
#define synth_ntom_8bit INT123_synth_ntom_8bit
#define synth_ntom_8bit_mono INT123_synth_ntom_8bit_mono
#define synth_ntom_8bit_m2s INT123_synth_ntom_8bit_m2s
#define synth_1to1_real INT123_synth_1to1_real
#define synth_1to1_real_i386 INT123_synth_1to1_real_i386
#define synth_1to1_real_sse INT123_synth_1to1_real_sse
#define synth_1to1_real_stereo_sse INT123_synth_1to1_real_stereo_sse
#define synth_1to1_real_x86_64 INT123_synth_1to1_real_x86_64
#define synth_1to1_real_stereo_x86_64 INT123_synth_1to1_real_stereo_x86_64
#define synth_1to1_real_altivec INT123_synth_1to1_real_altivec
#define synth_1to1_real_stereo_altivec INT123_synth_1to1_real_stereo_altivec
#define synth_1to1_real_neon INT123_synth_1to1_real_neon
#define synth_1to1_real_stereo_neon INT123_synth_1to1_real_stereo_neon
#define synth_1to1_real_mono INT123_synth_1to1_real_mono
#define synth_1to1_real_m2s INT123_synth_1to1_real_m2s
#define synth_2to1_real INT123_synth_2to1_real
#define synth_2to1_real_i386 INT123_synth_2to1_real_i386
#define synth_2to1_real_mono INT123_synth_2to1_real_mono
#define synth_2to1_real_m2s INT123_synth_2to1_real_m2s
#define synth_4to1_real INT123_synth_4to1_real
#define synth_4to1_real_i386 INT123_synth_4to1_real_i386
#define synth_4to1_real_mono INT123_synth_4to1_real_mono
#define synth_4to1_real_m2s INT123_synth_4to1_real_m2s
#define synth_ntom_real INT123_synth_ntom_real
#define synth_ntom_real_mono INT123_synth_ntom_real_mono
#define synth_ntom_real_m2s INT123_synth_ntom_real_m2s
#define synth_1to1_s32 INT123_synth_1to1_s32
#define synth_1to1_s32_i386 INT123_synth_1to1_s32_i386
#define synth_1to1_s32_sse INT123_synth_1to1_s32_sse
#define synth_1to1_s32_stereo_sse INT123_synth_1to1_s32_stereo_sse
#define synth_1to1_s32_x86_64 INT123_synth_1to1_s32_x86_64
#define synth_1to1_s32_stereo_x86_64 INT123_synth_1to1_s32_stereo_x86_64
#define synth_1to1_s32_altivec INT123_synth_1to1_s32_altivec
#define synth_1to1_s32_stereo_altivec INT123_synth_1to1_s32_stereo_altivec
#define synth_1to1_s32_neon INT123_synth_1to1_s32_neon
#define synth_1to1_s32_stereo_neon INT123_synth_1to1_s32_stereo_neon
#define synth_1to1_s32_mono INT123_synth_1to1_s32_mono
#define synth_1to1_s32_m2s INT123_synth_1to1_s32_m2s
#define synth_2to1_s32 INT123_synth_2to1_s32
#define synth_2to1_s32_i386 INT123_synth_2to1_s32_i386
#define synth_2to1_s32_mono INT123_synth_2to1_s32_mono
#define synth_2to1_s32_m2s INT123_synth_2to1_s32_m2s
#define synth_4to1_s32 INT123_synth_4to1_s32
#define synth_4to1_s32_i386 INT123_synth_4to1_s32_i386
#define synth_4to1_s32_mono INT123_synth_4to1_s32_mono
#define synth_4to1_s32_m2s INT123_synth_4to1_s32_m2s
#define synth_ntom_s32 INT123_synth_ntom_s32
#define synth_ntom_s32_mono INT123_synth_ntom_s32_mono
#define synth_ntom_s32_m2s INT123_synth_ntom_s32_m2s
#define dct64 INT123_dct64
#define dct64_i386 INT123_dct64_i386
#define dct64_altivec INT123_dct64_altivec
#define dct64_i486 INT123_dct64_i486
#define dct36 INT123_dct36
#define dct36_3dnow INT123_dct36_3dnow
#define dct36_3dnowext INT123_dct36_3dnowext
#define synth_ntom_set_step INT123_synth_ntom_set_step
#define ntom_val INT123_ntom_val
#define ntom_frame_outsamples INT123_ntom_frame_outsamples
#define ntom_frmouts INT123_ntom_frmouts
#define ntom_ins2outs INT123_ntom_ins2outs
#define ntom_frameoff INT123_ntom_frameoff
#define init_layer3 INT123_init_layer3
#define init_layer3_gainpow2 INT123_init_layer3_gainpow2
#define init_layer3_stuff INT123_init_layer3_stuff
#define init_layer12 INT123_init_layer12
#define init_layer12_table INT123_init_layer12_table
#define init_layer12_stuff INT123_init_layer12_stuff
#define prepare_decode_tables INT123_prepare_decode_tables
#define make_decode_tables INT123_make_decode_tables
#define make_decode_tables_mmx INT123_make_decode_tables_mmx
#define init_layer3_gainpow2_mmx INT123_init_layer3_gainpow2_mmx
#define init_layer12_table_mmx INT123_init_layer12_table_mmx
#define make_conv16to8_table INT123_make_conv16to8_table
#define do_layer3 INT123_do_layer3
#define do_layer2 INT123_do_layer2
#define do_layer1 INT123_do_layer1
#define do_equalizer INT123_do_equalizer
#define dither_table_init INT123_dither_table_init
#define frame_dither_init INT123_frame_dither_init
#define invalidate_format INT123_invalidate_format
#define frame_init INT123_frame_init
#define frame_init_par INT123_frame_init_par
#define frame_outbuffer INT123_frame_outbuffer
#define frame_output_format INT123_frame_output_format
#define frame_buffers INT123_frame_buffers
#define frame_reset INT123_frame_reset
#define frame_buffers_reset INT123_frame_buffers_reset
#define frame_exit INT123_frame_exit
#define frame_index_find INT123_frame_index_find
#define frame_index_setup INT123_frame_index_setup
#define do_volume INT123_do_volume
#define do_rva INT123_do_rva
#define frame_gapless_init INT123_frame_gapless_init
#define frame_gapless_realinit INT123_frame_gapless_realinit
#define frame_gapless_update INT123_frame_gapless_update
#define frame_gapless_bytify INT123_frame_gapless_bytify
#define frame_gapless_ignore INT123_frame_gapless_ignore
#define frame_expect_outsamples INT123_frame_expect_outsamples
#define frame_skip INT123_frame_skip
#define frame_ins2outs INT123_frame_ins2outs
#define frame_outs INT123_frame_outs
#define frame_expect_outsampels INT123_frame_expect_outsampels
#define frame_offset INT123_frame_offset
#define frame_set_frameseek INT123_frame_set_frameseek
#define frame_set_seek INT123_frame_set_seek
#define frame_tell_seek INT123_frame_tell_seek
#define frame_fill_toc INT123_frame_fill_toc
#define getbits INT123_getbits
#define getcpuflags INT123_getcpuflags
#define icy2utf8 INT123_icy2utf8
#define init_icy INT123_init_icy
#define clear_icy INT123_clear_icy
#define reset_icy INT123_reset_icy
#define init_id3 INT123_init_id3
#define exit_id3 INT123_exit_id3
#define reset_id3 INT123_reset_id3
#define id3_link INT123_id3_link
#define parse_new_id3 INT123_parse_new_id3
#define id3_to_utf8 INT123_id3_to_utf8
#define fi_init INT123_fi_init
#define fi_exit INT123_fi_exit
#define fi_resize INT123_fi_resize
#define fi_add INT123_fi_add
#define fi_set INT123_fi_set
#define fi_reset INT123_fi_reset
#define double_to_long_rounded INT123_double_to_long_rounded
#define scale_rounded INT123_scale_rounded
#define decode_update INT123_decode_update
#define samples_to_bytes INT123_samples_to_bytes
#define bytes_to_samples INT123_bytes_to_samples
#define frame_cpu_opt INT123_frame_cpu_opt
#define set_synth_functions INT123_set_synth_functions
#define dectype INT123_dectype
#define defdec INT123_defdec
#define decclass INT123_decclass
#define check_decoders INT123_check_decoders
#define read_frame_init INT123_read_frame_init
#define frame_bitrate INT123_frame_bitrate
#define frame_freq INT123_frame_freq
#define read_frame_recover INT123_read_frame_recover
#define read_frame INT123_read_frame
#define set_pointer INT123_set_pointer
#define position_info INT123_position_info
#define compute_bpf INT123_compute_bpf
#define time_to_frame INT123_time_to_frame
#define get_songlen INT123_get_songlen
#define open_stream INT123_open_stream
#define open_stream_handle INT123_open_stream_handle
#define open_feed INT123_open_feed
#define feed_more INT123_feed_more
#define feed_forget INT123_feed_forget
#define feed_set_pos INT123_feed_set_pos
#define open_bad INT123_open_bad
#define dct64_3dnow INT123_dct64_3dnow
#define dct64_3dnowext INT123_dct64_3dnowext
#define dct64_mmx INT123_dct64_mmx
#define dct64_MMX INT123_dct64_MMX
#define dct64_sse INT123_dct64_sse
#define dct64_real_sse INT123_dct64_real_sse
#define dct64_x86_64 INT123_dct64_x86_64
#define dct64_real_x86_64 INT123_dct64_real_x86_64
#define dct64_neon INT123_dct64_neon
#define dct64_real_neon INT123_dct64_real_neon
#define do_equalizer_3dnow INT123_do_equalizer_3dnow
#define synth_1to1_3dnow_asm INT123_synth_1to1_3dnow_asm
#define synth_1to1_arm_asm INT123_synth_1to1_arm_asm
#define synth_1to1_arm_accurate_asm INT123_synth_1to1_arm_accurate_asm
#define synth_1to1_i586_asm INT123_synth_1to1_i586_asm
#define synth_1to1_i586_asm_dither INT123_synth_1to1_i586_asm_dither
#define synth_1to1_MMX INT123_synth_1to1_MMX
#define synth_1to1_sse_accurate_asm INT123_synth_1to1_sse_accurate_asm
#define synth_1to1_real_sse_asm INT123_synth_1to1_real_sse_asm
#define synth_1to1_s32_sse_asm INT123_synth_1to1_s32_sse_asm
#define synth_1to1_s_sse_accurate_asm INT123_synth_1to1_s_sse_accurate_asm
#define synth_1to1_real_s_sse_asm INT123_synth_1to1_real_s_sse_asm
#define synth_1to1_s32_s_sse_asm INT123_synth_1to1_s32_s_sse_asm
#define synth_1to1_s_x86_64_asm INT123_synth_1to1_s_x86_64_asm
#define synth_1to1_s_x86_64_accurate_asm INT123_synth_1to1_s_x86_64_accurate_asm
#define synth_1to1_real_s_x86_64_asm INT123_synth_1to1_real_s_x86_64_asm
#define synth_1to1_s32_s_x86_64_asm INT123_synth_1to1_s32_s_x86_64_asm
#define synth_1to1_x86_64_asm INT123_synth_1to1_x86_64_asm
#define synth_1to1_x86_64_accurate_asm INT123_synth_1to1_x86_64_accurate_asm
#define synth_1to1_real_x86_64_asm INT123_synth_1to1_real_x86_64_asm
#define synth_1to1_s32_x86_64_asm INT123_synth_1to1_s32_x86_64_asm
#define synth_1to1_neon_asm INT123_synth_1to1_neon_asm
#define synth_1to1_neon_accurate_asm INT123_synth_1to1_neon_accurate_asm
#define synth_1to1_real_neon_asm INT123_synth_1to1_real_neon_asm
#define synth_1to1_s32_neon_asm INT123_synth_1to1_s32_neon_asm
#define synth_1to1_s_neon_asm INT123_synth_1to1_s_neon_asm
#define synth_1to1_s_neon_accurate_asm INT123_synth_1to1_s_neon_accurate_asm
#define synth_1to1_real_s_neon_asm INT123_synth_1to1_real_s_neon_asm
#define synth_1to1_s32_s_neon_asm INT123_synth_1to1_s32_s_neon_asm
#define costab_mmxsse INT123_costab_mmxsse
#define make_decode_tables_mmx_asm INT123_make_decode_tables_mmx_asm
#endif

View File

@ -13,7 +13,7 @@
#ifndef _MPG123_L2TABLES_H_
#define _MPG123_L2TABLES_H_
const struct al_table alloc_0[] = {
static const struct al_table alloc_0[] = {
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
@ -53,7 +53,7 @@ const struct al_table alloc_0[] = {
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767} };
const struct al_table alloc_1[] = {
static const struct al_table alloc_1[] = {
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
{4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
@ -96,7 +96,7 @@ const struct al_table alloc_1[] = {
{2,0},{5,3},{7,5},{16,-32767},
{2,0},{5,3},{7,5},{16,-32767} };
const struct al_table alloc_2[] = {
static const struct al_table alloc_2[] = {
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
@ -108,7 +108,7 @@ const struct al_table alloc_2[] = {
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
const struct al_table alloc_3[] = {
static const struct al_table alloc_3[] = {
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
{4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
@ -124,7 +124,7 @@ const struct al_table alloc_3[] = {
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
{3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
const struct al_table alloc_4[] = {
static const struct al_table alloc_4[] = {
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
{9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
{4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},

View File

@ -1,7 +1,7 @@
/*
layer1.c: the layer 1 decoder
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
@ -11,7 +11,7 @@
#include "mpg123lib_intern.h"
#include "getbits.h"
void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
static void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
{
unsigned int *ba=balloc;
unsigned int *sca = (unsigned int *) scale_index;
@ -55,7 +55,7 @@ void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],mpg1
}
}
void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
static void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
{
int i,n;
int smpb[2*SBLIMIT]; /* values: 0-65535 */
@ -129,7 +129,7 @@ int do_layer1(mpg123_handle *fr)
int i,stereo = fr->stereo;
unsigned int balloc[2*SBLIMIT];
unsigned int scale_index[2][SBLIMIT];
ALIGNED(16) real fraction[2][SBLIMIT];
real (*fraction)[SBLIMIT] = fr->layer1.fraction; /* fraction[2][SBLIMIT] */
int single = fr->single;
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32;

View File

@ -1,7 +1,7 @@
/*
layer2.c: the layer 2 decoder, root of mpg123
copyright 1994-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 1994-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
@ -94,7 +94,7 @@ real* init_layer12_table(mpg123_handle *fr, real *table, int m)
real* init_layer12_table_mmx(mpg123_handle *fr, real *table, int m)
{
int i,j;
if(!fr->p.down_sample)
if(!fr->p.down_sample)
{
for(j=3,i=0;i<63;i++,j--)
*table++ = DOUBLE_TO_REAL(16384 * mulmul[m] * pow(2.0,(double) j / 3.0));
@ -114,7 +114,7 @@ real* init_layer12_table_mmx(mpg123_handle *fr, real *table, int m)
#ifndef NO_LAYER2
void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
static void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
{
int stereo = fr->stereo-1;
int sblimit = fr->II_sblimit;
@ -167,17 +167,17 @@ void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
if(*bita++)
switch(*scfsi++)
{
case 0:
case 0:
*scale++ = getbits_fast(fr, 6);
*scale++ = getbits_fast(fr, 6);
*scale++ = getbits_fast(fr, 6);
break;
case 1 :
case 1 :
*scale++ = sc = getbits_fast(fr, 6);
*scale++ = sc;
*scale++ = getbits_fast(fr, 6);
break;
case 2:
case 2:
*scale++ = sc = getbits_fast(fr, 6);
*scale++ = sc;
*scale++ = sc;
@ -191,7 +191,7 @@ void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
}
void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,mpg123_handle *fr,int x1)
static void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,mpg123_handle *fr,int x1)
{
int i,j,k,ba;
int stereo = fr->stereo;
@ -206,17 +206,17 @@ void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale
step = alloc1->bits;
for(j=0;j<stereo;j++)
{
if( (ba=*bita++) )
if( (ba=*bita++) )
{
k=(alloc2 = alloc1+ba)->bits;
if( (d1=alloc2->d) < 0)
if( (d1=alloc2->d) < 0)
{
real cm=fr->muls[k][scale[x1]];
fraction[j][0][i] = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1), cm);
fraction[j][1][i] = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1), cm);
fraction[j][2][i] = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1), cm);
}
else
}
else
{
const int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
unsigned int idx,*tab,m=scale[x1];
@ -224,7 +224,7 @@ void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale
tab = (unsigned int *) (table[d1] + idx + idx + idx);
fraction[j][0][i] = REAL_SCALE_LAYER12(fr->muls[*tab++][m]);
fraction[j][1][i] = REAL_SCALE_LAYER12(fr->muls[*tab++][m]);
fraction[j][2][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m]);
fraction[j][2][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m]);
}
scale+=3;
}
@ -277,10 +277,10 @@ void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale
Historic comment...
should we use individual scalefac for channel 2 or
is the current way the right one , where we just copy channel 1 to
channel 2 ??
channel 2 ??
The current 'strange' thing is, that we throw away the scalefac
values for the second channel ...!!
-> changed .. now we use the scalefac values of channel one !!
-> changed .. now we use the scalefac values of channel one !!
*/
}
@ -331,7 +331,9 @@ int do_layer2(mpg123_handle *fr)
int clip=0;
int i,j;
int stereo = fr->stereo;
ALIGNED(16) real fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */
/* pick_table clears unused subbands */
/* replacement for real fraction[2][4][SBLIMIT], needs alignment. */
real (*fraction)[4][SBLIMIT] = fr->layer2.fraction;
unsigned int bit_alloc[64];
int scale[192];
int single = fr->single;
@ -341,7 +343,7 @@ int do_layer2(mpg123_handle *fr)
if(fr->jsbound > fr->II_sblimit)
{
// fprintf(stderr, "Truncating stereo boundary to sideband limit.\n");
fprintf(stderr, "Truncating stereo boundary to sideband limit.\n");
fr->jsbound=fr->II_sblimit;
}
@ -354,7 +356,7 @@ int do_layer2(mpg123_handle *fr)
for(i=0;i<SCALE_BLOCK;i++)
{
II_step_two(bit_alloc,fraction,scale,fr,i>>2);
for(j=0;j<3;j++)
for(j=0;j<3;j++)
{
if(single != SINGLE_STEREO)
clip += (fr->synth_mono)(fraction[single][j], fr);

View File

@ -1,7 +1,7 @@
/*
leyer3.c: the layer 3 decoder
layer3.c: the layer 3 decoder
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
@ -56,9 +56,9 @@ struct gr_info_s
unsigned block_type;
unsigned mixed_block_flag;
unsigned table_select[3];
unsigned subblock_gain[3];
unsigned maxband[3];
unsigned maxbandl;
/* Making those two signed int as workaround for open64/pathscale/sun compilers, and also for consistency, since they're worked on together with other signed variables. */
int maxband[3];
int maxbandl;
unsigned maxb;
unsigned region1start;
unsigned region2start;
@ -79,14 +79,14 @@ struct III_sideinfo
struct bandInfoStruct
{
int longIdx[23];
int longDiff[22];
int shortIdx[14];
int shortDiff[13];
unsigned short longIdx[23];
unsigned char longDiff[22];
unsigned short shortIdx[14];
unsigned char shortDiff[13];
};
/* Techy details about our friendly MPEG data. Fairly constant over the years;-) */
const struct bandInfoStruct bandInfo[9] =
static const struct bandInfoStruct bandInfo[9] =
{
{ /* MPEG 1.0 */
{0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
@ -270,7 +270,7 @@ void init_layer3(void)
const struct bandInfoStruct *bi = &bandInfo[j];
int *mp;
int cb,lwin;
const int *bdf;
const unsigned char *bdf;
mp = map[j][0] = mapbuf0[j];
bdf = bi->longDiff;
@ -403,7 +403,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
if(si->main_data_begin > fr->bitreservoir)
{
if(VERBOSE2) fprintf(stderr, "Note: missing %d bytes in bit reservoir for frame %li\n", (int)(si->main_data_begin - fr->bitreservoir), (long)fr->num);
if(!fr->to_ignore && VERBOSE2) fprintf(stderr, "Note: missing %d bytes in bit reservoir for frame %li\n", (int)(si->main_data_begin - fr->bitreservoir), (long)fr->num);
/* overwrite main_data_begin for the really available bit reservoir */
backbits(fr, tab[1]);
@ -451,7 +451,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
gr_info->big_values = getbits(fr, 9);
if(gr_info->big_values > 288)
{
error("big_values too large!");
if(NOQUIET) error("big_values too large!");
gr_info->big_values = 288;
}
gr_info->pow2gain = fr->gainpow2+256 - getbits_fast(fr, 8) + powdiff;
@ -476,7 +476,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
if(gr_info->block_type == 0)
{
error("Blocktype == 0 and window-switching == 1 not allowed.");
if(NOQUIET) error("Blocktype == 0 and window-switching == 1 not allowed.");
return 1;
}
@ -494,6 +494,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
if((gr_info->block_type == 2) && (!gr_info->mixed_block_flag) ) r0c = 5;
else r0c = 7;
/* r0c+1+r1c+1 == 22, always. */
r1c = 20 - r0c;
gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
@ -511,12 +512,12 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
for (i=0; i<3; i++)
gr_info->table_select[i] = getbits_fast(fr, 5);
r0c = getbits_fast(fr, 4);
r1c = getbits_fast(fr, 3);
r0c = getbits_fast(fr, 4); /* 0 .. 15 */
r1c = getbits_fast(fr, 3); /* 0 .. 7 */
gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
if(r0c + r1c + 2 > 22) gr_info->region2start = 576>>1;
/* max(r0c+r1c+2) = 15+7+2 = 24 */
if(r0c+1+r1c+1 > 22) gr_info->region2start = 576>>1;
else gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
gr_info->block_type = 0;
@ -677,8 +678,11 @@ static int III_get_scale_factors_2(mpg123_handle *fr, int *scf,struct gr_info_s
return numbits;
}
static const int pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
static const int pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static unsigned char pretab_choice[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}
};
/*
Dequantize samples
@ -716,16 +720,6 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
int bv = gr_info->big_values;
int region1 = gr_info->region1start;
int region2 = gr_info->region2start;
if(region1 > region2)
{
/*
That's not optimal: it fixes a segfault with fuzzed data, but also apparently triggers where it shouldn't, see bug 1641196.
The benefit of not crashing / having this security risk is bigger than these few frames of a lame-3.70 file that aren't audible anyway.
But still, I want to know if indeed this check or the old lame is at fault.
*/
error("You got some really nasty file there... region1>region2!");
return 1;
}
l3 = ((576>>1)-bv)>>1;
/* we may lose the 'odd' bit here !! check this later again */
@ -778,7 +772,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
for(i=0;i<2;i++)
{
int lp = l[i];
struct newhuff *h = ht+gr_info->table_select[i];
const struct newhuff *h = ht+gr_info->table_select[i];
for(;lp;lp--,mc--)
{
register int x,y;
@ -806,7 +800,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
}
}
{
register short *val = h->table;
const short *val = h->table;
REFRESH_MASK;
while((y=*val++)<0)
{
@ -871,8 +865,8 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
for(;l3 && (part2remain+num > 0);l3--)
{
struct newhuff* h;
register short* val;
const struct newhuff* h;
const short* val;
register short a;
/*
This is only a humble hack to prevent a special segfault.
@ -990,7 +984,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
else
{
/* decoding with 'long' BandIndex table (block_type != 2) */
const int *pretab = gr_info->preflag ? pretab1 : pretab2;
const unsigned char *pretab = pretab_choice[gr_info->preflag];
int i,max = -1;
int cb = 0;
int *m = map[sfreq][2];
@ -1001,7 +995,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
for(i=0;i<3;i++)
{
int lp = l[i];
struct newhuff *h = ht+gr_info->table_select[i];
const struct newhuff *h = ht+gr_info->table_select[i];
for(;lp;lp--,mc--)
{
@ -1023,7 +1017,7 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
}
}
{
register short *val = h->table;
const short *val = h->table;
REFRESH_MASK;
while((y=*val++)<0)
{
@ -1087,8 +1081,9 @@ static int III_dequantize_sample(mpg123_handle *fr, real xr[SBLIMIT][SSLIMIT],in
/* short (count1table) values */
for(;l3 && (part2remain+num > 0);l3--)
{
struct newhuff *h = htc+gr_info->count1table_select;
register short *val = h->table,a;
const struct newhuff *h = htc+gr_info->count1table_select;
const short *val = h->table;
register short a;
REFRESH_MASK;
while((a=*val++)<0)
@ -1933,8 +1928,10 @@ int do_layer3(mpg123_handle *fr)
for(gr=0;gr<granules;gr++)
{
ALIGNED(16) real hybridIn[2][SBLIMIT][SSLIMIT];
ALIGNED(16) real hybridOut[2][SSLIMIT][SBLIMIT];
/* hybridIn[2][SBLIMIT][SSLIMIT] */
real (*hybridIn)[SBLIMIT][SSLIMIT] = fr->layer3.hybrid_in;
/* hybridOut[2][SSLIMIT][SBLIMIT] */
real (*hybridOut)[SSLIMIT][SBLIMIT] = fr->layer3.hybrid_out;
{
struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);

View File

@ -0,0 +1,252 @@
/*
lfs_alias: Aliases to the small/native API functions with the size of long int as suffix.
copyright 2010 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
Use case: Client code on Linux/x86-64 that defines _FILE_OFFSET_BITS to 64, which is the only choice on that platform anyway. It should be no-op, but prompts the platform-agnostic header of mpg123 to define API calls with the corresponding suffix.
This file provides the names for this case. It's cruft, but glibc does it, too -- so people rely on it.
Oh, and it also caters for the lunatics that define _FILE_OFFSET_BITS=32 on 32 bit platforms.
There is also the strange case that the mpg123 build itself is configured for unnecessary _FILE_OFFSET_BITS == LFS_ALIAS_BITS =^ sizeof(long). In that case, the "native" function will have the suffix and the alias shall be provided without the suffix.
So, two basic cases:
1. mpg123_bla_32 alias for mpg123_bla
2. mpg123_bla alias for mpg123_bla_32
Confusing, I know. It sucks.
*/
#include "config.h"
/* Hack for Solaris: Some system headers included from compat.h might force _FILE_OFFSET_BITS. Need to follow that here. */
#include "compat.h"
#ifndef LFS_ALIAS_BITS
#error "I need the count of alias bits here."
#endif
#define MACROCAT_REALLY(a, b) a ## b
#define MACROCAT(a, b) MACROCAT_REALLY(a, b)
/* This is wicked switchery: Decide which way the aliases are facing. */
#if _FILE_OFFSET_BITS+0 == LFS_ALIAS_BITS
/* The native functions are actually _with_ suffix, so let the mpg123 header use large file hackery to define the correct interfaces. */
#include "mpg123.h"
/* Don't forget to undef the function symbols before usage... */
/* The native functions have suffix, the aliases not. */
#define NATIVE_SUFFIX MACROCAT(_, _FILE_OFFSET_BITS)
#define NATIVE_NAME(func) MACROCAT(func, NATIVE_SUFFIX)
#define ALIAS_NAME(func) func
#else
/* Native functions are without suffix... */
#define MPG123_NO_LARGENAME
#include "mpg123.h"
/* The alias functions have suffix, the native ones not. */
#define ALIAS_SUFFIX MACROCAT(_, LFS_ALIAS_BITS)
#define ALIAS_NAME(func) MACROCAT(func, ALIAS_SUFFIX)
#define NATIVE_NAME(func) func
#endif
/* Now get the rest of the infrastructure on speed, namely attribute_align_arg, to stay safe. */
#include "mpg123lib_intern.h"
/*
Extract the list of functions we need wrappers for, pregenerating the wrappers for simple cases (inline script for nedit):
perl -ne '
if(/^\s*EXPORT\s+(\S+)\s+(mpg123_\S+)\((.*)\);\s*$/)
{
my $type = $1;
my $name = $2;
my $args = $3;
next unless ($type =~ /off_t/ or $args =~ /off_t/ or ($name =~ /open/ and $name ne mpg123_open_feed));
$type =~ s/off_t/long/g;
my @nargs = ();
$args =~ s/off_t/long/g;
foreach my $a (split(/,/, $args))
{
$a =~ s/^.*\s\**([a-z_]+)$/$1/;
push(@nargs, $a);
}
my $nargs = join(", ", @nargs);
$nargs = "Human: figure me out." if($nargs =~ /\(/);
print <<EOT
##ifdef $name
##undef $name
##endif
$type attribute_align_arg ALIAS_NAME($name)($args)
{
return NATIVE_NAME($name)($nargs);
}
EOT
}' < mpg123.h.in
*/
#ifdef mpg123_open
#undef mpg123_open
#endif
int attribute_align_arg ALIAS_NAME(mpg123_open)(mpg123_handle *mh, const char *path)
{
return NATIVE_NAME(mpg123_open)(mh, path);
}
#ifdef mpg123_open_fd
#undef mpg123_open_fd
#endif
int attribute_align_arg ALIAS_NAME(mpg123_open_fd)(mpg123_handle *mh, int fd)
{
return NATIVE_NAME(mpg123_open_fd)(mh, fd);
}
#ifdef mpg123_open_handle
#undef mpg123_open_handle
#endif
int attribute_align_arg ALIAS_NAME(mpg123_open_handle)(mpg123_handle *mh, void *iohandle)
{
return NATIVE_NAME(mpg123_open_handle)(mh, iohandle);
}
#ifdef mpg123_decode_frame
#undef mpg123_decode_frame
#endif
int attribute_align_arg ALIAS_NAME(mpg123_decode_frame)(mpg123_handle *mh, long *num, unsigned char **audio, size_t *bytes)
{
return NATIVE_NAME(mpg123_decode_frame)(mh, num, audio, bytes);
}
#ifdef mpg123_framebyframe_decode
#undef mpg123_framebyframe_decode
#endif
int attribute_align_arg ALIAS_NAME(mpg123_framebyframe_decode)(mpg123_handle *mh, long *num, unsigned char **audio, size_t *bytes)
{
return NATIVE_NAME(mpg123_framebyframe_decode)(mh, num, audio, bytes);
}
#ifdef mpg123_framepos
#undef mpg123_framepos
#endif
long attribute_align_arg ALIAS_NAME(mpg123_framepos)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_framepos)(mh);
}
#ifdef mpg123_tell
#undef mpg123_tell
#endif
long attribute_align_arg ALIAS_NAME(mpg123_tell)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_tell)(mh);
}
#ifdef mpg123_tellframe
#undef mpg123_tellframe
#endif
long attribute_align_arg ALIAS_NAME(mpg123_tellframe)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_tellframe)(mh);
}
#ifdef mpg123_tell_stream
#undef mpg123_tell_stream
#endif
long attribute_align_arg ALIAS_NAME(mpg123_tell_stream)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_tell_stream)(mh);
}
#ifdef mpg123_seek
#undef mpg123_seek
#endif
long attribute_align_arg ALIAS_NAME(mpg123_seek)(mpg123_handle *mh, long sampleoff, int whence)
{
return NATIVE_NAME(mpg123_seek)(mh, sampleoff, whence);
}
#ifdef mpg123_feedseek
#undef mpg123_feedseek
#endif
long attribute_align_arg ALIAS_NAME(mpg123_feedseek)(mpg123_handle *mh, long sampleoff, int whence, long *input_offset)
{
return NATIVE_NAME(mpg123_feedseek)(mh, sampleoff, whence, input_offset);
}
#ifdef mpg123_seek_frame
#undef mpg123_seek_frame
#endif
long attribute_align_arg ALIAS_NAME(mpg123_seek_frame)(mpg123_handle *mh, long frameoff, int whence)
{
return NATIVE_NAME(mpg123_seek_frame)(mh, frameoff, whence);
}
#ifdef mpg123_timeframe
#undef mpg123_timeframe
#endif
long attribute_align_arg ALIAS_NAME(mpg123_timeframe)(mpg123_handle *mh, double sec)
{
return NATIVE_NAME(mpg123_timeframe)(mh, sec);
}
#ifdef mpg123_index
#undef mpg123_index
#endif
int attribute_align_arg ALIAS_NAME(mpg123_index)(mpg123_handle *mh, long **offsets, long *step, size_t *fill)
{
return NATIVE_NAME(mpg123_index)(mh, offsets, step, fill);
}
#ifdef mpg123_set_index
#undef mpg123_set_index
#endif
int attribute_align_arg ALIAS_NAME(mpg123_set_index)(mpg123_handle *mh, long *offsets, long step, size_t fill)
{
return NATIVE_NAME(mpg123_set_index)(mh, offsets, step, fill);
}
#ifdef mpg123_position
#undef mpg123_position
#endif
int attribute_align_arg ALIAS_NAME(mpg123_position)( mpg123_handle *mh, long frame_offset, long buffered_bytes, long *current_frame, long *frames_left, double *current_seconds, double *seconds_left)
{
return NATIVE_NAME(mpg123_position)(mh, frame_offset, buffered_bytes, current_frame, frames_left, current_seconds, seconds_left);
}
#ifdef mpg123_length
#undef mpg123_length
#endif
long attribute_align_arg ALIAS_NAME(mpg123_length)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_length)(mh);
}
#ifdef mpg123_set_filesize
#undef mpg123_set_filesize
#endif
int attribute_align_arg ALIAS_NAME(mpg123_set_filesize)(mpg123_handle *mh, long size)
{
return NATIVE_NAME(mpg123_set_filesize)(mh, size);
}
#ifdef mpg123_replace_reader
#undef mpg123_replace_reader
#endif
int attribute_align_arg ALIAS_NAME(mpg123_replace_reader)(mpg123_handle *mh, ssize_t (*r_read) (int, void *, size_t), long (*r_lseek)(int, long, int))
{
return NATIVE_NAME(mpg123_replace_reader)(mh, r_read, r_lseek);
}
#ifdef mpg123_replace_reader_handle
#undef mpg123_replace_reader_handle
#endif
int attribute_align_arg ALIAS_NAME(mpg123_replace_reader_handle)(mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), long (*r_lseek)(void *, long, int), void (*cleanup)(void*))
{
return NATIVE_NAME(mpg123_replace_reader_handle)(mh, r_read, r_lseek, cleanup);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
EXPORTS
mpg123_add_string
mpg123_add_substring
mpg123_chomp_string
mpg123_clip
mpg123_close
mpg123_copy_string
mpg123_current_decoder
mpg123_decode
mpg123_decode_frame
mpg123_decode_frame_32
mpg123_decoder
mpg123_decoders
mpg123_delete
mpg123_delete_pars
mpg123_enc_from_id3
mpg123_encodings
mpg123_encsize
mpg123_eq
mpg123_errcode
mpg123_exit
mpg123_feature
mpg123_feed
mpg123_feedseek
mpg123_feedseek_32
mpg123_fmt
mpg123_fmt_all
mpg123_fmt_none
mpg123_fmt_support
mpg123_format
mpg123_format_all
mpg123_format_none
mpg123_format_support
mpg123_framebyframe_decode
mpg123_framebyframe_decode_32
mpg123_framebyframe_next
mpg123_framedata
mpg123_framepos
mpg123_framepos_32
mpg123_free_string
mpg123_geteq
mpg123_getformat
mpg123_getpar
mpg123_getparam
mpg123_getstate
mpg123_getvolume
mpg123_grow_string
mpg123_icy
mpg123_icy2utf8
mpg123_id3
mpg123_index
mpg123_index_32
mpg123_info
mpg123_init
mpg123_init_string
mpg123_length
mpg123_length_32
mpg123_meta_check
mpg123_meta_free
mpg123_new
mpg123_new_pars
mpg123_noise
mpg123_open
mpg123_open_32
mpg123_open_fd
mpg123_open_fd_32
mpg123_open_feed
mpg123_open_handle
mpg123_open_handle_32
mpg123_outblock
mpg123_par
mpg123_param
mpg123_parnew
mpg123_plain_strerror
mpg123_position
mpg123_position_32
mpg123_rates
mpg123_read
mpg123_replace_buffer
mpg123_replace_reader
mpg123_replace_reader_32
mpg123_replace_reader_handle
mpg123_replace_reader_handle_32
mpg123_reset_eq
mpg123_resize_string
mpg123_safe_buffer
mpg123_scan
mpg123_seek
mpg123_seek_32
mpg123_seek_frame
mpg123_seek_frame_32
mpg123_set_filesize
mpg123_set_filesize_32
mpg123_set_index
mpg123_set_index_32
mpg123_set_string
mpg123_set_substring
mpg123_spf
mpg123_store_utf8
mpg123_strerror
mpg123_strlen
mpg123_supported_decoders
mpg123_tell
mpg123_tell_32
mpg123_tell_stream
mpg123_tell_stream_32
mpg123_tellframe
mpg123_tellframe_32
mpg123_timeframe
mpg123_timeframe_32
mpg123_tpf
mpg123_volume
mpg123_volume_change

View File

@ -11,6 +11,7 @@
#define __MANGLE_H
#include "config.h"
#include "intsym.h"
#ifdef CCALIGN
#define MOVUAPS movaps
@ -18,26 +19,52 @@
#define MOVUAPS movups
#endif
/*
ALIGNX: align to X bytes
This differs per compiler/platform in taking the byte count or an exponent for base 2.
A way out is balign, if the assembler supports it (gas extension).
*/
#ifdef ASMALIGN_BALIGN
#define ALIGN4 .balign 4
#define ALIGN8 .balign 8
#define ALIGN16 .balign 16
#define ALIGN32 .balign 32
#else
#ifdef ASMALIGN_EXP
#define ALIGN4 .align 2
#define ALIGN8 .align 3
#define ALIGN16 .align 4
#define ALIGN32 .align 5
#else
#ifdef ASMALIGN_BYTE
#define ALIGN4 .align 4
#define ALIGN8 .align 8
#define ALIGN16 .align 16
#define ALIGN32 .align 32
#else
#error "Dunno how assembler alignment works. Please specify."
#endif
#endif
#endif
#define MANGLE_MACROCAT_REALLY(a, b) a ## b
#define MANGLE_MACROCAT(a, b) MANGLE_MACROCAT_REALLY(a, b)
/* Feel free to add more to the list, eg. a.out IMO */
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__OS2__) || defined(_MSC_VER) || \
#if defined(__USER_LABEL_PREFIX__)
#define ASM_NAME(a) MANGLE_MACROCAT(__USER_LABEL_PREFIX__,a)
#define ASM_VALUE(a) MANGLE_MACROCAT($,ASM_NAME(a))
#elif defined(__CYGWIN__) || defined(_WIN32) && !defined (_WIN64) || defined(__OS2__) || \
(defined(__OpenBSD__) && !defined(__ELF__)) || defined(__APPLE__)
#define ASM_NAME(a) _##a
#define ASM_VALUE(a) $_##a
#define ASM_NAME(a) MANGLE_MACROCAT(_,a)
#define ASM_VALUE(a) MANGLE_MACROCAT($_,a)
#else
#define ASM_NAME(a) a
#define ASM_VALUE(a) $##a
#define ASM_VALUE(a) MANGLE_MACROCAT($,a)
#endif
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__APPLE__)
@ -51,5 +78,14 @@
#else
#define BSS .bss
#endif
/* Mark non-executable stack.
It's mainly for GNU on Linux... who else does (not) like this? */
#if !defined(__SUNPRO_C) && defined(__linux__) && defined(__ELF__)
#define NONEXEC_STACK .section .note.GNU-stack,"",%progbits
#else
#define NONEXEC_STACK
#endif
#endif /* !__MANGLE_H */

View File

@ -0,0 +1,89 @@
/*
mpeghead: the bits of an MPEG frame header
copyright ?-2011 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp & Thomas Orgis (from parse.c)
*/
#ifndef MPG123_MPEGHEAD_H
#define MPG123_MPEGHEAD_H
/*
Avoid human error, let perl do the work of dissecting an MPEG header into parts.
To be clear: Never edit the following definitions by hand, modify the code block inside this comment and run it through perl instead!
$head = "AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM";
%parts = qw(A sync B version C layer D crc E bitrate F samplerate G padding H private I channel J chanex K copyright L original M emphasis);
for(sort keys %parts)
{
$name = uc($parts{$_});
$bits = $head;
$bits =~ s/$_/1/g;
$bits =~ s/[^1 ]/0/g;
print "\/\* $bits \*\/\n";
$bits =~ s/\s//g;
print "#define HDR_$name".(" " x (18-length($name))).sprintf("0x%08x", eval("0b$bits"))."\n";
$bits =~ m/(0*)$/;
print "#define HDR_${name}_VAL(h)".(" " x (11-length($name)))."(((h)\&HDR_$name) >> ".length($1).")\n";
}
*/
/* 11111111 11100000 00000000 00000000 */
#define HDR_SYNC 0xffe00000
#define HDR_SYNC_VAL(h) (((h)&HDR_SYNC) >> 21)
/* 00000000 00011000 00000000 00000000 */
#define HDR_VERSION 0x00180000
#define HDR_VERSION_VAL(h) (((h)&HDR_VERSION) >> 19)
/* 00000000 00000110 00000000 00000000 */
#define HDR_LAYER 0x00060000
#define HDR_LAYER_VAL(h) (((h)&HDR_LAYER) >> 17)
/* 00000000 00000001 00000000 00000000 */
#define HDR_CRC 0x00010000
#define HDR_CRC_VAL(h) (((h)&HDR_CRC) >> 16)
/* 00000000 00000000 11110000 00000000 */
#define HDR_BITRATE 0x0000f000
#define HDR_BITRATE_VAL(h) (((h)&HDR_BITRATE) >> 12)
/* 00000000 00000000 00001100 00000000 */
#define HDR_SAMPLERATE 0x00000c00
#define HDR_SAMPLERATE_VAL(h) (((h)&HDR_SAMPLERATE) >> 10)
/* 00000000 00000000 00000010 00000000 */
#define HDR_PADDING 0x00000200
#define HDR_PADDING_VAL(h) (((h)&HDR_PADDING) >> 9)
/* 00000000 00000000 00000001 00000000 */
#define HDR_PRIVATE 0x00000100
#define HDR_PRIVATE_VAL(h) (((h)&HDR_PRIVATE) >> 8)
/* 00000000 00000000 00000000 11000000 */
#define HDR_CHANNEL 0x000000c0
#define HDR_CHANNEL_VAL(h) (((h)&HDR_CHANNEL) >> 6)
/* 00000000 00000000 00000000 00110000 */
#define HDR_CHANEX 0x00000030
#define HDR_CHANEX_VAL(h) (((h)&HDR_CHANEX) >> 4)
/* 00000000 00000000 00000000 00001000 */
#define HDR_COPYRIGHT 0x00000008
#define HDR_COPYRIGHT_VAL(h) (((h)&HDR_COPYRIGHT) >> 3)
/* 00000000 00000000 00000000 00000100 */
#define HDR_ORIGINAL 0x00000004
#define HDR_ORIGINAL_VAL(h) (((h)&HDR_ORIGINAL) >> 2)
/* 00000000 00000000 00000000 00000011 */
#define HDR_EMPHASIS 0x00000003
#define HDR_EMPHASIS_VAL(h) (((h)&HDR_EMPHASIS) >> 0)
/*
A generic mask for telling if a header is somewhat valid for the current stream.
Meaning: Most basic info is not allowed to change.
Checking of channel count needs to be done, too, though. So,
if channel count matches, frames are decoded the same way: frame buffers and decoding
routines can stay the same, especially frame buffers (think spf * channels!).
*/
#define HDR_CMPMASK (HDR_SYNC|HDR_VERSION|HDR_LAYER|HDR_SAMPLERATE)
/* A stricter mask, for matching free format headers. */
#define HDR_SAMEMASK (HDR_SYNC|HDR_VERSION|HDR_LAYER|HDR_BITRATE|HDR_SAMPLERATE|HDR_CHANNEL|HDR_CHANEX)
/* Free format headers have zero bitrate value. */
#define HDR_FREE_FORMAT(head) (!(head & HDR_BITRATE))
/* A mask for changed sampling rate (version or rate bits). */
#define HDR_SAMPMASK (HDR_VERSION|HDR_SAMPLERATE)
#endif

View File

@ -1,7 +1,7 @@
/*
libmpg123: MPEG Audio Decoder library (version 1.9.0)
libmpg123: MPEG Audio Decoder library (version 1.15.4)
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 1995-2010 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
*/
@ -10,6 +10,10 @@
/** \file mpg123.h The header file for the libmpg123 MPEG Audio decoder */
/* A macro to check at compile time which set of API functions to expect.
This should be incremented at least each time a new symbol is added to the header. */
#define MPG123_API_VERSION 37
/* These aren't actually in use... seems to work without using libtool. */
#ifdef BUILD_MPG123_DLL
/* The dll exports. */
@ -28,34 +32,59 @@
#include <stdlib.h>
#include <sys/types.h>
#if 0 /* If we need trickery for large file support. */
/* Simplified large file handling.
I used to have a check here that prevents building for a library with conflicting large file setup
(application that uses 32 bit offsets with library that uses 64 bits).
While that was perfectly fine in an environment where there is one incarnation of the library,
it hurt GNU/Linux and Solaris systems with multilib where the distribution fails to provide the
correct header matching the 32 bit library (where large files need explicit support) or
the 64 bit library (where there is no distinction).
/* Check for compiling programs agains this libmpg123. */
#if (defined _FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS+0 == )
/* ...all is fine, having enabled large file support and also the correct sort of which. */
#else
#error "Mismatch in large file setup! Enable/disable large file support appropriately to use libmpg123."
New approach: When the app defines _FILE_OFFSET_BITS, it wants non-default large file support,
and thus functions with added suffix (mpg123_open_64).
Any mismatch will be caught at link time because of the _FILE_OFFSET_BITS setting used when
building libmpg123. Plus, there's dual mode large file support in mpg123 since 1.12 now.
Link failure is not the expected outcome of any half-sane usage anymore.
More complication: What about client code defining _LARGEFILE64_SOURCE? It might want direct access to the _64 functions, along with the ones without suffix. Well, that's possible now via defining MPG123_NO_LARGENAME and MPG123_LARGESUFFIX, respectively, for disabling or enforcing the suffix names.
*/
/*
Now, the renaming of large file aware functions.
By default, it appends underscore _FILE_OFFSET_BITS (so, mpg123_seek_64 for mpg123_seek), if _FILE_OFFSET_BITS is defined. You can force a different suffix via MPG123_LARGESUFFIX (that must include the underscore), or you can just disable the whole mess by defining MPG123_NO_LARGENAME.
*/
#if (!defined MPG123_NO_LARGENAME) && ((defined _FILE_OFFSET_BITS) || (defined MPG123_LARGESUFFIX))
/* Need some trickery to concatenate the value(s) of the given macro(s). */
#define MPG123_MACROCAT_REALLY(a, b) a ## b
#define MPG123_MACROCAT(a, b) MPG123_MACROCAT_REALLY(a, b)
#ifndef MPG123_LARGESUFFIX
#define MPG123_LARGESUFFIX MPG123_MACROCAT(_, _FILE_OFFSET_BITS)
#endif
#define MPG123_LARGENAME(func) MPG123_MACROCAT(func, MPG123_LARGESUFFIX)
/* Redefine names of functions dealing with file and file offsets
...everything handling off_t, for example, which can be 32 or 64 bits. */
#define mpg123_open MPG123_LARGENAME(mpg123_open)
#define mpg123_open_fd MPG123_LARGENAME(mpg123_open_fd)
#define mpg123_open_handle MPG123_LARGENAME(mpg123_open_handle)
#define mpg123_framebyframe_decode MPG123_LARGENAME(mpg123_framebyframe_decode)
#define mpg123_decode_frame MPG123_LARGENAME(mpg123_decode_frame)
#define mpg123_tell MPG123_LARGENAME(mpg123_tell)
#define mpg123_tellframe MPG123_LARGENAME(mpg123_tellframe)
#define mpg123_tell_stream MPG123_LARGENAME(mpg123_tell_stream)
#define mpg123_seek MPG123_LARGENAME(mpg123_seek)
#define mpg123_feedseek MPG123_LARGENAME(mpg123_feedseek)
#define mpg123_seek_frame MPG123_LARGENAME(mpg123_seek_frame)
#define mpg123_timeframe MPG123_LARGENAME(mpg123_timeframe)
#define mpg123_index MPG123_LARGENAME(mpg123_index)
#define mpg123_set_index MPG123_LARGENAME(mpg123_set_index)
#define mpg123_position MPG123_LARGENAME(mpg123_position)
#define mpg123_length MPG123_LARGENAME(mpg123_length)
#define mpg123_set_filesize MPG123_LARGENAME(mpg123_set_filesize)
#define mpg123_replace_reader MPG123_LARGENAME(mpg123_replace_reader)
#define mpg123_replace_reader_handle MPG123_LARGENAME(mpg123_replace_reader_handle)
#define mpg123_framepos MPG123_LARGENAME(mpg123_framepos)
#define mpg123_open mpg123_open
#define mpg123_open_fd mpg123_open_fd
#define mpg123_decode_frame mpg123_decode_frame
#define mpg123_tell mpg123_tell
#define mpg123_tellframe mpg123_tellframe
#define mpg123_tell_stream mpg123_tell_stream
#define mpg123_seek mpg123_seek
#define mpg123_feedseek mpg123_feedseek
#define mpg123_seek_frame mpg123_seek_frame
#define mpg123_timeframe mpg123_timeframe
#define mpg123_index mpg123_index
#define mpg123_position mpg123_position
#define mpg123_length mpg123_length
#define mpg123_set_filesize mpg123_set_filesize
#endif /* LARGEFILE_SWITCH */
#endif /* largefile hackery */
#endif /* MPG123_NO_CONFIGURE */
@ -105,7 +134,7 @@ EXPORT void mpg123_delete(mpg123_handle *mh);
/** Enumeration of the parameters types that it is possible to set/get. */
enum mpg123_parms
{
MPG123_VERBOSE, /**< set verbosity value for enabling messages to stderr, >= 0 makes sense (integer) */
MPG123_VERBOSE = 0, /**< set verbosity value for enabling messages to stderr, >= 0 makes sense (integer) */
MPG123_FLAGS, /**< set all flags, p.ex val = MPG123_GAPLESS|MPG123_MONO_MIX (integer) */
MPG123_ADD_FLAGS, /**< add some flags (integer) */
MPG123_FORCE_RATE, /**< when value > 0, force output rate to that value (integer) */
@ -119,9 +148,11 @@ enum mpg123_parms
MPG123_OUTSCALE, /**< the scale for output samples (amplitude - integer or float according to mpg123 output format, normally integer) */
MPG123_TIMEOUT, /**< timeout for reading from a stream (not supported on win32, integer) */
MPG123_REMOVE_FLAGS, /**< remove some flags (inverse of MPG123_ADD_FLAGS, integer) */
MPG123_RESYNC_LIMIT, /**< Try resync on frame parsing for that many bytes or until end of stream (<0 ... integer). */
MPG123_RESYNC_LIMIT, /**< Try resync on frame parsing for that many bytes or until end of stream (<0 ... integer). This can enlarge the limit for skipping junk on beginning, too (but not reduce it). */
MPG123_INDEX_SIZE /**< Set the frame index size (if supported). Values <0 mean that the index is allowed to grow dynamically in these steps (in positive direction, of course) -- Use this when you really want a full index with every individual frame. */
,MPG123_PREFRAMES /**< Decode/ignore that many frames in advance for layer 3. This is needed to fill bit reservoir after seeking, for example (but also at least one frame in advance is needed to have all "normal" data for layer 3). Give a positive integer value, please.*/
,MPG123_FEEDPOOL /**< For feeder mode, keep that many buffers in a pool to avoid frequent malloc/free. The pool is allocated on mpg123_open_feed(). If you change this parameter afterwards, you can trigger growth and shrinkage during decoding. The default value could change any time. If you care about this, then set it. (integer) */
,MPG123_FEEDBUFFER /**< Minimal size of one internal feeder buffer, again, the default value is subject to change. (integer) */
};
/** Flag bits for MPG123_FLAGS, use the usual binary or to combine. */
@ -140,6 +171,10 @@ enum mpg123_param_flags
,MPG123_FUZZY = 0x200 /**< 001000000000 Enable fuzzy seeks (guessing byte offsets or using approximate seek points from Xing TOC) */
,MPG123_FORCE_FLOAT = 0x400 /**< 010000000000 Force floating point output (32 or 64 bits depends on mpg123 internal precision). */
,MPG123_PLAIN_ID3TEXT = 0x800 /**< 100000000000 Do not translate ID3 text data to UTF-8. ID3 strings will contain the raw text data, with the first byte containing the ID3 encoding code. */
,MPG123_IGNORE_STREAMLENGTH = 0x1000 /**< 1000000000000 Ignore any stream length information contained in the stream, which can be contained in a 'TLEN' frame of an ID3v2 tag or a Xing tag */
,MPG123_SKIP_ID3V2 = 0x2000 /**< 10 0000 0000 0000 Do not parse ID3v2 tags, just skip them. */
,MPG123_IGNORE_INFOFRAME = 0x4000 /**< 100 0000 0000 0000 Do not parse the LAME/Xing info frame, treat it as normal MPEG data. */
,MPG123_AUTO_RESAMPLE = 0x8000 /**< 1000 0000 0000 0000 Allow automatic internal resampling of any kind (default on if supported). Especially when going lowlevel with replacing output buffer, you might want to unset this flag. Setting MPG123_DOWNSAMPLE or MPG123_FORCE_RATE will override this. */
};
/** choices for MPG123_RVA */
@ -161,6 +196,28 @@ EXPORT int mpg123_param(mpg123_handle *mh, enum mpg123_parms type, long value, d
* See the mpg123_parms enumeration for a list of available parameters. */
EXPORT int mpg123_getparam(mpg123_handle *mh, enum mpg123_parms type, long *val, double *fval);
/** Feature set available for query with mpg123_feature. */
enum mpg123_feature_set
{
MPG123_FEATURE_ABI_UTF8OPEN = 0 /**< mpg123 expects path names to be given in UTF-8 encoding instead of plain native. */
,MPG123_FEATURE_OUTPUT_8BIT /**< 8bit output */
,MPG123_FEATURE_OUTPUT_16BIT /**< 16bit output */
,MPG123_FEATURE_OUTPUT_32BIT /**< 32bit output */
,MPG123_FEATURE_INDEX /**< support for building a frame index for accurate seeking */
,MPG123_FEATURE_PARSE_ID3V2 /**< id3v2 parsing */
,MPG123_FEATURE_DECODE_LAYER1 /**< mpeg layer-1 decoder enabled */
,MPG123_FEATURE_DECODE_LAYER2 /**< mpeg layer-2 decoder enabled */
,MPG123_FEATURE_DECODE_LAYER3 /**< mpeg layer-3 decoder enabled */
,MPG123_FEATURE_DECODE_ACCURATE /**< accurate decoder rounding */
,MPG123_FEATURE_DECODE_DOWNSAMPLE /**< downsample (sample omit) */
,MPG123_FEATURE_DECODE_NTOM /**< flexible rate decoding */
,MPG123_FEATURE_PARSE_ICY /**< ICY support */
,MPG123_FEATURE_TIMEOUT_READ /**< Reader with timeout (network). */
};
/** Query libmpg123 feature, 1 for success, 0 for unimplemented functions. */
EXPORT int mpg123_feature(const enum mpg123_feature_set key);
/* @} */
@ -209,7 +266,7 @@ enum mpg123_errors
MPG123_NO_SEEK, /**< Seek not supported by stream. */
MPG123_NO_READER, /**< No stream opened. */
MPG123_BAD_PARS, /**< Bad parameter handle. */
MPG123_BAD_INDEX_PAR, /**< Bad parameters to mpg123_index() */
MPG123_BAD_INDEX_PAR, /**< Bad parameters to mpg123_index() and mpg123_set_index() */
MPG123_OUT_OF_SYNC, /**< Lost track in bytestream and did not try to resync. */
MPG123_RESYNC_FAIL, /**< Resync failed to find valid MPEG data. */
MPG123_NO_8BIT, /**< No 8bit encoding possible. */
@ -224,6 +281,9 @@ enum mpg123_errors
MPG123_MISSING_FEATURE /**< This feature has not been built into libmpg123. */
,MPG123_BAD_VALUE /**< A bad value has been given, somewhere. */
,MPG123_LSEEK_FAILED /**< Low-level seek failed. */
,MPG123_BAD_CUSTOM_IO /**< Custom I/O not prepared. */
,MPG123_LFS_OVERFLOW /**< Offset value overflow during translation of large file API calls -- your client program cannot handle that large file. */
,MPG123_INT_OVERFLOW /**< Some integer overflow. */
};
/** Return a string describing that error errcode means. */
@ -250,10 +310,10 @@ EXPORT int mpg123_errcode(mpg123_handle *mh);
*/
/** Return a NULL-terminated array of generally available decoder names (plain 8bit ASCII). */
EXPORT const char **mpg123_decoders();
EXPORT const char **mpg123_decoders(void);
/** Return a NULL-terminated array of the decoders supported by the CPU (plain 8bit ASCII). */
EXPORT const char **mpg123_supported_decoders();
EXPORT const char **mpg123_supported_decoders(void);
/** Set the chosen decoder to 'decoder_name' */
EXPORT int mpg123_decoder(mpg123_handle *mh, const char* decoder_name);
@ -272,6 +332,16 @@ EXPORT const char* mpg123_current_decoder(mpg123_handle *mh);
*
* Functions to get and select the format of the decoded audio.
*
* Before you dive in, please be warned that you might get confused by this. This seems to happen a lot, therefore I am trying to explain in advance.
*
* The mpg123 library decides what output format to use when encountering the first frame in a stream, or actually any frame that is still valid but differs from the frames before in the prompted output format. At such a deciding point, an internal table of allowed encodings, sampling rates and channel setups is consulted. According to this table, an output format is chosen and the decoding engine set up accordingly (including ptimized routines for different output formats). This might seem unusual but it just follows from the non-existence of "MPEG audio files" with defined overall properties. There are streams, streams are concatenations of (semi) independent frames. We store streams on disk and call them "MPEG audio files", but that does not change their nature as the decoder is concerned (the LAME/Xing header for gapless decoding makes things interesting again).
*
* To get to the point: What you do with mpg123_format() and friends is to fill the internal table of allowed formats before it is used. That includes removing support for some formats or adding your forced sample rate (see MPG123_FORCE_RATE) that will be used with the crude internal resampler. Also keep in mind that the sample encoding is just a question of choice -- the MPEG frames do only indicate their native sampling rate and channel count. If you want to decode to integer or float samples, 8 or 16 bit ... that is your decision. In a "clean" world, libmpg123 would always decode to 32 bit float and let you handle any sample conversion. But there are optimized routines that work faster by directly decoding to the desired encoding / accuracy. We prefer efficiency over conceptual tidyness.
*
* People often start out thinking that mpg123_format() should change the actual decoding format on the fly. That is wrong. It only has effect on the next natural change of output format, when libmpg123 will consult its format table again. To make life easier, you might want to call mpg123_format_none() before any thing else and then just allow one desired encoding and a limited set of sample rates / channel choices that you actually intend to deal with. You can force libmpg123 to decode everything to 44100 KHz, stereo, 16 bit integer ... it will duplicate mono channels and even do resampling if needed (unless that feature is disabled in the build, same with some encodings). But I have to stress that the resampling of libmpg123 is very crude and doesn't even contain any kind of "proper" interpolation.
*
* In any case, watch out for MPG123_NEW_FORMAT as return message from decoding routines and call mpg123_getformat() to get the currently active output format.
*
* @{
*/
@ -281,20 +351,23 @@ EXPORT const char* mpg123_current_decoder(mpg123_handle *mh);
* Note that (your build of) libmpg123 does not necessarily support all these.
* Usually, you can expect the 8bit encodings and signed 16 bit.
* Also 32bit float will be usual beginning with mpg123-1.7.0 .
* What you should bear in mind is that (SSE, etc) optimized routines are just for
* signed 16bit (and 8bit derived from that). Other formats use plain C code.
* What you should bear in mind is that (SSE, etc) optimized routines may be absent
* for some formats. We do have SSE for 16, 32 bit and float, though.
* 24 bit integer is done via postprocessing of 32 bit output -- just cutting
* the last byte, no rounding, even. If you want better, do it yourself.
*
* All formats are in native byte order. On a little endian machine this should mean
* that you can just feed the MPG123_ENC_SIGNED_32 data to common 24bit hardware that
* ignores the lowest byte (or you could choose to do rounding with these lower bits).
* All formats are in native byte order. If you need different endinaness, you
* can simply postprocess the output buffers (libmpg123 wouldn't do anything else).
* mpg123_encsize() can be helpful there.
*/
enum mpg123_enc_enum
{
MPG123_ENC_8 = 0x00f /**< 0000 0000 1111 Some 8 bit integer encoding. */
,MPG123_ENC_16 = 0x040 /**< 0000 0100 0000 Some 16 bit integer encoding. */
,MPG123_ENC_32 = 0x100 /**< 0001 0000 0000 Some 32 bit integer encoding. */
,MPG123_ENC_SIGNED = 0x080 /**< 0000 1000 0000 Some signed integer encoding. */
,MPG123_ENC_FLOAT = 0xe00 /**< 1110 0000 0000 Some float encoding. */
MPG123_ENC_8 = 0x00f /**< 0000 0000 1111 Some 8 bit integer encoding. */
,MPG123_ENC_16 = 0x040 /**< 0000 0100 0000 Some 16 bit integer encoding. */
,MPG123_ENC_24 = 0x4000 /**< 0100 0000 0000 0000 Some 24 bit integer encoding. */
,MPG123_ENC_32 = 0x100 /**< 0001 0000 0000 Some 32 bit integer encoding. */
,MPG123_ENC_SIGNED = 0x080 /**< 0000 1000 0000 Some signed integer encoding. */
,MPG123_ENC_FLOAT = 0xe00 /**< 1110 0000 0000 Some float encoding. */
,MPG123_ENC_SIGNED_16 = (MPG123_ENC_16|MPG123_ENC_SIGNED|0x10) /**< 1101 0000 signed 16 bit */
,MPG123_ENC_UNSIGNED_16 = (MPG123_ENC_16|0x20) /**< 0110 0000 unsigned 16 bit */
,MPG123_ENC_UNSIGNED_8 = 0x01 /**< 0000 0001 unsigned 8 bit */
@ -303,12 +376,15 @@ enum mpg123_enc_enum
,MPG123_ENC_ALAW_8 = 0x08 /**< 0000 1000 alaw 8 bit */
,MPG123_ENC_SIGNED_32 = MPG123_ENC_32|MPG123_ENC_SIGNED|0x1000 /**< 0001 0001 1000 0000 signed 32 bit */
,MPG123_ENC_UNSIGNED_32 = MPG123_ENC_32|0x2000 /**< 0010 0001 0000 0000 unsigned 32 bit */
,MPG123_ENC_SIGNED_24 = MPG123_ENC_24|MPG123_ENC_SIGNED|0x1000 /**< 0101 0000 1000 0000 signed 24 bit */
,MPG123_ENC_UNSIGNED_24 = MPG123_ENC_24|0x2000 /**< 0110 0000 0000 0000 unsigned 24 bit */
,MPG123_ENC_FLOAT_32 = 0x200 /**< 0010 0000 0000 32bit float */
,MPG123_ENC_FLOAT_64 = 0x400 /**< 0100 0000 0000 64bit float */
,MPG123_ENC_ANY = ( MPG123_ENC_SIGNED_16 | MPG123_ENC_UNSIGNED_16 | MPG123_ENC_UNSIGNED_8
| MPG123_ENC_SIGNED_8 | MPG123_ENC_ULAW_8 | MPG123_ENC_ALAW_8
| MPG123_ENC_SIGNED_32 | MPG123_ENC_UNSIGNED_32
| MPG123_ENC_FLOAT_32 | MPG123_ENC_FLOAT_64 ) /**< any encoding */
| MPG123_ENC_SIGNED_24 | MPG123_ENC_UNSIGNED_24
| MPG123_ENC_FLOAT_32 | MPG123_ENC_FLOAT_64 ) /**< Any encoding on the list. */
};
/** They can be combined into one number (3) to indicate mono and stereo... */
@ -331,6 +407,11 @@ EXPORT void mpg123_rates(const long **list, size_t *number);
* \param number Store the number of encodings there. */
EXPORT void mpg123_encodings(const int **list, size_t *number);
/** Return the size (in bytes) of one mono sample of the named encoding.
* \param encoding The encoding value to analyze.
* \return positive size of encoding in bytes, 0 on invalid encoding. */
EXPORT int mpg123_encsize(int encoding);
/** Configure a mpg123 handle to accept no output format at all,
* use before specifying supported formats with mpg123_format */
EXPORT int mpg123_format_none(mpg123_handle *mh);
@ -380,6 +461,12 @@ EXPORT int mpg123_open(mpg123_handle *mh, const char *path);
*/
EXPORT int mpg123_open_fd(mpg123_handle *mh, int fd);
/** Use an opaque handle as bitstream input. This works only with the
* replaced I/O from mpg123_replace_reader_handle()!
* mpg123_close() will call the cleanup callback for your handle (if you gave one).
*/
EXPORT int mpg123_open_handle(mpg123_handle *mh, void *iohandle);
/** Open a new bitstream and prepare for direct feeding
* This works together with mpg123_decode(); you are responsible for reading and feeding the input bitstream.
*/
@ -416,8 +503,7 @@ EXPORT int mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size);
* \param done address to store the number of actually decoded bytes to
* \return error/message code (watch out especially for MPG123_NEED_MORE)
*/
EXPORT int mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize,
unsigned char *outmemory, size_t outmemsize, size_t *done);
EXPORT int mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done);
/** Decode next MPEG frame to internal buffer
* or read a frame and return after setting a new format.
@ -427,6 +513,39 @@ EXPORT int mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_
*/
EXPORT int mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes);
/** Decode current MPEG frame to internal buffer.
* Warning: This is experimental API that might change in future releases!
* Please watch mpg123 development closely when using it.
* \param num last frame offset gets stored there
* \param audio this pointer is set to the internal buffer to read the decoded audio from.
* \param bytes number of output bytes ready in the buffer
*/
EXPORT int mpg123_framebyframe_decode(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes);
/** Find, read and parse the next mp3 frame
* Warning: This is experimental API that might change in future releases!
* Please watch mpg123 development closely when using it.
*/
EXPORT int mpg123_framebyframe_next(mpg123_handle *mh);
/** Get access to the raw input data for the last parsed frame.
* This gives you a direct look (and write access) to the frame body data.
* Together with the raw header, you can reconstruct the whole raw MPEG stream without junk and meta data, or play games by actually modifying the frame body data before decoding this frame (mpg123_framebyframe_decode()).
* A more sane use would be to use this for CRC checking (see mpg123_info() and MPG123_CRC), the first two bytes of the body make up the CRC16 checksum, if present.
* You can provide NULL for a parameter pointer when you are not interested in the value.
*
* \param header the 4-byte MPEG header
* \param bodydata pointer to the frame body stored in the handle (without the header)
* \param bodybytes size of frame body in bytes (without the header)
* \return MPG123_OK if there was a yet un-decoded frame to get the data from, MPG123_ERR otherwise (without further explanation, the error state of the mpg123_handle is not modified by this function).
*/
EXPORT int mpg123_framedata(mpg123_handle *mh, unsigned long *header, unsigned char **bodydata, size_t *bodybytes);
/** Get the input position (byte offset in stream) of the last parsed frame.
* This can be used for external seek index building, for example.
* It just returns the internally stored offset, regardless of validity -- you ensure that a valid frame has been parsed before! */
EXPORT off_t mpg123_framepos(mpg123_handle *mh);
/*@}*/
@ -482,11 +601,20 @@ EXPORT off_t mpg123_seek_frame(mpg123_handle *mh, off_t frameoff, int whence);
EXPORT off_t mpg123_timeframe(mpg123_handle *mh, double sec);
/** Give access to the frame index table that is managed for seeking.
* You are asked not to modify the values... unless you are really aware of what you are doing.
* You are asked not to modify the values... Use mpg123_set_index to set the
* seek index
* \param offsets pointer to the index array
* \param step one index byte offset advances this many MPEG frames
* \param fill number of recorded index offsets; size of the array */
EXPORT int mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill);
/** Set the frame index table
* Setting offsets to NULL and fill > 0 will allocate fill entries. Setting offsets
* to NULL and fill to 0 will clear the index and free the allocated memory used by the index.
* \param offsets pointer to the index array
* \param step one index byte offset advances this many MPEG frames
* \param fill number of recorded index offsets; size of the array */
EXPORT int mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill);
* \param fill number of recorded index offsets; size of the array */
EXPORT int mpg123_set_index(mpg123_handle *mh, off_t *offsets, off_t step, size_t fill);
/** Get information about current and remaining frames/seconds.
* WARNING: This function is there because of special usage by standalone mpg123 and may be removed in the final version of libmpg123!
@ -494,10 +622,7 @@ EXPORT int mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t
* served by libmpg123 but not yet played. You get the projected current frame
* and seconds, as well as the remaining frames/seconds. This does _not_ care
* about skipped samples due to gapless playback. */
EXPORT int mpg123_position( mpg123_handle *mh, off_t frame_offset,
off_t buffered_bytes, off_t *current_frame,
off_t *frames_left, double *current_seconds,
double *seconds_left);
EXPORT int mpg123_position( mpg123_handle *mh, off_t frame_offset, off_t buffered_bytes, off_t *current_frame, off_t *frames_left, double *current_seconds, double *seconds_left);
/*@}*/
@ -593,8 +718,8 @@ struct mpg123_frameinfo
long rate; /**< The sampling rate in Hz. */
enum mpg123_mode mode; /**< The audio mode (Mono, Stereo, Joint-stero, Dual Channel). */
int mode_ext; /**< The mode extension bit flag. */
int framesize; /**< The size of the frame (in bytes). */
enum mpg123_flags flags; /**< MPEG Audio flag bits. */
int framesize; /**< The size of the frame (in bytes, including header). */
enum mpg123_flags flags; /**< MPEG Audio flag bits. Just now I realize that it should be declared as int, not enum. It's a bitwise combination of the enum values. */
int emphasis; /**< The emphasis type. */
int bitrate; /**< Bitrate of the frame (kbps). */
int abr_rate; /**< The target average bitrate. */
@ -605,7 +730,7 @@ struct mpg123_frameinfo
EXPORT int mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi);
/** Get the safe output buffer size for all cases (when you want to replace the internal buffer) */
EXPORT size_t mpg123_safe_buffer();
EXPORT size_t mpg123_safe_buffer(void);
/** Make a full parsing scan of each frame in the file. ID3 tags are found. An accurate length
* value is stored. Seek index will be filled. A seek back to current position
@ -627,6 +752,9 @@ EXPORT int mpg123_set_filesize(mpg123_handle *mh, off_t size);
/** Returns the time (seconds) per frame; <0 is error. */
EXPORT double mpg123_tpf(mpg123_handle *mh);
/** Returns the samples per frame for the most recently parsed frame; <0 is error. */
EXPORT int mpg123_spf(mpg123_handle *mh);
/** Get and reset the clip count. */
EXPORT long mpg123_clip(mpg123_handle *mh);
@ -635,6 +763,8 @@ EXPORT long mpg123_clip(mpg123_handle *mh);
enum mpg123_state
{
MPG123_ACCURATE = 1 /**< Query if positons are currently accurate (integer value, 0 if false, 1 if true) */
,MPG123_BUFFERFILL /**< Get fill of internal (feed) input buffer as integer byte count returned as long and as double. An error is returned on integer overflow while converting to (signed) long, but the returned floating point value shold still be fine. */
,MPG123_FRANKENSTEIN /**< Stream consists of carelessly stitched together files (the leading one featuring gapless info). */
};
/** Get various current decoder/stream state information.
@ -705,6 +835,20 @@ EXPORT int mpg123_set_string(mpg123_string* sb, const char* stuff);
* \param count number of characters to copy (a null-byte is always appended) */
EXPORT int mpg123_set_substring(mpg123_string *sb, const char *stuff, size_t from, size_t count);
/** Count characters in a mpg123 string (non-null bytes or UTF-8 characters).
* \return character count
* \param sb the string
* \param utf8 a flag to tell if the string is in utf8 encoding
* Even with the fill property, the character count is not obvious as there could be multiple trailing null bytes.
*/
EXPORT size_t mpg123_strlen(mpg123_string *sb, int utf8);
/** Remove trailing \r and \n, if present.
* \return 0 on error, 1 on success
* \param sb the string
*/
EXPORT int mpg123_chomp_string(mpg123_string *sb);
/** The mpg123 text encodings. This contains encodings we encounter in ID3 tags or ICY meta info. */
enum mpg123_text_encoding
{
@ -810,6 +954,9 @@ typedef struct
The check function returns a combination of flags. */
EXPORT int mpg123_meta_check(mpg123_handle *mh); /* On error (no valid handle) just 0 is returned. */
/** Clean up meta data storage (ID3v2 and ICY), freeing memory. */
EXPORT void mpg123_meta_free(mpg123_handle *mh);
/** Point v1 and v2 to existing data structures wich may change on any next read/decode function call.
* v1 and/or v2 can be set to NULL when there is no corresponding data.
* \return Return value is MPG123_OK or MPG123_ERR, */
@ -907,16 +1054,26 @@ EXPORT size_t mpg123_outblock(mpg123_handle *mh);
/** Replace low-level stream access functions; read and lseek as known in POSIX.
* You can use this to make any fancy file opening/closing yourself,
* using open_fd to set the file descriptor for your read/lseek (doesn't need to be a "real" file descriptor...).
* using mpg123_open_fd() to set the file descriptor for your read/lseek (doesn't need to be a "real" file descriptor...).
* Setting a function to NULL means that the default internal read is
* used (active from next mpg123_open call on). */
EXPORT int mpg123_replace_reader( mpg123_handle *mh,
ssize_t (*r_read) (int, void *, size_t),
off_t (*r_lseek)(int, off_t, int) );
* used (active from next mpg123_open call on).
* Note: As it would be troublesome to mess with this while having a file open,
* this implies mpg123_close(). */
EXPORT int mpg123_replace_reader(mpg123_handle *mh, ssize_t (*r_read) (int, void *, size_t), off_t (*r_lseek)(int, off_t, int));
/** Replace I/O functions with your own ones operating on some kind of handle instead of integer descriptors.
* The handle is a void pointer, so you can pass any data you want...
* mpg123_open_handle() is the call you make to use the I/O defined here.
* There is no fallback to internal read/seek here.
* Note: As it would be troublesome to mess with this while having a file open,
* this mpg123_close() is implied here.
* \param r_read The callback for reading (behaviour like posix read).
* \param r_lseek The callback for seeking (like posix lseek).
* \param cleanup A callback to clean up an I/O handle on mpg123_close, can be NULL for none (you take care of cleaning your handles). */
EXPORT int mpg123_replace_reader_handle(mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), off_t (*r_lseek)(void *, off_t, int), void (*cleanup)(void*));
/* @} */
#ifdef __cplusplus
}
#endif

View File

@ -11,9 +11,10 @@
#define MPG123_H_INTERN
#define MPG123_RATES 9
#define MPG123_ENCODINGS 10
#define MPG123_ENCODINGS 12
#include "config.h" /* Load this before _anything_ */
#include "intsym.h" /* Prefixing of internal symbols that still are public in a static lib. */
/* ABI conformance for other compilers.
mpg123 needs 16byte-aligned stack for SSE and friends.
@ -24,8 +25,14 @@
# define attribute_align_arg __attribute__((force_align_arg_pointer))
/* The gcc that can align the stack does not need the check... nor does it work with gcc 4.3+, anyway. */
#else
# define attribute_align_arg
# define NEED_ALIGNCHECK /* Other compilers get code to catch misaligned stack. */
/* Other compilers get code to catch misaligned stack.
Well, except Sun Studio, which accepts the aligned attribute but does not honor it. */
#if !defined(__SUNPRO_C)
# define NEED_ALIGNCHECK
#endif
#endif
#endif
#else
@ -130,7 +137,7 @@ static inline long scale_rounded(long x, int shift)
"srwi %0, %0, %4 \n\t" \
"rlwimi %0, %1, %5, 0, %6 \n\t" \
: "=&r" (_mull), "=&r" (_mulh) \
: "%r" (_x), "r" (_y), "i" (radix), "i" (32-(radix)), "i" ((radix)-1) \
: "r" (_x), "r" (_y), "i" (radix), "i" (32-(radix)), "i" ((radix)-1) \
); \
_mull; \
})
@ -146,7 +153,7 @@ static inline long scale_rounded(long x, int shift)
"slw %1, %1, %2 \n\t" \
"or %0, %0, %1 \n\t" \
: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \
: "%r" (_x), "r" (_y), "r" (_radix) \
: "r" (_x), "r" (_y), "r" (_radix) \
: "cc" \
); \
_mull; \
@ -161,7 +168,7 @@ static inline long scale_rounded(long x, int shift)
"mov %0, %0, lsr %4 \n\t" \
"orr %0, %0, %1, lsl %5 \n\t" \
: "=&r" (_mull), "=&r" (_mulh) \
: "%r" (_x), "r" (_y), "M" (radix), "M" (32-(radix)) \
: "r" (_x), "r" (_y), "M" (radix), "M" (32-(radix)) \
); \
_mull; \
})
@ -173,9 +180,10 @@ static inline long scale_rounded(long x, int shift)
"smull %0, %1, %3, %4 \n\t" \
"mov %0, %0, lsr %5 \n\t" \
"rsb %2, %5, #32 \n\t" \
"orr %0, %0, %1, lsl %2 \n\t" \
"mov %1, %1, lsl %2 \n\t" \
"orr %0, %0, %1 \n\t" \
: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \
: "%r" (_x), "r" (_y), "r" (_radix) \
: "r" (_x), "r" (_y), "r" (_radix) \
); \
_mull; \
})
@ -306,16 +314,25 @@ static inline long scale_rounded(long x, int shift)
#include "frame.h"
/* fr is a mpg123_handle* by convention here... */
#define NOQUIET 0 /*(!(fr->p.flags & MPG123_QUIET))*/
#define NOQUIET (!(fr->p.flags & MPG123_QUIET))
#define VERBOSE (NOQUIET && fr->p.verbose)
#define VERBOSE2 (NOQUIET && fr->p.verbose > 1)
#define VERBOSE3 (NOQUIET && fr->p.verbose > 2)
#define VERBOSE4 (NOQUIET && fr->p.verbose > 3)
#define PVERB(mp, level) 0 /*(!((mp)->flags & MPG123_QUIET) && (mp)->verbose >= (level)) */
#define PVERB(mp, level) (!((mp)->flags & MPG123_QUIET) && (mp)->verbose >= (level))
int decode_update(mpg123_handle *mh);
/* residing in format.c */
off_t samples_to_storage(mpg123_handle *fr , off_t s);
off_t samples_to_bytes(mpg123_handle *fr , off_t s);
off_t bytes_to_samples(mpg123_handle *fr , off_t b);
/* Postprocessing format conversion of freshly decoded buffer. */
void postprocess_buffer(mpg123_handle *fr);
/* If networking is enabled and we really mean internal networking, the timeout_read function is available. */
#if defined (NETWORK) && !defined (WANT_WIN32_SOCKETS)
/* Does not work with win32 */
#define TIMEOUT_READ
#endif
#endif

View File

@ -0,0 +1,148 @@
/*
ntom.c: N->M down/up sampling; the setup code.
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#define SAFE_NTOM /* Do not depend on off_t*off_t with big values still being in the range... */
#include "mpg123lib_intern.h"
#include "debug.h"
int synth_ntom_set_step(mpg123_handle *fr)
{
long m,n;
m = frame_freq(fr);
n = fr->af.rate;
if(VERBOSE2)
fprintf(stderr,"Init rate converter: %ld->%ld\n",m,n);
if(n > NTOM_MAX_FREQ || m > NTOM_MAX_FREQ || m <= 0 || n <= 0) {
if(NOQUIET) error("NtoM converter: illegal rates");
fr->err = MPG123_BAD_RATE;
return -1;
}
n *= NTOM_MUL;
fr->ntom_step = (unsigned long) n / m;
if(fr->ntom_step > (unsigned long)NTOM_MAX*NTOM_MUL) {
if(NOQUIET) error3("max. 1:%i conversion allowed (%lu vs %lu)!", NTOM_MAX, fr->ntom_step, (unsigned long)8*NTOM_MUL);
fr->err = MPG123_BAD_RATE;
return -1;
}
fr->ntom_val[0] = fr->ntom_val[1] = ntom_val(fr, fr->num);
return 0;
}
/*
The SAFE_NTOM does iterative loops instead of straight multiplication.
The safety is not just about the algorithm closely mimicking the decoder instead of applying some formula,
it is more about avoiding multiplication of possibly big sample offsets (a 32bit off_t could overflow too easily).
*/
unsigned long ntom_val(mpg123_handle *fr, off_t frame)
{
off_t ntm;
#ifdef SAFE_NTOM /* Carry out the loop, without the threatening integer overflow. */
off_t f;
ntm = NTOM_MUL>>1; /* for frame 0 */
for(f=0; f<frame; ++f) /* for frame > 0 */
{
ntm += spf(fr)*fr->ntom_step;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
}
#else /* Just make one computation with overall sample offset. */
ntm = (NTOM_MUL>>1) + spf(fr)*frame*fr->ntom_step;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
#endif
return (unsigned long) ntm;
}
/* Set the ntom value for next expected frame to be decoded.
This is for keeping output consistent across seeks. */
void ntom_set_ntom(mpg123_handle *fr, off_t num)
{
fr->ntom_val[1] = fr->ntom_val[0] = ntom_val(fr, num);
}
/* Carry out the ntom sample count operation for this one frame.
No fear of integer overflow here. */
off_t ntom_frame_outsamples(mpg123_handle *fr)
{
/* The do this before decoding the separate channels, so there is only one common ntom value. */
int ntm = fr->ntom_val[0];
ntm += spf(fr)*fr->ntom_step;
return ntm/NTOM_MUL;
}
/* Convert frame offset to unadjusted output sample offset. */
off_t ntom_frmouts(mpg123_handle *fr, off_t frame)
{
#ifdef SAFE_NTOM
off_t f;
#endif
off_t soff = 0;
off_t ntm = ntom_val(fr,0);
#ifdef SAFE_NTOM
if(frame <= 0) return 0;
for(f=0; f<frame; ++f)
{
ntm += spf(fr)*fr->ntom_step;
soff += ntm/NTOM_MUL;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
}
#else
soff = (ntm + frame*(off_t)spf(fr)*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
#endif
return soff;
}
/* Convert input samples to unadjusted output samples. */
off_t ntom_ins2outs(mpg123_handle *fr, off_t ins)
{
off_t soff = 0;
off_t ntm = ntom_val(fr,0);
#ifdef SAFE_NTOM
{
off_t block = spf(fr);
if(ins <= 0) return 0;
do
{
off_t nowblock = ins > block ? block : ins;
ntm += nowblock*fr->ntom_step;
soff += ntm/NTOM_MUL;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
ins -= nowblock;
} while(ins > 0);
}
#else
/* Beware of overflows: when off_t is 32bits, the multiplication blows too easily.
Of course, it blows for 64bits, too, in theory, but that's for _really_ large files. */
soff = ((off_t)ntm + (off_t)ins*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
#endif
return soff;
}
/* Determine frame offset from unadjusted output sample offset. */
off_t ntom_frameoff(mpg123_handle *fr, off_t soff)
{
off_t ioff = 0; /* frames or samples */
off_t ntm = ntom_val(fr,0);
#ifdef SAFE_NTOM
if(soff <= 0) return 0;
for(ioff=0; 1; ++ioff)
{
ntm += spf(fr)*fr->ntom_step;
if(ntm/NTOM_MUL > soff) break;
soff -= ntm/NTOM_MUL;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
}
return ioff;
#else
ioff = (soff*(off_t)NTOM_MUL-ntm)/(off_t)fr->ntom_step;
return ioff/(off_t)spf(fr);
#endif
}

View File

@ -41,20 +41,21 @@ echo "
#define dn_SSE "SSE"
#define dn_x86_64 "x86-64"
#define dn_ARM "ARM"
#define dn_NEON "NEON"
static const char* decname[] =
{
"auto"
, dn_generic, dn_generic_dither, dn_i386, dn_i486, dn_i586, dn_i586_dither, dn_MMX, dn_3DNow, dn_3DNowExt, dn_AltiVec, dn_SSE, dn_x86_64, dn_ARM
, dn_generic, dn_generic_dither, dn_i386, dn_i486, dn_i586, dn_i586_dither, dn_MMX, dn_3DNow, dn_3DNowExt, dn_AltiVec, dn_SSE, dn_x86_64, dn_ARM, dn_NEON
, "nodec"
};
#if (defined OPT_X86) && (defined OPT_MULTI)
#include "getcpuflags.h"
struct cpuflags cpu_flags;
static struct cpuflags cpu_flags;
#else
/* Faking stuff for non-multi builds. The same code for synth function choice is used.
Just no runtime dependency of result... */
char cpu_flags;
#define cpu_flags nothing
#define cpu_i586(s) 1
#define cpu_fpu(s) 1
#define cpu_mmx(s) 1
@ -91,7 +92,17 @@ char cpu_flags;
# define OUT_SYNTHS(synth_16, synth_8, synth_real, synth_32) { IF8(synth_8) IFREAL(synth_real) IF32(synth_32) }
#endif
const struct synth_s synth_base =
/* The call of left and right plain synth, wrapped.
This may be replaced by a direct stereo optimized synth. */
static int synth_stereo_wrap(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
{
int clip;
clip = (fr->synth)(bandPtr_l, 0, fr, 0);
clip += (fr->synth)(bandPtr_r, 1, fr, 1);
return clip;
}
static const struct synth_s synth_base =
{
{ /* plain */
OUT_SYNTHS(synth_1to1, synth_1to1_8bit, synth_1to1_real, synth_1to1_s32)
@ -114,13 +125,13 @@ const struct synth_s synth_base =
# endif
},
{ /* mono2stereo */
OUT_SYNTHS(synth_1to1_mono2stereo, synth_1to1_8bit_mono2stereo, synth_1to1_real_mono2stereo, synth_1to1_s32_mono2stereo)
OUT_SYNTHS(synth_1to1_m2s, synth_1to1_8bit_m2s, synth_1to1_real_m2s, synth_1to1_s32_m2s)
# ifndef NO_DOWNSAMPLE
,OUT_SYNTHS(synth_2to1_mono2stereo, synth_2to1_8bit_mono2stereo, synth_2to1_real_mono2stereo, synth_2to1_s32_mono2stereo)
,OUT_SYNTHS(synth_4to1_mono2stereo, synth_4to1_8bit_mono2stereo, synth_4to1_real_mono2stereo, synth_4to1_s32_mono2stereo)
,OUT_SYNTHS(synth_2to1_m2s, synth_2to1_8bit_m2s, synth_2to1_real_m2s, synth_2to1_s32_m2s)
,OUT_SYNTHS(synth_4to1_m2s, synth_4to1_8bit_m2s, synth_4to1_real_m2s, synth_4to1_s32_m2s)
# endif
# ifndef NO_NTOM
,OUT_SYNTHS(synth_ntom_mono2stereo, synth_ntom_8bit_mono2stereo, synth_ntom_real_mono2stereo, synth_ntom_s32_mono2stereo)
,OUT_SYNTHS(synth_ntom_m2s, synth_ntom_8bit_m2s, synth_ntom_real_m2s, synth_ntom_s32_m2s)
# endif
},
{ /* mono*/
@ -155,7 +166,7 @@ enum optdec defdec(void){ return defopt; }
enum optcla decclass(const enum optdec type)
{
return (type == mmx || type == sse || type == dreidnowext || type == x86_64 ) ? mmxsse : normal;
return (type == mmx || type == sse || type == dreidnowext || type == x86_64 || type == neon) ? mmxsse : normal;
}
@ -215,6 +226,9 @@ static int find_dectype(mpg123_handle *fr)
#ifdef OPT_ARM
else if(basic_synth == synth_1to1_arm) type = arm;
#endif
#ifdef OPT_NEON
else if(basic_synth == synth_1to1_neon) type = neon;
#endif
#ifdef OPT_GENERIC_DITHER
else if(basic_synth == synth_1to1_dither) type = generic_dither;
#endif
@ -239,6 +253,9 @@ static int find_dectype(mpg123_handle *fr)
#ifdef OPT_ALTIVEC
else if(basic_synth == synth_1to1_real_altivec) type = altivec;
#endif
#ifdef OPT_NEON
else if(basic_synth == synth_1to1_real_neon) type = neon;
#endif
#endif /* real */
@ -252,6 +269,9 @@ static int find_dectype(mpg123_handle *fr)
#ifdef OPT_ALTIVEC
else if(basic_synth == synth_1to1_s32_altivec) type = altivec;
#endif
#ifdef OPT_NEON
else if(basic_synth == synth_1to1_s32_neon) type = neon;
#endif
#endif /* 32bit */
#ifdef OPT_X86
@ -308,7 +328,8 @@ int set_synth_functions(mpg123_handle *fr)
basic_format = f_real;
#endif
#ifndef NO_32BIT
else if(fr->af.encoding & MPG123_ENC_32)
/* 24 bit integer means decoding to 32 bit first. */
else if(fr->af.encoding & MPG123_ENC_32 || fr->af.encoding & MPG123_ENC_24)
basic_format = f_32;
#endif
@ -387,6 +408,7 @@ int set_synth_functions(mpg123_handle *fr)
# ifdef ACCURATE_ROUNDING
&& fr->cpu_opts.type != sse
&& fr->cpu_opts.type != x86_64
&& fr->cpu_opts.type != neon
# endif
)
{
@ -445,9 +467,11 @@ int frame_cpu_opt(mpg123_handle *fr, const char* cpu)
/* covers any i386+ cpu; they actually differ only in the synth_1to1 function, mostly... */
#ifdef OPT_X86
#ifdef OPT_MULTI
#ifndef NO_LAYER3
#if (defined OPT_3DNOW || defined OPT_3DNOWEXT)
fr->cpu_opts.dct36 = dct36;
fr->cpu_opts.the_dct36 = dct36;
#endif
#endif
#endif
@ -487,9 +511,12 @@ int frame_cpu_opt(mpg123_handle *fr, const char* cpu)
{
chosen = "3DNowExt";
fr->cpu_opts.type = dreidnowext;
#ifdef OPT_MULTI
# ifndef NO_LAYER3
fr->cpu_opts.dct36 = dct36_3dnowext;
/* The DCT36 is _bad_, at least compared to gcc 4.4-built C code. */
/* fr->cpu_opts.the_dct36 = dct36_3dnowext; */
# endif
#endif
# ifndef NO_16BIT
fr->synths.plain[r_1to1][f_16] = synth_1to1_3dnowext;
# endif
@ -502,9 +529,12 @@ int frame_cpu_opt(mpg123_handle *fr, const char* cpu)
{
chosen = "3DNow";
fr->cpu_opts.type = dreidnow;
#ifdef OPT_MULTI
# ifndef NO_LAYER3
fr->cpu_opts.dct36 = dct36_3dnow;
/* The DCT36 is _bad_, at least compared to gcc 4.4-built C code. */
/* fr->cpu_opts.the_dct36 = dct36_3dnow; */
# endif
#endif
# ifndef NO_16BIT
fr->synths.plain[r_1to1][f_16] = synth_1to1_3dnow;
# endif
@ -585,7 +615,7 @@ int frame_cpu_opt(mpg123_handle *fr, const char* cpu)
{
fr->synths.plain[r_1to1][f_8] = synth_1to1_8bit_wrap;
fr->synths.mono[r_1to1][f_8] = synth_1to1_8bit_wrap_mono;
fr->synths.mono2stereo[r_1to1][f_8] = synth_1to1_8bit_wrap_mono2stereo;
fr->synths.mono2stereo[r_1to1][f_8] = synth_1to1_8bit_wrap_m2s;
}
# endif
# endif
@ -658,6 +688,27 @@ int frame_cpu_opt(mpg123_handle *fr, const char* cpu)
}
# endif
# ifdef OPT_NEON
if(!done && (auto_choose || want_dec == neon))
{
chosen = "NEON";
fr->cpu_opts.type = neon;
# ifndef NO_16BIT
fr->synths.plain[r_1to1][f_16] = synth_1to1_neon;
fr->synths.stereo[r_1to1][f_16] = synth_1to1_stereo_neon;
# endif
# ifndef NO_REAL
fr->synths.plain[r_1to1][f_real] = synth_1to1_real_neon;
fr->synths.stereo[r_1to1][f_real] = synth_1to1_real_stereo_neon;
# endif
# ifndef NO_32BIT
fr->synths.plain[r_1to1][f_32] = synth_1to1_s32_neon;
fr->synths.stereo[r_1to1][f_32] = synth_1to1_s32_stereo_neon;
# endif
done = 1;
}
# endif
# ifdef OPT_ARM
if(!done && (auto_choose || want_dec == arm))
{
@ -690,7 +741,7 @@ int frame_cpu_opt(mpg123_handle *fr, const char* cpu)
{
fr->synths.plain[r_1to1][f_8] = synth_1to1_8bit_wrap;
fr->synths.mono[r_1to1][f_8] = synth_1to1_8bit_wrap_mono;
fr->synths.mono2stereo[r_1to1][f_8] = synth_1to1_8bit_wrap_mono2stereo;
fr->synths.mono2stereo[r_1to1][f_8] = synth_1to1_8bit_wrap_m2s;
}
# endif
# endif
@ -770,6 +821,9 @@ static const char *mpg123_supported_decoder_list[] =
#ifdef OPT_ARM
NULL,
#endif
#ifdef OPT_NEON
NULL,
#endif
#ifdef OPT_GENERIC_FLOAT
NULL,
#endif
@ -818,6 +872,9 @@ static const char *mpg123_decoder_list[] =
#ifdef OPT_ARM
dn_ARM,
#endif
#ifdef OPT_NEON
dn_NEON,
#endif
#ifdef OPT_GENERIC
dn_generic,
#endif
@ -877,6 +934,9 @@ void check_decoders(void )
#ifdef OPT_ARM
*(d++) = decname[arm];
#endif
#ifdef OPT_NEON
*(d++) = decname[neon];
#endif
#ifdef OPT_GENERIC
*(d++) = decname[generic];
#endif
@ -893,8 +953,8 @@ const char* attribute_align_arg mpg123_current_decoder(mpg123_handle *mh)
return decname[mh->cpu_opts.type];
}
const char attribute_align_arg **mpg123_decoders(){ return mpg123_decoder_list; }
const char attribute_align_arg **mpg123_supported_decoders()
const char attribute_align_arg **mpg123_decoders(void){ return mpg123_decoder_list; }
const char attribute_align_arg **mpg123_supported_decoders(void)
{
#ifdef OPT_MULTI
return mpg123_supported_decoder_list;

View File

@ -37,7 +37,7 @@ enum optdec
{ /* autodec needs to be =0 and the first, nodec needs to be the last -- for loops! */
autodec=0, generic, generic_dither, idrei,
ivier, ifuenf, ifuenf_dither, mmx,
dreidnow, dreidnowext, altivec, sse, x86_64, arm,
dreidnow, dreidnowext, altivec, sse, x86_64, arm, neon,
nodec
};
enum optcla { nocla=0, normal, mmxsse };
@ -67,7 +67,8 @@ enum optcla decclass(const enum optdec);
#ifdef REAL_IS_FIXED
#if (defined OPT_I486) || (defined OPT_I586) || (defined OPT_I586_DITHER) \
|| (defined OPT_MMX) || (defined OPT_SSE) || (defined_OPT_ALTIVEC) \
|| (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) || (defined OPT_X86_64) || (defined OPT_GENERIC_DITHER)
|| (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) || (defined OPT_X86_64) \
|| (defined OPT_NEON) || (defined OPT_GENERIC_DITHER)
#error "Bad decoder choice together with fixed point math!"
#endif
#endif
@ -184,6 +185,13 @@ extern const int costab_mmxsse[];
#endif
#endif
#ifdef OPT_NEON
#define OPT_MMXORSSE
#ifndef OPT_MULTI
# define defopt neon
#endif
#endif
/* used for multi opt mode and the single 3dnow mode to have the old 3dnow test flag still working */
void check_decoders(void);
@ -198,7 +206,7 @@ void check_decoders(void);
# define defopt nodec
# if (defined OPT_3DNOW || defined OPT_3DNOWEXT)
# define opt_dct36(fr) ((fr)->cpu_opts.dct36)
# define opt_dct36(fr) ((fr)->cpu_opts.the_dct36)
# endif
#endif /* OPT_MULTI else */

File diff suppressed because it is too large Load Diff

View File

@ -12,13 +12,16 @@
#include "config.h"
#include "mpg123.h"
#ifndef NO_FEEDER
struct buffy
{
unsigned char *data;
ssize_t size;
ssize_t realsize;
struct buffy *next;
};
struct bufferchain
{
struct buffy* first; /* The beginning of the chain. */
@ -29,27 +32,51 @@ struct bufferchain
ssize_t firstpos; /* The point of return on non-forget() */
/* The "real" filepos is fileoff + pos. */
off_t fileoff; /* Beginning of chain is at this file offset. */
size_t bufblock; /* Default (minimal) size of buffers. */
size_t pool_size; /* Keep that many buffers in storage. */
size_t pool_fill; /* That many buffers are there. */
/* A pool of buffers to re-use, if activated. It's a linked list that is worked on from the front. */
struct buffy *pool;
};
/* Call this before any buffer chain use (even bc_init()). */
void bc_prepare(struct bufferchain *, size_t pool_size, size_t bufblock);
/* Free persistent data in the buffer chain, after bc_reset(). */
void bc_cleanup(struct bufferchain *);
/* Change pool size. This does not actually allocate/free anything on itself, just instructs later operations to free less / allocate more buffers. */
void bc_poolsize(struct bufferchain *, size_t pool_size, size_t bufblock);
/* Return available byte count in the buffer. */
size_t bc_fill(struct bufferchain *bc);
#endif
struct reader_data
{
off_t filelen; /* total file length or total buffer size */
off_t filepos; /* position in file or position in buffer chain */
int filept;
/* Custom opaque I/O handle from the client. */
void *iohandle;
int flags;
#ifndef WIN32
long timeout_sec;
#endif
ssize_t (*fdread) (mpg123_handle *, void *, size_t);
/* User can replace the read and lseek functions. The r_* are the stored replacement functions or NULL,
The second two pointers are the actual workers (default map to POSIX read/lseek). */
/* User can replace the read and lseek functions. The r_* are the stored replacement functions or NULL. */
ssize_t (*r_read) (int fd, void *buf, size_t count);
off_t (*r_lseek)(int fd, off_t offset, int whence);
/* These are custom I/O routines for opaque user handles.
They get picked if there's some iohandle set. */
ssize_t (*r_read_handle) (void *handle, void *buf, size_t count);
off_t (*r_lseek_handle)(void *handle, off_t offset, int whence);
/* An optional cleaner for the handle on closing the stream. */
void (*cleanup_handle)(void *handle);
/* These two pointers are the actual workers (default map to POSIX read/lseek). */
ssize_t (*read) (int fd, void *buf, size_t count);
off_t (*lseek)(int fd, off_t offset, int whence);
/* Buffered readers want that abstracted, set internally. */
ssize_t (*fullread)(mpg123_handle *, unsigned char *, ssize_t);
#ifndef NO_FEEDER
struct bufferchain buffer; /* Not dynamically allocated, these few struct bytes aren't worth the trouble. */
#endif
};
/* start to use off_t to properly do LFS in future ... used to be long */
@ -71,6 +98,8 @@ struct reader
/* Open a file by path or use an opened file descriptor. */
int open_stream(mpg123_handle *, const char *path, int fd);
/* Open an external handle. */
int open_stream_handle(mpg123_handle *, void *iohandle);
/* feed based operation has some specials */
int open_feed(mpg123_handle *);
@ -86,6 +115,7 @@ void open_bad(mpg123_handle *);
#define READER_SEEKABLE 0x4
#define READER_BUFFERED 0x8
#define READER_NONBLOCK 0x20
#define READER_HANDLEIO 0x40
#define READER_STREAM 0
#define READER_ICY_STREAM 1

View File

@ -12,33 +12,32 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
/* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */
/* Including these here although it works without on my Linux install... curious about _why_. */
/* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h (the latter two included in compat.h already). */
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _MSC_VER
#include <io.h>
#endif
#include "compat.h"
#include "debug.h"
static int default_init(mpg123_handle *fr);
static off_t get_fileinfo(mpg123_handle *);
static ssize_t posix_read(int fd, void *buf, size_t count){ return read(fd, buf, count); }
static off_t posix_lseek(int fd, off_t offset, int whence){ return lseek(fd, offset, whence); }
static off_t nix_lseek(int fd, off_t offset, int whence){ return -1; }
static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t count);
/* Wrapper to decide between descriptor-based and external handle-based I/O. */
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence);
static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count);
#ifndef NO_FEEDER
/* Bufferchain methods. */
static void bc_init(struct bufferchain *bc);
@ -52,19 +51,41 @@ static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
static ssize_t bc_skip(struct bufferchain *bc, ssize_t count);
static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count);
static void bc_forget(struct bufferchain *bc);
#else
#define bc_init(a)
#define bc_reset(a)
#endif
/* A normal read and a read with timeout. */
static ssize_t plain_read(mpg123_handle *fr, void *buf, size_t count)
{
ssize_t ret = fr->rdat.read(fr->rdat.filept, buf, count);
ssize_t ret = io_read(&fr->rdat, buf, count);
if(VERBOSE3) debug2("read %li bytes of %li", (long)ret, (long)count);
return ret;
}
#ifdef TIMEOUT_READ
/* Wait for data becoming available, allowing soft-broken network connection to die
This is needed for Shoutcast servers that have forgotten about us while connection was temporarily down. */
static ssize_t timeout_read(mpg123_handle *fr, void *buf, size_t count)
{
struct timeval tv;
ssize_t ret = 0;
fd_set fds;
tv.tv_sec = fr->rdat.timeout_sec;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(fr->rdat.filept, &fds);
ret = select(fr->rdat.filept+1, &fds, NULL, NULL, &tv);
/* This works only with "my" read function. Not user-replaced. */
if(ret > 0) ret = read(fr->rdat.filept, buf, count);
else
{
ret=-1; /* no activity is the error */
if(NOQUIET) error("stream timed out");
}
return ret;
}
#endif
#ifndef NO_ICY
/* stream based operation with icy meta data*/
static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
@ -98,7 +119,7 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
if(fr->icy.next > 0)
{
cut_pos = fr->icy.next;
ret = fr->rdat.fdread(fr,buf,cut_pos);
ret = fr->rdat.fdread(fr,buf+cnt,cut_pos);
if(ret < 1)
{
if(ret == 0) break; /* Just EOF. */
@ -106,7 +127,8 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
return READER_ERROR;
}
fr->rdat.filepos += ret;
if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
cnt += ret;
fr->icy.next -= ret;
if(fr->icy.next > 0)
@ -118,7 +140,7 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
/* now off to read icy data */
/* one byte icy-meta size (must be multiplied by 16 to get icy-meta length) */
ret = fr->rdat.fdread(fr,&temp_buff,1); /* Getting one single byte hast to suceed. */
if(ret < 0){ if(NOQUIET) error("reading icy size"); return READER_ERROR; }
if(ret == 0) break;
@ -130,6 +152,7 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
{
/* we have got some metadata */
char *meta_buff;
/* TODO: Get rid of this malloc ... perhaps hooking into the reader buffer pool? */
meta_buff = malloc(meta_size+1);
if(meta_buff != NULL)
{
@ -157,13 +180,15 @@ static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count
}
fr->icy.next = fr->icy.interval;
}
else
{
ret = plain_fullread(fr, buf+cnt, count-cnt);
if(ret < 0){ if(NOQUIET) error1("reading the rest of %li", (long)(count-cnt)); return READER_ERROR; }
if(ret == 0) break;
ret = plain_fullread(fr, buf+cnt, count-cnt);
if(ret < 0){ if(NOQUIET) error1("reading the rest of %li", (long)(count-cnt)); return READER_ERROR; }
if(ret == 0) break;
cnt += ret;
fr->icy.next -= ret;
cnt += ret;
fr->icy.next -= ret;
}
}
/* debug1("done reading, got %li", (long)cnt); */
return cnt;
@ -177,6 +202,9 @@ static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t coun
{
ssize_t ret,cnt=0;
#ifdef EXTRA_DEBUG
debug1("plain fullread of %"SSIZE_P, (size_p)count);
#endif
/*
There used to be a check for expected file end here (length value or ID3 flag).
This is not needed:
@ -198,7 +226,7 @@ static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t coun
static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
{
off_t ret;
ret = fr->rdat.lseek(fr->rdat.filept, pos, whence);
ret = io_seek(&fr->rdat, pos, whence);
if (ret >= 0) fr->rdat.filepos = ret;
else
{
@ -210,8 +238,19 @@ static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
static void stream_close(mpg123_handle *fr)
{
if(fr->rdat.flags & READER_FD_OPENED) close(fr->rdat.filept);
if(fr->rdat.flags & READER_FD_OPENED) compat_close(fr->rdat.filept);
fr->rdat.filept = 0;
#ifndef NO_FEEDER
if(fr->rdat.flags & READER_BUFFERED) bc_reset(&fr->rdat.buffer);
#endif
if(fr->rdat.flags & READER_HANDLEIO)
{
if(fr->rdat.cleanup_handle != NULL) fr->rdat.cleanup_handle(fr->rdat.iohandle);
fr->rdat.iohandle = NULL;
}
}
static int stream_seek_frame(mpg123_handle *fr, off_t newframe)
@ -311,6 +350,7 @@ static off_t stream_skip_bytes(mpg123_handle *fr,off_t len)
}
return fr->rd->tell(fr);
}
#ifndef NO_FEEDER
else if(fr->rdat.flags & READER_BUFFERED)
{ /* Perhaps we _can_ go a bit back. */
if(fr->rdat.buffer.pos >= -len)
@ -324,6 +364,7 @@ static off_t stream_skip_bytes(mpg123_handle *fr,off_t len)
return READER_ERROR;
}
}
#endif
else
{
fr->err = MPG123_NO_SEEK;
@ -351,17 +392,17 @@ static int generic_read_frame_body(mpg123_handle *fr,unsigned char *buf, int siz
{
long ll = l;
if(ll <= 0) ll = 0;
/* This allows partial frames at the end... do we really want to pad and decode these?! */
memset(buf+ll,0,size-ll);
return READER_MORE;
}
return l;
}
static off_t generic_tell(mpg123_handle *fr)
{
#ifndef NO_FEEDER
if(fr->rdat.flags & READER_BUFFERED)
fr->rdat.filepos = fr->rdat.buffer.fileoff+fr->rdat.buffer.pos;
#endif
return fr->rdat.filepos;
}
@ -370,13 +411,20 @@ static off_t generic_tell(mpg123_handle *fr)
static void stream_rewind(mpg123_handle *fr)
{
if(fr->rdat.flags & READER_SEEKABLE)
fr->rdat.buffer.fileoff = fr->rdat.filepos = stream_lseek(fr,0,SEEK_SET);
{
fr->rdat.filepos = stream_lseek(fr,0,SEEK_SET);
#ifndef NO_FEEDER
fr->rdat.buffer.fileoff = fr->rdat.filepos;
#endif
}
#ifndef NO_FEEDER
if(fr->rdat.flags & READER_BUFFERED)
{
fr->rdat.buffer.pos = 0;
fr->rdat.buffer.firstpos = 0;
fr->rdat.filepos = fr->rdat.buffer.fileoff;
}
#endif
}
/*
@ -384,20 +432,19 @@ static void stream_rewind(mpg123_handle *fr)
* reads the last 128 bytes information into buffer
* ... that is not totally safe...
*/
static off_t get_fileinfo(mpg123_handle *fr)
{
off_t len;
if((len=fr->rdat.lseek(fr->rdat.filept,0,SEEK_END)) < 0) return -1;
if((len=io_seek(&fr->rdat,0,SEEK_END)) < 0) return -1;
if(fr->rdat.lseek(fr->rdat.filept,-128,SEEK_END) < 0) return -1;
if(io_seek(&fr->rdat,-128,SEEK_END) < 0) return -1;
if(fr->rd->fullread(fr,(unsigned char *)fr->id3buf,128) != 128) return -1;
if(!strncmp((char*)fr->id3buf,"TAG",3)) len -= 128;
if(fr->rdat.lseek(fr->rdat.filept,0,SEEK_SET) < 0) return -1;
if(io_seek(&fr->rdat,0,SEEK_SET) < 0) return -1;
if(len <= 0) return -1;
@ -407,6 +454,133 @@ static off_t get_fileinfo(mpg123_handle *fr)
#ifndef NO_FEEDER
/* Methods for the buffer chain, mainly used for feed reader, but not just that. */
static struct buffy* buffy_new(size_t size, size_t minsize)
{
struct buffy *newbuf;
newbuf = malloc(sizeof(struct buffy));
if(newbuf == NULL) return NULL;
newbuf->realsize = size > minsize ? size : minsize;
newbuf->data = malloc(newbuf->realsize);
if(newbuf->data == NULL)
{
free(newbuf);
return NULL;
}
newbuf->size = 0;
newbuf->next = NULL;
return newbuf;
}
static void buffy_del(struct buffy* buf)
{
if(buf)
{
free(buf->data);
free(buf);
}
}
/* Delete this buffy and all following buffies. */
static void buffy_del_chain(struct buffy* buf)
{
while(buf)
{
struct buffy* next = buf->next;
buffy_del(buf);
buf = next;
}
}
void bc_prepare(struct bufferchain *bc, size_t pool_size, size_t bufblock)
{
bc_poolsize(bc, pool_size, bufblock);
bc->pool = NULL;
bc->pool_fill = 0;
bc_init(bc); /* Ensure that members are zeroed for read-only use. */
}
size_t bc_fill(struct bufferchain *bc)
{
return (size_t)(bc->size - bc->pos);
}
void bc_poolsize(struct bufferchain *bc, size_t pool_size, size_t bufblock)
{
bc->pool_size = pool_size;
bc->bufblock = bufblock;
}
void bc_cleanup(struct bufferchain *bc)
{
buffy_del_chain(bc->pool);
bc->pool = NULL;
bc->pool_fill = 0;
}
/* Fetch a buffer from the pool (if possible) or create one. */
static struct buffy* bc_alloc(struct bufferchain *bc, size_t size)
{
/* Easy route: Just try the first available buffer.
Size does not matter, it's only a hint for creation of new buffers. */
if(bc->pool)
{
struct buffy *buf = bc->pool;
bc->pool = buf->next;
buf->next = NULL; /* That shall be set to a sensible value later. */
buf->size = 0;
--bc->pool_fill;
debug2("bc_alloc: picked %p from pool (fill now %"SIZE_P")", (void*)buf, (size_p)bc->pool_fill);
return buf;
}
else return buffy_new(size, bc->bufblock);
}
/* Either stuff the buffer back into the pool or free it for good. */
static void bc_free(struct bufferchain *bc, struct buffy* buf)
{
if(!buf) return;
if(bc->pool_fill < bc->pool_size)
{
buf->next = bc->pool;
bc->pool = buf;
++bc->pool_fill;
}
else buffy_del(buf);
}
/* Make the buffer count in the pool match the pool size. */
static int bc_fill_pool(struct bufferchain *bc)
{
/* Remove superfluous ones. */
while(bc->pool_fill > bc->pool_size)
{
/* Lazyness: Just work on the front. */
struct buffy* buf = bc->pool;
bc->pool = buf->next;
buffy_del(buf);
--bc->pool_fill;
}
/* Add missing ones. */
while(bc->pool_fill < bc->pool_size)
{
/* Again, just work on the front. */
struct buffy* buf;
buf = buffy_new(0, bc->bufblock); /* Use default block size. */
if(!buf) return -1;
buf->next = bc->pool;
bc->pool = buf;
++bc->pool_fill;
}
return 0;
}
static void bc_init(struct bufferchain *bc)
{
bc->first = NULL;
@ -419,15 +593,14 @@ static void bc_init(struct bufferchain *bc)
static void bc_reset(struct bufferchain *bc)
{
/* free the buffer chain */
struct buffy *b = bc->first;
while(b != NULL)
/* Free current chain, possibly stuffing back into the pool. */
while(bc->first)
{
struct buffy *n = b->next;
free(b->data);
free(b);
b = n;
struct buffy* buf = bc->first;
bc->first = buf->next;
bc_free(bc, buf);
}
bc_fill_pool(bc); /* Ignoring an error here... */
bc_init(bc);
}
@ -437,49 +610,66 @@ static int bc_append(struct bufferchain *bc, ssize_t size)
struct buffy *newbuf;
if(size < 1) return -1;
newbuf = malloc(sizeof(struct buffy));
newbuf = bc_alloc(bc, size);
if(newbuf == NULL) return -2;
newbuf->data = malloc(size);
if(newbuf->data == NULL)
{
free(newbuf);
return -3;
}
newbuf->size = size;
newbuf->next = NULL;
if(bc->last != NULL) bc->last->next = newbuf;
else if(bc->first == NULL) bc->first = newbuf;
bc->last = newbuf;
bc->size += size;
debug3("bc_append: new last buffer %p with %"SSIZE_P" B (really %"SSIZE_P")", (void*)bc->last, (ssize_p)bc->last->size, (ssize_p)bc->last->realsize);
return 0;
}
/* Append a new buffer and copy content to it. */
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
{
int ret = 0;
if((ret = bc_append(bc, size)) == 0)
memcpy(bc->last->data, data, size);
ssize_t part = 0;
debug2("bc_add: adding %"SSIZE_P" bytes at %"OFF_P, (ssize_p)size, (off_p)(bc->fileoff+bc->size));
if(size >=4) debug4("first bytes: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]);
while(size > 0)
{
/* Try to fill up the last buffer block. */
if(bc->last != NULL && bc->last->size < bc->last->realsize)
{
part = bc->last->realsize - bc->last->size;
if(part > size) part = size;
debug2("bc_add: adding %"SSIZE_P" B to existing block %p", (ssize_p)part, (void*)bc->last);
memcpy(bc->last->data+bc->last->size, data, part);
bc->last->size += part;
size -= part;
bc->size += part;
data += part;
}
/* If there is still data left, put it into a new buffer block. */
if(size > 0 && (ret = bc_append(bc, size)) != 0)
break;
}
return ret;
}
/* Common handler for "You want more than I can give." situation. */
static ssize_t bc_need_more(struct bufferchain *bc)
{
debug3("hit end, back to beginning (%li - %li < %li)", (long)bc->size, (long)bc->pos, (long)bc->size);
/* go back to firstpos, undo the previous reads */
bc->pos = bc->firstpos;
return READER_MORE;
}
/* Give some data, advancing position but not forgetting yet. */
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
{
struct buffy *b = bc->first;
ssize_t gotcount = 0;
ssize_t offset = 0;
if(bc->size - bc->pos < size)
{
debug3("hit end, back to beginning (%li - %li < %li)", (long)bc->size, (long)bc->pos, (long)size);
/* go back to firstpos, undo the previous reads */
bc->pos = bc->firstpos;
return READER_MORE;
}
if(bc->size - bc->pos < size) return bc_need_more(bc);
/* find the current buffer */
while(b != NULL && (offset + b->size) <= bc->pos)
{
@ -494,7 +684,7 @@ static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
if(chunk > b->size - loff) chunk = b->size - loff;
#ifdef EXTRA_DEBUG
debug3("copying %liB from %p+%li",(long)chunk, b->data, (long)loff); */
debug3("copying %liB from %p+%li",(long)chunk, b->data, (long)loff);
#endif
memcpy(out+gotcount, b->data+loff, chunk);
@ -516,7 +706,7 @@ static ssize_t bc_skip(struct bufferchain *bc, ssize_t count)
{
if(count >= 0)
{
if(bc->size - bc->pos < count) return READER_MORE;
if(bc->size - bc->pos < count) return bc_need_more(bc);
else return bc->pos += count;
}
else return READER_ERROR;
@ -534,10 +724,9 @@ static void bc_forget(struct bufferchain *bc)
struct buffy *b = bc->first;
/* free all buffers that are def'n'tly outdated */
/* we have buffers until filepos... delete all buffers fully below it */
#ifdef EXTRA_DEBUG
if(b) debug2("bc_forget: block %lu pos %lu", (unsigned long)b->size, (unsigned long)bc->pos);
else debug("forget with nothing there!");
#endif
while(b != NULL && bc->pos >= b->size)
{
struct buffy *n = b->next; /* != NULL or this is indeed the end and the last cycle anyway */
@ -545,11 +734,10 @@ static void bc_forget(struct bufferchain *bc)
bc->fileoff += b->size;
bc->pos -= b->size;
bc->size -= b->size;
#ifdef EXTRA_DEBUG
debug5("bc_forget: forgot %p with %lu, pos=%li, size=%li, fileoff=%li", (void*)b->data, (long)b->size, (long)bc->pos, (long)bc->size, (long)bc->fileoff);
#endif
free(b->data);
free(b);
bc_free(bc, b);
b = n;
}
bc->first = b;
@ -561,6 +749,7 @@ static void bc_forget(struct bufferchain *bc)
static int feed_init(mpg123_handle *fr)
{
bc_init(&fr->rdat.buffer);
bc_fill_pool(&fr->rdat.buffer);
fr->rdat.filelen = 0;
fr->rdat.filepos = 0;
fr->rdat.flags |= READER_BUFFERED;
@ -594,7 +783,11 @@ static ssize_t feed_read(mpg123_handle *fr, unsigned char *out, ssize_t count)
/* returns reached position... negative ones are bad... */
static off_t feed_skip_bytes(mpg123_handle *fr,off_t len)
{
return fr->rdat.buffer.fileoff+bc_skip(&fr->rdat.buffer, (ssize_t)len);
/* This is either the new buffer offset or some negative error value. */
off_t res = bc_skip(&fr->rdat.buffer, (ssize_t)len);
if(res < 0) return res;
return fr->rdat.buffer.fileoff+res;
}
static int feed_back_bytes(mpg123_handle *fr, off_t bytes)
@ -620,32 +813,32 @@ off_t feed_set_pos(mpg123_handle *fr, off_t pos)
if(pos >= bc->fileoff && pos-bc->fileoff < bc->size)
{ /* We have the position! */
bc->pos = (ssize_t)(pos - bc->fileoff);
return pos+bc->size; /* Next input after end of buffer... */
debug1("feed_set_pos inside, next feed from %"OFF_P, (off_p)(bc->fileoff+bc->size));
return bc->fileoff+bc->size; /* Next input after end of buffer... */
}
else
{ /* I expect to get the specific position on next feed. Forget what I have now. */
bc_reset(bc);
bc->fileoff = pos;
debug1("feed_set_pos outside, buffer reset, next feed from %"OFF_P, (off_p)pos);
return pos; /* Next input from exactly that position. */
}
}
/* The specific stuff for buffered stream reader. */
/* Let's work in nice 4K blocks, that may be nicely reusable (by malloc(), even). */
#define BUFFBLOCK 4096
static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t count)
{
struct bufferchain *bc = &fr->rdat.buffer;
ssize_t gotcount;
if(bc->size - bc->pos < count)
{ /* Add more stuff to buffer. If hitting end of file, adjust count. */
unsigned char readbuf[BUFFBLOCK];
unsigned char readbuf[4096];
ssize_t need = count - (bc->size-bc->pos);
while(need>0)
{
int ret;
ssize_t got = fr->rdat.fullread(fr, readbuf, BUFFBLOCK);
ssize_t got = fr->rdat.fullread(fr, readbuf, sizeof(readbuf));
if(got < 0)
{
if(NOQUIET) error("buffer reading");
@ -660,7 +853,7 @@ static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t
}
need -= got; /* May underflow here... */
if(got < BUFFBLOCK) /* That naturally catches got == 0, too. */
if(got < sizeof(readbuf)) /* That naturally catches got == 0, too. */
{
if(VERBOSE3) fprintf(stderr, "Note: Input data end.\n");
break; /* End. */
@ -694,17 +887,17 @@ off_t feed_set_pos(mpg123_handle *fr, off_t pos)
*/
#define bugger_off { mh->err = MPG123_NO_READER; return MPG123_ERR; }
int bad_init(mpg123_handle *mh) bugger_off
void bad_close(mpg123_handle *mh){}
ssize_t bad_fullread(mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_off
int bad_head_read(mpg123_handle *mh, unsigned long *newhead) bugger_off
int bad_head_shift(mpg123_handle *mh, unsigned long *head) bugger_off
off_t bad_skip_bytes(mpg123_handle *mh, off_t len) bugger_off
int bad_read_frame_body(mpg123_handle *mh, unsigned char *data, int size) bugger_off
int bad_back_bytes(mpg123_handle *mh, off_t bytes) bugger_off
int bad_seek_frame(mpg123_handle *mh, off_t num) bugger_off
off_t bad_tell(mpg123_handle *mh) bugger_off
void bad_rewind(mpg123_handle *mh){}
static int bad_init(mpg123_handle *mh) bugger_off
static void bad_close(mpg123_handle *mh){}
static ssize_t bad_fullread(mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_off
static int bad_head_read(mpg123_handle *mh, unsigned long *newhead) bugger_off
static int bad_head_shift(mpg123_handle *mh, unsigned long *head) bugger_off
static off_t bad_skip_bytes(mpg123_handle *mh, off_t len) bugger_off
static int bad_read_frame_body(mpg123_handle *mh, unsigned char *data, int size) bugger_off
static int bad_back_bytes(mpg123_handle *mh, off_t bytes) bugger_off
static int bad_seek_frame(mpg123_handle *mh, off_t num) bugger_off
static off_t bad_tell(mpg123_handle *mh) bugger_off
static void bad_rewind(mpg123_handle *mh){}
#undef bugger_off
#define READER_STREAM 0
@ -712,7 +905,7 @@ void bad_rewind(mpg123_handle *mh){}
#define READER_FEED 2
#define READER_BUF_STREAM 3
#define READER_BUF_ICY_STREAM 4
struct reader readers[] =
static struct reader readers[] =
{
{ /* READER_STREAM */
default_init,
@ -811,7 +1004,7 @@ struct reader readers[] =
#endif
};
struct reader bad_reader =
static struct reader bad_reader =
{
bad_init,
bad_close,
@ -829,12 +1022,40 @@ struct reader bad_reader =
static int default_init(mpg123_handle *fr)
{
fr->rdat.fdread = plain_read;
#ifdef TIMEOUT_READ
if(fr->p.timeout > 0)
{
int flags;
if(fr->rdat.r_read != NULL)
{
error("Timeout reading does not work with user-provided read function. Implement it yourself!");
return -1;
}
flags = fcntl(fr->rdat.filept, F_GETFL);
flags |= O_NONBLOCK;
fcntl(fr->rdat.filept, F_SETFL, flags);
fr->rdat.fdread = timeout_read;
fr->rdat.timeout_sec = fr->p.timeout;
fr->rdat.flags |= READER_NONBLOCK;
}
else
#endif
fr->rdat.fdread = plain_read;
fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : posix_read;
fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : posix_lseek;
#ifndef NO_ICY
/* ICY streams of any sort shall not be seekable. */
if(fr->p.icy_interval > 0) fr->rdat.lseek = nix_lseek;
#endif
fr->rdat.filelen = get_fileinfo(fr);
fr->rdat.filepos = 0;
/*
Don't enable seeking on ICY streams, just plain normal files.
This check is necessary since the client can enforce ICY parsing on files that would otherwise be seekable.
It is a task for the future to make the ICY parsing safe with seeks ... or not.
*/
if(fr->rdat.filelen >= 0)
{
fr->rdat.flags |= READER_SEEKABLE;
@ -880,12 +1101,16 @@ static int default_init(mpg123_handle *fr)
void open_bad(mpg123_handle *mh)
{
debug("open_bad");
#ifndef NO_ICY
clear_icy(&mh->icy);
#endif
mh->rd = &bad_reader;
mh->rdat.flags = 0;
#ifndef NO_FEEDER
bc_init(&mh->rdat.buffer);
#endif
mh->rdat.filelen = -1;
}
int open_feed(mpg123_handle *fr)
@ -908,37 +1133,15 @@ int open_feed(mpg123_handle *fr)
fr->rd = &readers[READER_FEED];
fr->rdat.flags = 0;
if(fr->rd->init(fr) < 0) return -1;
debug("feed reader init successful");
return 0;
#endif /* NO_FEEDER */
}
int open_stream(mpg123_handle *fr, const char *bs_filenam, int fd)
/* Final code common to open_stream and open_stream_handle. */
static int open_finish(mpg123_handle *fr)
{
int filept_opened = 1;
int filept; /* descriptor of opened file/stream */
clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
{
filept = fd;
filept_opened = 0; /* and don't try to close it... */
}
#ifndef O_BINARY
#define O_BINARY (0)
#endif
else if((filept = open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */
{
if(NOQUIET) error2("Cannot open file %s: %s", bs_filenam, strerror(errno));
fr->err = MPG123_BAD_FILE;
return MPG123_ERR; /* error... */
}
/* now we have something behind filept and can init the reader */
fr->rdat.filelen = -1;
fr->rdat.filept = filept;
fr->rdat.flags = 0;
if(filept_opened) fr->rdat.flags |= READER_FD_OPENED;
#ifndef NO_ICY
if(fr->p.icy_interval > 0)
{
@ -958,3 +1161,75 @@ int open_stream(mpg123_handle *fr, const char *bs_filenam, int fd)
return MPG123_OK;
}
int open_stream(mpg123_handle *fr, const char *bs_filenam, int fd)
{
int filept_opened = 1;
int filept; /* descriptor of opened file/stream */
clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
{
filept = fd;
filept_opened = 0; /* and don't try to close it... */
}
#ifndef O_BINARY
#define O_BINARY (0)
#endif
else if((filept = compat_open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */
{
if(NOQUIET) error2("Cannot open file %s: %s", bs_filenam, strerror(errno));
fr->err = MPG123_BAD_FILE;
return MPG123_ERR; /* error... */
}
/* now we have something behind filept and can init the reader */
fr->rdat.filelen = -1;
fr->rdat.filept = filept;
fr->rdat.flags = 0;
if(filept_opened) fr->rdat.flags |= READER_FD_OPENED;
return open_finish(fr);
}
int open_stream_handle(mpg123_handle *fr, void *iohandle)
{
clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
fr->rdat.filelen = -1;
fr->rdat.filept = -1;
fr->rdat.iohandle = iohandle;
fr->rdat.flags = 0;
fr->rdat.flags |= READER_HANDLEIO;
return open_finish(fr);
}
/* Wrappers for actual reading/seeking... I'm full of wrappers here. */
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
{
if(rdat->flags & READER_HANDLEIO)
{
if(rdat->r_lseek_handle != NULL)
{
return rdat->r_lseek_handle(rdat->iohandle, offset, whence);
}
else return -1;
}
else
return rdat->lseek(rdat->filept, offset, whence);
}
static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count)
{
if(rdat->flags & READER_HANDLEIO)
{
if(rdat->r_read_handle != NULL)
{
return rdat->r_read_handle(rdat->iohandle, buf, count);
}
else return -1;
}
else
return rdat->read(rdat->filept, buf, count);
}

View File

@ -88,12 +88,32 @@ static inline short ftoi16(float x)
/* The actual storage of a decoded sample is separated in the following macros.
We can handle different types, we could also handle dithering here. */
#ifdef NEWOLD_WRITE_SAMPLE
/* This is the old new mpg123 WRITE_SAMPLE, fixed for newer GCC by MPlayer folks.
Makes a huge difference on old machines. */
#if WORDS_BIGENDIAN
#define MANTISSA_OFFSET 1
#else
#define MANTISSA_OFFSET 0
#endif
#define WRITE_SHORT_SAMPLE(samples,sum,clip) { \
union { double dtemp; int itemp[2]; } u; int v; \
u.dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum);\
v = u.itemp[MANTISSA_OFFSET] - 0x80000000; \
if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \
else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \
else { *(samples) = v; } \
}
#else
/* Macro to produce a short (signed 16bit) output sample from internal representation,
which may be float, double or indeed some integer for fixed point handling. */
#define WRITE_SHORT_SAMPLE(samples,sum,clip) \
if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
else { *(samples) = REAL_TO_SHORT(sum); }
#endif
/* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */
#define WRITE_SHORT_SAMPLE_ACCURATE(samples,sum,clip) \

View File

@ -1,7 +1,7 @@
/*
stringbuf: mimicking a bit of C++ to more safely handle strings
copyright 2006-8 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 2006-10 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
@ -129,3 +129,58 @@ int attribute_align_arg mpg123_set_string(mpg123_string* sb, const char* stuff)
sb->fill = 0;
return mpg123_add_string(sb, stuff);
}
size_t attribute_align_arg mpg123_strlen(mpg123_string *sb, int utf8)
{
size_t i;
size_t bytelen;
/* Notions of empty string. If there's only a single character, it has to be the trailing zero, and if the first is the trailing zero anyway, we got empty. */
if(sb->fill < 2 || sb->p[0] == 0) return 0;
/* Find the first non-null character from the back.
We already established that the first character is non-null
That at fill-2 has to be null, though. */
for(i=sb->fill-2; i>0; --i)
if(sb->p[i] != 0) break;
/* For simple byte strings, we are done now. */
bytelen = i+1;
if(!utf8) return bytelen;
else
{
/* Work out the actual count of UTF8 bytes.
This employs no particular encoding error checking. */
size_t len = 0;
for(i=0; i<bytelen; ++i)
{
/* Every byte that is not a continuation byte ( 0xc0 == 10xx xxxx ) stands for a character. */
if((sb->p[i] & 0xc0) != 0x80) len++;
}
return len;
}
}
int attribute_align_arg mpg123_chomp_string(mpg123_string *sb)
{
ssize_t i;
if(!sb || !sb->fill) return 0;
/* Ensure that it is zero-terminated. */
sb->p[sb->fill-1] = 0;
for(i=sb->fill-2; i>=0; --i)
{
char *c = sb->p+i;
/* Stop at the first proper character. */
if(*c && *c != '\r' && *c != '\n') break;
else *c = 0;
}
/* initial fill at least 1, so i at least -1,
+2 means nothing happened for fill=1 .
With i=0, we got one non-null character, fill shall be 2
to accomodate the trailing zero. */
sb->fill = (size_t)i+2;
return 1;
}

View File

@ -10,20 +10,11 @@
#include "sample.h"
#include "debug.h"
/* Stereo-related synth, wrapping over _some_ plain synth. */
int synth_stereo_wrap(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
{
int clip;
clip = (fr->synth)(bandPtr_l, 0, fr, 0);
clip += (fr->synth)(bandPtr_r, 1, fr, 1);
return clip;
}
/*
Part 1: All synth functions that produce signed short.
That is:
- synth_1to1 with cpu-specific variants (synth_1to1_i386, synth_1to1_i586 ...)
- synth_1to1_mono and synth_1to1_mono2stereo; which use fr->synths.plain[r_1to1][f_16].
- synth_1to1_mono and synth_1to1_m2s; which use fr->synths.plain[r_1to1][f_16].
Nearly every decoder variant has it's own synth_1to1, while the mono conversion is shared.
*/
@ -40,7 +31,7 @@ int synth_stereo_wrap(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
/* Mono-related synths; they wrap over _some_ synth_1to1. */
#define SYNTH_NAME fr->synths.plain[r_1to1][f_16]
#define MONO_NAME synth_1to1_mono
#define MONO2STEREO_NAME synth_1to1_mono2stereo
#define MONO2STEREO_NAME synth_1to1_m2s
#include "synth_mono.h"
#undef SYNTH_NAME
#undef MONO_NAME
@ -152,7 +143,7 @@ int synth_1to1_mmx(real *bandPtr, int channel, mpg123_handle *fr, int final)
#ifdef ACCURATE_ROUNDING
/* This is defined in assembler. */
int synth_1to1_sse_accurate_asm(real *window, real *b0, short *samples, int bo1);
int synth_1to1_stereo_sse_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
int synth_1to1_s_sse_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
void dct64_real_sse(real *out0, real *out1, real *samples);
/* This is just a hull to use the mpg123 handle. */
int synth_1to1_sse(real *bandPtr,int channel, mpg123_handle *fr, int final)
@ -232,7 +223,7 @@ int synth_1to1_stereo_sse(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
dct64_real_sse(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
}
clip = synth_1to1_stereo_sse_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
clip = synth_1to1_s_sse_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
fr->buffer.fill += 128;
@ -271,7 +262,7 @@ int synth_1to1_3dnowext(real *bandPtr, int channel, mpg123_handle *fr, int final
#ifdef ACCURATE_ROUNDING
/* Assembler routines. */
int synth_1to1_x86_64_accurate_asm(real *window, real *b0, short *samples, int bo1);
int synth_1to1_stereo_x86_64_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
int synth_1to1_s_x86_64_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
void dct64_real_x86_64(real *out0, real *out1, real *samples);
/* Hull for C mpg123 API */
int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
@ -352,7 +343,7 @@ int synth_1to1_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr
dct64_real_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
}
clip = synth_1to1_stereo_x86_64_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
clip = synth_1to1_s_x86_64_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
fr->buffer.fill += 128;
@ -361,7 +352,7 @@ int synth_1to1_stereo_x86_64(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr
#else
/* This is defined in assembler. */
int synth_1to1_x86_64_asm(short *window, short *b0, short *samples, int bo1);
int synth_1to1_stereo_x86_64_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
int synth_1to1_s_x86_64_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
void dct64_x86_64(short *out0, short *out1, real *samples);
/* This is just a hull to use the mpg123 handle. */
int synth_1to1_x86_64(real *bandPtr,int channel, mpg123_handle *fr, int final)
@ -440,7 +431,7 @@ int synth_1to1_stereo_x86_64(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
dct64_x86_64(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
}
clip = synth_1to1_stereo_x86_64_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
clip = synth_1to1_s_x86_64_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
fr->buffer.fill += 128;
@ -543,6 +534,188 @@ int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
#endif
#endif
#ifdef OPT_NEON
#ifdef ACCURATE_ROUNDING
/* This is defined in assembler. */
int synth_1to1_neon_accurate_asm(real *window, real *b0, short *samples, int bo1);
int synth_1to1_s_neon_accurate_asm(real *window, real *b0l, real *b0r, short *samples, int bo1);
void dct64_real_neon(real *out0, real *out1, real *samples);
/* Hull for C mpg123 API */
int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
{
short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
real *b0, **buf;
int bo1;
int clip;
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
if(!channel)
{
fr->bo--;
fr->bo &= 0xf;
buf = fr->real_buffs[0];
}
else
{
samples++;
buf = fr->real_buffs[1];
}
if(fr->bo & 0x1)
{
b0 = buf[0];
bo1 = fr->bo;
dct64_real_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
}
else
{
b0 = buf[1];
bo1 = fr->bo+1;
dct64_real_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
}
clip = synth_1to1_neon_accurate_asm(fr->decwin, b0, samples, bo1);
if(final) fr->buffer.fill += 128;
return clip;
}
int synth_1to1_stereo_neon(real *bandPtr_l, real *bandPtr_r, mpg123_handle *fr)
{
short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
real *b0l, *b0r, **bufl, **bufr;
int bo1;
int clip;
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
fr->bo--;
fr->bo &= 0xf;
bufl = fr->real_buffs[0];
bufr = fr->real_buffs[1];
if(fr->bo & 0x1)
{
b0l = bufl[0];
b0r = bufr[0];
bo1 = fr->bo;
dct64_real_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
dct64_real_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
}
else
{
b0l = bufl[1];
b0r = bufr[1];
bo1 = fr->bo+1;
dct64_real_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
dct64_real_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
}
clip = synth_1to1_s_neon_accurate_asm(fr->decwin, b0l, b0r, samples, bo1);
fr->buffer.fill += 128;
return clip;
}
#else
/* This is defined in assembler. */
int synth_1to1_neon_asm(short *window, short *b0, short *samples, int bo1);
int synth_1to1_s_neon_asm(short *window, short *b0l, short *b0r, short *samples, int bo1);
void dct64_neon(short *out0, short *out1, real *samples);
/* Hull for C mpg123 API */
int synth_1to1_neon(real *bandPtr,int channel, mpg123_handle *fr, int final)
{
short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
short *b0, **buf;
int clip;
int bo1;
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
if(!channel)
{
fr->bo--;
fr->bo &= 0xf;
buf = fr->short_buffs[0];
}
else
{
samples++;
buf = fr->short_buffs[1];
}
if(fr->bo & 0x1)
{
b0 = buf[0];
bo1 = fr->bo;
dct64_neon(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
}
else
{
b0 = buf[1];
bo1 = fr->bo+1;
dct64_neon(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
}
clip = synth_1to1_neon_asm((short *)fr->decwins, b0, samples, bo1);
if(final) fr->buffer.fill += 128;
return clip;
}
int synth_1to1_stereo_neon(real *bandPtr_l,real *bandPtr_r, mpg123_handle *fr)
{
short *samples = (short *) (fr->buffer.data+fr->buffer.fill);
short *b0l, *b0r, **bufl, **bufr;
int clip;
int bo1;
if(fr->have_eq_settings)
{
do_equalizer(bandPtr_l,0,fr->equalizer);
do_equalizer(bandPtr_r,1,fr->equalizer);
}
fr->bo--;
fr->bo &= 0xf;
bufl = fr->short_buffs[0];
bufr = fr->short_buffs[1];
if(fr->bo & 0x1)
{
b0l = bufl[0];
b0r = bufr[0];
bo1 = fr->bo;
dct64_neon(bufl[1]+((fr->bo+1)&0xf),bufl[0]+fr->bo,bandPtr_l);
dct64_neon(bufr[1]+((fr->bo+1)&0xf),bufr[0]+fr->bo,bandPtr_r);
}
else
{
b0l = bufl[1];
b0r = bufr[1];
bo1 = fr->bo+1;
dct64_neon(bufl[0]+fr->bo,bufl[1]+fr->bo+1,bandPtr_l);
dct64_neon(bufr[0]+fr->bo,bufr[1]+fr->bo+1,bandPtr_r);
}
clip = synth_1to1_s_neon_asm((short *)fr->decwins, b0l, b0r, samples, bo1);
fr->buffer.fill += 128;
return clip;
}
#endif
#endif
#ifndef NO_DOWNSAMPLE
/*
@ -565,7 +738,7 @@ int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
#define SYNTH_NAME fr->synths.plain[r_2to1][f_16]
#define MONO_NAME synth_2to1_mono
#define MONO2STEREO_NAME synth_2to1_mono2stereo
#define MONO2STEREO_NAME synth_2to1_m2s
#include "synth_mono.h"
#undef SYNTH_NAME
#undef MONO_NAME
@ -602,7 +775,7 @@ int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
#define SYNTH_NAME fr->synths.plain[r_4to1][f_16] /* This is just for the _i386 one... gotta check if it is really useful... */
#define MONO_NAME synth_4to1_mono
#define MONO2STEREO_NAME synth_4to1_mono2stereo
#define MONO2STEREO_NAME synth_4to1_m2s
#include "synth_mono.h"
#undef SYNTH_NAME
#undef MONO_NAME
@ -630,7 +803,7 @@ int synth_1to1_arm(real *bandPtr,int channel, mpg123_handle *fr, int final)
/* These are all in one header, there's no flexibility to gain. */
#define SYNTH_NAME synth_ntom
#define MONO_NAME synth_ntom_mono
#define MONO2STEREO_NAME synth_ntom_mono2stereo
#define MONO2STEREO_NAME synth_ntom_m2s
#include "synth_ntom.h"
#undef SYNTH_NAME
#undef MONO_NAME

View File

@ -0,0 +1,318 @@
/*
decode_3dnow.s - 3DNow! optimized synth_1to1()
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Syuuhei Kashiyama
This code based 'decode_3dnow.s' by Syuuhei Kashiyama
<squash@mb.kcom.ne.jp>,only two types of changes have been made:
- remove PREFETCH instruction for speedup
- change function name for support 3DNow! automatic detect
- femms moved to before 'call dct64_3dnow'
You can find Kashiyama's original 3dnow! support patch
(for mpg123-0.59o) at
http://user.ecc.u-tokyo.ac.jp/~g810370/linux-simd/ (Japanese).
by KIMURA Takuhiro <kim@hannah.ipc.miyakyo-u.ac.jp> - until 31.Mar.1999
<kim@comtec.co.jp> - after 1.Apr.1999
Replacement of synth_1to1() with AMD's 3DNow! SIMD operations support
Syuuhei Kashiyama <squash@mb.kcom.ne.jp>
The author of this program disclaim whole expressed or implied
warranties with regard to this program, and in no event shall the
author of this program liable to whatever resulted from the use of
this program. Use it at your own risk.
*/
#include "mangle.h"
#ifdef ACCURATE_ROUNDING
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN8
max_s16:
.long 1191181824 /* 32767.0 */
.long 1191181824
min_s16:
.long -956301312 /* -32768.0 */
.long -956301312
ftoi_magic:
.long 1262485504 /* 2^23 + 2^22 */
.long 1262485504
#endif
.text
ALIGN16
.globl ASM_NAME(synth_1to1_3dnow_asm)
/* int synth_1to1_3dnow_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin); */
ASM_NAME(synth_1to1_3dnow_asm):
subl $24,%esp
pushl %ebp
pushl %edi
xorl %ebp,%ebp
pushl %esi
pushl %ebx
/* stack old: 0=ebx 4=esi 8=edi 12=ebp 16,20,24,28,32,36=local 40=back 44=bandptr 48=channel 52=out 56=pnt */
/* stack new: 0=ebx 4=esi 8=edi 12=ebp 16,20,24,28,32,36=local 40=back 44=bandptr 48=channel 52=out 56=buffs 60=bo 64=decwin */
#define OUT 52(%esp)
#define CHANNEL 48(%esp)
#define BANDPTR 44(%esp)
#define BUFFS 56(%esp)
#define BO 60(%esp)
#define DECWIN 64(%esp)
#define LOCAL0 16(%esp)
#define LOCAL1 20(%esp)
#define LOCAL5 36(%esp)
movl OUT,%esi
movl %esi,LOCAL0 /* save buffer start (samples pointer) to another local var */
movl CHANNEL,%ebx
movl BO,%esi /* bo address */
movl (%esi),%edx /* bo value */
femms
testl %ebx,%ebx
jne .L26
/* if(!channel) */
decl %edx /* --bo */
andl $15,%edx
movl %edx,(%esi) /* save bo */
movl BUFFS,%ecx
jmp .L27
.L26: /* if(channel) */
addl $2,LOCAL0 /* samples++ */
movl BUFFS,%ecx
addl $2176,%ecx
.L27:
/* edx (and it's lower end) still holds bo value */
testb $1,%dl /* bo & 0x1 */
je .L28
movl %edx,LOCAL5
movl %ecx,%ebx
movl BANDPTR,%esi
movl %edx,%edi
pushl %esi
sall $2,%edi
movl %ebx,%eax
movl %edi,24(%esp) /* LOCAL1, actually */
addl %edi,%eax
pushl %eax
movl %edx,%eax
incl %eax
andl $15,%eax
leal 1088(,%eax,4),%eax
addl %ebx,%eax
pushl %eax
call ASM_NAME(dct64_3dnow)
addl $12,%esp
jmp .L29
.L28:
leal 1(%edx),%esi
movl BANDPTR,%edi
movl %esi,LOCAL5
leal 1092(%ecx,%edx,4),%eax
pushl %edi
leal 1088(%ecx),%ebx
pushl %eax
sall $2,%esi
leal (%ecx,%edx,4),%eax
pushl %eax
call ASM_NAME(dct64_3dnow)
addl $12,%esp
movl %esi,LOCAL1
.L29:
movl DECWIN,%edx
addl $64,%edx
movl $16,%ecx
subl LOCAL1,%edx
movl LOCAL0,%edi
pcmpeqb %mm7,%mm7
pslld $31,%mm7
movq (%edx),%mm0
movq (%ebx),%mm1
ALIGN32
.L33:
movq 8(%edx),%mm3
pfmul %mm1,%mm0
movq 8(%ebx),%mm4
movq 16(%edx),%mm5
pfmul %mm4,%mm3
movq 16(%ebx),%mm6
pfadd %mm3,%mm0
movq 24(%edx),%mm1
pfmul %mm6,%mm5
movq 24(%ebx),%mm2
pfadd %mm5,%mm0
movq 32(%edx),%mm3
pfmul %mm2,%mm1
movq 32(%ebx),%mm4
pfadd %mm1,%mm0
movq 40(%edx),%mm5
pfmul %mm4,%mm3
movq 40(%ebx),%mm6
pfadd %mm3,%mm0
movq 48(%edx),%mm1
pfmul %mm6,%mm5
movq 48(%ebx),%mm2
pfadd %mm0,%mm5
movq 56(%edx),%mm3
pfmul %mm1,%mm2
movq 56(%ebx),%mm4
pfadd %mm5,%mm2
addl $64,%ebx
subl $-128,%edx
movq (%edx),%mm0
pfmul %mm4,%mm3
movq (%ebx),%mm1
pfadd %mm3,%mm2
movq %mm2,%mm3
psrlq $32,%mm3
pfsub %mm3,%mm2
incl %ebp
#ifdef ACCURATE_ROUNDING
pfmin (max_s16),%mm2
pfmax (min_s16),%mm2
pfadd (ftoi_magic),%mm2
#else
pf2id %mm2,%mm2
packssdw %mm2,%mm2
#endif
movd %mm2,%eax
movw %ax,0(%edi)
addl $4,%edi
decl %ecx
jnz .L33
movd (%ebx),%mm0
movd (%edx),%mm1
punpckldq 8(%ebx),%mm0
punpckldq 8(%edx),%mm1
movd 16(%ebx),%mm3
movd 16(%edx),%mm4
pfmul %mm1,%mm0
punpckldq 24(%ebx),%mm3
punpckldq 24(%edx),%mm4
movd 32(%ebx),%mm5
movd 32(%edx),%mm6
pfmul %mm4,%mm3
punpckldq 40(%ebx),%mm5
punpckldq 40(%edx),%mm6
pfadd %mm3,%mm0
movd 48(%ebx),%mm1
movd 48(%edx),%mm2
pfmul %mm6,%mm5
punpckldq 56(%ebx),%mm1
punpckldq 56(%edx),%mm2
pfadd %mm5,%mm0
pfmul %mm2,%mm1
pfadd %mm1,%mm0
pfacc %mm1,%mm0
#ifdef ACCURATE_ROUNDING
pfmin (max_s16),%mm0
pfmax (min_s16),%mm0
pfadd (ftoi_magic),%mm0
#else
pf2id %mm0,%mm0
packssdw %mm0,%mm0
#endif
movd %mm0,%eax
movw %ax,0(%edi)
incl %ebp
movl LOCAL5,%esi
addl $-64,%ebx
movl $15,%ebp
addl $4,%edi
leal -128(%edx,%esi,8),%edx
movl $15,%ecx
movd (%ebx),%mm0
movd -4(%edx),%mm1
punpckldq 4(%ebx),%mm0
punpckldq -8(%edx),%mm1
ALIGN32
.L46:
movd 8(%ebx),%mm3
movd -12(%edx),%mm4
pfmul %mm1,%mm0
punpckldq 12(%ebx),%mm3
punpckldq -16(%edx),%mm4
movd 16(%ebx),%mm5
movd -20(%edx),%mm6
pfmul %mm4,%mm3
punpckldq 20(%ebx),%mm5
punpckldq -24(%edx),%mm6
pfadd %mm3,%mm0
movd 24(%ebx),%mm1
movd -28(%edx),%mm2
pfmul %mm6,%mm5
punpckldq 28(%ebx),%mm1
punpckldq -32(%edx),%mm2
pfadd %mm5,%mm0
movd 32(%ebx),%mm3
movd -36(%edx),%mm4
pfmul %mm2,%mm1
punpckldq 36(%ebx),%mm3
punpckldq -40(%edx),%mm4
pfadd %mm1,%mm0
movd 40(%ebx),%mm5
movd -44(%edx),%mm6
pfmul %mm4,%mm3
punpckldq 44(%ebx),%mm5
punpckldq -48(%edx),%mm6
pfadd %mm3,%mm0
movd 48(%ebx),%mm1
movd -52(%edx),%mm2
pfmul %mm6,%mm5
punpckldq 52(%ebx),%mm1
punpckldq -56(%edx),%mm2
pfadd %mm0,%mm5
movd 56(%ebx),%mm3
movd -60(%edx),%mm4
pfmul %mm2,%mm1
punpckldq 60(%ebx),%mm3
punpckldq (%edx),%mm4
pfadd %mm1,%mm5
addl $-128,%edx
addl $-64,%ebx
movd (%ebx),%mm0
movd -4(%edx),%mm1
pfmul %mm4,%mm3
punpckldq 4(%ebx),%mm0
punpckldq -8(%edx),%mm1
pfadd %mm5,%mm3
pfacc %mm3,%mm3
incl %ebp
pxor %mm7,%mm3
#ifdef ACCURATE_ROUNDING
pfmin (max_s16),%mm3
pfmax (min_s16),%mm3
pfadd (ftoi_magic),%mm3
#else
pf2id %mm3,%mm3
packssdw %mm3,%mm3
#endif
movd %mm3,%eax
movw %ax,(%edi)
addl $4,%edi
decl %ecx
jnz .L46
femms
movl %ebp,%eax
popl %ebx
popl %esi
popl %edi
popl %ebp
addl $24,%esp
ret
NONEXEC_STACK

View File

@ -0,0 +1,6 @@
#include "mangle.h"
#define MPL_DCT64 ASM_NAME(dct64_3dnowext)
#define SYNTH_NAME ASM_NAME(synth_1to1_3dnowext_asm)
#include "synth_sse3d.h"
NONEXEC_STACK

View File

@ -0,0 +1,336 @@
/*
decode_i586: asm synth
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Stefan Bieschewski
synth_1to1 works the same way as the c version of this
file. only two types of changes have been made:
- reordered floating point instructions to
prevent pipline stalls
- made WRITE_SAMPLE use integer instead of
(slower) floating point
all kinds of x86 processors should benefit from these
modifications.
useful sources of information on optimizing x86 code include:
Intel Architecture Optimization Manual
http://www.intel.com/design/pentium/manuals/242816.htm
Cyrix 6x86 Instruction Set Summary
ftp://ftp.cyrix.com/6x86/6x-dbch6.pdf
AMD-K5 Processor Software Development
http://www.amd.com/products/cpg/techdocs/appnotes/20007e.pdf
Stefan Bieschewski <stb@acm.org>
$Id: decode_i586.s 1 2004-09-18 13:30:08Z thomas $
*/
#include "mangle.h"
.data
#ifndef __APPLE__
.section .rodata
#endif
ALIGN8
.LC0:
.long 0x0,0x40dfffc0
ALIGN8
.LC1:
.long 0x0,0xc0e00000
ALIGN8
.text
/* int synth_1to1_i586_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin); */
.globl ASM_NAME(synth_1to1_i586_asm)
ASM_NAME(synth_1to1_i586_asm):
subl $12,%esp
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
/* stack: 0=ebx, 4=esi, 8=edi, 12=ebp, 16,20,24=local, 28=back, 32=bandPtr, 36=channel, 40=out, 44=buffs, 48=bo, 52=decwin */
movl 32(%esp),%eax /* *bandPtr */
movl 40(%esp),%esi /* *out */
movl 48(%esp),%edi /* *bo */
movl (%edi),%ebp /* store bo value in ebp */
xorl %edi,%edi
cmpl %edi,36(%esp)
jne .L48 /* if(!channel) */
decl %ebp /* bo-- */
andl $15,%ebp /* bo &= 0xf */
movl 48(%esp), %edi /* *bo */
movl %ebp,(%edi) /* write back bo */
xorl %edi,%edi /* restore %edi to 0; it's used later */
movl 44(%esp),%ecx /* use buffs */
jmp .L49
.L48: /* if(channel) use buffs+2176 */
addl $2,%esi
movl 44(%esp),%ecx /* *buffs */
addl $2176,%ecx
.L49:
testl $1,%ebp
je .L50
movl %ecx,%ebx
movl %ebp,16(%esp)
pushl %eax
movl 20(%esp),%edx
leal (%ebx,%edx,4),%eax
pushl %eax
movl 24(%esp),%eax
incl %eax
andl $15,%eax
leal 1088(,%eax,4),%eax
addl %ebx,%eax
jmp .L74
.L50:
leal 1088(%ecx),%ebx
leal 1(%ebp),%edx
movl %edx,16(%esp)
pushl %eax
leal 1092(%ecx,%ebp,4),%eax
pushl %eax
leal (%ecx,%ebp,4),%eax
.L74:
pushl %eax
call ASM_NAME(dct64_i386)
addl $12,%esp
/* stack now back on track */
movl 16(%esp),%edx
leal 0(,%edx,4),%edx
movl 52(%esp),%eax /* decwin */
addl $64,%eax
movl %eax,%ecx
subl %edx,%ecx
movl $16,%ebp
.L55:
flds (%ecx)
fmuls (%ebx)
flds 4(%ecx)
fmuls 4(%ebx)
fxch %st(1)
flds 8(%ecx)
fmuls 8(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 12(%ecx)
fmuls 12(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 16(%ecx)
fmuls 16(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 20(%ecx)
fmuls 20(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 24(%ecx)
fmuls 24(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 28(%ecx)
fmuls 28(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 32(%ecx)
fmuls 32(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 36(%ecx)
fmuls 36(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 40(%ecx)
fmuls 40(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 44(%ecx)
fmuls 44(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 48(%ecx)
fmuls 48(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 52(%ecx)
fmuls 52(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 56(%ecx)
fmuls 56(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 60(%ecx)
fmuls 60(%ebx)
fxch %st(2)
subl $4,%esp
faddp %st,%st(1)
fxch %st(1)
fsubrp %st,%st(1)
fistpl (%esp)
popl %eax
cmpl $32767,%eax
jg 1f
cmpl $-32768,%eax
jl 2f
movw %ax,(%esi)
jmp 4f
1: movw $32767,(%esi)
jmp 3f
2: movw $-32768,(%esi)
3: incl %edi
4:
.L54:
addl $64,%ebx
subl $-128,%ecx
addl $4,%esi
decl %ebp
jnz .L55
flds (%ecx)
fmuls (%ebx)
flds 8(%ecx)
fmuls 8(%ebx)
flds 16(%ecx)
fmuls 16(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 24(%ecx)
fmuls 24(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 32(%ecx)
fmuls 32(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 40(%ecx)
fmuls 40(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 48(%ecx)
fmuls 48(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 56(%ecx)
fmuls 56(%ebx)
fxch %st(2)
subl $4,%esp
faddp %st,%st(1)
fxch %st(1)
faddp %st,%st(1)
fistpl (%esp)
popl %eax
cmpl $32767,%eax
jg 1f
cmpl $-32768,%eax
jl 2f
movw %ax,(%esi)
jmp 4f
1: movw $32767,(%esi)
jmp 3f
2: movw $-32768,(%esi)
3: incl %edi
4:
.L62:
addl $-64,%ebx
addl $4,%esi
movl 16(%esp),%edx
leal -128(%ecx,%edx,8),%ecx
movl $15,%ebp
.L68:
flds -4(%ecx)
fchs
fmuls (%ebx)
flds -8(%ecx)
fmuls 4(%ebx)
fxch %st(1)
flds -12(%ecx)
fmuls 8(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -16(%ecx)
fmuls 12(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -20(%ecx)
fmuls 16(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -24(%ecx)
fmuls 20(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -28(%ecx)
fmuls 24(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -32(%ecx)
fmuls 28(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -36(%ecx)
fmuls 32(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -40(%ecx)
fmuls 36(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -44(%ecx)
fmuls 40(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -48(%ecx)
fmuls 44(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -52(%ecx)
fmuls 48(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -56(%ecx)
fmuls 52(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -60(%ecx)
fmuls 56(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds (%ecx)
fmuls 60(%ebx)
fxch %st(2)
subl $4,%esp
fsubrp %st,%st(1)
fxch %st(1)
fsubrp %st,%st(1)
fistpl (%esp)
popl %eax
cmpl $32767,%eax
jg 1f
cmpl $-32768,%eax
jl 2f
movw %ax,(%esi)
jmp 4f
1: movw $32767,(%esi)
jmp 3f
2: movw $-32768,(%esi)
3: incl %edi
4:
.L67:
addl $-64,%ebx
addl $-128,%ecx
addl $4,%esi
decl %ebp
jnz .L68
movl %edi,%eax
popl %ebx
popl %esi
popl %edi
popl %ebp
addl $12,%esp
ret
NONEXEC_STACK

View File

@ -0,0 +1,375 @@
/*
decode_i586_dither: asm synth with dither noise
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Stefan Bieschewski as decode_i586.s without dither
This version uses "circular" 64k dither noise.
(Patch by Adrian <adrian.bacon@xs4all.nl>)
Thomas learned something about assembler and the stack while making this one thread safe (removing static data).
*/
#include "mangle.h"
.data
#ifndef __APPLE__
.section .rodata
#endif
ALIGN8
.LC0:
.long 0x0,0x40dfffc0
ALIGN8
.LC1:
.long 0x0,0xc0e00000
ALIGN8
.text
/* int synth_1to1_i586_asm_dither(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int bo_and_ditherindex[2], real *decwin, real* dithernoise); */
.globl ASM_NAME(synth_1to1_i586_asm_dither)
ASM_NAME(synth_1to1_i586_asm_dither):
subl $16,%esp
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
/* stack: 0(%esp)=%ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo 56=decwin 60=dithernoise */
#define BANDPTR 36(%esp)
#define CHANNEL 40(%esp)
#define OUT 44(%esp)
#define BUFFS 48(%esp)
#define BO 52(%esp)
#define DECWIN 56(%esp)
#define DITHERNOISE 60(%esp)
/*#define DITHERNOISE $(ASM_NAME(dithernoise))*/
#define LOC0 16(%esp)
#define LOC1 20(%esp)
#define LOC2 24(%esp)
#define DITHERINDEX 28(%esp)
/* During application of the dithering, we need the shifted locations because there's an additional value on the stack. */
#define DITHERNOISE2 64(%esp)
#define DITHERINDEX2 32(%esp)
movl BANDPTR,%eax
movl OUT,%esi
movl BO, %ebx
movl (%ebx),%ebp /* get bo value */
movl 4(%ebx),%edi; /* get the ditherindex behind bo */
movl %edi,DITHERINDEX
xorl %edi,%edi
cmpl %edi,CHANNEL
jne .L48
decl %ebp
andl $15,%ebp
movl %ebp,(%ebx) /* save bo back */
movl BUFFS,%ecx
jmp .L49
.L48:
/* In stereo mode , "rewind" dither pointer 32 samples , so 2nd channel */
/* has same dither values. Tested OK for mono and stereo MP2 and MP3 */
subl $128,DITHERINDEX /* better move to %edi for the two calculations? */
andl $0x0003fffc,DITHERINDEX
addl $2,%esi
movl BUFFS,%ecx
addl $2176,%ecx
.L49:
/* now the call of dct64 is prepared, stuff pushed to the stack, but soon after it's removed again */
testl $1,%ebp
je .L50
movl %ecx,%ebx
movl %ebp,LOC0
pushl %eax
movl LOC1,%edx
leal (%ebx,%edx,4),%eax
pushl %eax
movl LOC2,%eax
incl %eax
andl $15,%eax
leal 1088(,%eax,4),%eax
addl %ebx,%eax
jmp .L74
.L50:
leal 1088(%ecx),%ebx
leal 1(%ebp),%edx
movl %edx,LOC0
pushl %eax
leal 1092(%ecx,%ebp,4),%eax
pushl %eax
leal (%ecx,%ebp,4),%eax
.L74:
pushl %eax
call ASM_NAME(dct64_i386)
addl $12,%esp
/* Now removed the parameters.
stack: 0(%esp)=%ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo 56=decwin 60=dithernoise */
movl LOC0,%edx
leal 0(,%edx,4),%edx
/* movl ASM_VALUE(decwin)+64,%eax */
movl DECWIN,%eax
addl $64,%eax
movl %eax,%ecx
subl %edx,%ecx
movl $16,%ebp
.L55:
flds (%ecx)
fmuls (%ebx)
flds 4(%ecx)
fmuls 4(%ebx)
fxch %st(1)
flds 8(%ecx)
fmuls 8(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 12(%ecx)
fmuls 12(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 16(%ecx)
fmuls 16(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 20(%ecx)
fmuls 20(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 24(%ecx)
fmuls 24(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 28(%ecx)
fmuls 28(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 32(%ecx)
fmuls 32(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 36(%ecx)
fmuls 36(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 40(%ecx)
fmuls 40(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 44(%ecx)
fmuls 44(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 48(%ecx)
fmuls 48(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 52(%ecx)
fmuls 52(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 56(%ecx)
fmuls 56(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds 60(%ecx)
fmuls 60(%ebx)
fxch %st(2)
subl $4,%esp
faddp %st,%st(1)
fxch %st(1)
fsubrp %st,%st(1)
addl $4,DITHERINDEX2
andl $0x0003fffc,DITHERINDEX2
movl DITHERNOISE2,%edi
addl DITHERINDEX2,%edi
fadds (%edi)
/* fistpl and popl as a unit keep the stack unchanged */
fistpl (%esp)
popl %eax
cmpl $32767,%eax
jg 1f
cmpl $-32768,%eax
jl 2f
movw %ax,(%esi)
jmp 4f
1: movw $32767,(%esi)
jmp 3f
2: movw $-32768,(%esi)
3:
/* incl %edi */
4:
.L54:
addl $64,%ebx
subl $-128,%ecx
addl $4,%esi
decl %ebp
jnz .L55
flds (%ecx)
fmuls (%ebx)
flds 8(%ecx)
fmuls 8(%ebx)
flds 16(%ecx)
fmuls 16(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 24(%ecx)
fmuls 24(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 32(%ecx)
fmuls 32(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 40(%ecx)
fmuls 40(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 48(%ecx)
fmuls 48(%ebx)
fxch %st(2)
faddp %st,%st(1)
flds 56(%ecx)
fmuls 56(%ebx)
fxch %st(2)
subl $4,%esp
faddp %st,%st(1)
fxch %st(1)
faddp %st,%st(1)
addl $4,DITHERINDEX2
andl $0x0003fffc,DITHERINDEX2
movl DITHERNOISE2,%edi
addl DITHERINDEX2,%edi
fadds (%edi)
/* fistpl and popl as a unit keep the stack unchanged */
fistpl (%esp)
popl %eax
cmpl $32767,%eax
jg 1f
cmpl $-32768,%eax
jl 2f
movw %ax,(%esi)
jmp 4f
1: movw $32767,(%esi)
jmp 3f
2: movw $-32768,(%esi)
3:
/* incl %edi */
4:
.L62:
addl $-64,%ebx
addl $4,%esi
movl LOC0,%edx
leal -128(%ecx,%edx,8),%ecx
movl $15,%ebp
.L68:
flds -4(%ecx)
fchs
fmuls (%ebx)
flds -8(%ecx)
fmuls 4(%ebx)
fxch %st(1)
flds -12(%ecx)
fmuls 8(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -16(%ecx)
fmuls 12(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -20(%ecx)
fmuls 16(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -24(%ecx)
fmuls 20(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -28(%ecx)
fmuls 24(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -32(%ecx)
fmuls 28(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -36(%ecx)
fmuls 32(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -40(%ecx)
fmuls 36(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -44(%ecx)
fmuls 40(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -48(%ecx)
fmuls 44(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -52(%ecx)
fmuls 48(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -56(%ecx)
fmuls 52(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds -60(%ecx)
fmuls 56(%ebx)
fxch %st(2)
fsubrp %st,%st(1)
flds (%ecx)
fmuls 60(%ebx)
fxch %st(2)
subl $4,%esp
fsubrp %st,%st(1)
fxch %st(1)
fsubrp %st,%st(1)
addl $4,DITHERINDEX2
andl $0x0003fffc,DITHERINDEX2
movl DITHERNOISE2,%edi
addl DITHERINDEX2,%edi
fadds (%edi)
/* fistpl and popl as a unit keep the stack unchanged */
fistpl (%esp)
popl %eax
cmpl $32767,%eax
jg 1f
cmpl $-32768,%eax
jl 2f
movw %ax,(%esi)
jmp 4f
1: movw $32767,(%esi)
jmp 3f
2: movw $-32768,(%esi)
3:
/* incl %edi */
4:
.L67:
addl $-64,%ebx
addl $-128,%ecx
addl $4,%esi
decl %ebp
jnz .L68
/* return ipv edi 0 in eax */
movl $0,%eax
/* save ditherindex */
movl BO,%ebx
movl DITHERINDEX,%esi
movl %esi,4(%ebx);
/* stack: 0=ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo */
popl %ebx
popl %esi
popl %edi
popl %ebp
addl $16,%esp
/* The stack must be now: 0=back 4=bandptr 8=channel 12=out 16=buffs 20=bo */
ret
NONEXEC_STACK

View File

@ -122,8 +122,4 @@ ASM_NAME(synth_1to1_MMX):
popl %ebp
ret
/* Mark non-executable stack. */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
NONEXEC_STACK

View File

@ -0,0 +1,6 @@
#include "mangle.h"
#define MPL_DCT64 ASM_NAME(dct64_sse)
#define SYNTH_NAME ASM_NAME(synth_1to1_sse_asm)
#include "synth_sse3d.h"
NONEXEC_STACK

View File

@ -41,7 +41,7 @@ null_one:
.long 65535
.text
ALIGN16,,15
ALIGN16
/* void SYNTH_NAME(real *bandPtr, int channel, short *samples, short *buffs, int *bo, float *decwins) */
.globl SYNTH_NAME
SYNTH_NAME:

View File

@ -0,0 +1,241 @@
/*
synth_sse_float: SSE optimized synth (float output version)
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
/* real *window; */
#define WINDOW %ebx
/* real *b0; */
#define B0 %edx
/* real *samples; */
#define SAMPLES %esi
/*
int synth_1to1_real_sse_asm(real *window, real *b0, real *samples, int bo1);
return value: number of clipped samples (0)
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
ASM_NAME(scale_sse):
.long 939524096
.long 939524096
.long 939524096
.long 939524096
.text
ALIGN16
.globl ASM_NAME(synth_1to1_real_sse_asm)
ASM_NAME(synth_1to1_real_sse_asm):
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
movl 8(%ebp), WINDOW
movl 12(%ebp), B0
movl 16(%ebp), SAMPLES
movl 20(%ebp), %eax
shll $2, %eax
leal 64(WINDOW), WINDOW
subl %eax, WINDOW
movl $4, %ecx
ALIGN16
Loop_start_1:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm4
movups 144(WINDOW), %xmm5
movups 160(WINDOW), %xmm6
movups 176(WINDOW), %xmm7
mulps 0(B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps 64(B0), %xmm4
mulps 80(B0), %xmm5
mulps 96(B0), %xmm6
mulps 112(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm4, %xmm5
movaps %xmm0, %xmm4
leal 256(WINDOW), WINDOW
leal 128(B0), B0
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm6
movups 144(WINDOW), %xmm7
mulps (B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps 64(B0), %xmm6
mulps 80(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm7, %xmm6
movups 160(WINDOW), %xmm1
movups 176(WINDOW), %xmm3
mulps 96(B0), %xmm1
mulps 112(B0), %xmm3
addps %xmm2, %xmm0
addps %xmm3, %xmm1
addps %xmm1, %xmm6
movaps %xmm6, %xmm7
movaps %xmm0, %xmm6
leal 256(WINDOW), WINDOW
leal 128(B0), B0
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
subps %xmm6, %xmm4
subps %xmm1, %xmm0
addps %xmm4, %xmm0
movups (SAMPLES), %xmm1
movups 16(SAMPLES), %xmm2
mulps ASM_NAME(scale_sse), %xmm0
shufps $0xdd, %xmm2, %xmm1
movaps %xmm0, %xmm2
unpcklps %xmm1, %xmm0
unpckhps %xmm1, %xmm2
movups %xmm0, (SAMPLES)
movups %xmm2, 16(SAMPLES)
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_1
movl $4, %ecx
ALIGN16
Loop_start_2:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm4
movups 144(WINDOW), %xmm5
movups 160(WINDOW), %xmm6
movups 176(WINDOW), %xmm7
mulps 0(B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps -64(B0), %xmm4
mulps -48(B0), %xmm5
mulps -32(B0), %xmm6
mulps -16(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm4, %xmm5
movaps %xmm0, %xmm4
leal 256(WINDOW), WINDOW
leal -128(B0), B0
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm6
movups 144(WINDOW), %xmm7
mulps (B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps -64(B0), %xmm6
mulps -48(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm7, %xmm6
movups 160(WINDOW), %xmm1
movups 176(WINDOW), %xmm3
mulps -32(B0), %xmm1
mulps -16(B0), %xmm3
addps %xmm2, %xmm0
addps %xmm3, %xmm1
addps %xmm1, %xmm6
movaps %xmm6, %xmm7
movaps %xmm0, %xmm6
leal 256(WINDOW), WINDOW
leal -128(B0), B0
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
addps %xmm6, %xmm4
addps %xmm1, %xmm0
addps %xmm4, %xmm0
movups (SAMPLES), %xmm1
movups 16(SAMPLES), %xmm2
mulps ASM_NAME(scale_sse), %xmm0
shufps $0xdd, %xmm2, %xmm1
movaps %xmm0, %xmm2
unpcklps %xmm1, %xmm0
unpckhps %xmm1, %xmm2
movups %xmm0, (SAMPLES)
movups %xmm2, 16(SAMPLES)
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_2
xorl %eax, %eax
popl %esi
popl %ebx
movl %ebp, %esp
popl %ebp
ret
NONEXEC_STACK

View File

@ -0,0 +1,306 @@
/*
synth_sse_s32: SSE optimized synth (s32 output version)
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
/* real *window; */
#define WINDOW %ebx
/* real *b0; */
#define B0 %edx
/* real *samples; */
#define SAMPLES %esi
#define MMREG_CLIP %mm7
/*
int synth_1to1_s32_sse_asm(real *window, real *b0, int32_t *samples, int bo1);
return value: number of clipped samples
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
ASM_NAME(scale_s32):
.long 1199570944 /* 65536.0 */
.long 1199570944
.long 1199570944
.long 1199570944
ALIGN16
ASM_NAME(maxmin_s32):
.long 1191182335 /* 32767.999 */
.long 1191182335
.long 1191182335
.long 1191182335
.long -956301312 /* -32768.0 */
.long -956301312
.long -956301312
.long -956301312
.text
ALIGN16
.globl ASM_NAME(synth_1to1_s32_sse_asm)
ASM_NAME(synth_1to1_s32_sse_asm):
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
pxor MMREG_CLIP, MMREG_CLIP
movl 8(%ebp), WINDOW
movl 12(%ebp), B0
movl 16(%ebp), SAMPLES
movl 20(%ebp), %eax
shll $2, %eax
leal 64(WINDOW), WINDOW
subl %eax, WINDOW
movl $4, %ecx
ALIGN16
Loop_start_1:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm4
movups 144(WINDOW), %xmm5
movups 160(WINDOW), %xmm6
movups 176(WINDOW), %xmm7
mulps 0(B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps 64(B0), %xmm4
mulps 80(B0), %xmm5
mulps 96(B0), %xmm6
mulps 112(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm4, %xmm5
movaps %xmm0, %xmm4
leal 256(WINDOW), WINDOW
leal 128(B0), B0
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm6
movups 144(WINDOW), %xmm7
mulps (B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps 64(B0), %xmm6
mulps 80(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm7, %xmm6
movups 160(WINDOW), %xmm1
movups 176(WINDOW), %xmm3
mulps 96(B0), %xmm1
mulps 112(B0), %xmm3
addps %xmm2, %xmm0
addps %xmm3, %xmm1
addps %xmm1, %xmm6
movaps %xmm6, %xmm7
movaps %xmm0, %xmm6
leal 256(WINDOW), WINDOW
leal 128(B0), B0
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
subps %xmm6, %xmm4
subps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm0, %xmm1
movaps %xmm0, %xmm2
mulps ASM_NAME(scale_s32), %xmm0
cmpnleps ASM_NAME(maxmin_s32), %xmm1
cmpltps ASM_NAME(maxmin_s32)+16, %xmm2
cvtps2pi %xmm0, %mm0
movhlps %xmm0, %xmm0
cvtps2pi %xmm0, %mm1
cvtps2pi %xmm1, %mm2
movhlps %xmm1, %xmm1
cvtps2pi %xmm1, %mm3
psrad $31, %mm2
psrad $31, %mm3
pxor %mm2, %mm0
pxor %mm3, %mm1
movd %mm0, (SAMPLES)
psrlq $32, %mm0
movd %mm0, 8(SAMPLES)
movd %mm1, 16(SAMPLES)
psrlq $32, %mm1
movd %mm1, 24(SAMPLES)
cvtps2pi %xmm2, %mm0
movhlps %xmm2, %xmm2
cvtps2pi %xmm2, %mm1
packssdw %mm3, %mm2
packssdw %mm1, %mm0
psrlw $15, %mm2
psrlw $15, %mm0
paddw %mm2, %mm0
paddw %mm0, MMREG_CLIP
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_1
movl $4, %ecx
ALIGN16
Loop_start_2:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm4
movups 144(WINDOW), %xmm5
movups 160(WINDOW), %xmm6
movups 176(WINDOW), %xmm7
mulps 0(B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps -64(B0), %xmm4
mulps -48(B0), %xmm5
mulps -32(B0), %xmm6
mulps -16(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm4, %xmm5
movaps %xmm0, %xmm4
leal 256(WINDOW), WINDOW
leal -128(B0), B0
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movups 128(WINDOW), %xmm6
movups 144(WINDOW), %xmm7
mulps (B0), %xmm0
mulps 16(B0), %xmm1
mulps 32(B0), %xmm2
mulps 48(B0), %xmm3
mulps -64(B0), %xmm6
mulps -48(B0), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm7, %xmm6
movups 160(WINDOW), %xmm1
movups 176(WINDOW), %xmm3
mulps -32(B0), %xmm1
mulps -16(B0), %xmm3
addps %xmm2, %xmm0
addps %xmm3, %xmm1
addps %xmm1, %xmm6
movaps %xmm6, %xmm7
movaps %xmm0, %xmm6
leal 256(WINDOW), WINDOW
leal -128(B0), B0
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
addps %xmm6, %xmm4
addps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm0, %xmm1
movaps %xmm0, %xmm2
mulps ASM_NAME(scale_s32), %xmm0
cmpnleps ASM_NAME(maxmin_s32), %xmm1
cmpltps ASM_NAME(maxmin_s32)+16, %xmm2
cvtps2pi %xmm0, %mm0
movhlps %xmm0, %xmm0
cvtps2pi %xmm0, %mm1
cvtps2pi %xmm1, %mm2
movhlps %xmm1, %xmm1
cvtps2pi %xmm1, %mm3
psrad $31, %mm2
psrad $31, %mm3
pxor %mm2, %mm0
pxor %mm3, %mm1
movd %mm0, (SAMPLES)
psrlq $32, %mm0
movd %mm0, 8(SAMPLES)
movd %mm1, 16(SAMPLES)
psrlq $32, %mm1
movd %mm1, 24(SAMPLES)
cvtps2pi %xmm2, %mm0
movhlps %xmm2, %xmm2
cvtps2pi %xmm2, %mm1
packssdw %mm3, %mm2
packssdw %mm1, %mm0
psrlw $15, %mm2
psrlw $15, %mm0
paddw %mm2, %mm0
paddw %mm0, MMREG_CLIP
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_2
pshufw $0xee, MMREG_CLIP, %mm0
paddw MMREG_CLIP, %mm0
pshufw $0x55, %mm0, %mm1
paddw %mm1, %mm0
movd %mm0, %eax
andl $0xffff, %eax
popl %esi
popl %ebx
movl %ebp, %esp
popl %ebp
emms
ret
NONEXEC_STACK

View File

@ -0,0 +1,416 @@
/*
synth_sse_float: SSE optimized synth (stereo specific, float output version)
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
/* real *window; */
#define WINDOW %ebx
/* real *b0l; */
#define B0L %edx
/* real *b0r; */
#define B0R %esi
/* real *samples; */
#define SAMPLES %edi
#define TEMP(n) (12+16*n)(%esp)
/*
int synth_1to1_real_s_sse_asm(real *window, real *b0l, real *b0r, real *samples, int bo1);
return value: number of clipped samples (0)
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
ASM_NAME(scale_sse):
.long 939524096
.long 939524096
.long 939524096
.long 939524096
.text
ALIGN16
.globl ASM_NAME(synth_1to1_real_s_sse_asm)
ASM_NAME(synth_1to1_real_s_sse_asm):
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $128, %esp
pushl %ebx
pushl %esi
pushl %edi
movl 8(%ebp), WINDOW
movl 12(%ebp), B0L
movl 16(%ebp), B0R
movl 20(%ebp), SAMPLES
movl 24(%ebp), %eax
shll $2, %eax
leal 64(WINDOW), WINDOW
subl %eax, WINDOW
movl $4, %ecx
ALIGN16
Loop_start_1:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(0)
movaps %xmm4, TEMP(4)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(1)
movaps %xmm4, TEMP(5)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(2)
movaps %xmm4, TEMP(6)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, %xmm7
movaps %xmm4, TEMP(7)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movaps TEMP(0), %xmm4
movaps TEMP(1), %xmm5
movaps TEMP(2), %xmm6
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
subps %xmm6, %xmm4
subps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm0, %xmm2
movaps TEMP(4), %xmm4
movaps TEMP(5), %xmm5
movaps TEMP(6), %xmm6
movaps TEMP(7), %xmm7
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm2, %xmm5
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
subps %xmm6, %xmm4
subps %xmm1, %xmm0
addps %xmm4, %xmm0
mulps ASM_NAME(scale_sse), %xmm5
mulps ASM_NAME(scale_sse), %xmm0
movaps %xmm5, %xmm1
unpcklps %xmm0, %xmm5
unpckhps %xmm0, %xmm1
movups %xmm5, (SAMPLES)
movups %xmm1, 16(SAMPLES)
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_1
movl $4, %ecx
ALIGN16
Loop_start_2:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(0)
movaps %xmm4, TEMP(4)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(1)
movaps %xmm4, TEMP(5)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(2)
movaps %xmm4, TEMP(6)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, %xmm7
movaps %xmm4, TEMP(7)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movaps TEMP(0), %xmm4
movaps TEMP(1), %xmm5
movaps TEMP(2), %xmm6
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
addps %xmm6, %xmm4
addps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm0, %xmm2
movaps TEMP(4), %xmm4
movaps TEMP(5), %xmm5
movaps TEMP(6), %xmm6
movaps TEMP(7), %xmm7
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm2, %xmm5
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
addps %xmm6, %xmm4
addps %xmm1, %xmm0
addps %xmm4, %xmm0
mulps ASM_NAME(scale_sse), %xmm5
mulps ASM_NAME(scale_sse), %xmm0
movaps %xmm5, %xmm1
unpcklps %xmm0, %xmm5
unpckhps %xmm0, %xmm1
movups %xmm5, (SAMPLES)
movups %xmm1, 16(SAMPLES)
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_2
xorl %eax, %eax
popl %edi
popl %esi
popl %ebx
movl %ebp, %esp
popl %ebp
ret
NONEXEC_STACK

View File

@ -0,0 +1,540 @@
/*
synth_stereo_sse_s32: SSE optimized synth (stereo specific, s32 output version)
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
/* real *window; */
#define WINDOW %ebx
/* real *b0l; */
#define B0L %edx
/* real *b0r; */
#define B0R %esi
/* real *samples; */
#define SAMPLES %edi
#define TEMP(n) (12+16*n)(%esp)
#define MMREG_CLIP %mm7
/*
int synth_1to1_s32_s_sse_asm(real *window, real *b0l, real *b0r, int32_t *samples, int bo1);
return value: number of clipped samples
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
ASM_NAME(scale_s32):
.long 1199570944 /* 65536.0 */
.long 1199570944
.long 1199570944
.long 1199570944
ALIGN16
ASM_NAME(maxmin_s32):
.long 1191182335 /* 32767.999 */
.long 1191182335
.long 1191182335
.long 1191182335
.long -956301312 /* -32768.0 */
.long -956301312
.long -956301312
.long -956301312
.text
ALIGN16
.globl ASM_NAME(synth_1to1_s32_s_sse_asm)
ASM_NAME(synth_1to1_s32_s_sse_asm):
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $128, %esp
pushl %ebx
pushl %esi
pushl %edi
pxor MMREG_CLIP, MMREG_CLIP
movl 8(%ebp), WINDOW
movl 12(%ebp), B0L
movl 16(%ebp), B0R
movl 20(%ebp), SAMPLES
movl 24(%ebp), %eax
shll $2, %eax
leal 64(WINDOW), WINDOW
subl %eax, WINDOW
movl $4, %ecx
ALIGN16
Loop_start_1:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(0)
movaps %xmm4, TEMP(4)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(1)
movaps %xmm4, TEMP(5)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(2)
movaps %xmm4, TEMP(6)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, %xmm7
movaps %xmm4, TEMP(7)
leal 128(WINDOW), WINDOW
leal 64(B0L), B0L
leal 64(B0R), B0R
movaps TEMP(0), %xmm4
movaps TEMP(1), %xmm5
movaps TEMP(2), %xmm6
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
subps %xmm6, %xmm4
subps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm0, %xmm2
movaps TEMP(4), %xmm4
movaps TEMP(5), %xmm5
movaps TEMP(6), %xmm6
movaps TEMP(7), %xmm7
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm2, %xmm5
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
subps %xmm6, %xmm4
subps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm5, %xmm1
movaps %xmm5, %xmm2
movaps %xmm0, %xmm3
movaps %xmm0, %xmm4
mulps ASM_NAME(scale_s32), %xmm5
mulps ASM_NAME(scale_s32), %xmm0
cmpnleps ASM_NAME(maxmin_s32), %xmm1
cmpltps ASM_NAME(maxmin_s32)+16, %xmm2
cmpnleps ASM_NAME(maxmin_s32), %xmm3
cmpltps ASM_NAME(maxmin_s32)+16, %xmm4
cvtps2pi %xmm5, %mm0
cvtps2pi %xmm0, %mm1
cvtps2pi %xmm1, %mm2
cvtps2pi %xmm3, %mm3
psrad $31, %mm2
psrad $31, %mm3
pxor %mm2, %mm0
pxor %mm3, %mm1
movq %mm0, %mm4
punpckldq %mm1, %mm0
punpckhdq %mm1, %mm4
movq %mm0, (SAMPLES)
movq %mm4, 8(SAMPLES)
movhlps %xmm5, %xmm5
movhlps %xmm0, %xmm0
movhlps %xmm1, %xmm1
movhlps %xmm3, %xmm3
cvtps2pi %xmm5, %mm0
cvtps2pi %xmm0, %mm1
cvtps2pi %xmm1, %mm4
cvtps2pi %xmm3, %mm5
psrad $31, %mm4
psrad $31, %mm5
pxor %mm4, %mm0
pxor %mm5, %mm1
movq %mm0, %mm6
punpckldq %mm1, %mm0
punpckhdq %mm1, %mm6
movq %mm0, 16(SAMPLES)
movq %mm6, 24(SAMPLES)
packssdw %mm4, %mm2
packssdw %mm5, %mm3
psrlw $15, %mm2
psrlw $15, %mm3
cvtps2pi %xmm2, %mm0
cvtps2pi %xmm4, %mm1
movhlps %xmm2, %xmm2
movhlps %xmm4, %xmm4
cvtps2pi %xmm2, %mm4
cvtps2pi %xmm4, %mm5
packssdw %mm4, %mm0
packssdw %mm5, %mm1
psrlw $15, %mm0
psrlw $15, %mm1
paddw %mm3, %mm2
paddw %mm1, %mm0
paddw %mm2, %mm0
paddw %mm0, MMREG_CLIP
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_1
movl $4, %ecx
ALIGN16
Loop_start_2:
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(0)
movaps %xmm4, TEMP(4)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(1)
movaps %xmm4, TEMP(5)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, TEMP(2)
movaps %xmm4, TEMP(6)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movups (WINDOW), %xmm0
movups 16(WINDOW), %xmm1
movups 32(WINDOW), %xmm2
movups 48(WINDOW), %xmm3
movaps %xmm0, %xmm4
movaps %xmm1, %xmm5
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
mulps 0(B0L), %xmm0
mulps 16(B0L), %xmm1
mulps 32(B0L), %xmm2
mulps 48(B0L), %xmm3
mulps 0(B0R), %xmm4
mulps 16(B0R), %xmm5
mulps 32(B0R), %xmm6
mulps 48(B0R), %xmm7
addps %xmm1, %xmm0
addps %xmm3, %xmm2
addps %xmm5, %xmm4
addps %xmm7, %xmm6
addps %xmm2, %xmm0
addps %xmm6, %xmm4
movaps %xmm0, %xmm7
movaps %xmm4, TEMP(7)
leal 128(WINDOW), WINDOW
leal -64(B0L), B0L
leal -64(B0R), B0R
movaps TEMP(0), %xmm4
movaps TEMP(1), %xmm5
movaps TEMP(2), %xmm6
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
addps %xmm6, %xmm4
addps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm0, %xmm2
movaps TEMP(4), %xmm4
movaps TEMP(5), %xmm5
movaps TEMP(6), %xmm6
movaps TEMP(7), %xmm7
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps %xmm5, %xmm4
unpcklps %xmm7, %xmm6
unpckhps %xmm5, %xmm0
unpckhps %xmm7, %xmm1
movaps %xmm2, %xmm5
movaps %xmm4, %xmm2
movaps %xmm0, %xmm3
movlhps %xmm6, %xmm4
movhlps %xmm2, %xmm6
movlhps %xmm1, %xmm0
movhlps %xmm3, %xmm1
addps %xmm6, %xmm4
addps %xmm1, %xmm0
addps %xmm4, %xmm0
movaps %xmm5, %xmm1
movaps %xmm5, %xmm2
movaps %xmm0, %xmm3
movaps %xmm0, %xmm4
mulps ASM_NAME(scale_s32), %xmm5
mulps ASM_NAME(scale_s32), %xmm0
cmpnleps ASM_NAME(maxmin_s32), %xmm1
cmpltps ASM_NAME(maxmin_s32)+16, %xmm2
cmpnleps ASM_NAME(maxmin_s32), %xmm3
cmpltps ASM_NAME(maxmin_s32)+16, %xmm4
cvtps2pi %xmm5, %mm0
cvtps2pi %xmm0, %mm1
cvtps2pi %xmm1, %mm2
cvtps2pi %xmm3, %mm3
psrad $31, %mm2
psrad $31, %mm3
pxor %mm2, %mm0
pxor %mm3, %mm1
movq %mm0, %mm4
punpckldq %mm1, %mm0
punpckhdq %mm1, %mm4
movq %mm0, (SAMPLES)
movq %mm4, 8(SAMPLES)
movhlps %xmm5, %xmm5
movhlps %xmm0, %xmm0
movhlps %xmm1, %xmm1
movhlps %xmm3, %xmm3
cvtps2pi %xmm5, %mm0
cvtps2pi %xmm0, %mm1
cvtps2pi %xmm1, %mm4
cvtps2pi %xmm3, %mm5
psrad $31, %mm4
psrad $31, %mm5
pxor %mm4, %mm0
pxor %mm5, %mm1
movq %mm0, %mm6
punpckldq %mm1, %mm0
punpckhdq %mm1, %mm6
movq %mm0, 16(SAMPLES)
movq %mm6, 24(SAMPLES)
packssdw %mm4, %mm2
packssdw %mm5, %mm3
psrlw $15, %mm2
psrlw $15, %mm3
cvtps2pi %xmm2, %mm0
cvtps2pi %xmm4, %mm1
movhlps %xmm2, %xmm2
movhlps %xmm4, %xmm4
cvtps2pi %xmm2, %mm4
cvtps2pi %xmm4, %mm5
packssdw %mm4, %mm0
packssdw %mm5, %mm1
psrlw $15, %mm0
psrlw $15, %mm1
paddw %mm3, %mm2
paddw %mm1, %mm0
paddw %mm2, %mm0
paddw %mm0, MMREG_CLIP
leal 32(SAMPLES), SAMPLES
decl %ecx
jnz Loop_start_2
pshufw $0xee, MMREG_CLIP, %mm0
paddw MMREG_CLIP, %mm0
pshufw $0x55, %mm0, %mm1
paddw %mm1, %mm0
movd %mm0, %eax
andl $0xffff, %eax
popl %edi
popl %esi
popl %ebx
movl %ebp, %esp
popl %ebp
emms
ret
NONEXEC_STACK

View File

@ -10,7 +10,7 @@
typedef int (*func_synth)(real *,int, mpg123_handle *,int );
typedef int (*func_synth_mono)(real *, mpg123_handle *);
typedef int (*func_synth_stereo)(real *, real *, mpg123_handle *);
enum synth_channel { c_plain=0, c_stereo, c_mono2stereo, c_mono, c_limit };
enum synth_channel { c_plain=0, c_stereo, c_m2s, c_mono, c_limit };
enum synth_resample
{
r_none=-1

View File

@ -90,7 +90,7 @@ void prepare_decode_tables()
}
#ifdef OPT_MMXORSSE
#ifndef OPT_X86_64
#if !defined(OPT_X86_64) && !defined(OPT_NEON)
void make_decode_tables_mmx_asm(long scaleval, float* decwin_mmx, float *decwins);
void make_decode_tables_mmx(mpg123_handle *fr)
{
@ -210,8 +210,8 @@ void make_decode_tables(mpg123_handle *fr)
scaleval = - scaleval;
#endif
}
#if defined(OPT_X86_64) || defined(OPT_ALTIVEC) || defined(OPT_SSE) || defined(OPT_ARM)
if(fr->cpu_opts.type == x86_64 || fr->cpu_opts.type == altivec || fr->cpu_opts.type == sse || fr->cpu_opts.type == arm)
#if defined(OPT_X86_64) || defined(OPT_ALTIVEC) || defined(OPT_SSE) || defined(OPT_ARM) || defined(OPT_NEON)
if(fr->cpu_opts.type == x86_64 || fr->cpu_opts.type == altivec || fr->cpu_opts.type == sse || fr->cpu_opts.type == arm || fr->cpu_opts.type == neon)
{ /* for float SSE / AltiVec / ARM decoder */
for(i=512; i<512+32; i++)
{
@ -221,6 +221,15 @@ void make_decode_tables(mpg123_handle *fr)
{
fr->decwin[512+32+i] = -fr->decwin[511-i];
}
#ifdef OPT_NEON
if(fr->cpu_opts.type == neon)
{
for(i=0; i<512; i+=2)
{
fr->decwin[i] = -fr->decwin[i];
}
}
#endif
}
#endif
debug("decode tables done");

View File

@ -45,39 +45,39 @@ ASM_NAME(costab_mmxsse):
.long 1060439283
ALIGN32
intwinbase:
.value 0, -1, -1, -1, -1, -1, -1, -2
.value -2, -2, -2, -3, -3, -4, -4, -5
.value -5, -6, -7, -7, -8, -9, -10, -11
.value -13, -14, -16, -17, -19, -21, -24, -26
.value -29, -31, -35, -38, -41, -45, -49, -53
.value -58, -63, -68, -73, -79, -85, -91, -97
.value -104, -111, -117, -125, -132, -139, -147, -154
.value -161, -169, -176, -183, -190, -196, -202, -208
.value -213, -218, -222, -225, -227, -228, -228, -227
.value -224, -221, -215, -208, -200, -189, -177, -163
.value -146, -127, -106, -83, -57, -29, 2, 36
.value 72, 111, 153, 197, 244, 294, 347, 401
.value 459, 519, 581, 645, 711, 779, 848, 919
.value 991, 1064, 1137, 1210, 1283, 1356, 1428, 1498
.value 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962
.value 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063
.value 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535
.value 1414, 1280, 1131, 970, 794, 605, 402, 185
.value -45, -288, -545, -814, -1095, -1388, -1692, -2006
.value -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788
.value -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597
.value -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585
.value -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750
.value -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134
.value -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082
.value -70, 998, 2122, 3300, 4533, 5818, 7154, 8540
.value 9975, 11455, 12980, 14548, 16155, 17799, 19478, 21189
.value 22929, 24694, 26482, 28289, 30112, 31947,-26209,-24360
.value -22511,-20664,-18824,-16994,-15179,-13383,-11610, -9863
.value -8147, -6466, -4822, -3222, -1667, -162, 1289, 2684
.value 4019, 5290, 6494, 7629, 8692, 9679, 10590, 11420
.value 12169, 12835, 13415, 13908, 14313, 14630, 14856, 14992
.value 15038
.short 0, -1, -1, -1, -1, -1, -1, -2
.short -2, -2, -2, -3, -3, -4, -4, -5
.short -5, -6, -7, -7, -8, -9, -10, -11
.short -13, -14, -16, -17, -19, -21, -24, -26
.short -29, -31, -35, -38, -41, -45, -49, -53
.short -58, -63, -68, -73, -79, -85, -91, -97
.short -104, -111, -117, -125, -132, -139, -147, -154
.short -161, -169, -176, -183, -190, -196, -202, -208
.short -213, -218, -222, -225, -227, -228, -228, -227
.short -224, -221, -215, -208, -200, -189, -177, -163
.short -146, -127, -106, -83, -57, -29, 2, 36
.short 72, 111, 153, 197, 244, 294, 347, 401
.short 459, 519, 581, 645, 711, 779, 848, 919
.short 991, 1064, 1137, 1210, 1283, 1356, 1428, 1498
.short 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962
.short 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063
.short 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535
.short 1414, 1280, 1131, 970, 794, 605, 402, 185
.short -45, -288, -545, -814, -1095, -1388, -1692, -2006
.short -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788
.short -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597
.short -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585
.short -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750
.short -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134
.short -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082
.short -70, 998, 2122, 3300, 4533, 5818, 7154, 8540
.short 9975, 11455, 12980, 14548, 16155, 17799, 19478, 21189
.short 22929, 24694, 26482, 28289, 30112, 31947,-26209,-24360
.short -22511,-20664,-18824,-16994,-15179,-13383,-11610, -9863
.short -8147, -6466, -4822, -3222, -1667, -162, 1289, 2684
.short 4019, 5290, 6494, 7629, 8692, 9679, 10590, 11420
.short 12169, 12835, 13415, 13908, 14313, 14630, 14856, 14992
.short 15038
intwindiv:
.long 0x47800000 # 65536.0
@ -119,11 +119,11 @@ ASM_NAME(make_decode_tables_mmx_asm):
/* stack: 20=scaleval 24=decwin_mmx, 28=decwins */
.L02:
leal -1(%esi),%edx
and %ebx,%edx
cmp $31,%edx
andl %ebx,%edx
cmpl $31,%edx
jnz .L03
addl $-1023,%ecx
test %esi,%ebx
testl %esi,%ebx
jz .L03
negl 20(%esp)
.L03:
@ -132,7 +132,7 @@ ASM_NAME(make_decode_tables_mmx_asm):
incl %ebx
cmpl $intwinbase,%edi
jz .L04
cmp $256,%ebx
cmpl $256,%ebx
jnz .L00
negl (%esp)
jmp .L00
@ -182,11 +182,11 @@ ASM_NAME(make_decode_tables_mmx_asm):
popl %ebx /* that has to match the pushl before */
.L11:
leal -1(%esi),%edx
and %ebx,%edx
cmp $31,%edx
andl %ebx,%edx
cmpl $31,%edx
jnz .L12
addl $-1023,%ecx
test %esi,%ebx
testl %esi,%ebx
jz .L12
negl 20(%esp)
.L12:
@ -195,7 +195,7 @@ ASM_NAME(make_decode_tables_mmx_asm):
incl %ebx
cmpl $intwinbase,%edi
jz .L13
cmp $256,%ebx
cmpl $256,%ebx
jnz .L05
negl (%esp)
jmp .L05
@ -207,7 +207,4 @@ ASM_NAME(make_decode_tables_mmx_asm):
popl %edi
ret
/* Mark non-executable stack. */
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits
#endif
NONEXEC_STACK

View File

@ -0,0 +1,113 @@
import libmpg123,\
mpg123_add_string,'mpg123_add_string',\
mpg123_add_substring,'mpg123_add_substring',\
mpg123_chomp_string,'mpg123_chomp_string',\
mpg123_clip,'mpg123_clip',\
mpg123_close,'mpg123_close',\
mpg123_copy_string,'mpg123_copy_string',\
mpg123_current_decoder,'mpg123_current_decoder',\
mpg123_decode,'mpg123_decode',\
mpg123_decode_frame,'mpg123_decode_frame',\
mpg123_decode_frame_32,'mpg123_decode_frame_32',\
mpg123_decoder,'mpg123_decoder',\
mpg123_decoders,'mpg123_decoders',\
mpg123_delete,'mpg123_delete',\
mpg123_delete_pars,'mpg123_delete_pars',\
mpg123_enc_from_id3,'mpg123_enc_from_id3',\
mpg123_encodings,'mpg123_encodings',\
mpg123_encsize,'mpg123_encsize',\
mpg123_eq,'mpg123_eq',\
mpg123_errcode,'mpg123_errcode',\
mpg123_exit,'mpg123_exit',\
mpg123_feature,'mpg123_feature',\
mpg123_feed,'mpg123_feed',\
mpg123_feedseek,'mpg123_feedseek',\
mpg123_feedseek_32,'mpg123_feedseek_32',\
mpg123_fmt,'mpg123_fmt',\
mpg123_fmt_all,'mpg123_fmt_all',\
mpg123_fmt_none,'mpg123_fmt_none',\
mpg123_fmt_support,'mpg123_fmt_support',\
mpg123_format,'mpg123_format',\
mpg123_format_all,'mpg123_format_all',\
mpg123_format_none,'mpg123_format_none',\
mpg123_format_support,'mpg123_format_support',\
mpg123_framebyframe_decode,'mpg123_framebyframe_decode',\
mpg123_framebyframe_decode_32,'mpg123_framebyframe_decode_32',\
mpg123_framebyframe_next,'mpg123_framebyframe_next',\
mpg123_framedata,'mpg123_framedata',\
mpg123_framepos,'mpg123_framepos',\
mpg123_framepos_32,'mpg123_framepos_32',\
mpg123_free_string,'mpg123_free_string',\
mpg123_geteq,'mpg123_geteq',\
mpg123_getformat,'mpg123_getformat',\
mpg123_getpar,'mpg123_getpar',\
mpg123_getparam,'mpg123_getparam',\
mpg123_getstate,'mpg123_getstate',\
mpg123_getvolume,'mpg123_getvolume',\
mpg123_grow_string,'mpg123_grow_string',\
mpg123_icy,'mpg123_icy',\
mpg123_icy2utf8,'mpg123_icy2utf8',\
mpg123_id3,'mpg123_id3',\
mpg123_index,'mpg123_index',\
mpg123_index_32,'mpg123_index_32',\
mpg123_info,'mpg123_info',\
mpg123_init,'mpg123_init',\
mpg123_init_string,'mpg123_init_string',\
mpg123_length,'mpg123_length',\
mpg123_length_32,'mpg123_length_32',\
mpg123_meta_check,'mpg123_meta_check',\
mpg123_meta_free,'mpg123_meta_free',\
mpg123_new,'mpg123_new',\
mpg123_new_pars,'mpg123_new_pars',\
mpg123_noise,'mpg123_noise',\
mpg123_open,'mpg123_open',\
mpg123_open_32,'mpg123_open_32',\
mpg123_open_fd,'mpg123_open_fd',\
mpg123_open_fd_32,'mpg123_open_fd_32',\
mpg123_open_feed,'mpg123_open_feed',\
mpg123_open_handle,'mpg123_open_handle',\
mpg123_open_handle_32,'mpg123_open_handle_32',\
mpg123_outblock,'mpg123_outblock',\
mpg123_par,'mpg123_par',\
mpg123_param,'mpg123_param',\
mpg123_parnew,'mpg123_parnew',\
mpg123_plain_strerror,'mpg123_plain_strerror',\
mpg123_position,'mpg123_position',\
mpg123_position_32,'mpg123_position_32',\
mpg123_rates,'mpg123_rates',\
mpg123_read,'mpg123_read',\
mpg123_replace_buffer,'mpg123_replace_buffer',\
mpg123_replace_reader,'mpg123_replace_reader',\
mpg123_replace_reader_32,'mpg123_replace_reader_32',\
mpg123_replace_reader_handle,'mpg123_replace_reader_handle',\
mpg123_replace_reader_handle_32,'mpg123_replace_reader_handle_32',\
mpg123_reset_eq,'mpg123_reset_eq',\
mpg123_resize_string,'mpg123_resize_string',\
mpg123_safe_buffer,'mpg123_safe_buffer',\
mpg123_scan,'mpg123_scan',\
mpg123_seek,'mpg123_seek',\
mpg123_seek_32,'mpg123_seek_32',\
mpg123_seek_frame,'mpg123_seek_frame',\
mpg123_seek_frame_32,'mpg123_seek_frame_32',\
mpg123_set_filesize,'mpg123_set_filesize',\
mpg123_set_filesize_32,'mpg123_set_filesize_32',\
mpg123_set_index,'mpg123_set_index',\
mpg123_set_index_32,'mpg123_set_index_32',\
mpg123_set_string,'mpg123_set_string',\
mpg123_set_substring,'mpg123_set_substring',\
mpg123_spf,'mpg123_spf',\
mpg123_store_utf8,'mpg123_store_utf8',\
mpg123_strerror,'mpg123_strerror',\
mpg123_strlen,'mpg123_strlen',\
mpg123_supported_decoders,'mpg123_supported_decoders',\
mpg123_tell,'mpg123_tell',\
mpg123_tell_32,'mpg123_tell_32',\
mpg123_tell_stream,'mpg123_tell_stream',\
mpg123_tell_stream_32,'mpg123_tell_stream_32',\
mpg123_tellframe,'mpg123_tellframe',\
mpg123_tellframe_32,'mpg123_tellframe_32',\
mpg123_timeframe,'mpg123_timeframe',\
mpg123_timeframe_32,'mpg123_timeframe_32',\
mpg123_tpf,'mpg123_tpf',\
mpg123_volume,'mpg123_volume',\
mpg123_volume_change,'mpg123_volume_change'