ac3dec: Remove the ac3dec tool

There may be some licencing issues for the name and decoder (it is not
build in the Fedora distro anyway).

Sources will stay in repos, but almost all current players are able
to handle DD AC-3.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2013-04-09 11:10:02 +02:00
parent c416c1180d
commit 4f0f875032
51 changed files with 1 additions and 6224 deletions

View file

@ -1,6 +1,6 @@
VERSION = 1.0.26.1
TOP = .
SUBDIRS = ac3dec as10k1 envy24control hdsploader hdspconf hdspmixer \
SUBDIRS = as10k1 envy24control hdsploader hdspconf hdspmixer \
mixartloader pcxhrloader rmedigicontrol sb16_csp seq sscape_ctl \
us428control usx2yloader vxloader echomixer ld10k1 qlo10k1 \
hwmixvolume hdajackretask hda-verb

View file

@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
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 Library 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
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -1,58 +0,0 @@
ac3dec-0.6.1 Mon Mar 27 20:27:06 EST 2000
-Fix another 2.0 problem (rematrix was wrong).
-Fix the never resync on a bad crc bug.
ac3dec-0.6.0 Sat Mar 18 19:43:25 EST 2000
-New library interface
-Fix bug wrt coupling channels that was causing sound quality problems.
-Fix 2.0 mode problems (aka the I forgot to implement the phase flags bug).
-All around speed improvements (almost twice as fast)
-Improved robustness when fed bad data. The entire frame is checksummed before playback.
ac3dec-0.5.6 Tue Nov 16 00:37:34 EST 1999
-Irix support
-Alpha fixes
-Minor performance enhancements to downmix and imdct
-OpenBSD fixes
-extract_ac3 can now read from stdin
-Change output_linux to block on write instead of using the
ring buffer. Let me know if this causes/fixes any problems
ac3dec-0.5.5 Wed Aug 25 15:36:44 EDT 1999
-Fixed a cut and paste bug (argh!) in parse.c which potentially
screwed up delta bit allocation info.
-Martin Mueller <mamueller@topmail.de> informed me that I was missing
some corrections from the AC-3 errata document. It turns out that
I used an earlier version of the errata when I initially wrote ac3dec.
Fortunately the errata fix the outstanding bugs that I was pulling
my hair out on for a long time. Woohoo! Thanks Martin. Kudos to Dolby
Labs for keeping their documentation up to date as well.
-stereo downmixing (downmix.c) is now in. Matrix encoded surround
(Dolby Prologic Surround) should work too.
-clipping due to high level signals has been fixed. We normalize a
block of samples by its maximum absolute value if the max exceeds
the %100 digital level. This shouldn't be a problem, but for some
reason some channels have a dynamic range that exceeds [-1.0,1.0].
I blame the encoder :)
-Multiple track support in extract_ac3. Simply just give it the track
number you want [1,8] after the filename.
ac3dec-0.5.4 Thu Jul 29 16:55:10 PDT 1999
-Fixed a stupid bug with the coupling channel that was causing
high frequencies to be attenuated.
-Re-wrote the extract_ac3 tool.
-Added to a tool to verify the checksums on a given AC3 stream.
(tools/verify_ac3)
ac3dec-0.5.3 Mon Jul 12 10:45:56 PDT 1999
-Fixed problems related to streams with coupling channel enabled.
-Minor performance enhancements
ac3dec-0.5.2 Sun Jul 4 12:00:25 PDT 1999
-output_linux.c patch provided by Michael Holzt <kju@flummi.de>
ac3dec-0.5.1 Wed Jun 30 17:48:52 PDT 1999
-Compiles and dies gracefully under Linux now.
ac3dec-0.5.0 Wed Jun 23 11:06:06 EDT 1999
-First public release of ac3dec.

View file

@ -1,22 +0,0 @@
# # Process this file with automake to produce Makefile.in.
AUTOMAKE_OPTIONS = 1.3 foreign
bin_PROGRAMS = ac3dec
ac3dec_LDADD= -L./libac3 -lac3 -lm
noinst_HEADERS = output.h
ac3dec_SOURCES = ac3dec.c output.c ac3spdif.c
ac3dec_DEPENDENCIES = libac3/libac3.a
EXTRA_DIST = gitcompile README Changelog TODO plot_spectrum.m autogen.sh \
depcomp
SUBDIRS = libac3 tools test .
alsa-dist: distdir
@rm -rf ../distdir/ac3dec
@mkdir -p ../distdir/ac3dec
@cp -RLpv $(distdir)/* ../distdir/ac3dec
@rm -rf $(distdir)

View file

@ -1,52 +0,0 @@
ac3dec - a free AC-3 stream decoder
Written by Aaron Holtzman (aholtzma@engr.uvic.ca)
Contributors:
Michael Holzt <kju@flummi.de> - OSS output.c and misc errata
Jim Miller <jmiller@heli.engr.sgi.com> - IRIX output.c
Angelos Keromytis <angelos@dsl.cis.upenn.edu> - OpenBSD fixes
Don Mahurin <dmahurin@dma.org> - stdin support for extract_ac3
Takefumi SAYO <stake@niagara.shiojiri.ne.jp> - FreeBSD tweak
Charles M. Hannum <root@ihack.net> - fixes
See the file COPYING for license details.
The currently supported platforms are Linux, Solaris, IRIX, OpenBSD, and
FreeBSD. If you want support for other platforms, take a look at
output_*.c for an idea of what you need to do.
This software is completely useless to 99.99 percent of users
out there. It is mostly of use to those interested in audio
coding research and evaluating codecs. It could theoretically
be used as a portion of a DVD playback system for unix systems.
HOW TO COMPILE
Building ac3dec should be easy. Here's how:
./configure && make all
USAGE
To find AC-3 streams on the internet, use www.google.com and
search for "vob trailer". A vob is a "Video Object" which is
just an MPEG-2 stream. The site www.hollywood.com has a
few good MPEG-2s with AC-3 audio. The program tools/extract_ac3
will take an MPEG-2 stream and spit out AC-3 audio to stdout if
it exists. You can easily pipe this data to the ac3 player like
this:
./tools/extract_ac3 foo.vob | ./ac3dec/
You can also get AC-3 streams on a DVD. Check out
http://www.linuxvideo.org for details.
DEBUG OUTPUT
You can get a whole pile of debug info by setting the environment
variable AC3_DEBUG=1. Be sure to pipe stderr to a file or you probably
won't get realtime playback. You can pipe stderr to a file like so:
./ac3dec foo.ac3 2> debug.out

View file

@ -1,22 +0,0 @@
- Detect hrtime on solaris and enable it via config.h
- Add multilevel debug output
- change the divides/moduluos in coeff_get_mantissa to table
lookups. Need to look at stats first though.
- rewrite imdct to use split 2/4 radix fft
- investigate strangeness in 256 point imdct (weird transients?)
DONE
- fix the bitstream interface to allow on aligned buffers - Feb 2000 -AH
- change dither.c, crc.c to use a lookup table - March 2000 -AH
- the output signal from the IMDCT sometimes is outside the rand
of [-1.0,1.0]. This is why there is the normalization pass in
output.c. Need to investigate and hopefully we can move the
normalization. - Feb 2000 -AH
- Mute frame on error. Feb 2000 -AH
- Revisit convert_to_float and use int->float with scaling - Feb 2000 -AH
- Use proper frame sizes in auxdata parsing - July 1999 - AH
- fix clipping in output (normalize to max digital output) - Aug 99 -AH
- Fix coupling channel support - July 1999 - AH
- Add delta bit allocation support - July 1999 - AH
- Add downmixing support - Sept 1999 - AH, Yeqing Deng

View file

@ -1,251 +0,0 @@
/*
* ac3dec.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/errno.h>
#include <sys/signal.h>
#include <errno.h>
#include "config.h"
#include "libac3/ac3.h"
#include "output.h"
void init_spdif(void);
int output_spdif_zero(int frames);
int output_spdif_leadin(void);
int output_spdif(uint_8 *data_start, uint_8 *data_end, int quiet);
static int end_flag = 0;
static int quiet = 0;
static void help(void)
{
printf("Usage: ac3dec <options> [file] [[file]] ...\n");
printf("\nAvailable options:\n");
printf(" -h,--help this help\n");
printf(" -v,--version print version of this program\n");
printf(" -D,--device=NAME select PCM by NAME\n");
printf(" -c,--card=ID select card for bellow modes\n");
printf(" -4,--4ch four channels mode\n");
printf(" -6,--6ch six channels mode\n");
printf(" -C,--iec958c raw IEC958 (S/PDIF) consumer mode\n");
printf(" -P,--iec958p raw IEC958 (S/PDIF) professional mode\n");
printf(" -R,--iec958r raw IEC958 (S/PDIF) PCM\n");
printf(" -H,--hdmi output to HDMI device\n");
printf(" -Z,--zero=# add # zero-AC3-frames before stream\n");
printf(" -q,--quiet quiet mode\n");
}
#define CHUNK_SIZE 2047
uint_8 buf[CHUNK_SIZE];
FILE *in_file;
ssize_t fill_buffer(uint_8 **start,uint_8 **end)
{
uint_32 bytes_read;
*start = buf;
bytes_read = fread(*start,1,CHUNK_SIZE,in_file);
if (feof(in_file) || ferror(in_file) || bytes_read < CHUNK_SIZE) {
end_flag = 1;
return EOF;
}
*end = *start + bytes_read;
return bytes_read;
}
static void ac3dec_signal_handler(int signal)
{
if (!quiet)
fprintf(stderr, "Aborted...\n");
// it's important to close the PCM handle(s), because
// some driver settings have to be recovered
output_close();
fclose(in_file);
exit(EXIT_FAILURE);
}
int main(int argc,char *argv[])
{
struct option long_option[] =
{
{"help", 0, NULL, 'h'},
{"version", 0, NULL, 'v'},
{"device", 1, NULL, 'D'},
{"4ch", 0, NULL, '4'},
{"6ch", 0, NULL, '6'},
{"card", 1, NULL, 'c'},
{"iec958c", 0, NULL, 'C'},
{"spdif", 0, NULL, 'C'},
{"iec958p", 0, NULL, 'P'},
{"iec958r", 0, NULL, 'R'},
{"hdmi", 0, NULL, 'H'},
{"zero", 1, NULL, 'Z'},
{"quiet", 0, NULL, 'q'},
{NULL, 0, NULL, 0},
};
ac3_config_t ac3_config;
output_t out_config;
int morehelp, loop = 0;
int zero = 0;
bzero(&ac3_config, sizeof(ac3_config));
ac3_config.fill_buffer_callback = fill_buffer;
ac3_config.num_output_ch = 2;
ac3_config.flags = 0;
bzero(&out_config, sizeof(out_config));
out_config.pcm_name = NULL;
out_config.card = NULL;
out_config.bits = 16;
out_config.rate = 48000;
out_config.channels = 2;
out_config.spdif = SPDIF_NONE;
out_config.hdmi = 0;
if (isatty(fileno(stdin)) && (argc == 1)) {
help();
return 1;
}
morehelp = 0;
while (1) {
int c;
if ((c = getopt_long(argc, argv, "hvc:D:46HCPRZ:q", long_option, NULL)) < 0)
break;
switch (c) {
case 'h':
morehelp++;
break;
case 'v':
printf("ac3dec version " VERSION "\n");
return 1;
case 'c':
out_config.card = strdup(optarg);
break;
case 'D':
out_config.pcm_name = optarg;
break;
case '4':
if (out_config.spdif == SPDIF_NONE)
ac3_config.num_output_ch = 4;
break;
case '6':
if (out_config.spdif == SPDIF_NONE)
ac3_config.num_output_ch = 6;
break;
case 'C':
ac3_config.num_output_ch = 2;
out_config.spdif = SPDIF_CON;
break;
case 'P':
ac3_config.num_output_ch = 2;
out_config.spdif = SPDIF_PRO;
break;
case 'R':
ac3_config.num_output_ch = 2;
out_config.spdif = SPDIF_PCM;
break;
case 'H':
out_config.hdmi = 1;
break;
case 'Z':
zero = atoi(optarg);
break;
case 'q':
ac3_config.flags |= AC3_QUIET;
out_config.quiet = 1;
quiet = 1;
break;
default:
fprintf(stderr, "\07Invalid switch or option needs an argument.\n");
morehelp++;
}
}
out_config.channels = ac3_config.num_output_ch;
if (morehelp) {
help();
return 1;
}
while (1) {
if (argc - optind <= 0) {
if (loop || end_flag)
break;
in_file = stdin;
} else {
in_file = fopen(argv[optind],"r");
if(!in_file) {
fprintf(stderr,"%s - Couldn't open file %s\n",strerror(errno),argv[optind]);
exit(EXIT_FAILURE);
}
optind++;
loop++;
}
if ((out_config.spdif == SPDIF_NONE) || (out_config.spdif == SPDIF_PCM)) {
ac3_frame_t *ac3_frame;
ac3_init(&ac3_config);
ac3_frame = ac3_decode_frame();
out_config.rate = ac3_frame->sampling_rate;
if (output_open(&out_config) < 0) {
fprintf(stderr, "Output open failed\n");
exit(EXIT_FAILURE);
}
signal(SIGINT, ac3dec_signal_handler);
signal(SIGTERM, ac3dec_signal_handler);
signal(SIGABRT, ac3dec_signal_handler);
do {
//Send the samples to the output device
output_play(ac3_frame->audio_data, 256 * 6);
} while((ac3_frame = ac3_decode_frame()));
} else {
uint_8 *start, *end;
init_spdif();
if (output_open(&out_config) < 0) {
fprintf(stderr, "Output open failed\n");
exit(EXIT_FAILURE);
}
signal(SIGINT, ac3dec_signal_handler);
signal(SIGTERM, ac3dec_signal_handler);
signal(SIGABRT, ac3dec_signal_handler);
if (zero > 0)
output_spdif_zero(zero);
else
output_spdif_leadin();
while (fill_buffer(&start, &end) > 0)
if (output_spdif(start, end, quiet) < 0)
break;
}
output_close();
fclose(in_file);
}
return EXIT_SUCCESS;
}

View file

@ -1,166 +0,0 @@
/***************************************************************************/
/* This code has been fully inspired from various place */
/* I will give their name later. May they be bless .... It works */
/* */
/* For the moment test it. */
/* */
/* 27-08-00 -- Ze'ev Maor -- fixed recovery from flase syncword detection */
/* */
/* 24-08-00 -- Ze'ev Maor -- Modified for integrtion with DXR3-OMS-plugin */
/***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <inttypes.h>
#include <libac3/ac3.h>
#include <libac3/ac3_internal.h>
#include <libac3/parse.h>
#include <libac3/crc.h>
#include "output.h"
void swab(const void*, void*, size_t);
#define BLOCK_SIZE 6144
static unsigned char buf[BLOCK_SIZE];
static uint32_t sbuffer_size;
static syncinfo_t syncinfo;
static char *sbuffer;
static int done_banner;
static uint32_t
buffer_syncframe(syncinfo_t *syncinfo, uint8_t **start, uint8_t *end)
{
uint8_t *cur = *start;
uint16_t syncword = syncinfo->syncword;
uint32_t ret = 0;
//
// Find an ac3 sync frame.
//
while(syncword != 0x0b77)
{
if(cur >= end)
goto done;
syncword = (syncword << 8) + *cur++;
}
//need the next 3 bytes to decide how big the frame is
while(sbuffer_size < 3)
{
if(cur >= end)
goto done;
sbuffer[sbuffer_size++] = *cur++;
}
parse_syncinfo_data(syncinfo,sbuffer);
while(sbuffer_size < (uint32_t)syncinfo->frame_size * 2 - 2)
{
if(cur >= end)
goto done;
sbuffer[sbuffer_size++] = *cur++;
}
crc_init();
crc_process_frame(sbuffer,syncinfo->frame_size * 2 - 2);
if(!crc_validate())
{
//error_flag = 1;
fprintf(stderr,"** CRC failed - skipping frame **\n");
syncword = 0xffff;
sbuffer_size = 0;
bzero(buf,BLOCK_SIZE);
goto done;
}
//
//if we got to this point, we found a valid ac3 frame to decode
//
//reset the syncword for next time
syncword = 0xffff;
sbuffer_size = 0;
ret = 1;
done:
syncinfo->syncword = syncword;
*start = cur;
return ret;
}
void
init_spdif(void)
{
sbuffer_size = 0;
sbuffer = &buf[10];
done_banner = 0;
}
int
output_spdif_zero(int frames)
{
int res;
buf[0] = 0x72; buf[1] = 0xf8; // spdif syncword
buf[2] = 0x1f; buf[3] = 0x4e; // ..............
buf[4] = 0x00; // null frame (no data)
buf[5] = 7 << 5; // stream = 7
buf[6] = 0x00; buf[7] = 0x00; // frame size
memset(&buf[8], 0, BLOCK_SIZE - 8);
while (frames-- > 0) {
res = output_play((short *)buf, BLOCK_SIZE / 2 / 2); /* 2 channels, 16-bit samples */
if (res < 0)
return res;
}
return 0;
}
int
output_spdif_leadin(void)
{
memset(buf, 0, 8);
return output_play((short *)buf, 8);
}
int
output_spdif(uint8_t *data_start, uint8_t *data_end, int quiet)
{
int ret = 0, res;
while(buffer_syncframe(&syncinfo, &data_start, data_end))
{
buf[0] = 0x72; buf[1] = 0xf8; // spdif syncword
buf[2] = 0x1f; buf[3] = 0x4e; // ..............
buf[4] = 0x01; // AC3 data
buf[5] = buf[13] & 7; // bsmod, stream = 0
buf[6] = (syncinfo.frame_size * 16) & 0xff;
buf[7] = ((syncinfo.frame_size * 16) >> 8) & 0xff;
buf[8] = 0x77; buf[9] = 0x0b; // AC3 syncwork
if (!done_banner && !quiet) {
fprintf(stdout,"AC3 Stream ");
fprintf(stdout,"%2.1f KHz",syncinfo.sampling_rate * 1e-3);
fprintf(stdout,"%4d kbps",syncinfo.bit_rate);
fprintf(stdout,"\n");
done_banner = 1;
}
#ifndef _a_b_c_d_e_f /* WORDS_BIGENDIAN */
// extract_ac3 seems to write swabbed data
swab(&buf[10], &buf[10], syncinfo.frame_size * 2 - 2);
#endif
res = output_play((short *)buf, BLOCK_SIZE / 2 / 2); /* 2 channels, 16-bit samples */
ret = ret < 0 ? ret : res;
bzero(buf,BLOCK_SIZE);
}
return ret;
}

View file

@ -1,55 +0,0 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
# This was lifted from the Gimp, and adapted slightly by
# Raph Levien .
DIE=0
PROG=ac3dec
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $PROG."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
# Do we really need libtool?
#(libtool --version) < /dev/null > /dev/null 2>&1 || {
# echo
# echo "You must have libtool installed to compile $PROG."
# echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2.tar.gz"
# echo "(or a newer version if it is available)"
# DIE=1
#}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile $PROG."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
for dir in .
do
echo processing $dir
(cd $dir; \
aclocalinclude="$ACLOCAL_FLAGS"; \
aclocal $aclocalinclude; \
autoheader; automake --foreign -a; autoconf)
done
./configure "$@"
echo
echo "Now type 'make' to compile $PROG."

View file

@ -1,30 +0,0 @@
dnl Autoconf configuration script ac3dec
dnl
dnl Aaron Holtzman - May 1999
dnl
AC_INIT(ac3dec.c)
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_HOST
AC_PREREQ(2.13)
AM_INIT_AUTOMAKE(ac3dec, 0.6.1)
AM_MAINTAINER_MODE
AC_PROG_CC
AC_PROG_GCC_TRADITIONAL
AC_PROG_RANLIB
AC_C_BIGENDIAN
AM_PATH_ALSA(1.0.0)
dnl Set the appropriate architecture define
dnl case "$host" in
dnl i?86-*) AC_DEFINE(__i386__, 1, [Using i386 architecture]);;
dnl alpha*-*) AC_DEFINE(__alpha__, 1, [Using Alpha architecture]);;
dnl sparc-*) AC_DEFINE(__sparc__, 1, [Using SPARC architecture]);;
dnl ppc-*|powerpc-*) AC_DEFINE(__ppc__, 1, [Using PowerPC architecture]);;
dnl ia64-*) AC_DEFINE(__ia64__, 1, [Using IA-64 architecture]);;
dnl *) echo "$host is not currently supported by ac3dec"; exit 1;;
dnl esac
AC_OUTPUT(libac3/Makefile tools/Makefile test/Makefile Makefile )

View file

@ -1,11 +0,0 @@
#!/bin/sh
aclocal $ACLOCAL_FLAGS || exit 1
autoheader || exit 1
automake --add-missing --copy --foreign || exit 1
touch depcomp || exit 1
autoconf || exit 1
./configure $* || exit 1
if [ -z "$GITCOMPILE_NO_MAKE" ]; then
make || exit 1
fi

View file

@ -1,15 +0,0 @@
# # Process this file with automake to produce Makefile.in.
AUTOMAKE_OPTIONS = 1.3 foreign
CFLAGS = -Wall -O1 -g
noinst_LIBRARIES = libac3.a
libac3_a_SOURCES = bitstream.c decode.c imdct.c coeff.c exponent.c stats.c\
bit_allocate.c parse.c crc.c debug.c rematrix.c downmix.c dither.c \
sanity_check.c
noinst_HEADERS = ac3_internal.h bitstream.h decode.h imdct.h ac3.h stats.h coeff.h\
exponent.h bit_allocate.h parse.h crc.h debug.h rematrix.h downmix.h dither.h \
sanity_check.h

View file

@ -1,63 +0,0 @@
/*
* ac3.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#ifndef AARONS_TYPES
#define AARONS_TYPES
typedef unsigned long long uint_64;
typedef unsigned int uint_32;
typedef unsigned short uint_16;
typedef unsigned char uint_8;
typedef signed long long sint_64;
typedef signed int sint_32;
typedef signed short sint_16;
typedef signed char sint_8;
#endif
#define AC3_DOLBY_SURR_ENABLE 0x1
#define AC3_3DNOW_ENABLE 0x2
#define AC3_MMX_ENABLE 0x4
#define AC3_ALTIVEC_ENABLE 0x8
#define AC3_QUIET 0x10
typedef struct ac3_config_s
{
//Bit flags that enable various things
uint_32 flags;
//Callback that points the decoder to new stream data
ssize_t (*fill_buffer_callback)(uint_8 **, uint_8 **);
//Number of discrete channels in final output (for downmixing)
uint_16 num_output_ch;
//Which channel of a dual mono stream to select
uint_16 dual_mono_ch_sel;
} ac3_config_t;
typedef struct ac3_frame_s
{
uint_32 sampling_rate;
sint_16 *audio_data;
} ac3_frame_t;
void ac3_init(ac3_config_t *config);
ac3_frame_t* ac3_decode_frame(void);

View file

@ -1,344 +0,0 @@
/*
* ac3_internal.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __GNUC__
#define inline
#endif
/* Exponent strategy constants */
#define EXP_REUSE (0)
#define EXP_D15 (1)
#define EXP_D25 (2)
#define EXP_D45 (3)
/* Delta bit allocation constants */
#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1)
#define DELTA_BIT_NONE (2)
#define DELTA_BIT_RESERVED (3)
/* samples work structure */
typedef float stream_samples_t[6][256];
/* global config structure */
extern ac3_config_t ac3_config;
/* global error flag */
extern uint_32 error_flag;
/* Everything you wanted to know about band structure */
/*
* The entire frequency domain is represented by 256 real
* floating point fourier coefficients. Only the lower 253
* coefficients are actually utilized however. We use arrays
* of 256 to be efficient in some cases.
*
* The 5 full bandwidth channels (fbw) can have their higher
* frequencies coupled together. These coupled channels then
* share their high frequency components.
*
* This coupling band is broken up into 18 sub-bands starting
* at mantissa number 37. Each sub-band is 12 bins wide.
*
* There are 50 bit allocation sub-bands which cover the entire
* frequency range. The sub-bands are of non-uniform width, and
* approximate a 1/6 octave scale.
*/
/* The following structures are filled in by their corresponding parse_*
* functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
* full details on each field. Indented fields are used to denote
* conditional fields.
*/
typedef struct syncinfo_s
{
uint_32 magic;
/* Sync word == 0x0B77 */
uint_16 syncword;
/* crc for the first 5/8 of the sync block */
/* uint_16 crc1; */
/* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
uint_16 fscod;
/* Frame size code */
uint_16 frmsizecod;
/* Information not in the AC-3 bitstream, but derived */
/* Frame size in 16 bit words */
uint_16 frame_size;
/* Bit rate in kilobits */
uint_16 bit_rate;
/* sampling rate in hertz */
uint_32 sampling_rate;
} syncinfo_t;
typedef struct bsi_s
{
uint_32 magic;
/* Bit stream identification == 0x8 */
uint_16 bsid;
/* Bit stream mode */
uint_16 bsmod;
/* Audio coding mode */
uint_16 acmod;
/* If we're using the centre channel then */
/* centre mix level */
uint_16 cmixlev;
/* If we're using the surround channel then */
/* surround mix level */
uint_16 surmixlev;
/* If we're in 2/0 mode then */
/* Dolby surround mix level - NOT USED - */
uint_16 dsurmod;
/* Low frequency effects on */
uint_16 lfeon;
/* Dialogue Normalization level */
uint_16 dialnorm;
/* Compression exists */
uint_16 compre;
/* Compression level */
uint_16 compr;
/* Language code exists */
uint_16 langcode;
/* Language code */
uint_16 langcod;
/* Audio production info exists*/
uint_16 audprodie;
uint_16 mixlevel;
uint_16 roomtyp;
/* If we're in dual mono mode (acmod == 0) then extra stuff */
uint_16 dialnorm2;
uint_16 compr2e;
uint_16 compr2;
uint_16 langcod2e;
uint_16 langcod2;
uint_16 audprodi2e;
uint_16 mixlevel2;
uint_16 roomtyp2;
/* Copyright bit */
uint_16 copyrightb;
/* Original bit */
uint_16 origbs;
/* Timecode 1 exists */
uint_16 timecod1e;
/* Timecode 1 */
uint_16 timecod1;
/* Timecode 2 exists */
uint_16 timecod2e;
/* Timecode 2 */
uint_16 timecod2;
/* Additional bit stream info exists */
uint_16 addbsie;
/* Additional bit stream length - 1 (in bytes) */
uint_16 addbsil;
/* Additional bit stream information (max 64 bytes) */
uint_8 addbsi[64];
/* Information not in the AC-3 bitstream, but derived */
/* Number of channels (excluding LFE)
* Derived from acmod */
uint_16 nfchans;
} bsi_t;
/* more pain */
typedef struct audblk_s
{
uint_32 magic1;
/* block switch bit indexed by channel num */
uint_16 blksw[5];
/* dither enable bit indexed by channel num */
uint_16 dithflag[5];
/* dynamic range gain exists */
uint_16 dynrnge;
/* dynamic range gain */
uint_16 dynrng;
/* if acmod==0 then */
/* dynamic range 2 gain exists */
uint_16 dynrng2e;
/* dynamic range 2 gain */
uint_16 dynrng2;
/* coupling strategy exists */
uint_16 cplstre;
/* coupling in use */
uint_16 cplinu;
/* channel coupled */
uint_16 chincpl[5];
/* if acmod==2 then */
/* Phase flags in use */
uint_16 phsflginu;
/* coupling begin frequency code */
uint_16 cplbegf;
/* coupling end frequency code */
uint_16 cplendf;
/* coupling band structure bits */
uint_16 cplbndstrc[18];
/* Do coupling co-ords exist for this channel? */
uint_16 cplcoe[5];
/* Master coupling co-ordinate */
uint_16 mstrcplco[5];
/* Per coupling band coupling co-ordinates */
uint_16 cplcoexp[5][18];
uint_16 cplcomant[5][18];
/* Phase flags for dual mono */
uint_16 phsflg[18];
/* Is there a rematrixing strategy */
uint_16 rematstr;
/* Rematrixing bits */
uint_16 rematflg[4];
/* Coupling exponent strategy */
uint_16 cplexpstr;
/* Exponent strategy for full bandwidth channels */
uint_16 chexpstr[5];
/* Exponent strategy for lfe channel */
uint_16 lfeexpstr;
/* Channel bandwidth for independent channels */
uint_16 chbwcod[5];
/* The absolute coupling exponent */
uint_16 cplabsexp;
/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
uint_16 cplexps[18 * 12 / 3];
/* Sanity checking constant */
uint_32 magic2;
/* fbw channel exponents */
uint_16 exps[5][252 / 3];
/* channel gain range */
uint_16 gainrng[5];
/* low frequency exponents */
uint_16 lfeexps[3];
/* Bit allocation info */
uint_16 baie;
/* Slow decay code */
uint_16 sdcycod;
/* Fast decay code */
uint_16 fdcycod;
/* Slow gain code */
uint_16 sgaincod;
/* dB per bit code */
uint_16 dbpbcod;
/* masking floor code */
uint_16 floorcod;
/* SNR offset info */
uint_16 snroffste;
/* coarse SNR offset */
uint_16 csnroffst;
/* coupling fine SNR offset */
uint_16 cplfsnroffst;
/* coupling fast gain code */
uint_16 cplfgaincod;
/* fbw fine SNR offset */
uint_16 fsnroffst[5];
/* fbw fast gain code */
uint_16 fgaincod[5];
/* lfe fine SNR offset */
uint_16 lfefsnroffst;
/* lfe fast gain code */
uint_16 lfefgaincod;
/* Coupling leak info */
uint_16 cplleake;
/* coupling fast leak initialization */
uint_16 cplfleak;
/* coupling slow leak initialization */
uint_16 cplsleak;
/* delta bit allocation info */
uint_16 deltbaie;
/* coupling delta bit allocation exists */
uint_16 cpldeltbae;
/* fbw delta bit allocation exists */
uint_16 deltbae[5];
/* number of cpl delta bit segments */
uint_16 cpldeltnseg;
/* coupling delta bit allocation offset */
uint_16 cpldeltoffst[8];
/* coupling delta bit allocation length */
uint_16 cpldeltlen[8];
/* coupling delta bit allocation length */
uint_16 cpldeltba[8];
/* number of delta bit segments */
uint_16 deltnseg[5];
/* fbw delta bit allocation offset */
uint_16 deltoffst[5][8];
/* fbw delta bit allocation length */
uint_16 deltlen[5][8];
/* fbw delta bit allocation length */
uint_16 deltba[5][8];
/* skip length exists */
uint_16 skiple;
/* skip length */
uint_16 skipl;
//Removed Feb 2000 -ah
/* channel mantissas */
//uint_16 chmant[5][256];
/* coupling mantissas */
uint_16 cplmant[256];
//Removed Feb 2000 -ah
/* coupling mantissas */
//uint_16 lfemant[7];
/* -- Information not in the bitstream, but derived thereof -- */
/* Number of coupling sub-bands */
uint_16 ncplsubnd;
/* Number of combined coupling sub-bands
* Derived from ncplsubnd and cplbndstrc */
uint_16 ncplbnd;
/* Number of exponent groups by channel
* Derived from strmant, endmant */
uint_16 nchgrps[5];
/* Number of coupling exponent groups
* Derived from cplbegf, cplendf, cplexpstr */
uint_16 ncplgrps;
/* End mantissa numbers of fbw channels */
uint_16 endmant[5];
/* Start and end mantissa numbers for the coupling channel */
uint_16 cplstrtmant;
uint_16 cplendmant;
/* Decoded exponent info */
uint_16 fbw_exp[5][256];
uint_16 cpl_exp[256];
uint_16 lfe_exp[7];
/* Bit allocation pointer results */
uint_16 fbw_bap[5][256];
uint_16 cpl_bap[256];
uint_16 lfe_bap[7];
uint_32 magic3;
} audblk_t;

View file

@ -1,494 +0,0 @@
/*
* bit_allocate.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <string.h>
#include "ac3.h"
#include "ac3_internal.h"
static inline sint_16 logadd(sint_16 a,sint_16 b);
static sint_16 calc_lowcomp(sint_16 a,sint_16 b0,sint_16 b1,sint_16 bin);
static inline uint_16 min(sint_16 a,sint_16 b);
static inline uint_16 max(sint_16 a,sint_16 b);
static void ba_compute_psd(sint_16 start, sint_16 end, sint_16 exps[],
sint_16 psd[], sint_16 bndpsd[]);
static void ba_compute_excitation(sint_16 start, sint_16 end,sint_16 fgain,
sint_16 fastleak, sint_16 slowleak, sint_16 is_lfe, sint_16 bndpsd[],
sint_16 excite[]);
static void ba_compute_mask(sint_16 start, sint_16 end, uint_16 fscod,
uint_16 deltbae, uint_16 deltnseg, uint_16 deltoffst[], uint_16 deltba[],
uint_16 deltlen[], sint_16 excite[], sint_16 mask[]);
static void ba_compute_bap(sint_16 start, sint_16 end, sint_16 snroffset,
sint_16 psd[], sint_16 mask[], sint_16 bap[]);
/* Misc LUTs for bit allocation process */
static sint_16 slowdec[] = { 0x0f, 0x11, 0x13, 0x15 };
static sint_16 fastdec[] = { 0x3f, 0x53, 0x67, 0x7b };
static sint_16 slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 };
static sint_16 dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 };
static uint_16 floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
static sint_16 fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
static sint_16 bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
34, 37, 40, 43, 46, 49, 55, 61, 67, 73,
79, 85, 97, 109, 121, 133, 157, 181, 205, 229 };
static sint_16 bndsz[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
6, 12, 12, 12, 12, 24, 24, 24, 24, 24 };
static sint_16 masktab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29,
29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34,
34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37,
37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0 };
static sint_16 latab[] = { 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000};
static sint_16 hth[][50] = {{ 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0,
0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390,
0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350,
0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0,
0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420,
0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800,
0x0840, 0x0840 },
{ 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0,
0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390,
0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360,
0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0,
0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0,
0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630,
0x0840, 0x0840 },
{ 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0,
0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0,
0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390,
0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330,
0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310,
0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440,
0x0450, 0x04e0 }};
static sint_16 baptab[] = { 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10,
10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
static sint_16 sdecay;
static sint_16 fdecay;
static sint_16 sgain;
static sint_16 dbknee;
static sint_16 floor;
static sint_16 psd[256];
static sint_16 bndpsd[256];
static sint_16 excite[256];
static sint_16 mask[256];
static inline uint_16
max(sint_16 a,sint_16 b)
{
return (a > b ? a : b);
}
static inline uint_16
min(sint_16 a,sint_16 b)
{
return (a < b ? a : b);
}
static inline sint_16
logadd(sint_16 a,sint_16 b)
{
sint_16 c;
sint_16 address;
c = a - b;
address = min((abs(c) >> 1), 255);
if (c >= 0)
return(a + latab[address]);
else
return(b + latab[address]);
}
void bit_allocate(uint_16 fscod, bsi_t *bsi, audblk_t *audblk)
{
uint_16 i;
sint_16 fgain;
sint_16 snroffset;
sint_16 start;
sint_16 end;
sint_16 fastleak;
sint_16 slowleak;
/* Only perform bit_allocation if the exponents have changed or we
* have new sideband information */
if (audblk->chexpstr[0] == 0 && audblk->chexpstr[1] == 0 &&
audblk->chexpstr[2] == 0 && audblk->chexpstr[3] == 0 &&
audblk->chexpstr[4] == 0 && audblk->cplexpstr == 0 &&
audblk->lfeexpstr == 0 && audblk->baie == 0 &&
audblk->snroffste == 0 && audblk->deltbaie == 0)
return;
/* Do some setup before we do the bit alloc */
sdecay = slowdec[audblk->sdcycod];
fdecay = fastdec[audblk->fdcycod];
sgain = slowgain[audblk->sgaincod];
dbknee = dbpbtab[audblk->dbpbcod];
floor = floortab[audblk->floorcod];
/* if all the SNR offset constants are zero then the whole block is zero */
if(!audblk->csnroffst && !audblk->fsnroffst[0] &&
!audblk->fsnroffst[1] && !audblk->fsnroffst[2] &&
!audblk->fsnroffst[3] && !audblk->fsnroffst[4] &&
!audblk->cplfsnroffst && !audblk->lfefsnroffst)
{
memset(audblk->fbw_bap,0,sizeof(uint_16) * 256 * 5);
memset(audblk->cpl_bap,0,sizeof(uint_16) * 256);
memset(audblk->lfe_bap,0,sizeof(uint_16) * 7);
return;
}
for(i = 0; i < bsi->nfchans; i++)
{
start = 0;
end = audblk->endmant[i] ;
fgain = fastgain[audblk->fgaincod[i]];
snroffset = (((audblk->csnroffst - 15) << 4) + audblk->fsnroffst[i]) << 2 ;
fastleak = 0;
slowleak = 0;
ba_compute_psd(start, end, audblk->fbw_exp[i], psd, bndpsd);
ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite);
ba_compute_mask(start, end, fscod, audblk->deltbae[i], audblk->deltnseg[i],
audblk->deltoffst[i], audblk->deltba[i], audblk->deltlen[i], excite, mask);
ba_compute_bap(start, end, snroffset, psd, mask, audblk->fbw_bap[i]);
}
if(audblk->cplinu)
{
start = audblk->cplstrtmant;
end = audblk->cplendmant;
fgain = fastgain[audblk->cplfgaincod];
snroffset = (((audblk->csnroffst - 15) << 4) + audblk->cplfsnroffst) << 2 ;
fastleak = (audblk->cplfleak << 8) + 768;
slowleak = (audblk->cplsleak << 8) + 768;
ba_compute_psd(start, end, audblk->cpl_exp, psd, bndpsd);
ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite);
ba_compute_mask(start, end, fscod, audblk->cpldeltbae, audblk->cpldeltnseg,
audblk->cpldeltoffst, audblk->cpldeltba, audblk->cpldeltlen, excite, mask);
ba_compute_bap(start, end, snroffset, psd, mask, audblk->cpl_bap);
}
if(bsi->lfeon)
{
start = 0;
end = 7;
fgain = fastgain[audblk->lfefgaincod];
snroffset = (((audblk->csnroffst - 15) << 4) + audblk->lfefsnroffst) << 2 ;
fastleak = 0;
slowleak = 0;
ba_compute_psd(start, end, audblk->lfe_exp, psd, bndpsd);
ba_compute_excitation(start, end , fgain, fastleak, slowleak, 1, bndpsd, excite);
/* Perform no delta bit allocation for lfe */
ba_compute_mask(start, end, fscod, 2, 0, 0, 0, 0, excite, mask);
ba_compute_bap(start, end, snroffset, psd, mask, audblk->lfe_bap);
}
}
static void ba_compute_psd(sint_16 start, sint_16 end, sint_16 exps[],
sint_16 psd[], sint_16 bndpsd[])
{
int bin,i,j,k;
sint_16 lastbin = 0;
/* Map the exponents into dBs */
for (bin=start; bin<end; bin++)
{
psd[bin] = (3072 - (exps[bin] << 7));
}
/* Integrate the psd function over each bit allocation band */
j = start;
k = masktab[start];
do
{
lastbin = min(bndtab[k] + bndsz[k], end);
bndpsd[k] = psd[j];
j++;
for (i = j; i < lastbin; i++)
{
bndpsd[k] = logadd(bndpsd[k], psd[j]);
j++;
}
k++;
} while (end > lastbin);
}
static void ba_compute_excitation(sint_16 start, sint_16 end,sint_16 fgain,
sint_16 fastleak, sint_16 slowleak, sint_16 is_lfe, sint_16 bndpsd[],
sint_16 excite[])
{
int bin;
sint_16 bndstrt;
sint_16 bndend;
sint_16 lowcomp = 0;
sint_16 begin = 0;
/* Compute excitation function */
bndstrt = masktab[start];
bndend = masktab[end - 1] + 1;
if (bndstrt == 0) /* For fbw and lfe channels */
{
lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0);
excite[0] = bndpsd[0] - fgain - lowcomp;
lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1);
excite[1] = bndpsd[1] - fgain - lowcomp;
begin = 7 ;
/* Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin = 6) */
for (bin = 2; bin < 7; bin++)
{
if (!(is_lfe && (bin == 6)))
lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
fastleak = bndpsd[bin] - fgain;
slowleak = bndpsd[bin] - sgain;
excite[bin] = fastleak - lowcomp;
if (!(is_lfe && (bin == 6)))
{
if (bndpsd[bin] <= bndpsd[bin+1])
{
begin = bin + 1 ;
break;
}
}
}
for (bin = begin; bin < min(bndend, 22); bin++)
{
if (!(is_lfe && (bin == 6)))
lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
fastleak -= fdecay ;
fastleak = max(fastleak, bndpsd[bin] - fgain);
slowleak -= sdecay ;
slowleak = max(slowleak, bndpsd[bin] - sgain);
excite[bin] = max(fastleak - lowcomp, slowleak);
}
begin = 22;
}
else /* For coupling channel */
{
begin = bndstrt;
}
for (bin = begin; bin < bndend; bin++)
{
fastleak -= fdecay;
fastleak = max(fastleak, bndpsd[bin] - fgain);
slowleak -= sdecay;
slowleak = max(slowleak, bndpsd[bin] - sgain);
excite[bin] = max(fastleak, slowleak) ;
}
}
static void ba_compute_mask(sint_16 start, sint_16 end, uint_16 fscod,
uint_16 deltbae, uint_16 deltnseg, uint_16 deltoffst[], uint_16 deltba[],
uint_16 deltlen[], sint_16 excite[], sint_16 mask[])
{
int bin,k;
sint_16 bndstrt;
sint_16 bndend;
sint_16 delta;
bndstrt = masktab[start];
bndend = masktab[end - 1] + 1;
/* Compute the masking curve */
for (bin = bndstrt; bin < bndend; bin++)
{
if (bndpsd[bin] < dbknee)
{
excite[bin] += ((dbknee - bndpsd[bin]) >> 2);
}
mask[bin] = max(excite[bin], hth[fscod][bin]);
}
/* Perform delta bit modulation if necessary */
if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW))
{
sint_16 band = 0;
sint_16 seg = 0;
for (seg = 0; seg < deltnseg+1; seg++)
{
band += deltoffst[seg];
if (deltba[seg] >= 4)
{
delta = (deltba[seg] - 3) << 7;
}
else
{
delta = (deltba[seg] - 4) << 7;
}
for (k = 0; k < deltlen[seg]; k++)
{
mask[band] += delta;
band++;
}
}
}
}
static void ba_compute_bap(sint_16 start, sint_16 end, sint_16 snroffset,
sint_16 psd[], sint_16 mask[], sint_16 bap[])
{
int i,j,k;
sint_16 lastbin = 0;
sint_16 address = 0;
/* Compute the bit allocation pointer for each bin */
i = start;
j = masktab[start];
do
{
lastbin = min(bndtab[j] + bndsz[j], end);
mask[j] -= snroffset;
mask[j] -= floor;
if (mask[j] < 0)
mask[j] = 0;
mask[j] &= 0x1fe0;
mask[j] += floor;
for (k = i; k < lastbin; k++)
{
address = (psd[i] - mask[j]) >> 5;
address = min(63, max(0, address));
bap[i] = baptab[address];
i++;
}
j++;
} while (end > lastbin);
}
static sint_16
calc_lowcomp(sint_16 a,sint_16 b0,sint_16 b1,sint_16 bin)
{
if (bin < 7)
{
if ((b0 + 256) == b1)
a = 384;
else if (b0 > b1)
a = max(0, a - 64);
}
else if (bin < 20)
{
if ((b0 + 256) == b1)
a = 320;
else if (b0 > b1)
a = max(0, a - 64) ;
}
else
a = max(0, a - 128);
return(a);
}

View file

@ -1,24 +0,0 @@
/*
* bit_allocate.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
void bit_allocate(uint_16 fscod, bsi_t *bsi, audblk_t *audblk);

View file

@ -1,133 +0,0 @@
/*
* bitstream.c
*
* Copyright (C) Aaron Holtzman - Dec 1999
*
* This file is part of ac3dec, a free AC-3 audio decoder
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
#define BUFFER_SIZE 4096
static uint_8 buffer[BUFFER_SIZE];
static uint_32 *buffer_start, *buffer_end;
static uint_8 *chunk_start, *chunk_end;
uint_32 bits_left;
uint_32 current_word;
ssize_t (*bitstream_fill_buffer)(uint_8**,uint_8**);
int bitstream_get_byte(void)
{
if(chunk_start == chunk_end)
if (bitstream_fill_buffer(&chunk_start,&chunk_end) <= 0)
return EOF;
return (*chunk_start++);
}
uint_8 *bitstream_get_buffer_start(void)
{
return (uint_8 *) buffer_start;
}
int
bitstream_buffer_frame(uint_32 frame_size)
{
uint_32 bytes_read;
uint_32 num_bytes;
bytes_read = 0;
do
{
if(chunk_start > chunk_end)
printf("argh!\n");
if(chunk_start == chunk_end)
if (bitstream_fill_buffer(&chunk_start,&chunk_end) <= 0)
return EOF;
num_bytes = chunk_end - chunk_start;
if(bytes_read + num_bytes > frame_size)
num_bytes = frame_size - bytes_read;
memcpy(&buffer[bytes_read], chunk_start, num_bytes);
bytes_read += num_bytes;
chunk_start += num_bytes;
}
while (bytes_read != frame_size);
buffer_start = (uint_32 *) buffer;
buffer_end = (uint_32 *) (buffer + frame_size);
bits_left = 0;
return 0;
}
static inline void
bitstream_fill_current()
{
current_word = *buffer_start++;
current_word = swab32(current_word);
}
//
// The fast paths for _get is in the
// bitstream.h header file so it can be inlined.
//
// The "bottom half" of this routine is suffixed _bh
//
// -ah
//
uint_32
bitstream_get_bh(uint_32 num_bits)
{
uint_32 result;
num_bits -= bits_left;
result = (current_word << (32 - bits_left)) >> (32 - bits_left);
bitstream_fill_current();
if(num_bits != 0)
result = (result << num_bits) | (current_word >> (32 - num_bits));
bits_left = 32 - num_bits;
return result;
}
void
bitstream_init(ssize_t(*fill_function)(uint_8**,uint_8**))
{
// Setup the buffer fill callback
bitstream_fill_buffer = fill_function;
}

View file

@ -1,76 +0,0 @@
/*
* bitstream.h
*
* Copyright (C) Aaron Holtzman - Dec 1999
*
* This file is part of ac3dec, a free AC-3 audio decoder
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
//My new and improved vego-matic endian swapping routine
//(stolen from the kernel)
#ifdef WORDS_BIGENDIAN
# define swab32(x) (x)
#else
# if defined (__i386__)
# define swab32(x) __i386_swab32(x)
static inline uint_32 __i386_swab32(uint_32 x)
{
__asm__("bswap %0" : "=r" (x) : "0" (x));
return x;
}
# else
# define swab32(x)\
((((uint_8*)&x)[0] << 24) | (((uint_8*)&x)[1] << 16) | \
(((uint_8*)&x)[2] << 8) | (((uint_8*)&x)[3]))
# endif
#endif
extern uint_32 bits_left;
extern uint_32 current_word;
void bitstream_init(ssize_t(*fill_function)(uint_8**,uint_8**));
int bitstream_get_byte(void);
uint_8 *bitstream_get_buffer_start(void);
int bitstream_buffer_frame(uint_32 frame_size);
uint_32 bitstream_get_bh(uint_32 num_bits);
static inline uint_32
bitstream_get(uint_32 num_bits)
{
uint_32 result;
if(num_bits < bits_left)
{
result = (current_word << (32 - bits_left)) >> (32 - num_bits);
bits_left -= num_bits;
return result;
}
return bitstream_get_bh(num_bits);
}

View file

@ -1,353 +0,0 @@
/*
* coeff.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "decode.h"
#include "bitstream.h"
#include "dither.h"
#include "coeff.h"
//
//Lookup tables of 0.15 two's complement quantization values
//
static const uint_16 q_1[3] =
{
( -2 << 15)/3, 0,( 2 << 15)/3
};
static const uint_16 q_2[5] =
{
( -4 << 15)/5,( -2 << 15)/5, 0,
( 2 << 15)/5,( 4 << 15)/5
};
static const uint_16 q_3[7] =
{
( -6 << 15)/7,( -4 << 15)/7,( -2 << 15)/7, 0,
( 2 << 15)/7,( 4 << 15)/7,( 6 << 15)/7
};
static const uint_16 q_4[11] =
{
(-10 << 15)/11,(-8 << 15)/11,(-6 << 15)/11, ( -4 << 15)/11,(-2 << 15)/11, 0,
( 2 << 15)/11,( 4 << 15)/11,( 6 << 15)/11, ( 8 << 15)/11,(10 << 15)/11
};
static const uint_16 q_5[15] =
{
(-14 << 15)/15,(-12 << 15)/15,(-10 << 15)/15,
( -8 << 15)/15,( -6 << 15)/15,( -4 << 15)/15,
( -2 << 15)/15, 0 ,( 2 << 15)/15,
( 4 << 15)/15,( 6 << 15)/15,( 8 << 15)/15,
( 10 << 15)/15,( 12 << 15)/15,( 14 << 15)/15
};
//
// Scale factors for convert_to_float
//
static const uint_32 u32_scale_factors[25] =
{
0x38000000, //2 ^ -(0 + 15)
0x37800000, //2 ^ -(1 + 15)
0x37000000, //2 ^ -(2 + 15)
0x36800000, //2 ^ -(3 + 15)
0x36000000, //2 ^ -(4 + 15)
0x35800000, //2 ^ -(5 + 15)
0x35000000, //2 ^ -(6 + 15)
0x34800000, //2 ^ -(7 + 15)
0x34000000, //2 ^ -(8 + 15)
0x33800000, //2 ^ -(9 + 15)
0x33000000, //2 ^ -(10 + 15)
0x32800000, //2 ^ -(11 + 15)
0x32000000, //2 ^ -(12 + 15)
0x31800000, //2 ^ -(13 + 15)
0x31000000, //2 ^ -(14 + 15)
0x30800000, //2 ^ -(15 + 15)
0x30000000, //2 ^ -(16 + 15)
0x2f800000, //2 ^ -(17 + 15)
0x2f000000, //2 ^ -(18 + 15)
0x2e800000, //2 ^ -(19 + 15)
0x2e000000, //2 ^ -(20 + 15)
0x2d800000, //2 ^ -(21 + 15)
0x2d000000, //2 ^ -(22 + 15)
0x2c800000, //2 ^ -(23 + 15)
0x2c000000 //2 ^ -(24 + 15)
};
static float *scale_factor = (float*)u32_scale_factors;
//These store the persistent state of the packed mantissas
static uint_16 m_1[3];
static uint_16 m_2[3];
static uint_16 m_4[2];
static uint_16 m_1_pointer;
static uint_16 m_2_pointer;
static uint_16 m_4_pointer;
//Conversion from bap to number of bits in the mantissas
//zeros account for cases 0,1,2,4 which are special cased
static uint_16 qnttztab[16] = { 0, 0, 0, 3, 0 , 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16};
static void coeff_reset(void);
static sint_16 coeff_get_mantissa(uint_16 bap, uint_16 dithflag);
static void coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint_32 ch);
//
// Convert a 0.15 fixed point number into IEEE single
// precision floating point and scale by 2^-exp
//
static inline float
convert_to_float(uint_16 exp, sint_16 mantissa)
{
float x;
//the scale by 2^-15 is built into the scale factor table
x = mantissa * scale_factor[exp];
return x;
}
void
coeff_unpack(bsi_t *bsi, audblk_t *audblk, stream_samples_t samples)
{
uint_16 i,j;
uint_32 done_cpl = 0;
sint_16 mantissa;
coeff_reset();
for(i=0; i< bsi->nfchans; i++)
{
for(j=0; j < audblk->endmant[i]; j++)
{
mantissa = coeff_get_mantissa(audblk->fbw_bap[i][j],audblk->dithflag[i]);
samples[i][j] = convert_to_float(audblk->fbw_exp[i][j],mantissa);
}
if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl))
{
// ncplmant is equal to 12 * ncplsubnd
// Don't dither coupling channel until channel separation so that
// interchannel noise is uncorrelated
for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++)
audblk->cplmant[j] = coeff_get_mantissa(audblk->cpl_bap[j],0);
done_cpl = 1;
}
}
//uncouple the channel if necessary
if(audblk->cplinu)
{
for(i=0; i< bsi->nfchans; i++)
{
if(audblk->chincpl[i])
coeff_uncouple_ch(samples[i],bsi,audblk,i);
}
}
if(bsi->lfeon)
{
// There are always 7 mantissas for lfe, no dither for lfe
for(j=0; j < 7 ; j++)
{
mantissa = coeff_get_mantissa(audblk->lfe_bap[j],0);
samples[5][j] = convert_to_float(audblk->lfe_exp[j],mantissa);
}
}
}
//
//Fetch a mantissa from the bitstream
//
//The mantissa returned is a signed 0.15 fixed point number
//
static sint_16
coeff_get_mantissa(uint_16 bap, uint_16 dithflag)
{
uint_16 mantissa;
uint_16 group_code;
//If the bap is 0-5 then we have special cases to take care of
switch(bap)
{
case 0:
if(dithflag)
mantissa = dither_gen();
else
mantissa = 0;
break;
case 1:
if(m_1_pointer > 2)
{
group_code = bitstream_get(5);
if(group_code > 26)
goto error;
m_1[0] = group_code / 9;
m_1[1] = (group_code % 9) / 3;
m_1[2] = (group_code % 9) % 3;
m_1_pointer = 0;
}
mantissa = m_1[m_1_pointer++];
mantissa = q_1[mantissa];
break;
case 2:
if(m_2_pointer > 2)
{
group_code = bitstream_get(7);
if(group_code > 124)
goto error;
m_2[0] = group_code / 25;
m_2[1] = (group_code % 25) / 5 ;
m_2[2] = (group_code % 25) % 5 ;
m_2_pointer = 0;
}
mantissa = m_2[m_2_pointer++];
mantissa = q_2[mantissa];
break;
case 3:
mantissa = bitstream_get(3);
if(mantissa > 6)
goto error;
mantissa = q_3[mantissa];
break;
case 4:
if(m_4_pointer > 1)
{
group_code = bitstream_get(7);
if(group_code > 120)
goto error;
m_4[0] = group_code / 11;
m_4[1] = group_code % 11;
m_4_pointer = 0;
}
mantissa = m_4[m_4_pointer++];
mantissa = q_4[mantissa];
break;
case 5:
mantissa = bitstream_get(4);
if(mantissa > 14)
goto error;
mantissa = q_5[mantissa];
break;
default:
mantissa = bitstream_get(qnttztab[bap]);
mantissa <<= 16 - qnttztab[bap];
}
return mantissa;
error:
if(!error_flag)
fprintf(stderr,"** Invalid mantissa - skipping frame **\n");
error_flag = 1;
return 0;
}
//
// Reset the mantissa state
//
static void
coeff_reset(void)
{
m_1[2] = m_1[1] = m_1[0] = 0;
m_2[2] = m_2[1] = m_2[0] = 0;
m_4[1] = m_4[0] = 0;
m_1_pointer = m_2_pointer = m_4_pointer = 3;
}
//
// Uncouple the coupling channel into a fbw channel
//
static void
coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint_32 ch)
{
uint_32 bnd = 0;
uint_32 sub_bnd = 0;
uint_32 i,j;
float cpl_coord = 1.0;
uint_32 cpl_exp_tmp;
uint_32 cpl_mant_tmp;
sint_16 mantissa;
for(i=audblk->cplstrtmant;i<audblk->cplendmant;)
{
if(!audblk->cplbndstrc[sub_bnd++])
{
cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch];
if(audblk->cplcoexp[ch][bnd] == 15)
cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11;
else
cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10;
cpl_coord = convert_to_float(cpl_exp_tmp,cpl_mant_tmp) * 8.0f;
//Invert the phase for the right channel if necessary
if(bsi->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd])
cpl_coord *= -1;
bnd++;
}
for(j=0;j < 12; j++)
{
//Get new dither values for each channel if necessary, so
//the channels are uncorrelated
if(audblk->dithflag[ch] && audblk->cpl_bap[i] == 0)
mantissa = dither_gen();
else
mantissa = audblk->cplmant[i];
samples[i] = cpl_coord * convert_to_float(audblk->cpl_exp[i],mantissa);
i++;
}
}
}

View file

@ -1,24 +0,0 @@
/*
* coeff.h
*
* Copyright (C) Aaron Holtzman - Feb 2000
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
void coeff_unpack(bsi_t *bsi, audblk_t *audblk,stream_samples_t samples);

View file

@ -1,96 +0,0 @@
/*
* crc.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include <sys/time.h>
#include "crc.h"
static const uint_16 crc_lut[256] =
{
0x0000,0x8005,0x800f,0x000a,0x801b,0x001e,0x0014,0x8011,
0x8033,0x0036,0x003c,0x8039,0x0028,0x802d,0x8027,0x0022,
0x8063,0x0066,0x006c,0x8069,0x0078,0x807d,0x8077,0x0072,
0x0050,0x8055,0x805f,0x005a,0x804b,0x004e,0x0044,0x8041,
0x80c3,0x00c6,0x00cc,0x80c9,0x00d8,0x80dd,0x80d7,0x00d2,
0x00f0,0x80f5,0x80ff,0x00fa,0x80eb,0x00ee,0x00e4,0x80e1,
0x00a0,0x80a5,0x80af,0x00aa,0x80bb,0x00be,0x00b4,0x80b1,
0x8093,0x0096,0x009c,0x8099,0x0088,0x808d,0x8087,0x0082,
0x8183,0x0186,0x018c,0x8189,0x0198,0x819d,0x8197,0x0192,
0x01b0,0x81b5,0x81bf,0x01ba,0x81ab,0x01ae,0x01a4,0x81a1,
0x01e0,0x81e5,0x81ef,0x01ea,0x81fb,0x01fe,0x01f4,0x81f1,
0x81d3,0x01d6,0x01dc,0x81d9,0x01c8,0x81cd,0x81c7,0x01c2,
0x0140,0x8145,0x814f,0x014a,0x815b,0x015e,0x0154,0x8151,
0x8173,0x0176,0x017c,0x8179,0x0168,0x816d,0x8167,0x0162,
0x8123,0x0126,0x012c,0x8129,0x0138,0x813d,0x8137,0x0132,
0x0110,0x8115,0x811f,0x011a,0x810b,0x010e,0x0104,0x8101,
0x8303,0x0306,0x030c,0x8309,0x0318,0x831d,0x8317,0x0312,
0x0330,0x8335,0x833f,0x033a,0x832b,0x032e,0x0324,0x8321,
0x0360,0x8365,0x836f,0x036a,0x837b,0x037e,0x0374,0x8371,
0x8353,0x0356,0x035c,0x8359,0x0348,0x834d,0x8347,0x0342,
0x03c0,0x83c5,0x83cf,0x03ca,0x83db,0x03de,0x03d4,0x83d1,
0x83f3,0x03f6,0x03fc,0x83f9,0x03e8,0x83ed,0x83e7,0x03e2,
0x83a3,0x03a6,0x03ac,0x83a9,0x03b8,0x83bd,0x83b7,0x03b2,
0x0390,0x8395,0x839f,0x039a,0x838b,0x038e,0x0384,0x8381,
0x0280,0x8285,0x828f,0x028a,0x829b,0x029e,0x0294,0x8291,
0x82b3,0x02b6,0x02bc,0x82b9,0x02a8,0x82ad,0x82a7,0x02a2,
0x82e3,0x02e6,0x02ec,0x82e9,0x02f8,0x82fd,0x82f7,0x02f2,
0x02d0,0x82d5,0x82df,0x02da,0x82cb,0x02ce,0x02c4,0x82c1,
0x8243,0x0246,0x024c,0x8249,0x0258,0x825d,0x8257,0x0252,
0x0270,0x8275,0x827f,0x027a,0x826b,0x026e,0x0264,0x8261,
0x0220,0x8225,0x822f,0x022a,0x823b,0x023e,0x0234,0x8231,
0x8213,0x0216,0x021c,0x8219,0x0208,0x820d,0x8207,0x0202
};
static uint_16 state;
void
crc_init(void)
{
state = 0;
}
inline void crc_process_byte(uint_8 data)
{
state = crc_lut[data ^ (state>>8)] ^ (state<<8);
}
void
crc_process_frame(uint_8 *data,uint_32 num_bytes)
{
uint_32 i;
for(i=0;i<num_bytes;i++)
crc_process_byte(data[i]);
}
int
crc_validate(void)
{
return(state == 0);
}

View file

@ -1,27 +0,0 @@
/*
* crc.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
int crc_validate(void);
void crc_init(void);
void crc_process_byte(uint_8 data);
void crc_process_frame(uint_8 *data,uint_32 num_bytes);

View file

@ -1,58 +0,0 @@
/*
*
* debug.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include "debug.h"
static int debug_level = -1;
// Determine is debug output is required.
// We could potentially have multiple levels of debug info
int debug_is_on(void)
{
char *env_var;
if(debug_level < 0)
{
env_var = getenv("AC3_DEBUG");
if (env_var)
{
debug_level = 1;
}
else
debug_level = 0;
}
return debug_level;
}
//If you don't have gcc, then ya don't get debug output
#ifndef __GNUC__
void dprintf(char fmt[],...)
{
int foo = 0;
}
#endif

View file

@ -1,37 +0,0 @@
/*
*
* debug.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
int debug_is_on(void);
#ifdef __GNUC__
#define dprintf(format,args...)\
{\
if (debug_is_on())\
{\
fprintf(stderr,format,## args);\
}\
}
#else
void dprintf(char fmt[],...);
#endif

View file

@ -1,150 +0,0 @@
/*
* decode.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
#include "imdct.h"
#include "exponent.h"
#include "coeff.h"
#include "bit_allocate.h"
#include "parse.h"
#include "crc.h"
#include "stats.h"
#include "rematrix.h"
#include "sanity_check.h"
#include "downmix.h"
#include "debug.h"
//our global config structure
ac3_config_t ac3_config;
uint_32 error_flag = 0;
static audblk_t audblk;
static bsi_t bsi;
static syncinfo_t syncinfo;
static uint_32 frame_count = 0;
static uint_32 done_banner;
static ac3_frame_t frame;
//the floating point samples for one audblk
static stream_samples_t samples;
//the integer samples for the entire frame (with enough space for 2 ch out)
//if this size change, be sure to change the size when muting
static sint_16 s16_samples[6 * 6 * 256];
void
ac3_init(ac3_config_t *config)
{
memcpy(&ac3_config,config,sizeof(ac3_config_t));
bitstream_init(config->fill_buffer_callback);
imdct_init();
sanity_check_init(&syncinfo,&bsi,&audblk);
frame.audio_data = s16_samples;
}
ac3_frame_t*
ac3_decode_frame(void)
{
uint_32 i;
//find a syncframe and parse
if (parse_syncinfo(&syncinfo) < 0)
return NULL;
if(error_flag)
goto error;
dprintf("(decode) begin frame %d\n",frame_count++);
frame.sampling_rate = syncinfo.sampling_rate;
parse_bsi(&bsi);
if(!done_banner && !(ac3_config.flags & AC3_QUIET))
{
stats_print_banner(&syncinfo,&bsi);
done_banner = 1;
}
for(i=0; i < 6; i++)
{
//Initialize freq/time sample storage
memset(samples,0,sizeof(float) * 256 * (bsi.nfchans + bsi.lfeon));
// Extract most of the audblk info from the bitstream
// (minus the mantissas
parse_audblk(&bsi,&audblk);
// Take the differential exponent data and turn it into
// absolute exponents
exponent_unpack(&bsi,&audblk);
if(error_flag)
goto error;
// Figure out how many bits per mantissa
bit_allocate(syncinfo.fscod,&bsi,&audblk);
// Extract the mantissas from the stream and
// generate floating point frequency coefficients
coeff_unpack(&bsi,&audblk,samples);
if(error_flag)
goto error;
if(bsi.acmod == 0x2)
rematrix(&audblk,samples);
// Convert the frequency samples into time samples
imdct(&bsi,&audblk,samples);
// Downmix into the requested number of channels
// and convert floating point to sint_16
downmix(&bsi,samples,&s16_samples[i * ac3_config.num_output_ch * 256]);
sanity_check(&syncinfo,&bsi,&audblk);
if(error_flag)
goto error;
}
parse_auxdata(&syncinfo);
return &frame;
error:
//mute the frame
memset(s16_samples,0,sizeof(sint_16) * 256 * 2 * 6);
error_flag = 0;
return &frame;
}

View file

@ -1,22 +0,0 @@
/*
* decode.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/

View file

@ -1,115 +0,0 @@
/*
* dither.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "dither.h"
const uint_16 dither_lut[256] =
{
0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055,
0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb,
0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198,
0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176,
0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf,
0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321,
0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202,
0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec,
0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761,
0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f,
0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac,
0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642,
0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb,
0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415,
0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536,
0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8,
0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c,
0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2,
0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1,
0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f,
0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6,
0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58,
0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b,
0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95,
0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918,
0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6,
0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5,
0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b,
0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82,
0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c,
0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f,
0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1
};
uint_16 lfsr_state = 1;
//
// see dither_gen (inline-able) in dither.h
//
#if 0
//
// this is the old dither_gen with is much slower than the new inlined
// lut version and is still here because it's easier to understand.
//
/*
* Generate eight bits of pseudo-entropy using a 16 bit linear
* feedback shift register (LFSR). The primitive polynomial used
* is 1 + x^4 + x^14 + x^16.
*
* The distribution is uniform, over the range [-0.707,0.707]
*
*/
uint_16 dither_gen(void)
{
int i;
uint_32 state;
//explicitly bring the state into a local var as gcc > 3.0?
//doesn't know how to optimize out the stores
state = lfsr_state;
//Generate eight pseudo random bits
for(i=0;i<8;i++)
{
state <<= 1;
if(state & 0x10000)
state ^= 0xa011;
}
lfsr_state = state;
return (((((sint_32)state<<8)>>8) * (sint_32) (0.707106 * 256.0))>>16);
}
#endif

View file

@ -1,37 +0,0 @@
/*
* dither.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
extern uint_16 lfsr_state;
extern const uint_16 dither_lut[256];
static inline uint_16 dither_gen(void)
{
sint_16 state;
state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
lfsr_state = (uint_16) state;
return ((state * (sint_32) (0.707106 * 256.0))>>8);
}

View file

@ -1,557 +0,0 @@
/*
*
* downmix.c
*
* Copyright (C) Aaron Holtzman - Sept 1999
*
* Originally based on code by Yuqing Deng.
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "decode.h"
#include "downmix.h"
#include "debug.h"
//Pre-scaled downmix coefficients
static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 };
static void
downmix_3f_2r_to_2ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float right_tmp;
float left_tmp;
float clev,slev;
float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
left = samples[0];
centre = samples[1];
right = samples[2];
left_sur = samples[3];
right_sur = samples[4];
clev = cmixlev_lut[bsi->cmixlev];
slev = smixlev_lut[bsi->surmixlev];
for (j = 0; j < 256; j++)
{
left_tmp = 0.4142f * *left++ + clev * *centre + slev * *left_sur++;
right_tmp= 0.4142f * *right++ + clev * *centre++ + slev * *right_sur++;
s16_samples[j * 2 ] = (sint_16) (left_tmp * 32767.0f);
s16_samples[j * 2 + 1] = (sint_16) (right_tmp * 32767.0f);
// printf("[0] = %.6f, [1] = %.6f\n", left_tmp, right_tmp);
}
}
static void
downmix_3f_2r_to_4ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float right_tmp, left_tmp, rear_right_tmp, rear_left_tmp;
float clev,slev;
float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
left = samples[0];
centre = samples[1];
right = samples[2];
left_sur = samples[3];
right_sur = samples[4];
clev = cmixlev_lut[bsi->cmixlev];
slev = smixlev_lut[bsi->surmixlev];
for (j = 0; j < 256; j++)
{
left_tmp = 0.4142f * *left++ + clev * *centre;
right_tmp= 0.4142f * *right++ + clev * *centre++;
rear_left_tmp = 0.4142f * *left_sur++;
rear_right_tmp = 0.4142f * *right_sur++;
s16_samples[j * 4 ] = (sint_16) (left_tmp * 32767.0f);
s16_samples[j * 4 + 1] = (sint_16) (right_tmp * 32767.0f);
s16_samples[j * 4 + 2] = (sint_16) (rear_left_tmp * 32767.0f);
s16_samples[j * 4 + 3] = (sint_16) (rear_right_tmp * 32767.0f);
#if 0
printf("[0] = %.6f, [1] = %.6f, [2] = %.6f, [3] = %.6f\n",
left_tmp, right_tmp, rear_left_tmp, rear_right_tmp);
#endif
}
}
static void
downmix_3f_2r_to_6ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float right_tmp, centre_tmp, left_tmp, rear_right_tmp, rear_left_tmp, lfe_tmp;
float clev,slev;
float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0, *lfe = 0;
left = samples[0];
centre = samples[1];
right = samples[2];
left_sur = samples[3];
right_sur = samples[4];
lfe = samples[5];
clev = cmixlev_lut[bsi->cmixlev];
slev = smixlev_lut[bsi->surmixlev];
for (j = 0; j < 256; j++)
{
left_tmp = 0.4142f * *left++;
right_tmp= 0.4142f * *right++;
centre_tmp = 0.4142f * *centre++;
rear_left_tmp = 0.4142f * *left_sur++;
rear_right_tmp = 0.4142f * *right_sur++;
lfe_tmp = bsi->lfeon ? 0.4142f * *lfe++ : (float)0.0;
s16_samples[j * 6 ] = (sint_16) (left_tmp * 32767.0f);
s16_samples[j * 6 + 1] = (sint_16) (right_tmp * 32767.0f);
s16_samples[j * 6 + 2] = (sint_16) (rear_left_tmp * 32767.0f);
s16_samples[j * 6 + 3] = (sint_16) (rear_right_tmp * 32767.0f);
s16_samples[j * 6 + 4] = (sint_16) (centre_tmp * 32767.0f);
s16_samples[j * 6 + 5] = (sint_16) (lfe_tmp * 32767.0f);
#if 0
printf("[0] = %.6f, [1] = %.6f, [2] = %.6f, [3] = %.6f, [4] = %.6f, [5] = %.6f\n",
left_tmp, right_tmp, rear_left_tmp, rear_right_tmp,
centre_tmp, lfe_tmp);
#endif
}
}
static void
downmix_2f_2r_to_2ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float right_tmp;
float left_tmp;
float slev;
float *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
left = samples[0];
right = samples[1];
left_sur = samples[2];
right_sur = samples[3];
slev = smixlev_lut[bsi->surmixlev];
for (j = 0; j < 256; j++)
{
left_tmp = 0.4142f * *left++ + slev * *left_sur++;
right_tmp= 0.4142f * *right++ + slev * *right_sur++;
s16_samples[j * 2 ] = (sint_16) (left_tmp * 32767.0f);
s16_samples[j * 2 + 1] = (sint_16) (right_tmp * 32767.0f);
}
}
static void
downmix_3f_1r_to_2ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float right_tmp;
float left_tmp;
float clev,slev;
float *centre = 0, *left = 0, *right = 0, *sur = 0;
left = samples[0];
centre = samples[1];
right = samples[2];
//Mono surround
sur = samples[3];
clev = cmixlev_lut[bsi->cmixlev];
slev = smixlev_lut[bsi->surmixlev];
for (j = 0; j < 256; j++)
{
left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *sur;
right_tmp= 0.4142f * *right++ + clev * *centre + slev * *sur++;
s16_samples[j * 2 ] = (sint_16) (left_tmp * 32767.0f);
s16_samples[j * 2 + 1] = (sint_16) (right_tmp * 32767.0f);
}
}
static void
downmix_2f_1r_to_2ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float right_tmp;
float left_tmp;
float slev;
float *left = 0, *right = 0, *sur = 0;
left = samples[0];
right = samples[1];
//Mono surround
sur = samples[2];
slev = smixlev_lut[bsi->surmixlev];
for (j = 0; j < 256; j++)
{
left_tmp = 0.4142f * *left++ + slev * *sur;
right_tmp= 0.4142f * *right++ + slev * *sur++;
s16_samples[j * 2 ] = (sint_16) (left_tmp * 32767.0f);
s16_samples[j * 2 + 1] = (sint_16) (right_tmp * 32767.0f);
}
}
static void
downmix_3f_0r_to_2ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float right_tmp;
float left_tmp;
float clev;
float *centre = 0, *left = 0, *right = 0;
left = samples[0];
centre = samples[1];
right = samples[2];
clev = cmixlev_lut[bsi->cmixlev];
for (j = 0; j < 256; j++)
{
left_tmp = 0.4142f * *left++ + clev * *centre;
right_tmp= 0.4142f * *right++ + clev * *centre++;
s16_samples[j * 2 ] = (sint_16) (left_tmp * 32767.0f);
s16_samples[j * 2 + 1] = (sint_16) (right_tmp * 32767.0f);
}
}
static void
downmix_2f_0r_to_6ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float *left = 0, *right = 0;
left = samples[0];
right = samples[1];
for (j = 0; j < 256; j++)
{
s16_samples[j * 6 ] = (sint_16) (*left++ * 32767.0f);
s16_samples[j * 6 + 1] = (sint_16) (*right++ * 32767.0f);
} //FIXME enable output on surround channels, too.
}
static void
downmix_2f_0r_to_2ch(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
uint_32 j;
float *left = 0, *right = 0;
left = samples[0];
right = samples[1];
for (j = 0; j < 256; j++)
{
s16_samples[j * 2 ] = (sint_16) (*left++ * 32767.0f);
s16_samples[j * 2 + 1] = (sint_16) (*right++ * 32767.0f);
}
}
static void
downmix_1f_0r_to_2ch(float *centre,sint_16 *s16_samples)
{
uint_32 j;
float tmp;
//Mono program!
for (j = 0; j < 256; j++)
{
tmp = 32767.0f * 0.7071f * *centre++;
s16_samples[j * 2 ] = s16_samples[j * 2 + 1] = (sint_16) tmp;
}
}
//
// Downmix into 2 or 4 channels (4 ch isn't in quite yet)
//
// The downmix function names have the following format
//
// downmix_Xf_Yr_to_[2|4|6]ch[_dolby]
//
// where X = number of front channels
// Y = number of rear channels
// [2|4] = number of output channels
// [_dolby] = with or without dolby surround mix
//
void downmix(bsi_t* bsi, stream_samples_t samples,sint_16 *s16_samples)
{
if(bsi->acmod > 7)
dprintf("(downmix) invalid acmod number\n");
//
//There are two main cases, with or without Dolby Surround
//
if(ac3_config.flags & AC3_DOLBY_SURR_ENABLE)
{
fprintf(stderr,"Dolby Surround Mixes not currently enabled\n");
exit(1);
}
//Non-Dolby surround downmixes
switch(bsi->acmod)
{
// 3/2
case 7:
switch (ac3_config.num_output_ch) {
case 2:
downmix_3f_2r_to_2ch(bsi,samples,s16_samples);
break;
case 4:
downmix_3f_2r_to_4ch(bsi,samples,s16_samples);
break;
case 6:
downmix_3f_2r_to_6ch(bsi,samples,s16_samples);
break;
default:
fprintf(stderr,"unsupported 3/2 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
break;
// 2/2
case 6:
if (ac3_config.num_output_ch != 2) {
fprintf(stderr,"unsupported 2/2 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
downmix_2f_2r_to_2ch(bsi,samples,s16_samples);
break;
// 3/1
case 5:
if (ac3_config.num_output_ch != 2) {
fprintf(stderr,"unsupported 3/1 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
downmix_3f_1r_to_2ch(bsi,samples,s16_samples);
break;
// 2/1
case 4:
if (ac3_config.num_output_ch != 2) {
fprintf(stderr,"unsupported 2/1 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
downmix_2f_1r_to_2ch(bsi,samples,s16_samples);
break;
// 3/0
case 3:
if (ac3_config.num_output_ch != 2) {
fprintf(stderr,"unsupported 3/0 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
downmix_3f_0r_to_2ch(bsi,samples,s16_samples);
break;
// 2/0 - 2f_0r_to_6ch not really, but allows -D pcm.surround51:1 with 2/0 and 3/2 input (VDR e.g.)
case 2:
switch (ac3_config.num_output_ch) {
case 2:
downmix_2f_0r_to_2ch(bsi,samples,s16_samples);
break;
case 6:
downmix_2f_0r_to_6ch(bsi,samples,s16_samples);
break;
default:
fprintf(stderr,"unsupported 2/0 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
break;
// 1/0
case 1:
if (ac3_config.num_output_ch != 2) {
fprintf(stderr,"unsupported 1/0 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
downmix_1f_0r_to_2ch(samples[0],s16_samples);
break;
// 1+1
case 0:
if (ac3_config.num_output_ch != 2) {
fprintf(stderr,"unsupported 1/1 channels %d\n", ac3_config.num_output_ch);
exit(1);
}
downmix_1f_0r_to_2ch(samples[ac3_config.dual_mono_ch_sel],s16_samples);
break;
}
}
#if 0
//the dolby mixes lay here for the time being
switch(bsi->acmod)
{
// 3/2
case 7:
left = samples[0];
centre = samples[1];
right = samples[2];
left_sur = samples[3];
right_sur = samples[4];
for (j = 0; j < 256; j++)
{
right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
left_tmp = -1 * right_tmp;
right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
samples[1][j] = right_tmp;
samples[0][j] = left_tmp;
}
break;
// 2/2
case 6:
left = samples[0];
right = samples[1];
left_sur = samples[2];
right_sur = samples[3];
for (j = 0; j < 256; j++)
{
right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
left_tmp = -1 * right_tmp;
right_tmp += 0.3204f * *right++;
left_tmp += 0.3204f * *left++ ;
samples[1][j] = right_tmp;
samples[0][j] = left_tmp;
}
break;
// 3/1
case 5:
left = samples[0];
centre = samples[1];
right = samples[2];
//Mono surround
right_sur = samples[3];
for (j = 0; j < 256; j++)
{
right_tmp = 0.2265f * *right_sur++;
left_tmp = -1 * right_tmp;
right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
samples[1][j] = right_tmp;
samples[0][j] = left_tmp;
}
break;
// 2/1
case 4:
left = samples[0];
right = samples[1];
//Mono surround
right_sur = samples[2];
for (j = 0; j < 256; j++)
{
right_tmp = 0.2265f * *right_sur++;
left_tmp = -1 * right_tmp;
right_tmp += 0.3204f * *right++;
left_tmp += 0.3204f * *left++;
samples[1][j] = right_tmp;
samples[0][j] = left_tmp;
}
break;
// 3/0
case 3:
left = samples[0];
centre = samples[1];
right = samples[2];
for (j = 0; j < 256; j++)
{
right_tmp = 0.3204f * *right++ + 0.2265f * *centre;
left_tmp = 0.3204f * *left++ + 0.2265f * *centre++;
samples[1][j] = right_tmp;
samples[0][j] = left_tmp;
}
break;
// 2/0
case 2:
//Do nothing!
break;
// 1/0
case 1:
//Mono program!
right = samples[0];
for (j = 0; j < 256; j++)
{
right_tmp = 0.7071f * *right++;
samples[1][j] = right_tmp;
samples[0][j] = right_tmp;
}
break;
// 1+1
case 0:
//Dual mono, output selected by user
right = samples[ac3_config.dual_mono_ch_sel];
for (j = 0; j < 256; j++)
{
right_tmp = 0.7071f * *right++;
samples[1][j] = right_tmp;
samples[0][j] = right_tmp;
}
break;
#endif

View file

@ -1,28 +0,0 @@
/*
*
* downmix.h
*
* Copyright (C) Aaron Holtzman - Sept 1999
*
* Originally based on code by Yeqing Deng.
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
void downmix(bsi_t* bsi, stream_samples_t stream_samples,sint_16 *s16_samples);

View file

@ -1,135 +0,0 @@
/*
* exponent.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "decode.h"
#include "exponent.h"
static void exp_unpack_ch(uint_16 type,uint_16 expstr,uint_16 ngrps,uint_16 initial_exp,
uint_16 exps[], uint_16 *dest);
void
exponent_unpack( bsi_t *bsi, audblk_t *audblk)
{
uint_16 i;
for(i=0; i< bsi->nfchans; i++)
exp_unpack_ch(UNPACK_FBW, audblk->chexpstr[i], audblk->nchgrps[i], audblk->exps[i][0],
&audblk->exps[i][1], audblk->fbw_exp[i]);
if(audblk->cplinu)
exp_unpack_ch(UNPACK_CPL, audblk->cplexpstr, audblk->ncplgrps, audblk->cplabsexp << 1,
audblk->cplexps, &audblk->cpl_exp[audblk->cplstrtmant]);
if(bsi->lfeon)
exp_unpack_ch(UNPACK_LFE, audblk->lfeexpstr, 2, audblk->lfeexps[0],
&audblk->lfeexps[1], audblk->lfe_exp);
}
static void
exp_unpack_ch(uint_16 type,uint_16 expstr,uint_16 ngrps,uint_16 initial_exp,
uint_16 exps[], uint_16 *dest)
{
uint_16 i,j;
sint_16 exp_acc;
sint_16 exp_1,exp_2,exp_3;
if(expstr == EXP_REUSE)
return;
/* Handle the initial absolute exponent */
exp_acc = initial_exp;
j = 0;
/* In the case of a fbw channel then the initial absolute values is
* also an exponent */
if(type != UNPACK_CPL)
dest[j++] = exp_acc;
/* Loop through the groups and fill the dest array appropriately */
for(i=0; i< ngrps; i++)
{
if(exps[i] > 124)
goto error;
exp_1 = exps[i] / 25;
exp_2 = (exps[i] - (exp_1 * 25)) / 5;
exp_3 = exps[i] - (exp_1 * 25) - (exp_2 * 5) ;
exp_acc += (exp_1 - 2);
switch(expstr)
{
case EXP_D45:
dest[j++] = exp_acc;
dest[j++] = exp_acc;
case EXP_D25:
dest[j++] = exp_acc;
case EXP_D15:
dest[j++] = exp_acc;
}
exp_acc += (exp_2 - 2);
switch(expstr)
{
case EXP_D45:
dest[j++] = exp_acc;
dest[j++] = exp_acc;
case EXP_D25:
dest[j++] = exp_acc;
case EXP_D15:
dest[j++] = exp_acc;
}
exp_acc += (exp_3 - 2);
switch(expstr)
{
case EXP_D45:
dest[j++] = exp_acc;
dest[j++] = exp_acc;
case EXP_D25:
dest[j++] = exp_acc;
case EXP_D15:
dest[j++] = exp_acc;
}
}
return;
goto error;
error:
if(!error_flag)
fprintf(stderr,"** Invalid exponent - skipping frame **\n");
error_flag = 1;
}

View file

@ -1,28 +0,0 @@
/*
* exponent.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#define UNPACK_FBW 1
#define UNPACK_CPL 2
#define UNPACK_LFE 4
void exponent_unpack( bsi_t *bsi, audblk_t *audblk);

View file

@ -1,479 +0,0 @@
/*
* imdct.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "decode.h"
#include "imdct.h"
void imdct_do_256(float data[],float delay[]);
void imdct_do_512(float data[],float delay[]);
typedef struct complex_s
{
float real;
float imag;
} complex_t;
#define N 512
/* 128 point bit-reverse LUT */
static uint_8 bit_reverse_512[] = {
0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70,
0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78,
0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74,
0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c,
0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72,
0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a,
0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76,
0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e,
0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71,
0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79,
0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75,
0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d,
0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73,
0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b,
0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77,
0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f};
static uint_8 bit_reverse_256[] = {
0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,
0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,
0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,
0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39,
0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,
0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,
0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f};
static complex_t buf[128];
/* Twiddle factor LUT */
static complex_t *w[7];
static complex_t w_1[1];
static complex_t w_2[2];
static complex_t w_4[4];
static complex_t w_8[8];
static complex_t w_16[16];
static complex_t w_32[32];
static complex_t w_64[64];
/* Twiddle factors for IMDCT */
static float xcos1[128];
static float xsin1[128];
static float xcos2[64];
static float xsin2[64];
/* Delay buffer for time domain interleaving */
static float delay[6][256];
/* Windowing function for Modified DCT - Thank you acroread */
static float window[] = {
0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 };
static inline void swap_cmplx(complex_t *a, complex_t *b)
{
complex_t tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
static inline complex_t cmplx_mult(complex_t a, complex_t b)
{
complex_t ret;
ret.real = a.real * b.real - a.imag * b.imag;
ret.imag = a.real * b.imag + a.imag * b.real;
return ret;
}
void imdct_init(void)
{
int i,k;
complex_t angle_step;
complex_t current_angle;
/* Twiddle factors to turn IFFT into IMDCT */
for( i=0; i < 128; i++)
{
xcos1[i] = -cos(2.0f * M_PI * (8*i+1)/(8*N)) ;
xsin1[i] = -sin(2.0f * M_PI * (8*i+1)/(8*N)) ;
}
/* More twiddle factors to turn IFFT into IMDCT */
for( i=0; i < 64; i++)
{
xcos2[i] = -cos(2.0f * M_PI * (8*i+1)/(4*N)) ;
xsin2[i] = -sin(2.0f * M_PI * (8*i+1)/(4*N)) ;
}
/* Canonical twiddle factors for FFT */
w[0] = w_1;
w[1] = w_2;
w[2] = w_4;
w[3] = w_8;
w[4] = w_16;
w[5] = w_32;
w[6] = w_64;
for( i = 0; i < 7; i++)
{
angle_step.real = cos(-2.0 * M_PI / (1 << (i+1)));
angle_step.imag = sin(-2.0 * M_PI / (1 << (i+1)));
current_angle.real = 1.0;
current_angle.imag = 0.0;
for (k = 0; k < 1 << i; k++)
{
w[i][k] = current_angle;
current_angle = cmplx_mult(current_angle,angle_step);
}
}
}
void
imdct_do_512(float data[],float delay[])
{
int i,k;
int p,q;
int m;
int two_m;
int two_m_plus_one;
float tmp_a_i;
float tmp_a_r;
float tmp_b_i;
float tmp_b_r;
float *data_ptr;
float *delay_ptr;
float *window_ptr;
//
// 512 IMDCT with source and dest data in 'data'
//
// Pre IFFT complex multiply plus IFFT cmplx conjugate
for( i=0; i < 128; i++)
{
/* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */
buf[i].real = (data[256-2*i-1] * xcos1[i]) - (data[2*i] * xsin1[i]);
buf[i].imag = -1.0 * ((data[2*i] * xcos1[i]) + (data[256-2*i-1] * xsin1[i]));
}
//Bit reversed shuffling
for(i=0; i<128; i++)
{
k = bit_reverse_512[i];
if (k < i)
swap_cmplx(&buf[i],&buf[k]);
}
/* FFT Merge */
for (m=0; m < 7; m++)
{
if(m)
two_m = (1 << m);
else
two_m = 1;
two_m_plus_one = (1 << (m+1));
for(k = 0; k < two_m; k++)
{
for(i = 0; i < 128; i += two_m_plus_one)
{
p = k + i;
q = p + two_m;
tmp_a_r = buf[p].real;
tmp_a_i = buf[p].imag;
tmp_b_r = buf[q].real * w[m][k].real - buf[q].imag * w[m][k].imag;
tmp_b_i = buf[q].imag * w[m][k].real + buf[q].real * w[m][k].imag;
buf[p].real = tmp_a_r + tmp_b_r;
buf[p].imag = tmp_a_i + tmp_b_i;
buf[q].real = tmp_a_r - tmp_b_r;
buf[q].imag = tmp_a_i - tmp_b_i;
}
}
}
/* Post IFFT complex multiply plus IFFT complex conjugate*/
for( i=0; i < 128; i++)
{
/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
tmp_a_r = buf[i].real;
tmp_a_i = -1.0 * buf[i].imag;
buf[i].real =(tmp_a_r * xcos1[i]) - (tmp_a_i * xsin1[i]);
buf[i].imag =(tmp_a_r * xsin1[i]) + (tmp_a_i * xcos1[i]);
}
data_ptr = data;
delay_ptr = delay;
window_ptr = window;
/* Window and convert to real valued signal */
for(i=0; i< 64; i++)
{
*data_ptr++ = 2.0f * (-buf[64+i].imag * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf[64-i-1].real * *window_ptr++ + *delay_ptr++);
}
for(i=0; i< 64; i++)
{
*data_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf[128-i-1].imag * *window_ptr++ + *delay_ptr++);
}
/* The trailing edge of the window goes into the delay line */
delay_ptr = delay;
for(i=0; i< 64; i++)
{
*delay_ptr++ = -buf[64+i].real * *--window_ptr;
*delay_ptr++ = buf[64-i-1].imag * *--window_ptr;
}
for(i=0; i<64; i++)
{
*delay_ptr++ = buf[i].imag * *--window_ptr;
*delay_ptr++ = -buf[128-i-1].real * *--window_ptr;
}
}
void
imdct_do_256(float data[],float delay[])
{
int i,k;
int p,q;
int m;
int two_m;
int two_m_plus_one;
float tmp_a_i;
float tmp_a_r;
float tmp_b_i;
float tmp_b_r;
float *data_ptr;
float *delay_ptr;
float *window_ptr;
complex_t *buf_1, *buf_2;
buf_1 = &buf[0];
buf_2 = &buf[64];
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for(k=0; k<64; k++)
{
/* X1[k] = X[2*k] */
/* X2[k] = X[2*k+1] */
p = 2 * (128-2*k-1);
q = 2 * (2 * k);
/* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf_1[k].real = data[p] * xcos2[k] - data[q] * xsin2[k];
buf_1[k].imag = -1.0f * (data[q] * xcos2[k] + data[p] * xsin2[k]);
/* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf_2[k].real = data[p + 1] * xcos2[k] - data[q + 1] * xsin2[k];
buf_2[k].imag = -1.0f * ( data[q + 1] * xcos2[k] + data[p + 1] * xsin2[k]);
}
//IFFT Bit reversed shuffling
for(i=0; i<64; i++)
{
k = bit_reverse_256[i];
if (k < i)
{
swap_cmplx(&buf_1[i],&buf_1[k]);
swap_cmplx(&buf_2[i],&buf_2[k]);
}
}
/* FFT Merge */
for (m=0; m < 6; m++)
{
two_m = (1 << m);
two_m_plus_one = (1 << (m+1));
//FIXME
if(m)
two_m = (1 << m);
else
two_m = 1;
for(k = 0; k < two_m; k++)
{
for(i = 0; i < 64; i += two_m_plus_one)
{
p = k + i;
q = p + two_m;
//Do block 1
tmp_a_r = buf_1[p].real;
tmp_a_i = buf_1[p].imag;
tmp_b_r = buf_1[q].real * w[m][k].real - buf_1[q].imag * w[m][k].imag;
tmp_b_i = buf_1[q].imag * w[m][k].real + buf_1[q].real * w[m][k].imag;
buf_1[p].real = tmp_a_r + tmp_b_r;
buf_1[p].imag = tmp_a_i + tmp_b_i;
buf_1[q].real = tmp_a_r - tmp_b_r;
buf_1[q].imag = tmp_a_i - tmp_b_i;
//Do block 2
tmp_a_r = buf_2[p].real;
tmp_a_i = buf_2[p].imag;
tmp_b_r = buf_2[q].real * w[m][k].real - buf_2[q].imag * w[m][k].imag;
tmp_b_i = buf_2[q].imag * w[m][k].real + buf_2[q].real * w[m][k].imag;
buf_2[p].real = tmp_a_r + tmp_b_r;
buf_2[p].imag = tmp_a_i + tmp_b_i;
buf_2[q].real = tmp_a_r - tmp_b_r;
buf_2[q].imag = tmp_a_i - tmp_b_i;
}
}
}
/* Post IFFT complex multiply */
for( i=0; i < 64; i++)
{
/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
tmp_a_r = buf_1[i].real;
tmp_a_i = -buf_1[i].imag;
buf_1[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf_1[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
/* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
tmp_a_r = buf_2[i].real;
tmp_a_i = -buf_2[i].imag;
buf_2[i].real =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf_2[i].imag =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
}
data_ptr = data;
delay_ptr = delay;
window_ptr = window;
/* Window and convert to real valued signal */
for(i=0; i< 64; i++)
{
*data_ptr++ = 2.0f * (-buf_1[i].imag * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf_1[64-i-1].real * *window_ptr++ + *delay_ptr++);
}
for(i=0; i< 64; i++)
{
*data_ptr++ = 2.0f * (-buf_1[i].real * *window_ptr++ + *delay_ptr++);
*data_ptr++ = 2.0f * ( buf_1[64-i-1].imag * *window_ptr++ + *delay_ptr++);
}
delay_ptr = delay;
for(i=0; i< 64; i++)
{
*delay_ptr++ = -buf_2[i].real * *--window_ptr;
*delay_ptr++ = buf_2[64-i-1].imag * *--window_ptr;
}
for(i=0; i< 64; i++)
{
*delay_ptr++ = buf_2[i].imag * *--window_ptr;
*delay_ptr++ = -buf_2[64-i-1].real * *--window_ptr;
}
}
//FIXME remove - for timing code
///#include <sys/time.h>
//FIXME remove
void
imdct(bsi_t *bsi,audblk_t *audblk, stream_samples_t samples) {
int i;
//handy timing code
//struct timeval start,end;
//gettimeofday(&start,0);
for(i=0; i<bsi->nfchans;i++)
{
if(audblk->blksw[i])
imdct_do_256(samples[i],delay[i]);
else
imdct_do_512(samples[i],delay[i]);
}
//gettimeofday(&end,0);
//printf("imdct %ld us\n",(end.tv_sec - start.tv_sec) * 1000000 +
//end.tv_usec - start.tv_usec);
//XXX We don't bother with the IMDCT for the LFE as it's currently
//unused.
//if (bsi->lfeon)
// imdct_do_512(coeffs->lfe,samples->channel[5],delay[5]);
//
}

View file

@ -1,26 +0,0 @@
/*
* imdct.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
void imdct(bsi_t *bsi,audblk_t *audblk, stream_samples_t samples);
void imdct_init(void);

View file

@ -1,656 +0,0 @@
/*
* parse.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
#include "stats.h"
#include "debug.h"
#include "crc.h"
#include "parse.h"
/* Misc LUT */
static const uint_16 nfchans[8] = {2,1,2,3,3,4,4,5};
struct frmsize_s
{
uint_16 bit_rate;
uint_16 frm_size[3];
};
static const struct frmsize_s frmsizecod_tbl[64] =
{
{ 32 ,{64 ,69 ,96 } },
{ 32 ,{64 ,70 ,96 } },
{ 40 ,{80 ,87 ,120 } },
{ 40 ,{80 ,88 ,120 } },
{ 48 ,{96 ,104 ,144 } },
{ 48 ,{96 ,105 ,144 } },
{ 56 ,{112 ,121 ,168 } },
{ 56 ,{112 ,122 ,168 } },
{ 64 ,{128 ,139 ,192 } },
{ 64 ,{128 ,140 ,192 } },
{ 80 ,{160 ,174 ,240 } },
{ 80 ,{160 ,175 ,240 } },
{ 96 ,{192 ,208 ,288 } },
{ 96 ,{192 ,209 ,288 } },
{ 112 ,{224 ,243 ,336 } },
{ 112 ,{224 ,244 ,336 } },
{ 128 ,{256 ,278 ,384 } },
{ 128 ,{256 ,279 ,384 } },
{ 160 ,{320 ,348 ,480 } },
{ 160 ,{320 ,349 ,480 } },
{ 192 ,{384 ,417 ,576 } },
{ 192 ,{384 ,418 ,576 } },
{ 224 ,{448 ,487 ,672 } },
{ 224 ,{448 ,488 ,672 } },
{ 256 ,{512 ,557 ,768 } },
{ 256 ,{512 ,558 ,768 } },
{ 320 ,{640 ,696 ,960 } },
{ 320 ,{640 ,697 ,960 } },
{ 384 ,{768 ,835 ,1152 } },
{ 384 ,{768 ,836 ,1152 } },
{ 448 ,{896 ,975 ,1344 } },
{ 448 ,{896 ,976 ,1344 } },
{ 512 ,{1024 ,1114 ,1536 } },
{ 512 ,{1024 ,1115 ,1536 } },
{ 576 ,{1152 ,1253 ,1728 } },
{ 576 ,{1152 ,1254 ,1728 } },
{ 640 ,{1280 ,1393 ,1920 } },
{ 640 ,{1280 ,1394 ,1920 } }
};
void
parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data)
{
// Get the sampling rate
syncinfo->fscod = (data[2] >> 6) & 0x3;
if(syncinfo->fscod == 3)
{
//invalid sampling rate code
error_flag = 1;
return;
}
else if(syncinfo->fscod == 2)
syncinfo->sampling_rate = 32000;
else if(syncinfo->fscod == 1)
syncinfo->sampling_rate = 44100;
else
syncinfo->sampling_rate = 48000;
// Get the frame size code
syncinfo->frmsizecod = data[2] & 0x3f;
// Calculate the frame size and bitrate
syncinfo->frame_size =
frmsizecod_tbl[syncinfo->frmsizecod].frm_size[syncinfo->fscod];
syncinfo->bit_rate = frmsizecod_tbl[syncinfo->frmsizecod].bit_rate;
}
/* Parse a syncinfo structure, minus the sync word */
int
parse_syncinfo(syncinfo_t *syncinfo)
{
int byte, idx;
uint_8 data[3];
uint_16 sync_word = 0;
uint_32 time_out = 1<<16;
//
// Find a ac3 sync frame. Time out if we read 64k without finding
// one.
//
while(time_out--)
{
byte = bitstream_get_byte();
if (byte < 0)
return -ENOENT;
sync_word = (sync_word << 8) + byte;
if(sync_word == 0x0b77)
break;
}
//
// We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
// in order to determine how big the frame is
//
for (idx = 0; idx < 3; idx++) {
byte = bitstream_get_byte();
if (byte < 0)
return -ENOENT;
data[idx] = byte;
}
parse_syncinfo_data(syncinfo, data);
// Buffer the entire syncframe
if (bitstream_buffer_frame(syncinfo->frame_size * 2 - 5) < 0)
return -ENOENT;
// Check the crc over the entire frame
crc_init();
crc_process_byte(data[0]);
crc_process_byte(data[1]);
crc_process_byte(data[2]);
crc_process_frame(bitstream_get_buffer_start(),syncinfo->frame_size * 2 - 5);
if(!crc_validate())
{
error_flag = 1;
fprintf(stderr,"** CRC failed - skipping frame **\n");
return 0;
}
if (!(ac3_config.flags & AC3_QUIET))
stats_print_syncinfo(syncinfo);
return 0;
}
/*
* This routine fills a bsi struct from the AC3 stream
*/
void
parse_bsi(bsi_t *bsi)
{
uint_32 i;
/* Check the AC-3 version number */
bsi->bsid = bitstream_get(5);
/* Get the audio service provided by the steram */
bsi->bsmod = bitstream_get(3);
/* Get the audio coding mode (ie how many channels)*/
bsi->acmod = bitstream_get(3);
/* Predecode the number of full bandwidth channels as we use this
* number a lot */
bsi->nfchans = nfchans[bsi->acmod];
/* If it is in use, get the centre channel mix level */
if ((bsi->acmod & 0x1) && (bsi->acmod != 0x1))
bsi->cmixlev = bitstream_get(2);
/* If it is in use, get the surround channel mix level */
if (bsi->acmod & 0x4)
bsi->surmixlev = bitstream_get(2);
/* Get the dolby surround mode if in 2/0 mode */
if(bsi->acmod == 0x2)
bsi->dsurmod= bitstream_get(2);
/* Is the low frequency effects channel on? */
bsi->lfeon = bitstream_get(1);
/* Get the dialogue normalization level */
bsi->dialnorm = bitstream_get(5);
/* Does compression gain exist? */
bsi->compre = bitstream_get(1);
if (bsi->compre)
{
/* Get compression gain */
bsi->compr = bitstream_get(8);
}
/* Does language code exist? */
bsi->langcode = bitstream_get(1);
if (bsi->langcode)
{
/* Get langauge code */
bsi->langcod = bitstream_get(8);
}
/* Does audio production info exist? */
bsi->audprodie = bitstream_get(1);
if (bsi->audprodie)
{
/* Get mix level */
bsi->mixlevel = bitstream_get(5);
/* Get room type */
bsi->roomtyp = bitstream_get(2);
}
/* If we're in dual mono mode then get some extra info */
if (bsi->acmod ==0)
{
/* Get the dialogue normalization level two */
bsi->dialnorm2 = bitstream_get(5);
/* Does compression gain two exist? */
bsi->compr2e = bitstream_get(1);
if (bsi->compr2e)
{
/* Get compression gain two */
bsi->compr2 = bitstream_get(8);
}
/* Does language code two exist? */
bsi->langcod2e = bitstream_get(1);
if (bsi->langcod2e)
{
/* Get langauge code two */
bsi->langcod2 = bitstream_get(8);
}
/* Does audio production info two exist? */
bsi->audprodi2e = bitstream_get(1);
if (bsi->audprodi2e)
{
/* Get mix level two */
bsi->mixlevel2 = bitstream_get(5);
/* Get room type two */
bsi->roomtyp2 = bitstream_get(2);
}
}
/* Get the copyright bit */
bsi->copyrightb = bitstream_get(1);
/* Get the original bit */
bsi->origbs = bitstream_get(1);
/* Does timecode one exist? */
bsi->timecod1e = bitstream_get(1);
if(bsi->timecod1e)
bsi->timecod1 = bitstream_get(14);
/* Does timecode two exist? */
bsi->timecod2e = bitstream_get(1);
if(bsi->timecod2e)
bsi->timecod2 = bitstream_get(14);
/* Does addition info exist? */
bsi->addbsie = bitstream_get(1);
if(bsi->addbsie)
{
/* Get how much info is there */
bsi->addbsil = bitstream_get(6);
/* Get the additional info */
for(i=0;i<(bsi->addbsil + 1);i++)
bsi->addbsi[i] = bitstream_get(8);
}
if (!(ac3_config.flags & AC3_QUIET))
stats_print_bsi(bsi);
}
/* More pain inducing parsing */
void
parse_audblk(bsi_t *bsi,audblk_t *audblk)
{
int i,j;
for (i=0;i < bsi->nfchans; i++)
{
/* Is this channel an interleaved 256 + 256 block ? */
audblk->blksw[i] = bitstream_get(1);
}
for (i=0;i < bsi->nfchans; i++)
{
/* Should we dither this channel? */
audblk->dithflag[i] = bitstream_get(1);
}
/* Does dynamic range control exist? */
audblk->dynrnge = bitstream_get(1);
if (audblk->dynrnge)
{
/* Get dynamic range info */
audblk->dynrng = bitstream_get(8);
}
/* If we're in dual mono mode then get the second channel DR info */
if (bsi->acmod == 0)
{
/* Does dynamic range control two exist? */
audblk->dynrng2e = bitstream_get(1);
if (audblk->dynrng2e)
{
/* Get dynamic range info */
audblk->dynrng2 = bitstream_get(8);
}
}
/* Does coupling strategy exist? */
audblk->cplstre = bitstream_get(1);
if (audblk->cplstre)
{
/* Is coupling turned on? */
audblk->cplinu = bitstream_get(1);
if(audblk->cplinu)
{
for(i=0;i < bsi->nfchans; i++)
audblk->chincpl[i] = bitstream_get(1);
if(bsi->acmod == 0x2)
audblk->phsflginu = bitstream_get(1);
audblk->cplbegf = bitstream_get(4);
audblk->cplendf = bitstream_get(4);
audblk->ncplsubnd = (audblk->cplendf + 2) - audblk->cplbegf + 1;
/* Calculate the start and end bins of the coupling channel */
audblk->cplstrtmant = (audblk->cplbegf * 12) + 37 ;
audblk->cplendmant = ((audblk->cplendf + 3) * 12) + 37;
/* The number of combined subbands is ncplsubnd minus each combined
* band */
audblk->ncplbnd = audblk->ncplsubnd;
for(i=1; i< audblk->ncplsubnd; i++)
{
audblk->cplbndstrc[i] = bitstream_get(1);
audblk->ncplbnd -= audblk->cplbndstrc[i];
}
}
}
if(audblk->cplinu)
{
/* Loop through all the channels and get their coupling co-ords */
for(i=0;i < bsi->nfchans;i++)
{
if(!audblk->chincpl[i])
continue;
/* Is there new coupling co-ordinate info? */
audblk->cplcoe[i] = bitstream_get(1);
if(audblk->cplcoe[i])
{
audblk->mstrcplco[i] = bitstream_get(2);
for(j=0;j < audblk->ncplbnd; j++)
{
audblk->cplcoexp[i][j] = bitstream_get(4);
audblk->cplcomant[i][j] = bitstream_get(4);
}
}
}
/* If we're in dual mono mode, there's going to be some phase info */
if( (bsi->acmod == 0x2) && audblk->phsflginu &&
(audblk->cplcoe[0] || audblk->cplcoe[1]))
{
for(j=0;j < audblk->ncplbnd; j++)
audblk->phsflg[j] = bitstream_get(1);
}
}
/* If we're in dual mono mode, there may be a rematrix strategy */
if(bsi->acmod == 0x2)
{
audblk->rematstr = bitstream_get(1);
if(audblk->rematstr)
{
if (audblk->cplinu == 0)
{
for(i = 0; i < 4; i++)
audblk->rematflg[i] = bitstream_get(1);
}
if((audblk->cplbegf > 2) && audblk->cplinu)
{
for(i = 0; i < 4; i++)
audblk->rematflg[i] = bitstream_get(1);
}
if((audblk->cplbegf <= 2) && audblk->cplinu)
{
for(i = 0; i < 3; i++)
audblk->rematflg[i] = bitstream_get(1);
}
if((audblk->cplbegf == 0) && audblk->cplinu)
for(i = 0; i < 2; i++)
audblk->rematflg[i] = bitstream_get(1);
}
}
if (audblk->cplinu)
{
/* Get the coupling channel exponent strategy */
audblk->cplexpstr = bitstream_get(2);
audblk->ncplgrps = (audblk->cplendmant - audblk->cplstrtmant) /
(3 << (audblk->cplexpstr-1));
}
for(i = 0; i < bsi->nfchans; i++)
audblk->chexpstr[i] = bitstream_get(2);
/* Get the exponent strategy for lfe channel */
if(bsi->lfeon)
audblk->lfeexpstr = bitstream_get(1);
/* Determine the bandwidths of all the fbw channels */
for(i = 0; i < bsi->nfchans; i++)
{
uint_16 grp_size;
if(audblk->chexpstr[i] != EXP_REUSE)
{
if (audblk->cplinu && audblk->chincpl[i])
{
audblk->endmant[i] = audblk->cplstrtmant;
}
else
{
audblk->chbwcod[i] = bitstream_get(6);
audblk->endmant[i] = ((audblk->chbwcod[i] + 12) * 3) + 37;
}
/* Calculate the number of exponent groups to fetch */
grp_size = 3 * (1 << (audblk->chexpstr[i] - 1));
audblk->nchgrps[i] = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size;
}
}
/* Get the coupling exponents if they exist */
if(audblk->cplinu && (audblk->cplexpstr != EXP_REUSE))
{
audblk->cplabsexp = bitstream_get(4);
for(i=0;i< audblk->ncplgrps;i++)
audblk->cplexps[i] = bitstream_get(7);
}
/* Get the fwb channel exponents */
for(i=0;i < bsi->nfchans; i++)
{
if(audblk->chexpstr[i] != EXP_REUSE)
{
audblk->exps[i][0] = bitstream_get(4);
for(j=1;j<=audblk->nchgrps[i];j++)
audblk->exps[i][j] = bitstream_get(7);
audblk->gainrng[i] = bitstream_get(2);
}
}
/* Get the lfe channel exponents */
if(bsi->lfeon && (audblk->lfeexpstr != EXP_REUSE))
{
audblk->lfeexps[0] = bitstream_get(4);
audblk->lfeexps[1] = bitstream_get(7);
audblk->lfeexps[2] = bitstream_get(7);
}
/* Get the parametric bit allocation parameters */
audblk->baie = bitstream_get(1);
if(audblk->baie)
{
audblk->sdcycod = bitstream_get(2);
audblk->fdcycod = bitstream_get(2);
audblk->sgaincod = bitstream_get(2);
audblk->dbpbcod = bitstream_get(2);
audblk->floorcod = bitstream_get(3);
}
/* Get the SNR off set info if it exists */
audblk->snroffste = bitstream_get(1);
if(audblk->snroffste)
{
audblk->csnroffst = bitstream_get(6);
if(audblk->cplinu)
{
audblk->cplfsnroffst = bitstream_get(4);
audblk->cplfgaincod = bitstream_get(3);
}
for(i = 0;i < bsi->nfchans; i++)
{
audblk->fsnroffst[i] = bitstream_get(4);
audblk->fgaincod[i] = bitstream_get(3);
}
if(bsi->lfeon)
{
audblk->lfefsnroffst = bitstream_get(4);
audblk->lfefgaincod = bitstream_get(3);
}
}
/* Get coupling leakage info if it exists */
if(audblk->cplinu)
{
audblk->cplleake = bitstream_get(1);
if(audblk->cplleake)
{
audblk->cplfleak = bitstream_get(3);
audblk->cplsleak = bitstream_get(3);
}
}
/* Get the delta bit alloaction info */
audblk->deltbaie = bitstream_get(1);
if(audblk->deltbaie)
{
if(audblk->cplinu)
audblk->cpldeltbae = bitstream_get(2);
for(i = 0;i < bsi->nfchans; i++)
audblk->deltbae[i] = bitstream_get(2);
if (audblk->cplinu && (audblk->cpldeltbae == DELTA_BIT_NEW))
{
audblk->cpldeltnseg = bitstream_get(3);
for(i = 0;i < audblk->cpldeltnseg + 1; i++)
{
audblk->cpldeltoffst[i] = bitstream_get(5);
audblk->cpldeltlen[i] = bitstream_get(4);
audblk->cpldeltba[i] = bitstream_get(3);
}
}
for(i = 0;i < bsi->nfchans; i++)
{
if (audblk->deltbae[i] == DELTA_BIT_NEW)
{
audblk->deltnseg[i] = bitstream_get(3);
for(j = 0; j < audblk->deltnseg[i] + 1; j++)
{
audblk->deltoffst[i][j] = bitstream_get(5);
audblk->deltlen[i][j] = bitstream_get(4);
audblk->deltba[i][j] = bitstream_get(3);
}
}
}
}
/* Check to see if there's any dummy info to get */
if((audblk->skiple = bitstream_get(1)))
{
uint_16 skip_data;
audblk->skipl = bitstream_get(9);
//XXX remove
//fprintf(stderr,"(parse) skipping %d bytes\n",audblk->skipl);
for(i = 0; i < audblk->skipl ; i++)
{
skip_data = bitstream_get(8);
//XXX remove
//fprintf(stderr,"skipped data %2x\n",skip_data);
//if(skip_data != 0)
//{
//dprintf("(parse) Invalid skipped data %2x\n",skip_data);
//exit(1);
//}
}
}
if (!(ac3_config.flags & AC3_QUIET))
stats_print_audblk(bsi,audblk);
}
void
parse_auxdata(syncinfo_t *syncinfo)
{
//FIXME keep this now that we don't really need it?
#if 0
int i;
int skip_length;
uint_16 crc;
uint_16 auxdatae;
skip_length = (syncinfo->frame_size * 16) - bitstream_get_total_bits() - 17 - 1;
//XXX remove
//dprintf("(auxdata) skipping %d auxbits\n",skip_length);
for(i=0; i < skip_length; i++)
//printf("Skipped bit %i\n",(uint_16)bitstream_get(1));
bitstream_get(1);
//get the auxdata exists bit
auxdatae = bitstream_get(1);
//XXX remove
//dprintf("auxdatae = %i\n",auxdatae);
//Skip the CRC reserved bit
bitstream_get(1);
//Get the crc
crc = bitstream_get(16);
#endif
}

View file

@ -1,29 +0,0 @@
/*
* parse.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
void parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data);
int parse_syncinfo(syncinfo_t *syncinfo);
void parse_audblk(bsi_t *bsi,audblk_t *audblk);
void parse_bsi(bsi_t *bsi);
void parse_auxdata(syncinfo_t *syncinfo);

View file

@ -1,83 +0,0 @@
/*
* rematrix.c
*
* Copyright (C) Aaron Holtzman - July 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "decode.h"
#include "rematrix.h"
struct rematrix_band_s
{
uint_32 start;
uint_32 end;
};
struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}};
static inline uint_32 min(uint_32 a,uint_32 b);
static inline uint_32
min(uint_32 a,uint_32 b)
{
return (a < b ? a : b);
}
/* This routine simply does stereo rematixing for the 2 channel
* stereo mode */
void rematrix(audblk_t *audblk, stream_samples_t samples)
{
uint_32 num_bands;
uint_32 start;
uint_32 end;
uint_32 i,j;
float left,right;
if(!audblk->cplinu || audblk->cplbegf > 2)
num_bands = 4;
else if (audblk->cplbegf > 0)
num_bands = 3;
else
num_bands = 2;
for(i=0;i < num_bands; i++)
{
if(!audblk->rematflg[i])
continue;
start = rematrix_band[i].start;
end = min(rematrix_band[i].end ,12 * audblk->cplbegf + 36);
for(j=start;j < end; j++)
{
left = samples[0][j] + samples[1][j];
right = samples[0][j] - samples[1][j];
samples[0][j] = left;
samples[1][j] = right;
}
}
}

View file

@ -1,25 +0,0 @@
/*
* rematrix.h
*
* Copyright (C) Aaron Holtzman - July 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
void rematrix(audblk_t *audblk, stream_samples_t samples);

View file

@ -1,131 +0,0 @@
/*
* sanity_check.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "sanity_check.h"
void
sanity_check_init(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk)
{
syncinfo->magic = AC3_MAGIC_NUMBER;
bsi->magic = AC3_MAGIC_NUMBER;
audblk->magic1 = AC3_MAGIC_NUMBER;
audblk->magic2 = AC3_MAGIC_NUMBER;
audblk->magic3 = AC3_MAGIC_NUMBER;
}
void
sanity_check(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk)
{
int i;
if(syncinfo->magic != AC3_MAGIC_NUMBER)
{
fprintf(stderr,"\n** Sanity check failed -- syncinfo magic number **");
error_flag = 1;
}
if(bsi->magic != AC3_MAGIC_NUMBER)
{
fprintf(stderr,"\n** Sanity check failed -- bsi magic number **");
error_flag = 1;
}
if(audblk->magic1 != AC3_MAGIC_NUMBER)
{
fprintf(stderr,"\n** Sanity check failed -- audblk magic number 1 **");
error_flag = 1;
}
if(audblk->magic2 != AC3_MAGIC_NUMBER)
{
fprintf(stderr,"\n** Sanity check failed -- audblk magic number 2 **");
error_flag = 1;
}
if(audblk->magic3 != AC3_MAGIC_NUMBER)
{
fprintf(stderr,"\n** Sanity check failed -- audblk magic number 3 **");
error_flag = 1;
}
for(i = 0;i < 5 ; i++)
{
if (audblk->fbw_exp[i][255] !=0 || audblk->fbw_exp[i][254] !=0 ||
audblk->fbw_exp[i][253] !=0)
{
fprintf(stderr,"\n** Sanity check failed -- fbw_exp out of bounds **");
error_flag = 1;
}
if (audblk->fbw_bap[i][255] !=0 || audblk->fbw_bap[i][254] !=0 ||
audblk->fbw_bap[i][253] !=0)
{
fprintf(stderr,"\n** Sanity check failed -- fbw_bap out of bounds **");
error_flag = 1;
}
}
if (audblk->cpl_exp[255] !=0 || audblk->cpl_exp[254] !=0 ||
audblk->cpl_exp[253] !=0)
{
fprintf(stderr,"\n** Sanity check failed -- cpl_exp out of bounds **");
error_flag = 1;
}
if (audblk->cpl_bap[255] !=0 || audblk->cpl_bap[254] !=0 ||
audblk->cpl_bap[253] !=0)
{
fprintf(stderr,"\n** Sanity check failed -- cpl_bap out of bounds **");
error_flag = 1;
}
if (audblk->cplmant[255] !=0 || audblk->cplmant[254] !=0 ||
audblk->cplmant[253] !=0)
{
fprintf(stderr,"\n** Sanity check failed -- cpl_mant out of bounds **");
error_flag = 1;
}
if ((audblk->cplinu == 1) && (audblk->cplbegf > (audblk->cplendf+2)))
{
fprintf(stderr,"\n** Sanity check failed -- cpl params inconsistent **");
error_flag = 1;
}
for(i=0; i < bsi->nfchans; i++)
{
if((audblk->chincpl[i] == 0) && (audblk->chbwcod[i] > 60))
{
fprintf(stderr,"\n** Sanity check failed -- chbwcod too big **");
error_flag = 1;
}
}
return;
}

View file

@ -1,27 +0,0 @@
/*
* sanity_check.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#define AC3_MAGIC_NUMBER 0xdeadbeef
void sanity_check_init(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk);
void sanity_check(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk);

View file

@ -1,178 +0,0 @@
/*
* stats.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "config.h"
#include "ac3.h"
#include "ac3_internal.h"
#include "decode.h"
#include "stats.h"
#include "debug.h"
static const char *service_ids[8] =
{
"CM","ME","VI","HI",
"D", "C","E", "VO"
};
struct mixlev_s
{
float clev;
char *desc;
};
static const struct mixlev_s cmixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"},
{0.500, "(-6.0 dB)"}, {1.0, "Invalid"}
};
static const struct mixlev_s smixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"},
{ 0.0, "off "}, { 1.0, "Invalid"}
};
static const char *language[128] =
{
"unknown", "Albanian", "Breton", "Catalan", "Croatian", "Welsh", "Czech", "Danish",
"German", "English", "Spanish", "Esperanto", "Estonian", "Basque", "Faroese", "French",
"Frisian", "Irish", "Gaelic", "Galician", "Icelandic", "Italian", "Lappish", "Latin",
"Latvian", "Luxembourgian", "Lithuanian", "Hungarian", "Maltese", "Dutch", "Norwegian", "Occitan",
"Polish", "Portugese", "Romanian", "Romansh", "Serbian", "Slovak", "Slovene", "Finnish",
"Swedish", "Turkish", "Flemish", "Walloon", "0x2c", "0x2d", "0x2e", "0x2f",
"0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37",
"0x38", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "0x3f",
"background", "0x41", "0x42", "0x43", "0x44", "Zulu", "Vietnamese", "Uzbek",
"Urdu", "Ukrainian", "Thai", "Telugu", "Tatar", "Tamil", "Tadzhik", "Swahili",
"Sranan Tongo", "Somali", "Sinhalese", "Shona", "Serbo-Croat", "Ruthenian", "Russian", "Quechua",
"Pustu", "Punjabi", "Persian", "Papamiento", "Oriya", "Nepali", "Ndebele", "Marathi",
"Moldavian", "Malaysian", "Malagasay", "Macedonian", "Laotian", "Korean", "Khmer", "Kazakh",
"Kannada", "Japanese", "Indonesian", "Hindi", "Hebrew", "Hausa", "Gurani", "Gujurati",
"Greek", "Georgian", "Fulani", "Dari", "Churash", "Chinese", "Burmese", "Bulgarian",
"Bengali", "Belorussian", "Bambora", "Azerbijani", "Assamese", "Armenian", "Arabic", "Amharic"
};
void stats_print_banner(syncinfo_t *syncinfo,bsi_t *bsi)
{
// fprintf(stdout,PACKAGE"-"VERSION" (C) 2000 Aaron Holtzman (aholtzma@ess.engr.uvic.ca)\n");
fprintf(stdout,"%d.%d Mode ",bsi->nfchans,bsi->lfeon);
fprintf(stdout,"%2.1f KHz",syncinfo->sampling_rate * 1e-3);
fprintf(stdout,"%4d kbps ",syncinfo->bit_rate);
if (bsi->langcode && (bsi->langcod < 128))
fprintf(stdout,"%s ", language[bsi->langcod]);
switch(bsi->bsmod)
{
case 0:
fprintf(stdout,"Complete Main Audio Service");
break;
case 1:
fprintf(stdout,"Music and Effects Audio Service");
case 2:
fprintf(stdout,"Visually Impaired Audio Service");
break;
case 3:
fprintf(stdout,"Hearing Impaired Audio Service");
break;
case 4:
fprintf(stdout,"Dialogue Audio Service");
break;
case 5:
fprintf(stdout,"Commentary Audio Service");
break;
case 6:
fprintf(stdout,"Emergency Audio Service");
break;
case 7:
fprintf(stdout,"Voice Over Audio Service");
break;
}
fprintf(stdout,"\n");
}
void stats_print_syncinfo(syncinfo_t *syncinfo)
{
dprintf("(syncinfo) ");
switch (syncinfo->fscod)
{
case 2:
dprintf("32 KHz ");
break;
case 1:
dprintf("44.1 KHz ");
break;
case 0:
dprintf("48 KHz ");
break;
default:
dprintf("Invalid sampling rate ");
break;
}
dprintf("%4d kbps %4d words per frame\n",syncinfo->bit_rate,
syncinfo->frame_size);
}
void stats_print_bsi(bsi_t *bsi)
{
dprintf("(bsi) ");
dprintf("%s",service_ids[bsi->bsmod]);
dprintf(" %d.%d Mode ",bsi->nfchans,bsi->lfeon);
if ((bsi->acmod & 0x1) && (bsi->acmod != 0x1))
dprintf(" Centre Mix Level %s ",cmixlev_tbl[bsi->cmixlev].desc);
if (bsi->acmod & 0x4)
dprintf(" Sur Mix Level %s ",smixlev_tbl[bsi->cmixlev].desc);
dprintf("\n");
}
char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "};
void stats_print_audblk(bsi_t *bsi,audblk_t *audblk)
{
uint_32 i;
dprintf("(audblk) ");
dprintf("%s ",audblk->cplinu ? "cpl on " : "cpl off");
dprintf("%s ",audblk->baie? "bai " : " ");
dprintf("%s ",audblk->snroffste? "snroffst " : " ");
dprintf("%s ",audblk->deltbaie? "deltba " : " ");
dprintf("%s ",audblk->phsflginu? "phsflg " : " ");
dprintf("(%s %s %s %s %s) ",exp_strat_tbl[audblk->chexpstr[0]],
exp_strat_tbl[audblk->chexpstr[1]],exp_strat_tbl[audblk->chexpstr[2]],
exp_strat_tbl[audblk->chexpstr[3]],exp_strat_tbl[audblk->chexpstr[4]]);
dprintf("[");
for(i=0;i<bsi->nfchans;i++)
dprintf("%1d",audblk->blksw[i]);
dprintf("]");
dprintf("\n");
}

View file

@ -1,27 +0,0 @@
/*
* stats.h
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
void stats_print_syncinfo(syncinfo_t *syncinfo);
void stats_print_bsi(bsi_t *bsi);
void stats_print_audblk(bsi_t *bsi,audblk_t *audblk);
void stats_print_banner(syncinfo_t *syncinfo,bsi_t *bsi);

View file

@ -1,224 +0,0 @@
/*
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <alloca.h>
#include <string.h>
#include <unistd.h>
#include <alsa/asoundlib.h>
typedef signed short sint_16;
typedef unsigned int uint_32;
#include "output.h"
static output_t out_config;
static snd_pcm_t *pcm;
/*
* open the audio device for writing to
*/
int output_open(output_t *output)
{
const char *pcm_name = output->pcm_name;
char devstr[128];
const char *basedev;
snd_pcm_hw_params_t *params;
unsigned int rate, buffer_time, period_time, tmp;
snd_pcm_format_t format = output->bits == 16 ? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U8;
int err, step;
snd_pcm_hw_params_alloca(&params);
out_config = *output;
/*
* Open the device driver
*/
if (pcm_name == NULL) {
switch (output->channels) {
case 1:
case 2:
if (output->spdif != SPDIF_NONE) {
unsigned char s[4];
if (output->spdif == SPDIF_PRO) {
s[0] = (IEC958_AES0_PROFESSIONAL |
IEC958_AES0_NONAUDIO |
IEC958_AES0_PRO_EMPHASIS_NONE |
IEC958_AES0_PRO_FS_48000);
s[1] = (IEC958_AES1_PRO_MODE_NOTID |
IEC958_AES1_PRO_USERBITS_NOTID);
s[2] = IEC958_AES2_PRO_WORDLEN_NOTID;
s[3] = 0;
} else {
s[0] = IEC958_AES0_CON_EMPHASIS_NONE;
if (output->spdif == SPDIF_CON)
s[0] |= IEC958_AES0_NONAUDIO;
s[1] = (IEC958_AES1_CON_ORIGINAL |
IEC958_AES1_CON_PCM_CODER);
s[2] = 0;
s[3] = IEC958_AES3_CON_FS_48000;
}
if (output->hdmi)
basedev = "hdmi";
else
basedev = "iec958";
sprintf(devstr, "plug:%s:{"
"AES0 0x%x AES1 0x%x "
"AES2 0x%x AES3 0x%x",
basedev,
s[0], s[1], s[2], s[3]);
if (out_config.card)
sprintf(devstr + strlen(devstr),
" CARD %s", out_config.card);
strcat(devstr, "}");
format = SND_PCM_FORMAT_S16_LE;
} else {
if (out_config.card)
sprintf(devstr, "plughw:%s", out_config.card);
else
sprintf(devstr, "default");
}
break;
case 4:
strcpy(devstr, "plug:surround40");
if (out_config.card)
sprintf(devstr + strlen(devstr), ":{CARD %s}", out_config.card);
break;
case 6:
strcpy(devstr, "plug:surround51");
if (out_config.card)
sprintf(devstr + strlen(devstr), ":{CARD %s}", out_config.card);
break;
default:
fprintf(stderr, "%d channels are not supported\n", output->channels);
return -EINVAL;
}
pcm_name = devstr;
}
if (!output->quiet)
fprintf(stdout, "Using PCM device '%s'\n", pcm_name);
if ((err = snd_pcm_open(&pcm, pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
fprintf(stderr, "snd_pcm_open: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_any(pcm, params);
if (err < 0) {
fprintf(stderr, "Broken configuration for this PCM: no configurations available");
goto __close;
}
/* set interleaved access */
err = snd_pcm_hw_params_set_access(pcm, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
fprintf(stderr, "Access type not available\n");
goto __close;
}
err = snd_pcm_hw_params_set_format(pcm, params, format);
if (err < 0) {
fprintf(stderr, "Sample format non available\n");
goto __close;
}
err = snd_pcm_hw_params_set_channels(pcm, params, output->channels);
if (err < 0) {
fprintf(stderr, "Channels count non available\n");
goto __close;
}
rate = output->rate;
err = snd_pcm_hw_params_set_rate_near(pcm, params, &rate, 0);
if (err < 0) {
fprintf(stderr, "Rate not available\n");
goto __close;
}
buffer_time = 500000;
err = snd_pcm_hw_params_set_buffer_time_near(pcm, params, &buffer_time, 0);
if (err < 0) {
fprintf(stderr, "Buffer time not available\n");
goto __close;
}
step = 2;
period_time = 10000 * 2;
do {
period_time /= 2;
tmp = period_time;
err = snd_pcm_hw_params_set_period_time_near(pcm, params, &tmp, 0);
if (err < 0) {
fprintf(stderr, "Period time not available\n");
goto __close;
}
if (tmp == period_time) {
period_time /= 3;
tmp = period_time;
err = snd_pcm_hw_params_set_period_time_near(pcm, params, &tmp, 0);
if (tmp == period_time)
period_time = 10000 * 2;
}
} while (buffer_time == period_time && period_time > 10000);
if (buffer_time == period_time) {
fprintf(stderr, "Buffer time and period time match, could not use\n");
goto __close;
}
if ((err = snd_pcm_hw_params(pcm, params)) < 0) {
fprintf(stderr, "PCM hw_params failed: %s\n", snd_strerror(err));
goto __close;
}
return 0;
__close:
snd_pcm_close(pcm);
pcm = NULL;
return err;
}
/*
* play the sample to the already opened file descriptor
*/
int output_play(sint_16* output_samples, uint_32 num_frames)
{
snd_pcm_sframes_t res = 0;
do {
if (res == -EPIPE) /* underrun */
res = snd_pcm_prepare(pcm);
else if (res == -ESTRPIPE) { /* suspend */
while ((res = snd_pcm_resume(pcm)) == -EAGAIN)
sleep(1);
if (res < 0)
res = snd_pcm_prepare(pcm);
}
res = res < 0 ? res : snd_pcm_writei(pcm, (void *)output_samples, num_frames);
if (res > 0) {
output_samples += out_config.channels * res;
num_frames -= res;
}
} while (res == -EPIPE || num_frames > 0);
if (res < 0)
fprintf(stderr, "writei returned error: %s\n", snd_strerror(res));
return res < 0 ? (int)res : 0;
}
void
output_close(void)
{
snd_pcm_close(pcm);
}

View file

@ -1,40 +0,0 @@
/*
*
* output.h
*
* Based on original code by Angus Mackay (amackay@gus.ml.org)
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
typedef struct {
const char *pcm_name;
char *card;
int bits;
int rate;
int channels;
unsigned int quiet: 1;
unsigned int hdmi: 1;
enum {SPDIF_NONE = 0, SPDIF_CON, SPDIF_PRO, SPDIF_PCM} spdif;
} output_t;
int output_open(output_t *output);
int output_play(sint_16* output_samples, uint_32 num_bytes);
void output_close(void);

View file

@ -1,17 +0,0 @@
window_size = 2048;
f = 0:48000/window_size:48000 * (1 - 1/window_size);
w = transpose(hamming(1536));
n = size(foo,1);
spectrum = zeros(1,window_size);
for i = [1:n]
data = w .* foo(i,:);
spectrum = spectrum + abs(fft(data,window_size));
end
plot(f,10*log10(spectrum/max(spectrum)));
grid;
axis([0 24000 -40 0]);

View file

@ -1,37 +0,0 @@
INCLUDES = -I../libac3
noinst_PROGRAMS = imdct_test dither_test
#noinst_PROGRAMS = bitstream_test imdct_test imdct_timing uncouple_timing\
#crc_timing
noinst_HEADERS = timing.h
#bitstream_test_SOURCES = bitstream_test.c
#bitstream_test_LDADD = ../bitstream.o ../crc.o
#
dither_test_SOURCES = dither_test.c
dither_test_LDADD = ../libac3/dither.o
imdct_test_SOURCES = imdct_test.c
imdct_test_LDADD = ../libac3/imdct.o -lm
#
#imdct_timing_SOURCES = imdct_timing.c timing.c
#imdct_timing_LDADD = ../imdct.o -lm
#
#uncouple_timing_SOURCES = uncouple_timing.c timing.c
#uncouple_timing_LDADD = ../uncouple.o ../dither.o -lm
#
#crc_timing_SOURCES = crc_timing.c timing.c
#crc_timing_LDADD = ../crc.o -lm
check:
# rm -f bitstream_test.out
# ./bitstream_test > bitstream_test.out
# diff bitstream_test.out bitstream_test.out.ref
# rm -f imdct_test.out
# ./imdct_test > imdct_test.out
# diff imdct_test.out imdct_test.out.ref
rm -f dither_test.out
./dither_test > dither_test.out
diff dither_test.out dither_test.out.ref
clean:
rm -f *.out

View file

@ -1,43 +0,0 @@
/*
* dither_test.c
*
* Aaron Holtzman - May 1999
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "dither.h"
#include <sys/time.h>
#include <unistd.h>
int main(void)
{
int i,j,foo;
struct timeval start,end;
/*
for(i=0;i < 65538 ;i++)
//printf("%04x\n",dither_gen());
printf("%f\n",((sint_16)dither_gen())/ 32768.0);
printf("\n");
*/
for(j=0;j < 10 ;j++)
{
gettimeofday(&start,0);
for(i=0;i < 10000 ;i++)
{
foo = dither_gen();
}
gettimeofday(&end,0);
printf("%f us\n",((end.tv_sec - start.tv_sec) * 1000000 +
(end.tv_usec - start.tv_usec))/10000.0);
}
}

View file

@ -1,38 +0,0 @@
/*
* imdct_test.c
*
* Aaron Holtzman - May 1999
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "imdct.h"
static stream_samples_t samples;
static bsi_t bsi;
static audblk_t audblk;
int main(void)
{
int i;
samples[0][20] = 0.4;
samples[0][40] = 0.4;
samples[0][30] = 1.0;
imdct_init();
bsi.nfchans = 1;
imdct(&bsi,&audblk,samples);
for(i=0;i<256;i++)
printf("%1.8f\n",samples[0][i]);
return 0;
}

View file

@ -1,14 +0,0 @@
/*
* timing.h
*
* Aaron Holtzman - May 1999
*
*/
//uint_64 get_time(void);
uint_64 timing_init(void);
void timing_test_2(void (*func)(void*,void*),void *arg_1,void *arg_2,char name[]);
void timing_test_3(void (*func)(void*,void*,void*),void *arg_1,void *arg_2,void *arg_3,char name[]);
double timing_once_3(void (*func)(void*,void*,void*),void *arg_1,void *arg_2,void *arg_3);

View file

@ -1,12 +0,0 @@
# # Process this file with automake to produce Makefile.in.
AUTOMAKE_OPTIONS = 1.3 foreign
CFLAGS = -Wall -O3 -g
bin_PROGRAMS = extract_ac3
extract_ac3_SOURCES = extract_ac3.c
#verify is broken right now
#verify_ac3_SOURCES = verify_ac3.c
#verify_ac3_LDADD = ../parse.o ../bitstream.o ../crc.o ../debug.o ../stats.o

View file

@ -1,314 +0,0 @@
/*
* extract_ac3.c
*
* Copyright (C) Aaron Holtzman <aholtzma@ess.engr.uvic.ca> - June 1999
*
* Extracts an AC-3 audio stream from an MPEG-2 system stream
* and writes it to stdout
*
* Ideas and bitstream syntax info borrowed from code written
* by Nathan Laredo <laredo@gnu.org>
*
* Multiple track support by Yuqing Deng <deng@tinker.chem.brown.edu>
*
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* ac3dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation,
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mman.h>
/* Audio track to play */
static unsigned char track_code = 0x80;
static unsigned char track_table[8] =
{
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87
};
#define BUFSIZE 512 /* needs to be as big as biggest header */
static int vobf;
static unsigned char buf[BUFSIZE];
static unsigned char *cur_pos;
static unsigned char *end_pos;
void file_init(char file_name[])
{
if(file_name[0] == '-' && file_name[1] == '\0')
{
vobf = STDIN_FILENO;
}
else if ((vobf = open(file_name, O_RDONLY)) < 0)
{
fprintf(stderr,"File not found\n");
exit(1);
}
cur_pos = buf;
end_pos = buf;
}
inline void increment_position(long x)
{
if(cur_pos + x <= end_pos)
{
cur_pos += x;
if(cur_pos == end_pos)
{
cur_pos = buf;
end_pos = buf;
}
}
else
{
long size = 0;
x -= (long)(end_pos - cur_pos);
#ifdef SEEK_PIPES
if(lseek(vobf, x, SEEK_CUR) < 0)
{
fprintf(stderr, "Error: unexpected end of stream\n");
exit(1);
}
#else
while(x)
{
size = (x > BUFSIZE) ? BUFSIZE : x;
if(read(vobf, buf, size) < size)
{
fprintf(stderr, "Error: unexpected end of stream\n");
exit(1);
}
x-=size;
}
#endif
cur_pos = buf;
end_pos = buf;
}
}
inline static void load_next_bytes(long count)
{
if(cur_pos + count <= end_pos)
return;
if(cur_pos + count > buf + BUFSIZE - 1 )
{
printf ("No buffer space to read %ld bytes\n", count);
exit(1);
}
count -= (long)(end_pos - cur_pos);
if(read(vobf, end_pos, count) < count)
{
fprintf(stderr, "Error: unexpected end of stream\n");
exit(1);
}
end_pos += count;
}
inline int next_24_bits(long x)
{
load_next_bytes(3);
if (cur_pos[0] != ((x >> 16) & 0xff))
return 0;
if (cur_pos[1] != ((x >> 8) & 0xff))
return 0;
if (cur_pos[2] != ((x ) & 0xff))
return 0;
return 1;
}
inline int next_32_bits(long x)
{
load_next_bytes(4);
if (cur_pos[0] != ((x >> 24) & 0xff))
return 0;
if (cur_pos[1] != ((x >> 16) & 0xff))
return 0;
if (cur_pos[2] != ((x >> 8) & 0xff))
return 0;
if (cur_pos[3] != ((x ) & 0xff))
return 0;
return 1;
}
void read_write_next_bytes(long count, int outfd)
{
long size;
size = (long)(end_pos - cur_pos);
if(size > count)
{
write(outfd, cur_pos, count);
cur_pos +=count;
if(cur_pos == end_pos)
{
cur_pos = buf;
end_pos = buf;
}
return;
}
else if(size > 0)
{
write(outfd, cur_pos, size);
}
while(count)
{
size = (count > BUFSIZE) ? BUFSIZE : count;
if(read(vobf, buf, size) < size ||
write(outfd, buf, size) < size)
{
fprintf(stderr, "Error: unexpected end of stream\n");
}
count -= size;
}
cur_pos = buf;
end_pos = buf;
}
void parse_pes(void)
{
unsigned long data_length;
unsigned long header_length;
load_next_bytes(9);
//The header length is the PES_header_data_length byte plus 6 for the packet
//start code and packet size, 3 for the PES_header_data_length and two
//misc bytes, and finally 4 bytes for the mystery AC3 packet tag
header_length = cur_pos[8] + 6 + 3 + 4 ;
data_length =(cur_pos[4]<<8) + cur_pos[5];
//If we have AC-3 audio then output it
if(cur_pos[3] == 0xbd)
{
load_next_bytes(header_length);
#if 0
//Debugging printfs
fprintf(stderr,"start of pes curpos[] = %02x%02x%02x%02x\n",
cur_pos[0],cur_pos[1],cur_pos[2],cur_pos[3]);
fprintf(stderr,"header_length = %d data_length = %x\n",
header_length, data_length);
fprintf(stderr,"extra crap 0x%02x%02x%02x%02x data size 0x%0lx\n",cur_pos[header_length-4],
cur_pos[header_length-3],cur_pos[header_length-2],cur_pos[header_length-1],data_length);
#endif
//Only extract the track we want
if((cur_pos[header_length-4] == track_code ))
{
increment_position(header_length);
read_write_next_bytes(data_length - header_length + 6, STDOUT_FILENO);
}
else
{
increment_position(data_length + 6);
}
}
else
{
//The packet size is data_length plus 6 bytes to account for the
//packet start code and the data_length itself.
increment_position(data_length + 6);
}
}
void parse_pack(void)
{
unsigned long skip_length;
// Deal with the pack header
// The first 13 bytes are junk. The fourteenth byte
// contains the number of stuff bytes
load_next_bytes(14);
skip_length = cur_pos[13] & 0x7;
increment_position(14 + skip_length);
// Deal with the system header if it exists
if(next_32_bits(0x000001bb))
{
// Bytes 5 and 6 contain the length of the header minus 6
load_next_bytes(6);
skip_length = (cur_pos[4] << 8) + cur_pos[5];
increment_position(6 + skip_length);
}
while(next_24_bits(0x000001) && !next_32_bits(0x000001ba))
{
parse_pes();
}
}
int main(int argc, char *argv[])
{
int track = 0;
if (argc < 2) {
fprintf(stderr, "usage: %s mpeg_stream [track number]\n", argv[0]);
exit(1);
}
if (argc == 3)
{
track = strtol(argv[2], NULL, 0);
fprintf(stderr,"Extracting track %d\n",track);
}
if (track < 0 || track > 7)
{
fprintf(stderr, "Invalid track number: %d\n", track);
exit(1);
}
track_code = track_table[track];
file_init(argv[1]);
if(!next_32_bits(0x000001ba))
{
fprintf(stderr, "Non-program streams not handled - exiting\n\n");
exit(1);
}
do
{
parse_pack();
}
while(next_32_bits(0x000001ba));
fprintf(stderr,"curpos[] = %x%x%x%x\n",cur_pos[0],cur_pos[1],cur_pos[2],cur_pos[3]);
if(!next_32_bits(0x000001b9))
{
fprintf(stderr, "Error: expected end of stream code\n");
exit(1);
}
if(vobf != STDIN_FILENO) close(vobf);
return 0;
}