1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Removed DVD support from the core VDR source

This commit is contained in:
Klaus Schmidinger 2002-02-24 14:07:21 +01:00
parent 44ee59b21a
commit 715ed57ab1
66 changed files with 26 additions and 8485 deletions

View File

@ -1031,3 +1031,12 @@ Video Disk Recorder Revision History
or don't have the equipment to replay Dolby Digital audio.
- Reading the 'setup.conf' file no longer terminates in case of an error, but
rather attempts to read the rest of the file.
- Removed DVD support from the core VDR source, since the current version from
Andreas Schultz is already much further developed (DVD menu navigation) and
the concept of "additional players" in VDR is going to change in version 1.1.0,
where a new "plugin" interface shall allow the easy implementation of new
players without having to patch the core VDR source. Until then, Andreas has
agreed to provide his DVD support as a completely external patch.
- The contents of the distribution archive now contains the directory name with
the current version number, as in 'vdr-1.0.0pre1/...' in order to avoid
inadvertently overwriting an existing VDR directory with a new version.

30
INSTALL
View File

@ -15,23 +15,6 @@ If you have the DVB driver source in a different location
you will have to change the definition of DVBDIR in the
Makefile.
If you want to use your DVD drive you will need to compile VDR with
make DVD=1
to activate DVD support. VDR then also needs the package 'libdvdread'
in order to replay DVDs. This package is expected to be located in the
directory ../DVD (seen from the VDR directory). Adjust the definition
of DVDDIR in the Makefile if necessary.
You can find 'libdvdread' at
http://www.dtek.chalmers.se/groups/dvd/downloads.shtml
If you want to replay CSS encrypted DVDs you also need to get the 'libdvdcss'
library from
http://www.videolan.org/libdvdcss/download.html
VDR requires the Linux-DVB card driver version dated 2001-09-14 or higher
to work properly.
@ -250,19 +233,6 @@ This program must be given to VDR with the '-a' option, as in
vdr -a ac3play
Accessing the DVD drive:
------------------------
By default VDR expects the DVD drive to be located at /dev/dvd (which
typically is a symbolic link to the actual device, for instance /dev/hdc).
You can use the '-V' option to overwrite this, as in
vdr -V /media/dvd
Note that the user id under which VDR runs needs to have write access to
the DVD device in order to replay CSS protected DVDs (which also requires
the presence of the 'libdvdcss' library).
The video data directory:
-------------------------

2
MANUAL
View File

@ -19,7 +19,7 @@ Video Disk Recorder User's Manual
Back - Menu off Main menu Main menu Discard Main menu Recordings menu
Red - Record Edit Edit - Play Jump
Green - Language New New - Rewind Skip -60s
Yellow - Eject DVD Delete Delete - Delete Skip +60s
Yellow - - Delete Delete - Delete Skip +60s
Blue - Resume Mark On/Off(1) - Summary Stop
0..9 Ch select - - - Numeric inp. - Editing

View File

@ -4,29 +4,18 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
# $Id: Makefile 1.30 2002/02/01 14:40:09 kls Exp $
# $Id: Makefile 1.31 2002/02/24 12:29:54 kls Exp $
.DELETE_ON_ERROR:
DVBDIR = ../DVB
DVDDIR = ../DVD
AC3DIR = ./ac3dec
DTVDIR = ./libdtv
INCLUDES = -I$(DVBDIR)/ost/include
DTVLIB = $(DTVDIR)/libdtv.a
ifdef DVD
INCLUDES += -I$(DVDDIR)/libdvdread
LIBDIRS += -L$(DVDDIR)/libdvdread/dvdread/.libs
DEFINES += -DDVDSUPPORT
DEFINES += -D_LARGEFILE64_SOURCE # needed by libdvdread
AC3LIB = $(AC3DIR)/libac3.a
DVDLIB = -ldvdread
endif
OBJS = config.o dvbapi.o dvbosd.o dvd.o eit.o font.o i18n.o interface.o menu.o osd.o\
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o i18n.o interface.o menu.o osd.o\
recording.o remote.o remux.o ringbuffer.o svdrp.o thread.o tools.o vdr.o\
videodir.o
@ -75,8 +64,8 @@ include $(DEPFILE)
# The main program:
vdr: $(OBJS) $(AC3LIB) $(DTVLIB)
g++ -g -O2 $(OBJS) $(NCURSESLIB) -ljpeg -lpthread $(LIBDIRS) $(DVDLIB) $(AC3LIB) $(DTVLIB) -o vdr
vdr: $(OBJS) $(DTVLIB)
g++ -g -O2 $(OBJS) $(NCURSESLIB) -ljpeg -lpthread $(LIBDIRS) $(DTVLIB) -o vdr
# The font files:
@ -90,11 +79,6 @@ fontosd.c:
genfontfile: genfontfile.c
gcc -o $@ -O2 -L/usr/X11R6/lib $< -lX11
# The ac3dec library:
$(AC3LIB):
make -C $(AC3DIR) all
# The libdtv library:
$(DTVLIB) $(DTVDIR)/libdtv.h:
@ -103,7 +87,6 @@ $(DTVLIB) $(DTVDIR)/libdtv.h:
# Housekeeping:
clean:
make -C $(AC3DIR) clean
make -C $(DTVDIR) clean
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~
fontclean:

View File

@ -1,28 +0,0 @@
#
# Makefile for 'ac3dec'
#
# $Id: Makefile 1.2 2001/08/09 11:41:39 kls Exp $
#OBJS = coeff.o decode.o exponent.o rematrix.o bit_allocate.o crc.o dither.o\
# imdct.o sanity_check.o bitstream.o debug.o downmix.o parse.o stats.o\
# downmix_c.o imdct.o
OBJS = bit_allocate.o bitstream.o coeff.o cpu_accel.o crc.o debug.o decode.o\
dither.o downmix.o downmix_c.o exponent.o imdct.o imdct_c.o imdct_kni.o\
parse.o rematrix.o sanity_check.o srfft.o srfft_kni_c.o stats.o
DEFINES += -DDOLBY_SURROUND
all: libac3.a
libac3.a: $(OBJS)
ar -rc libac3.a $(OBJS)
# Implicit rules:
%.o: %.c
gcc -g -O2 -Wall -m486 -I./ -c $(DEFINES) $<
clean:
rm -f *~ libac3.a $(OBJS)

View File

@ -1,64 +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.
*
*------------------------------------------------------------
*
* 24 Nov 2001
* Andreas Schultz <aschultz@cs.uni-magdeburg.de>
* Added ac3_buffersize()
*/
#define AC3_BUFFER_SIZE (6*1024*16)
#ifndef __AC3_H__
#define __AC3_H__
#ifdef __OMS__
#include <oms/plugin/output_audio.h>
#else
//#include "audio_out.h"
#endif
#include <inttypes.h>
#define AC3_DOLBY_SURR_ENABLE (1<<0)
#define AC3_ALTIVEC_ENABLE (1<<1)
typedef struct ac3_config_s {
// Bit flags that enable various things
uint32_t flags;
// Number of discrete channels in final output (for downmixing)
uint16_t num_output_ch;
// Which channel of a dual mono stream to select
uint16_t dual_mono_ch_sel;
} ac3_config_t;
void ac3dec_init (void);
#ifdef __OMS__
size_t ac3dec_decode_data (plugin_output_audio_t *output, uint8_t *data_start, uint8_t *data_end);
#else
size_t ac3dec_decode_data (uint8_t *data_start ,uint8_t *data_end, int ac3reset, int *input_pointer, int *output_pointer, char *ac3_data);
#endif
uint32_t ac3_buffersize();
#endif

View File

@ -1,353 +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
#include <setjmp.h>
/* 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 jmp_buf error_jmp_mark;
#define HANDLE_ERROR() longjmp (error_jmp_mark, -1)
/* 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
{
uint32_t magic;
/* Sync word == 0x0B77 */
uint16_t syncword;
/* crc for the first 5/8 of the sync block */
/* uint16_t crc1; */
/* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
uint16_t fscod;
/* Frame size code */
uint16_t frmsizecod;
/* Information not in the AC-3 bitstream, but derived */
/* Frame size in 16 bit words */
uint16_t frame_size;
/* Bit rate in kilobits */
uint16_t bit_rate;
/* sampling rate in hertz */
uint32_t sampling_rate;
} syncinfo_t;
typedef struct bsi_s
{
uint32_t magic;
/* Bit stream identification == 0x8 */
uint16_t bsid;
/* Bit stream mode */
uint16_t bsmod;
/* Audio coding mode */
uint16_t acmod;
/* If we're using the centre channel then */
/* centre mix level */
uint16_t cmixlev;
/* If we're using the surround channel then */
/* surround mix level */
uint16_t surmixlev;
/* If we're in 2/0 mode then */
/* Dolby surround mix level - NOT USED - */
uint16_t dsurmod;
/* Low frequency effects on */
uint16_t lfeon;
/* Dialogue Normalization level */
uint16_t dialnorm;
/* Compression exists */
uint16_t compre;
/* Compression level */
uint16_t compr;
/* Language code exists */
uint16_t langcode;
/* Language code */
uint16_t langcod;
/* Audio production info exists*/
uint16_t audprodie;
uint16_t mixlevel;
uint16_t roomtyp;
/* If we're in dual mono mode (acmod == 0) then extra stuff */
uint16_t dialnorm2;
uint16_t compr2e;
uint16_t compr2;
uint16_t langcod2e;
uint16_t langcod2;
uint16_t audprodi2e;
uint16_t mixlevel2;
uint16_t roomtyp2;
/* Copyright bit */
uint16_t copyrightb;
/* Original bit */
uint16_t origbs;
/* Timecode 1 exists */
uint16_t timecod1e;
/* Timecode 1 */
uint16_t timecod1;
/* Timecode 2 exists */
uint16_t timecod2e;
/* Timecode 2 */
uint16_t timecod2;
/* Additional bit stream info exists */
uint16_t addbsie;
/* Additional bit stream length - 1 (in bytes) */
uint16_t addbsil;
/* Additional bit stream information (max 64 bytes) */
uint8_t addbsi[64];
/* Information not in the AC-3 bitstream, but derived */
/* Number of channels (excluding LFE)
* Derived from acmod */
uint16_t nfchans;
} bsi_t;
/* more pain */
typedef struct audblk_s
{
uint32_t magic1;
/* block switch bit indexed by channel num */
uint16_t blksw[5];
/* dither enable bit indexed by channel num */
uint16_t dithflag[5];
/* dynamic range gain exists */
uint16_t dynrnge;
/* dynamic range gain */
uint16_t dynrng;
/* if acmod==0 then */
/* dynamic range 2 gain exists */
uint16_t dynrng2e;
/* dynamic range 2 gain */
uint16_t dynrng2;
/* coupling strategy exists */
uint16_t cplstre;
/* coupling in use */
uint16_t cplinu;
/* channel coupled */
uint16_t chincpl[5];
/* if acmod==2 then */
/* Phase flags in use */
uint16_t phsflginu;
/* coupling begin frequency code */
uint16_t cplbegf;
/* coupling end frequency code */
uint16_t cplendf;
/* coupling band structure bits */
uint16_t cplbndstrc[18];
/* Do coupling co-ords exist for this channel? */
uint16_t cplcoe[5];
/* Master coupling co-ordinate */
uint16_t mstrcplco[5];
/* Per coupling band coupling co-ordinates */
uint16_t cplcoexp[5][18];
uint16_t cplcomant[5][18];
/* Phase flags for dual mono */
uint16_t phsflg[18];
/* Is there a rematrixing strategy */
uint16_t rematstr;
/* Rematrixing bits */
uint16_t rematflg[4];
/* Coupling exponent strategy */
uint16_t cplexpstr;
/* Exponent strategy for full bandwidth channels */
uint16_t chexpstr[5];
/* Exponent strategy for lfe channel */
uint16_t lfeexpstr;
/* Channel bandwidth for independent channels */
uint16_t chbwcod[5];
/* The absolute coupling exponent */
uint16_t cplabsexp;
/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
uint16_t cplexps[18 * 12 / 3];
/* Sanity checking constant */
uint32_t magic2;
/* fbw channel exponents */
uint16_t exps[5][252 / 3];
/* channel gain range */
uint16_t gainrng[5];
/* low frequency exponents */
uint16_t lfeexps[3];
/* Bit allocation info */
uint16_t baie;
/* Slow decay code */
uint16_t sdcycod;
/* Fast decay code */
uint16_t fdcycod;
/* Slow gain code */
uint16_t sgaincod;
/* dB per bit code */
uint16_t dbpbcod;
/* masking floor code */
uint16_t floorcod;
/* SNR offset info */
uint16_t snroffste;
/* coarse SNR offset */
uint16_t csnroffst;
/* coupling fine SNR offset */
uint16_t cplfsnroffst;
/* coupling fast gain code */
uint16_t cplfgaincod;
/* fbw fine SNR offset */
uint16_t fsnroffst[5];
/* fbw fast gain code */
uint16_t fgaincod[5];
/* lfe fine SNR offset */
uint16_t lfefsnroffst;
/* lfe fast gain code */
uint16_t lfefgaincod;
/* Coupling leak info */
uint16_t cplleake;
/* coupling fast leak initialization */
uint16_t cplfleak;
/* coupling slow leak initialization */
uint16_t cplsleak;
/* delta bit allocation info */
uint16_t deltbaie;
/* coupling delta bit allocation exists */
uint16_t cpldeltbae;
/* fbw delta bit allocation exists */
uint16_t deltbae[5];
/* number of cpl delta bit segments */
uint16_t cpldeltnseg;
/* coupling delta bit allocation offset */
uint16_t cpldeltoffst[8];
/* coupling delta bit allocation length */
uint16_t cpldeltlen[8];
/* coupling delta bit allocation length */
uint16_t cpldeltba[8];
/* number of delta bit segments */
uint16_t deltnseg[5];
/* fbw delta bit allocation offset */
uint16_t deltoffst[5][8];
/* fbw delta bit allocation length */
uint16_t deltlen[5][8];
/* fbw delta bit allocation length */
uint16_t deltba[5][8];
/* skip length exists */
uint16_t skiple;
/* skip length */
uint16_t skipl;
//Removed Feb 2000 -ah
//added Jul 2000 ++dent
/* channel mantissas */
uint16_t chmant[5][256];
/* coupling mantissas */
// uint16_t cplmant[256];
//Added Jun 2000 -MaXX
/* coupling floats */
float cpl_flt[ 256 ];
//Removed Feb 2000 -ah
//added Jul 2000 ++dent
/* coupling mantissas */
uint16_t lfemant[7];
/* -- Information not in the bitstream, but derived thereof -- */
/* Number of coupling sub-bands */
uint16_t ncplsubnd;
/* Number of combined coupling sub-bands
* Derived from ncplsubnd and cplbndstrc */
uint16_t ncplbnd;
/* Number of exponent groups by channel
* Derived from strmant, endmant */
uint16_t nchgrps[5];
/* Number of coupling exponent groups
* Derived from cplbegf, cplendf, cplexpstr */
uint16_t ncplgrps;
/* End mantissa numbers of fbw channels */
uint16_t endmant[5];
/* Start and end mantissa numbers for the coupling channel */
uint16_t cplstrtmant;
uint16_t cplendmant;
/* Decoded exponent info */
uint16_t fbw_exp[5][256];
uint16_t cpl_exp[256];
uint16_t lfe_exp[7];
/* Bit allocation pointer results */
uint16_t fbw_bap[5][256];
uint16_t cpl_bap[256];
uint16_t lfe_bap[7];
uint32_t magic3;
} audblk_t;

View File

@ -1,506 +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 int16_t logadd(int16_t a,int16_t b);
static int16_t calc_lowcomp(int16_t a,int16_t b0,int16_t b1,int16_t bin);
static inline uint16_t min(int16_t a,int16_t b);
static inline uint16_t max(int16_t a,int16_t b);
static void ba_compute_psd(int16_t start, int16_t end, int16_t exps[],
int16_t psd[], int16_t bndpsd[]);
static void ba_compute_excitation(int16_t start, int16_t end,int16_t fgain,
int16_t fastleak, int16_t slowleak, int16_t is_lfe, int16_t bndpsd[],
int16_t excite[]);
static void ba_compute_mask(int16_t start, int16_t end, uint16_t fscod,
uint16_t deltbae, uint16_t deltnseg, uint16_t deltoffst[], uint16_t deltba[],
uint16_t deltlen[], int16_t excite[], int16_t mask[]);
static void ba_compute_bap(int16_t start, int16_t end, int16_t snroffset,
int16_t psd[], int16_t mask[], int16_t bap[]);
/* Misc LUTs for bit allocation process */
static int16_t slowdec[] = { 0x0f, 0x11, 0x13, 0x15 };
static int16_t fastdec[] = { 0x3f, 0x53, 0x67, 0x7b };
static int16_t slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 };
static int16_t dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 };
static uint16_t floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
static int16_t fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
static int16_t 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 int16_t 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 int16_t 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 int16_t 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 int16_t 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 int16_t 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 int16_t sdecay;
static int16_t fdecay;
static int16_t sgain;
static int16_t dbknee;
static int16_t floor;
static int16_t psd[256];
static int16_t bndpsd[256];
static int16_t excite[256];
static int16_t mask[256];
/**
*
**/
static inline uint16_t max(int16_t a,int16_t b)
{
return (a > b ? a : b);
}
/**
*
**/
static inline uint16_t min(int16_t a,int16_t b)
{
return (a < b ? a : b);
}
/**
*
**/
static inline int16_t logadd(int16_t a,int16_t b)
{
int16_t c;
int16_t 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(uint16_t fscod, bsi_t *bsi, audblk_t *audblk)
{
uint16_t i;
int16_t fgain;
int16_t snroffset;
int16_t start;
int16_t end;
int16_t fastleak;
int16_t 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(uint16_t) * 256 * 5);
memset(audblk->cpl_bap,0,sizeof(uint16_t) * 256);
memset(audblk->lfe_bap,0,sizeof(uint16_t) * 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(int16_t start, int16_t end, int16_t exps[],
int16_t psd[], int16_t bndpsd[])
{
int bin,i,j,k;
int16_t 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(int16_t start, int16_t end,int16_t fgain,
int16_t fastleak, int16_t slowleak, int16_t is_lfe, int16_t bndpsd[],
int16_t excite[])
{
int bin;
int16_t bndstrt;
int16_t bndend;
int16_t lowcomp = 0;
int16_t 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(int16_t start, int16_t end, uint16_t fscod,
uint16_t deltbae, uint16_t deltnseg, uint16_t deltoffst[], uint16_t deltba[],
uint16_t deltlen[], int16_t excite[], int16_t mask[])
{
int bin,k;
int16_t bndstrt;
int16_t bndend;
int16_t 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)) {
int16_t band = 0;
int16_t 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(int16_t start, int16_t end, int16_t snroffset,
int16_t psd[], int16_t mask[], int16_t bap[])
{
int i,j,k;
int16_t lastbin = 0;
int16_t 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 int16_t calc_lowcomp (int16_t a, int16_t b0, int16_t b1, int16_t 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(uint16_t fscod, bsi_t *bsi, audblk_t *audblk);

View File

@ -1,79 +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 <inttypes.h>
#include <bswap.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
uint32_t bits_left = 0;
uint64_t current_word;
uint64_t *buffer_start = 0;
static inline uint64_t getdword (void)
{
return be2me_64 (*buffer_start++);
}
static inline void bitstream_fill_current (void)
{
//current_word = bswap_64 (*buffer_start++);
current_word = getdword ();
}
uint32_t bitstream_get_bh (uint32_t num_bits)
{
uint32_t result;
num_bits -= bits_left;
result = (current_word << (64 - bits_left)) >> (64 - bits_left);
bitstream_fill_current();
if(num_bits != 0)
result = (result << num_bits) | (current_word >> (64 - num_bits));
bits_left = 64 - num_bits;
return result;
}
void bitstream_init (uint8_t *start)
{
//initialize the start of the buffer
buffer_start = (uint64_t *) start;
bits_left = 0;
}

View File

@ -1,44 +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.
*
*/
#include <inttypes.h>
extern uint32_t bits_left;
extern uint64_t current_word;
void bitstream_init(uint8_t *start);
inline uint32_t bitstream_get_bh(uint32_t num_bits);
static inline uint32_t bitstream_get (uint32_t num_bits)
{
uint32_t result;
if (num_bits < bits_left) {
result = (current_word << (64 - bits_left)) >> (64 - num_bits);
bits_left -= num_bits;
return result;
}
return bitstream_get_bh (num_bits);
}

View File

@ -1,80 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __BSWAP_H__
#define __BSWAP_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#else
#include <inttypes.h>
#ifdef WORDS_BIGENDIAN
// FIXME these need to actually swap ;)
#define bswap_16(x) (x)
#define bswap_32(x) (x)
#define bswap_64(x) (x)
#else
// This is wrong, 'cannot take address of ...'
#define bswap_16(x) ((((uint8_t*)&x)[2] << 8) \
| (((uint8_t*)&x)[3]))
// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc.
#define bswap_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#define bswap_64(x) \
(__extension__ \
({ union { __extension__ unsigned long long int __ll; \
unsigned long int __l[2]; } __w, __r; \
__w.__ll = (x); \
__r.__l[0] = bswap_32 (__w.__l[1]); \
__r.__l[1] = bswap_32 (__w.__l[0]); \
__r.__ll; }))
#endif
#endif
// be2me ... BigEndian to MachineEndian
// le2me ... LittleEndian to MachineEndian
#ifdef WORDS_BIGENDIAN
#define be2me_16(x) (x)
#define be2me_32(x) (x)
#define be2me_64(x) (x)
#define le2me_16(x) bswap_16(x)
#define le2me_32(x) bswap_32(x)
#define le2me_64(x) bswap_64(x)
#else
#define be2me_16(x) bswap_16(x)
#define be2me_32(x) bswap_32(x)
#define be2me_64(x) bswap_64(x)
#define le2me_16(x) (x)
#define le2me_32(x) (x)
#define le2me_64(x) (x)
#endif
#endif

View File

@ -1,29 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __COMPLEX_H__
#define __COMPLEX_H__
typedef struct complex {
float re;
float im;
} complex_t;
#endif

View File

@ -1,431 +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 "bitstream.h"
#include "dither.h"
#include "coeff.h"
//
//Lookup tables of 0.15 two's complement quantization values
//
#define Q0 ((-2 << 15) / 3.0)
#define Q1 (0)
#define Q2 ((2 << 15) / 3.0)
static const float q_1_0[ 32 ] =
{
Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
0,0,0,0,0
};
static const float q_1_1[ 32 ] =
{
Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
0,0,0,0,0
};
static const float q_1_2[ 32 ] =
{
Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
0,0,0,0,0
};
#undef Q0
#undef Q1
#undef Q2
#define Q0 ((-4 << 15) / 5.0)
#define Q1 ((-2 << 15) / 5.0)
#define Q2 (0)
#define Q3 ((2 << 15) / 5.0)
#define Q4 ((4 << 15) / 5.0)
static const float q_2_0[ 128 ] =
{
Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,
Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,
Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,
Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,
0,0,0
};
static const float q_2_1[ 128 ] =
{
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,
Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,
Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,
Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0,
Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,
Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,
Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,
Q4,Q4,Q4,Q4,Q4,0,0,0
};
static const float q_2_2[ 128 ] =
{
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
Q0,Q1,Q2,Q3,Q4,0,0,0
};
#undef Q0
#undef Q1
#undef Q2
#undef Q3
#undef Q4
static const float q_3[7] =
{
(-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0, 0.0,
( 2 << 15)/7.0, ( 4 << 15)/7.0, ( 6 << 15)/7.0
};
#define Q0 ((-10 << 15) / 11.0)
#define Q1 ((-8 << 15) / 11.0)
#define Q2 ((-6 << 15) / 11.0)
#define Q3 ((-4 << 15) / 11.0)
#define Q4 ((-2 << 15) / 11.0)
#define Q5 (0)
#define Q6 ((2 << 15) / 11.0)
#define Q7 ((4 << 15) / 11.0)
#define Q8 ((6 << 15) / 11.0)
#define Q9 ((8 << 15) / 11.0)
#define QA ((10 << 15) / 11.0)
static const float q_4_0[ 128 ] =
{
Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3,
Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4,
Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5,
Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6,
Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7,
Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8,
Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9,
QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA,
0, 0, 0, 0, 0, 0, 0
};
static const float q_4_1[ 128 ] =
{
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
0, 0, 0, 0, 0, 0, 0
};
#undef Q0
#undef Q1
#undef Q2
#undef Q3
#undef Q4
#undef Q5
#undef Q6
#undef Q7
#undef Q8
#undef Q9
#undef QA
static const float q_5[15] =
{
(-14 << 15)/15.0,(-12 << 15)/15.0,(-10 << 15)/15.0,
( -8 << 15)/15.0,( -6 << 15)/15.0,( -4 << 15)/15.0,
( -2 << 15)/15.0, 0.0 ,( 2 << 15)/15.0,
( 4 << 15)/15.0,( 6 << 15)/15.0,( 8 << 15)/15.0,
( 10 << 15)/15.0,( 12 << 15)/15.0,( 14 << 15)/15.0
};
//
// Scale factors for convert_to_float
//
static const uint32_t 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 float q_1[2];
static float q_2[2];
static float q_4[1];
static int32_t q_1_pointer;
static int32_t q_2_pointer;
static int32_t q_4_pointer;
static float __inline__
coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp);
//Conversion from bap to number of bits in the mantissas
//zeros account for cases 0,1,2,4 which are special cased
static uint16_t qnttztab[16] =
{
0, 0, 0, 3,
0, 4, 5, 6,
7, 8, 9, 10,
11, 12, 14, 16
};
static void coeff_reset(void);
static float coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp);
static void coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch);
void coeff_unpack(bsi_t *bsi, audblk_t *audblk, stream_samples_t samples)
{
uint16_t i,j;
uint32_t done_cpl = 0;
coeff_reset();
for(i=0; i< bsi->nfchans; i++) {
for(j=0; j < audblk->endmant[i]; j++)
samples[i][j] = coeff_get_float(audblk->fbw_bap[i][j], audblk->dithflag[i], audblk->fbw_exp[i][j]);
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->cpl_flt[j] = coeff_get_float(audblk->cpl_bap[j],0, audblk->cpl_exp[j]);
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++)
samples[5][j] = coeff_get_float(audblk->lfe_bap[j], 0, audblk->lfe_exp[j]);
}
}
/**
* Fetch a float from the bitstream
**/
static float inline coeff_get_float (uint16_t bap, uint16_t dithflag, uint16_t exp)
{
uint16_t dummy = 0;
//If the bap is 0-5 then we have special cases to take care of
switch(bap) {
case 0:
if(dithflag)
return (dither_gen() * scale_factor[exp]);
return 0.0;
case 1:
if (q_1_pointer >= 0)
return(q_1[q_1_pointer--] * scale_factor[exp]);
if ((dummy = bitstream_get (5)) > 26)
goto error;
q_1[1] = q_1_1[dummy];
q_1[0] = q_1_2[dummy];
q_1_pointer = 1;
return (q_1_0[dummy] * scale_factor[exp]);
case 2:
if(q_2_pointer >= 0)
return (q_2[q_2_pointer--] * scale_factor[exp]);
if ((dummy = bitstream_get (7)) > 124)
goto error;
q_2[1] = q_2_1[dummy];
q_2[0] = q_2_2[dummy];
q_2_pointer = 1;
return (q_2_0[dummy] * scale_factor[exp]);
case 3:
if ((dummy = bitstream_get (3)) > 6)
goto error;
return (q_3[dummy] * scale_factor[exp]);
case 4:
if(q_4_pointer >= 0)
return (q_4[q_4_pointer--] * scale_factor[exp]);
if ((dummy = bitstream_get (7)) > 120)
goto error;
q_4[0] = q_4_1[dummy];
q_4_pointer = 0;
return (q_4_0[dummy] * scale_factor[exp]);
case 5:
if ((dummy = bitstream_get (4)) > 14)
goto error;
return (q_5[dummy] * scale_factor[exp]);
default:
dummy = bitstream_get(qnttztab[bap]);
dummy <<= 16 - qnttztab[bap];
return ((int16_t)dummy * scale_factor[exp]);
}
error:
#ifdef DEBUG
fprintf(stderr,"** Invalid mantissa - skipping frame **\n");
#endif
HANDLE_ERROR();
}
/**
* Reset the mantissa state
**/
static void coeff_reset(void)
{
q_1_pointer = q_2_pointer = q_4_pointer = -1;
}
/**
* Uncouple the coupling channel into a fbw channel
**/
static void coeff_uncouple_ch (float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch)
{
uint32_t bnd = 0;
uint32_t sub_bnd = 0;
uint32_t i,j;
float cpl_coord = 1.0;
uint32_t cpl_exp_tmp;
uint32_t cpl_mant_tmp;
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 = (cpl_mant_tmp * scale_factor[cpl_exp_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])
samples[i] = cpl_coord * (dither_gen() * scale_factor[audblk->cpl_exp[i]]);
else
samples[i] = cpl_coord * audblk->cpl_flt[i];
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,129 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#include <inttypes.h>
#include "mm_accel.h"
//#ifdef __i386__
#if 0
#ifdef __PIC__
#define cpuid(op, eax, ebx, ecx, edx) \
__asm__ __volatile__ ("pushl %%ebx\n\t" \
"cpuid\n\t" \
"movl %%ebx, %%esi\n\t" \
"popl %%ebx" \
: "=a" (eax), \
"=S" (ebx), \
"=c" (ecx), \
"=d" (edx) \
: "a" (op) \
: "cc")
#else
#define cpuid(op, eax, ebx, ecx, edx) \
__asm__("cpuid" \
: "=a" (eax), \
"=b" (ebx), \
"=c" (ecx), \
"=d" (edx) \
: "a" (op) \
: "cc")
#endif
static inline int has_cpuid ()
{
return 1;
/*
uint32_t eax, ebx;
asm ("pushfl\n\t"
"popl %0\n\t"
"movl %0,%1\n\t"
"xorl $0x200000,%0\n\t"
"pushl %0\n\t"
"popfl\n\t"
"pushfl\n\t"
"popl %0"
: "=a" (eax),
"=b" (ebx)
:
: "cc");
return (eax != ebx);
*/
}
static uint32_t x86_accel (void)
{
uint32_t eax, ebx, ecx, edx;
int AMD;
uint32_t caps;
if (!has_cpuid ()) // no cpuid
return 0;
cpuid (0x00000000, eax, ebx, ecx, edx);
if (!eax) // vendor string only
return 0;
AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
cpuid (0x00000001, eax, ebx, ecx, edx);
if (! (edx & 0x00800000)) // no MMX
return 0;
caps = OMS_ACCEL_X86_MMX;
if (edx & 0x02000000) // SSE - identical to AMD MMX extensions
caps = OMS_ACCEL_X86_MMX | OMS_ACCEL_X86_MMXEXT;
cpuid (0x80000000, eax, ebx, ecx, edx);
if (eax < 0x80000001) // no extended capabilities
return caps;
cpuid (0x80000001, eax, ebx, ecx, edx);
if (edx & 0x80000000)
caps |= OMS_ACCEL_X86_3DNOW;
if (AMD && (edx & 0x00400000)) // AMD MMX extensions
caps |= OMS_ACCEL_X86_MMXEXT;
return caps;
}
#endif
uint32_t mm_accel (void)
{
//#ifdef __i386__
#if 0
static int got_accel = 0;
static uint32_t accel;
if (!got_accel) {
got_accel = 1;
accel = x86_accel ();
}
return accel;
#else
return 0;
#endif
}

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 uint16_t 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 uint16_t state;
void crc_init(void)
{
state = 0;
}
inline void crc_process_byte (uint8_t data)
{
state = crc_lut[data ^ (state>>8)] ^ (state<<8);
}
void crc_process_frame (uint8_t *data,uint32_t num_bytes)
{
uint32_t 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(uint8_t data);
void crc_process_frame(uint8_t *data,uint32_t num_bytes);

View File

@ -1,48 +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)
{
if(debug_level < 0) {
debug_level = getenv ("AC3_DEBUG") ? 1 : 0;
}
return debug_level;
}
//If you don't have gcc, then ya don't get debug output
#ifndef __GNUC__
void dprintf(char fmt[],...)
{
return;
}
#endif

View File

@ -1,41 +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__
#ifdef DEBUG
#define dprintf(args...)\
{\
if (debug_is_on())\
{\
fprintf(stderr, args);\
}\
}
#else
#define dprintf(args...) { };
#endif
#else
void dprintf(char fmt[],...);
#endif

View File

@ -1,312 +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.
*
*------------------------------------------------------------
*
* Thomas Mirlacher <dent@cosy.sbg.ac.at>
* added OMS support
* 11 Jan 2001
* Thomas Mirlacher <dent@cosy.sbg.ac.at>
* faster error response using jmp functions
*
* 9 Aug 2001
* Matjaz Thaler <matjaz.thaler@rd.iskraemeco.si>
* Added support for DVB-s PCI card
*
* 24 Nov 2001
* Andreas Schultz <aschultz@cs.uni-magdeburg.de>
* Added ac3_buffersize()
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#ifdef __OMS__
#include <oms/oms.h>
#include <oms/plugin/output_audio.h>
#endif
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
#include "downmix.h"
#include "srfft.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 "debug.h"
#ifndef __OMS__
//#include "audio_out.h"
#endif
//our global config structure
ac3_config_t ac3_config;
static audblk_t audblk;
static bsi_t bsi;
static syncinfo_t syncinfo;
#ifndef __OMS__
static uint32_t done_banner;
#endif
static uint32_t is_output_initialized = 0;
//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 int16_t s16_samples[2 * 6 * 256] __attribute__ ((aligned(16)));
// downmix stuff
static float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 };
static float smixlev_lut[4] = { 0.707, 0.500, 0.0 , 0.500 };
static dm_par_t dm_par;
//Storage for the syncframe
#define BUFFER_MAX_SIZE 4096
static uint8_t buffer[BUFFER_MAX_SIZE];
static uint32_t buffer_size = 0;;
// for error handling
jmp_buf error_jmp_mark;
uint32_t ac3_buffersize()
{
return buffer_size;
}
static uint32_t decode_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 (buffer_size < 3) {
if(cur >= end)
goto done;
buffer[buffer_size++] = *cur++;
}
parse_syncinfo (syncinfo,buffer);
stats_print_syncinfo (syncinfo);
while (buffer_size < syncinfo->frame_size * 2 - 2) {
if(cur >= end)
goto done;
buffer[buffer_size++] = *cur++;
}
#if 0
// Check the crc over the entire frame
crc_init();
crc_process_frame (buffer, syncinfo->frame_size * 2 - 2);
if (!crc_validate()) {
fprintf(stderr,"** CRC failed - skipping frame **\n");
goto done;
}
#endif
//if we got to this point, we found a valid ac3 frame to decode
bitstream_init (buffer);
//get rid of the syncinfo struct as we already parsed it
bitstream_get (24);
//reset the syncword for next time
syncword = 0xffff;
buffer_size = 0;
ret = 1;
done:
syncinfo->syncword = syncword;
*start = cur;
return ret;
}
void inline decode_mute (void)
{
//mute the frame
memset (s16_samples, 0, sizeof(int16_t) * 256 * 2 * 6);
}
void ac3dec_init (void)
{
// FIXME - don't do that statically here
ac3_config.num_output_ch = 2;
ac3_config.flags = 0;
imdct_init ();
downmix_init ();
memset (&syncinfo, 0, sizeof (syncinfo));
memset (&bsi, 0, sizeof (bsi));
memset (&audblk, 0, sizeof (audblk));
sanity_check_init (&syncinfo,&bsi,&audblk);
}
#ifdef __OMS__
size_t ac3dec_decode_data (plugin_output_audio_t *output, uint8_t *data_start, uint8_t *data_end)
#else
size_t ac3dec_decode_data (uint8_t *data_start ,uint8_t *data_end, int ac3reset, int *input_pointer, int *output_pointer, char *ac3_data)
#endif
{
uint32_t i;
int datasize;
char *data;
if(ac3reset != 0){
syncinfo.syncword = 0xffff;
buffer_size = 0;
}
if (setjmp (error_jmp_mark) < 0) {
ac3dec_init ();
return 0;
}
while (decode_buffer_syncframe (&syncinfo, &data_start, data_end)) {
parse_bsi (&bsi);
#ifndef __OMS__
if(!done_banner) {
// stats_print_banner(&syncinfo,&bsi);
done_banner = 1;
}
#endif
// compute downmix parameters
// downmix to tow channels for now
dm_par.clev = 0.0; dm_par.slev = 0.0; dm_par.unit = 1.0;
if (bsi.acmod & 0x1) // have center
dm_par.clev = cmixlev_lut[bsi.cmixlev];
if (bsi.acmod & 0x4) // have surround channels
dm_par.slev = smixlev_lut[bsi.surmixlev];
dm_par.unit /= 1.0 + dm_par.clev + dm_par.slev;
dm_par.clev *= dm_par.unit;
dm_par.slev *= dm_par.unit;
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);
// 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 (bsi.acmod == 0x2)
rematrix (&audblk,samples);
// Convert the frequency samples into time samples
imdct (&bsi,&audblk,samples, &s16_samples[i * 2 * 256], &dm_par);
// Downmix into the requested number of channels
// and convert floating point to int16_t
// downmix(&bsi,samples,&s16_samples[i * 2 * 256]);
if (sanity_check(&syncinfo,&bsi,&audblk) < 0) {
HANDLE_ERROR ();
return 0;
}
continue;
}
if (!is_output_initialized) {
#ifdef __OMS__
plugin_output_audio_attr_t attr;
#ifdef __sun__
attr.format = 16;
#else
attr.format = AFMT_S16_NE;
#endif
attr.speed = syncinfo.sampling_rate;
attr.channels = 2;
// output->setup (&attr);
#else
// ao_functions->open (16, syncinfo.sampling_rate, 2);
#endif
is_output_initialized = 1;
}
#ifdef __OMS__
output->write (s16_samples, 256 * 6 * 2 * 2);
#else
// ao_functions->play(s16_samples, 256 * 6 * 2);
data = (char *)s16_samples;
datasize = 0;
while(datasize < 6144){
if(((*input_pointer+1) % AC3_BUFFER_SIZE) != *output_pointer){ // There is room in the sync_buffer
ac3_data[*input_pointer]=data[datasize];
datasize++;
*input_pointer = (*input_pointer+1) % AC3_BUFFER_SIZE;
}
else{
*input_pointer = *output_pointer = 0;
break;
}
}
#endif
}
decode_mute ();
return 0;
}

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,114 +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 uint16_t 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
};
uint16_t 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]
*
*/
uint16_t dither_gen(void)
{
int i;
uint32_t 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 (((((int32_t)state<<8)>>8) * (int32_t) (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 uint16_t lfsr_state;
extern const uint16_t dither_lut[256];
static inline uint16_t dither_gen(void)
{
int16_t state;
state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
lfsr_state = (uint16_t) state;
return ((state * (int32_t) (0.707106 * 256.0))>>8);
}

View File

@ -1,89 +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 <mm_accel.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "debug.h"
#include "downmix.h"
#include "downmix_c.h"
#include "downmix_i386.h"
#ifdef HAVE_KNI
#include "downmix_kni.h"
#endif
void (*downmix_3f_2r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_3f_1r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_2f_2r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_2f_1r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_3f_0r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*stream_sample_2ch_to_s16)(int16_t *s16_samples, float *left, float *right);
void (*stream_sample_1ch_to_s16)(int16_t *s16_samples, float *center);
void downmix_init()
{
#ifdef __i386__
#ifdef HAVE_KNI
uint32_t accel = mm_accel ();
// other dowmixing should go here too
if (accel & MM_ACCEL_X86_MMXEXT) {
dprintf("Using SSE for downmix\n");
downmix_3f_2r_to_2ch = downmix_3f_2r_to_2ch_kni;
downmix_2f_2r_to_2ch = downmix_2f_2r_to_2ch_kni;
downmix_3f_1r_to_2ch = downmix_3f_1r_to_2ch_kni;
downmix_2f_1r_to_2ch = downmix_2f_1r_to_2ch_kni;
downmix_3f_0r_to_2ch = downmix_3f_0r_to_2ch_kni;
stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_kni;
stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_kni;
} else if (accel & MM_ACCEL_X86_3DNOW) {
} else
#endif
#endif
{
downmix_3f_2r_to_2ch = downmix_3f_2r_to_2ch_c;
downmix_2f_2r_to_2ch = downmix_2f_2r_to_2ch_c;
downmix_3f_1r_to_2ch = downmix_3f_1r_to_2ch_c;
downmix_2f_1r_to_2ch = downmix_2f_1r_to_2ch_c;
downmix_3f_0r_to_2ch = downmix_3f_0r_to_2ch_c;
#ifdef __i386__
#if 1
stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_c;
stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_c;
#else
stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_i386;
stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_i386;
#endif
#else
stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_c;
stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_c;
#endif
}
}

View File

@ -1,34 +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.
*
*
*/
typedef struct dm_par_s {
float unit;
float clev;
float slev;
} dm_par_t;
void downmix_init();

View File

@ -1,161 +0,0 @@
/*
* downmix_c.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 "debug.h"
#include "downmix.h"
#include "downmix_c.h"
void downmix_3f_2r_to_2ch_c (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center, *left_sur, *right_sur;
float left_tmp, right_tmp;
left = samples;
right = samples + 256 * 2;
center = samples + 256;
left_sur = samples + 256 * 3;
right_sur = samples + 256 * 4;
for (i=0; i < 256; i++) {
#if defined DOLBY_SURROUND
left_tmp = dm_par->unit * *left + dm_par->clev * *center - dm_par->slev * (*left_sur + *right_sur);
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * (*left_sur++ + *right_sur++);
#else
left_tmp = dm_par->unit * *left + dm_par->clev * *center + dm_par->slev * *left_sur++;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++;
#endif
*left++ = left_tmp;
*center++ = right_tmp;
}
}
void downmix_2f_2r_to_2ch_c (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *left_sur, *right_sur;
float left_tmp, right_tmp;
left = &samples[0];
right = &samples[256];
left_sur = &samples[512];
right_sur = &samples[768];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left + dm_par->slev * *left_sur++;
right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++;
*left++ = left_tmp;
*right++ = right_tmp;
}
}
void downmix_3f_1r_to_2ch_c (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center, *right_sur;
float left_tmp, right_tmp;
left = &samples[0];
right = &samples[512];
center = &samples[256];
right_sur = &samples[768];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left + dm_par->clev * *center - dm_par->slev * *right_sur;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++;
*left++ = left_tmp;
*center++ = right_tmp;
}
}
void downmix_2f_1r_to_2ch_c (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *right_sur;
float left_tmp, right_tmp;
left = &samples[0];
right = &samples[256];
right_sur = &samples[512];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left - dm_par->slev * *right_sur;
right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++;
*left++ = left_tmp;
*right++ = right_tmp;
}
}
void downmix_3f_0r_to_2ch_c (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center;
float left_tmp, right_tmp;
left = &samples[0];
center = &samples[256];
right = &samples[512];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left + dm_par->clev * *center;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center;
*left++ = left_tmp;
*center++ = right_tmp;
}
}
void stream_sample_2ch_to_s16_c (int16_t *s16_samples, float *left, float *right)
{
int i;
for (i=0; i < 256; i++) {
*s16_samples++ = (int16_t) *left++;
*s16_samples++ = (int16_t) *right++;
}
}
void stream_sample_1ch_to_s16_c (int16_t *s16_samples, float *center)
{
int i;
float tmp;
for (i=0; i < 256; i++) {
*s16_samples++ = tmp = (int16_t) (0.7071f * *center++);
*s16_samples++ = tmp;
}
}

View File

@ -1,32 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __DOWNMIX_C_H__
#define __DOWNMIX_C_H__
void downmix_3f_2r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_3f_1r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_2f_2r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_2f_1r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_3f_0r_to_2ch_c(float *samples, dm_par_t * dm_par);
void stream_sample_2ch_to_s16_c(int16_t *s16_samples, float *left, float *right);
void stream_sample_1ch_to_s16_c(int16_t *s16_samples, float *center);
#endif

View File

@ -1,92 +0,0 @@
/* This is basicly gcc generated.
* Only the floating point rounding mode loads and saves
* are removed in the stream_sample_to_s16 functions.
*/
#ifdef __i386__
.file "downmix.c"
.version "01.01"
gcc2_compiled.:
.text
.align 4
.globl stream_sample_2ch_to_s16_i386
.type stream_sample_2ch_to_s16_i386,@function
stream_sample_2ch_to_s16_i386:
pushl %ebp
movl %esp,%ebp
subl $28,%esp
pushl %edi
pushl %esi
pushl %ebx
movl 8(%ebp),%edx
movl 12(%ebp),%ebx
movl 16(%ebp),%ecx
movl $255,%esi
.p2align 4,,7
.L373:
flds (%ebx)
fistpl -8(%ebp)
movl -8(%ebp),%eax
movw %ax,(%edx)
addl $2,%edx
addl $4,%ebx
flds (%ecx)
fistpl -8(%ebp)
movl -8(%ebp),%eax
movw %ax,(%edx)
addl $4,%ecx
addl $2,%edx
decl %esi
jns .L373
popl %ebx
popl %esi
popl %edi
leave
ret
.Lfe6:
.size stream_sample_2ch_to_s16_i386,.Lfe6-stream_sample_2ch_to_s16_i386
.section .rodata
.align 4
.LC46:
.long 0x3f350481
.text
.align 4
.globl stream_sample_1ch_to_s16_i386
.type stream_sample_1ch_to_s16_i386,@function
stream_sample_1ch_to_s16_i386:
pushl %ebp
movl %esp,%ebp
subl $16,%esp
pushl %esi
pushl %ebx
movl 8(%ebp),%edx
movl 12(%ebp),%ecx
flds .LC46
movl $255,%ebx
.p2align 4,,7
.L379:
flds (%ecx)
fmul %st(1),%st
fistpl -8(%ebp)
movl -8(%ebp),%eax
movw %ax,-2(%ebp)
addl $4,%ecx
flds -2(%ebp)
fistpl -8(%ebp)
movl -8(%ebp),%eax
movw %ax,(%edx)
addl $2,%edx
movw %ax,(%edx)
addl $2,%edx
decl %ebx
jns .L379
fstp %st(0)
popl %ebx
popl %esi
leave
ret
.Lfe7:
.size stream_sample_1ch_to_s16_i386,.Lfe7-stream_sample_1ch_to_s16_i386
.ident "GCC: (GNU) 2.95.3 19991030 (prerelease)"
#endif

View File

@ -1,27 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __DOWNMIX_I386_H__
#define __DOWNMIX_I386_H__
void stream_sample_2ch_to_s16_i386(int16_t *s16_samples, float *left, float *right);
void stream_sample_1ch_to_s16_i386(int16_t *s16_samples, float *center);
#endif

View File

@ -1,396 +0,0 @@
/*
* downmix_kni.S
*
* Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - October 2000
*
*
* downmix_kni.S 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.
*
* downmix_kni.S 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 __i386__
.section .rodata
.align 4
sqrt2: .float 0f0.7071068
.p2align 5,0,
.section .text
.align 4
.global downmix_3f_2r_to_2ch_kni
.type downmix_3f_2r_to_2ch_kni, @function
downmix_3f_2r_to_2ch_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
movl 8(%ebp), %eax /* samples[] */
movl 12(%ebp), %ebx /* &dm_par */
movl $64, %ecx /* loop counter */
movss (%ebx), %xmm5 /* unit */
shufps $0, %xmm5, %xmm5 /* unit | unit | unit | unit */
movss 4(%ebx), %xmm6 /* clev */
shufps $0, %xmm6, %xmm6 /* clev | clev | clev | clev */
movss 8(%ebx), %xmm7 /* slev */
shufps $0, %xmm7, %xmm7 /* slev | slev | slev | slev */
.loop:
movaps (%eax), %xmm0 /* left */
movaps 2048(%eax), %xmm1 /* right */
movaps 1024(%eax), %xmm2 /* center */
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
mulps %xmm6, %xmm2
movaps 3072(%eax), %xmm3 /* leftsur */
movaps 4096(%eax), %xmm4 /* rithgsur */
addps %xmm2, %xmm0
addps %xmm2, %xmm1
mulps %xmm7, %xmm3
mulps %xmm7, %xmm4
addps %xmm3, %xmm0
addps %xmm4, %xmm1
movaps %xmm0, (%eax)
movaps %xmm1, 1024(%eax)
addl $16, %eax
decl %ecx
jnz .loop
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,,7
.global downmix_2f_2r_to_2ch_kni
.type downmix_2f_2r_to_2ch_kni, @function
downmix_2f_2r_to_2ch_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
movl 8(%ebp), %eax /* samples[] */
movl 12(%ebp), %ebx /* &dm_par */
movl $64, %ecx /* loop counter */
movss (%ebx), %xmm5 /* unit */
shufps $0, %xmm5, %xmm5 /* unit | unit | unit | unit */
movss 8(%ebx), %xmm7 /* slev */
shufps $0, %xmm7, %xmm7 /* slev | slev | slev | slev */
.loop3:
movaps (%eax), %xmm0 /* left */
movaps 1024(%eax), %xmm1 /* right */
movaps 2048(%eax), %xmm3 /* leftsur */
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
movaps 3072(%eax), %xmm4 /* rightsur */
mulps %xmm7, %xmm3
mulps %xmm7, %xmm4
addps %xmm3, %xmm0
addps %xmm4, %xmm1
movaps %xmm0, (%eax)
movaps %xmm1, 1024(%eax)
addl $16, %eax
decl %ecx
jnz .loop3
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,,7
.global downmix_3f_1r_to_2ch_kni
.type downmix_3f_1r_to_2ch_kni, @function
downmix_3f_1r_to_2ch_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
movl 8(%ebp), %eax /* samples[] */
movl 12(%ebp), %ebx /* &dm_par */
movl $64, %ecx /* loop counter */
movss (%ebx), %xmm5 /* unit */
shufps $0, %xmm5, %xmm5 /* unit | unit | unit | unit */
movss 4(%ebx), %xmm6 /* clev */
shufps $0, %xmm6, %xmm6 /* clev | clev | clev | clev */
movss 8(%ebx), %xmm7 /* slev */
shufps $0, %xmm7, %xmm7 /* slev | slev | slev | slev */
.loop4:
movaps (%eax), %xmm0 /* left */
movaps 2048(%eax), %xmm1 /* right */
movaps 1024(%eax), %xmm2 /* center */
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
mulps %xmm6, %xmm2
movaps 3072(%eax), %xmm3 /* sur */
addps %xmm2, %xmm0
mulps %xmm7, %xmm3
addps %xmm2, %xmm1
subps %xmm3, %xmm0
addps %xmm3, %xmm1
movaps %xmm0, (%eax)
movaps %xmm1, 1024(%eax)
addl $16, %eax
decl %ecx
jnz .loop4
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,,7
.global downmix_2f_1r_to_2ch_kni
.type downmix_2f_1r_to_2ch_kni, @function
downmix_2f_1r_to_2ch_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
movl 8(%ebp), %eax /* samples[] */
movl 12(%ebp), %ebx /* &dm_par */
movl $64, %ecx /* loop counter */
movss (%ebx), %xmm5 /* unit */
shufps $0, %xmm5, %xmm5 /* unit | unit | unit | unit */
movss 8(%ebx), %xmm7 /* slev */
shufps $0, %xmm7, %xmm7 /* slev | slev | slev | slev */
.loop5:
movaps (%eax), %xmm0 /* left */
movaps 1024(%eax), %xmm1 /* right */
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
movaps 2048(%eax), %xmm3 /* sur */
mulps %xmm7, %xmm3
subps %xmm3, %xmm0
addps %xmm3, %xmm1
movaps %xmm0, (%eax)
movaps %xmm1, 1024(%eax)
addl $16, %eax
decl %ecx
jnz .loop5
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,,7
.global downmix_3f_0r_to_2ch_kni
.type downmix_3f_0r_to_2ch_kni, @function
downmix_3f_0r_to_2ch_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
movl 8(%ebp), %eax /* samples[] */
movl 12(%ebp), %ebx /* &dm_par */
movl $64, %ecx /* loop counter */
movss (%ebx), %xmm5 /* unit */
shufps $0, %xmm5, %xmm5 /* unit | unit | unit | unit */
movss 4(%ebx), %xmm6 /* clev */
shufps $0, %xmm6, %xmm6 /* clev | clev | clev | clev */
.loop6:
movaps (%eax), %xmm0 /* left */
movaps 2048(%eax), %xmm1 /* right */
movaps 1024(%eax), %xmm2 /* center */
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
mulps %xmm6, %xmm2
addps %xmm2, %xmm0
addps %xmm2, %xmm1
movaps %xmm0, (%eax)
movaps %xmm1, 1024(%eax)
addl $16, %eax
decl %ecx
jnz .loop6
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,,7
.global stream_sample_2ch_to_s16_kni
.type stream_sample_2ch_to_s16_kni, @function
stream_sample_2ch_to_s16_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %edx
pushl %ecx
movl 8(%ebp), %eax /* s16_samples */
movl 12(%ebp), %ebx /* left */
movl 16(%ebp), %edx /* right */
movl $64, %ecx
.loop1:
movaps (%ebx), %xmm0 /* l3 | l2 | l1 | l0 */
movaps (%edx), %xmm1 /* r3 | r2 | r1 | r0 */
movhlps %xmm0, %xmm2 /* l3 | l2 */
movhlps %xmm1, %xmm3 /* r3 | r2 */
unpcklps %xmm1, %xmm0 /* r1 | l1 | r0 | l0 */
unpcklps %xmm3, %xmm2 /* r3 | l3 | r2 | l2 */
cvtps2pi %xmm0, %mm0 /* r0 l0 --> mm0, int_32 */
movhlps %xmm0, %xmm0
cvtps2pi %xmm0, %mm1 /* r1 l1 --> mm1, int_32 */
cvtps2pi %xmm2, %mm2 /* r2 l2 --> mm2, int_32 */
movhlps %xmm2, %xmm2
cvtps2pi %xmm2, %mm3 /* r3 l3 --> mm3, int_32 */
packssdw %mm1, %mm0 /* r1 l1 r0 l0 --> mm0, int_16 */
packssdw %mm3, %mm2 /* r3 l3 r2 l2 --> mm2, int_16 */
movq %mm0, (%eax)
movq %mm2, 8(%eax)
addl $16, %eax
addl $16, %ebx
addl $16, %edx
decl %ecx
jnz .loop1
popl %ecx
popl %edx
popl %ebx
popl %eax
emms
leave
ret
.p2align 4,,7
.global stream_sample_1ch_to_s16_kni
.type stream_sample_1ch_to_s16_kni, @function
stream_sample_1ch_to_s16_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
movl $sqrt2, %eax
movss (%eax), %xmm7
movl 8(%ebp), %eax /* s16_samples */
movl 12(%ebp), %ebx /* left */
shufps $0, %xmm7, %xmm7
movl $64, %ecx
.loop2:
movaps (%ebx), %xmm0 /* c3 | c2 | c1 | c0 */
mulps %xmm7, %xmm0
movhlps %xmm0, %xmm2 /* c3 | c2 */
cvtps2pi %xmm0, %mm0 /* c1 c0 --> mm0, int_32 */
cvtps2pi %xmm2, %mm1 /* c3 c2 --> mm1, int_32 */
packssdw %mm0, %mm0 /* c1 c1 c0 c0 --> mm0, int_16 */
packssdw %mm1, %mm1 /* c3 c3 c2 c2 --> mm1, int_16 */
movq %mm0, (%eax)
movq %mm1, 8(%eax)
addl $16, %eax
addl $16, %ebx
decl %ecx
jnz .loop2
popl %ecx
popl %ebx
popl %eax
emms
leave
ret
#endif

View File

@ -1,32 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __DOWNMIX_KNI_H__
#define __DOWNMIX_KNI_H__
void downmix_3f_2r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_3f_1r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_2f_2r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_2f_1r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_3f_0r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void stream_sample_2ch_to_s16_kni(int16_t *s16_samples, float *left, float *right);
void stream_sample_1ch_to_s16_kni(int16_t *s16_samples, float *center);
#endif

View File

@ -1,132 +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 "exponent.h"
static inline void exp_unpack_ch(uint16_t type,uint16_t expstr,uint16_t ngrps,uint16_t initial_exp, uint16_t exps[], uint16_t *dest);
/**
*
**/
void exponent_unpack( bsi_t *bsi, audblk_t *audblk)
{
uint16_t 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 inline void exp_unpack_ch(uint16_t type,uint16_t expstr,uint16_t ngrps,uint16_t initial_exp,
uint16_t exps[], uint16_t *dest)
{
uint16_t i,j;
int16_t exp_acc;
int16_t 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;
error:
#ifdef DEBUG
fprintf (stderr,"** Invalid exponent - skipping frame **\n");
#endif
HANDLE_ERROR ();
}

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,530 +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 "downmix.h"
#include "imdct.h"
#include "imdct_c.h"
#ifdef HAVE_KNI
#include "imdct_kni.h"
#endif
#include "srfft.h"
extern void (*downmix_3f_2r_to_2ch)(float *samples, dm_par_t * dm_par);
extern void (*downmix_3f_1r_to_2ch)(float *samples, dm_par_t * dm_par);
extern void (*downmix_2f_2r_to_2ch)(float *samples, dm_par_t * dm_par);
extern void (*downmix_2f_1r_to_2ch)(float *samples, dm_par_t * dm_par);
extern void (*downmix_3f_0r_to_2ch)(float *samples, dm_par_t * dm_par);
extern void (*stream_sample_2ch_to_s16)(int16_t *s16_samples, float *left, float *right);
extern void (*stream_sample_1ch_to_s16)(int16_t *s16_samples, float *center);
void (*fft_64p) (complex_t *);
void (*imdct_do_512) (float data[],float delay[]);
void (*imdct_do_512_nol) (float data[], float delay[]);
void imdct_do_256 (float data[],float delay[]);
#define N 512
/* static complex_t buf[128]; */
//static complex_t buf[128] __attribute__((aligned(16)));
complex_t buf[128] __attribute__((aligned(16)));
/* Delay buffer for time domain interleaving */
static float delay[6][256];
static float delay1[6][256];
/* Twiddle factors for IMDCT */
static float xcos2[64];
static float xsin2[64];
/* Windowing function for Modified DCT - Thank you acroread */
//static float window[] = {
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 const int pm128[128] =
const int pm128[128] =
{
0, 16, 32, 48, 64, 80, 96, 112, 8, 40, 72, 104, 24, 56, 88, 120,
4, 20, 36, 52, 68, 84, 100, 116, 12, 28, 44, 60, 76, 92, 108, 124,
2, 18, 34, 50, 66, 82, 98, 114, 10, 42, 74, 106, 26, 58, 90, 122,
6, 22, 38, 54, 70, 86, 102, 118, 14, 46, 78, 110, 30, 62, 94, 126,
1, 17, 33, 49, 65, 81, 97, 113, 9, 41, 73, 105, 25, 57, 89, 121,
5, 21, 37, 53, 69, 85, 101, 117, 13, 29, 45, 61, 77, 93, 109, 125,
3, 19, 35, 51, 67, 83, 99, 115, 11, 43, 75, 107, 27, 59, 91, 123,
7, 23, 39, 55, 71, 87, 103, 119, 15, 31, 47, 63, 79, 95, 111, 127
};
static const int pm64[64] =
{
0, 8, 16, 24, 32, 40, 48, 56,
4, 20, 36, 52, 12, 28, 44, 60,
2, 10, 18, 26, 34, 42, 50, 58,
6, 14, 22, 30, 38, 46, 54, 62,
1, 9, 17, 25, 33, 41, 49, 57,
5, 21, 37, 53, 13, 29, 45, 61,
3, 11, 19, 27, 35, 43, 51, 59,
7, 23, 39, 55, 15, 31, 47, 63
};
void imdct_init (void)
{
int i;
float scale = 255.99609372;
#ifdef __i386__
#ifdef HAVE_KNI
if (!imdct_init_kni ());
else
#endif
#endif
if (!imdct_init_c ());
// 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)) * scale;
xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
}
}
void imdct_do_256 (float data[],float delay[])
{
int i, j, k;
int p, q;
float tmp_a_i;
float tmp_a_r;
float *data_ptr;
float *delay_ptr;
float *window_ptr;
complex_t *buf1, *buf2;
buf1 = &buf[0];
buf2 = &buf[64];
// Pre IFFT complex multiply plus IFFT complex conjugate
for (k=0; k<64; k++) {
/* X1[k] = X[2*k] */
/* X2[k] = X[2*k+1] */
j = pm64[k];
p = 2 * (128-2*j-1);
q = 2 * (2 * j);
/* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf1[k].re = data[p] * xcos2[j] - data[q] * xsin2[j];
buf1[k].im = -1.0f * (data[q] * xcos2[j] + data[p] * xsin2[j]);
/* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf2[k].re = data[p + 1] * xcos2[j] - data[q + 1] * xsin2[j];
buf2[k].im = -1.0f * ( data[q + 1] * xcos2[j] + data[p + 1] * xsin2[j]);
}
fft_64p(&buf1[0]);
fft_64p(&buf2[0]);
#ifdef DEBUG
//DEBUG FFT
#if 0
printf ("Post FFT, buf1\n");
for (i=0; i < 64; i++)
printf("%d %f %f\n", i, buf_1[i].re, buf_1[i].im);
printf ("Post FFT, buf2\n");
for (i=0; i < 64; i++)
printf("%d %f %f\n", i, buf_2[i].re, buf_2[i].im);
#endif
#endif
// Post IFFT complex multiply
for( i=0; i < 64; i++) {
tmp_a_r = buf1[i].re;
tmp_a_i = -buf1[i].im;
buf1[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf1[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
tmp_a_r = buf2[i].re;
tmp_a_i = -buf2[i].im;
buf2[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf2[i].im =(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++ = -buf1[i].im * *window_ptr++ + *delay_ptr++;
*data_ptr++ = buf1[64-i-1].re * *window_ptr++ + *delay_ptr++;
}
for(i=0; i< 64; i++) {
*data_ptr++ = -buf1[i].re * *window_ptr++ + *delay_ptr++;
*data_ptr++ = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
}
delay_ptr = delay;
for(i=0; i< 64; i++) {
*delay_ptr++ = -buf2[i].re * *--window_ptr;
*delay_ptr++ = buf2[64-i-1].im * *--window_ptr;
}
for(i=0; i< 64; i++) {
*delay_ptr++ = buf2[i].im * *--window_ptr;
*delay_ptr++ = -buf2[64-i-1].re * *--window_ptr;
}
}
/**
*
**/
void imdct_do_256_nol (float data[], float delay[])
{
int i, j, k;
int p, q;
float tmp_a_i;
float tmp_a_r;
float *data_ptr;
float *delay_ptr;
float *window_ptr;
complex_t *buf1, *buf2;
buf1 = &buf[0];
buf2 = &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] */
j = pm64[k];
p = 2 * (128-2*j-1);
q = 2 * (2 * j);
/* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf1[k].re = data[p] * xcos2[j] - data[q] * xsin2[j];
buf1[k].im = -1.0f * (data[q] * xcos2[j] + data[p] * xsin2[j]);
/* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf2[k].re = data[p + 1] * xcos2[j] - data[q + 1] * xsin2[j];
buf2[k].im = -1.0f * ( data[q + 1] * xcos2[j] + data[p + 1] * xsin2[j]);
}
fft_64p(&buf1[0]);
fft_64p(&buf2[0]);
#ifdef DEBUG
//DEBUG FFT
#if 0
printf("Post FFT, buf1\n");
for (i=0; i < 64; i++)
printf("%d %f %f\n", i, buf_1[i].re, buf_1[i].im);
printf("Post FFT, buf2\n");
for (i=0; i < 64; i++)
printf("%d %f %f\n", i, buf_2[i].re, buf_2[i].im);
#endif
#endif
/* Post IFFT complex multiply */
for( i=0; i < 64; i++) {
/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
tmp_a_r = buf1[i].re;
tmp_a_i = -buf1[i].im;
buf1[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf1[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
/* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
tmp_a_r = buf2[i].re;
tmp_a_i = -buf2[i].im;
buf2[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
buf2[i].im =(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, no overlap */
for(i=0; i< 64; i++) {
*data_ptr++ = -buf1[i].im * *window_ptr++;
*data_ptr++ = buf1[64-i-1].re * *window_ptr++;
}
for(i=0; i< 64; i++) {
*data_ptr++ = -buf1[i].re * *window_ptr++ + *delay_ptr++;
*data_ptr++ = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
}
delay_ptr = delay;
for(i=0; i< 64; i++) {
*delay_ptr++ = -buf2[i].re * *--window_ptr;
*delay_ptr++ = buf2[64-i-1].im * *--window_ptr;
}
for(i=0; i< 64; i++) {
*delay_ptr++ = buf2[i].im * *--window_ptr;
*delay_ptr++ = -buf2[64-i-1].re * *--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, int16_t *s16_samples, dm_par_t* dm_par)
{
int i;
int doable = 0;
float *center=NULL, *left, *right, *left_sur, *right_sur;
float *delay_left, *delay_right;
float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl;
float right_tmp, left_tmp;
void (*do_imdct)(float data[], float deley[]);
// test if dm in frequency is doable
if (!(doable = audblk->blksw[0]))
do_imdct = imdct_do_512;
else
do_imdct = imdct_do_256;
// downmix in the frequency domain if all the channels
// use the same imdct
for (i=0; i < bsi->nfchans; i++) {
if (doable != audblk->blksw[i]) {
do_imdct = NULL;
break;
}
}
if (do_imdct) {
//dowmix first and imdct
switch(bsi->acmod) {
case 7: // 3/2
downmix_3f_2r_to_2ch (samples[0], dm_par);
break;
case 6: // 2/2
downmix_2f_2r_to_2ch (samples[0], dm_par);
break;
case 5: // 3/1
downmix_3f_1r_to_2ch (samples[0], dm_par);
break;
case 4: // 2/1
downmix_2f_1r_to_2ch (samples[0], dm_par);
break;
case 3: // 3/0
downmix_3f_0r_to_2ch (samples[0], dm_par);
break;
case 2:
break;
default: // 1/0
if (bsi->acmod == 1)
center = samples[0];
else if (bsi->acmod == 0)
center = samples[ac3_config.dual_mono_ch_sel];
do_imdct(center, delay[0]); // no downmix
stream_sample_1ch_to_s16 (s16_samples, center);
return;
//goto done;
break;
}
do_imdct (samples[0], delay[0]);
do_imdct (samples[1], delay[1]);
stream_sample_2ch_to_s16(s16_samples, samples[0], samples[1]);
} else { //imdct and then dowmix
// delay and samples should be saved and mixed
//fprintf(stderr, "time domain downmix\n");
for (i=0; i<bsi->nfchans; i++) {
if (audblk->blksw[i])
imdct_do_256_nol (samples[i],delay1[i]);
else
imdct_do_512_nol (samples[i],delay1[i]);
}
// mix the sample, overlap
switch(bsi->acmod) {
case 7: // 3/2
left = samples[0];
center = samples[1];
right = samples[2];
left_sur = samples[3];
right_sur = samples[4];
delay_left = delay[0];
delay_right = delay[1];
delay1_left = delay1[0];
delay1_center = delay1[1];
delay1_right = delay1[2];
delay1_sl = delay1[3];
delay1_sr = delay1[4];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left++ + dm_par->clev * *center + dm_par->slev * *left_sur++;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++ + dm_par->slev * *right_sur++;
*s16_samples++ = (int16_t)(left_tmp + *delay_left);
*s16_samples++ = (int16_t)(right_tmp + *delay_right);
*delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center + dm_par->slev * *delay1_sl++;
*delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++ + dm_par->slev * *delay1_sr++;
}
break;
case 6: // 2/2
left = samples[0];
right = samples[1];
left_sur = samples[2];
right_sur = samples[3];
delay_left = delay[0];
delay_right = delay[1];
delay1_left = delay1[0];
delay1_right = delay1[1];
delay1_sl = delay1[2];
delay1_sr = delay1[3];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left++ + dm_par->slev * *left_sur++;
right_tmp= dm_par->unit * *right++ + dm_par->slev * *right_sur++;
*s16_samples++ = (int16_t)(left_tmp + *delay_left);
*s16_samples++ = (int16_t)(right_tmp + *delay_right);
*delay_left++ = dm_par->unit * *delay1_left++ + dm_par->slev * *delay1_sl++;
*delay_right++ = dm_par->unit * *delay1_right++ + dm_par->slev * *delay1_sr++;
}
break;
case 5: // 3/1
left = samples[0];
center = samples[1];
right = samples[2];
right_sur = samples[3];
delay_left = delay[0];
delay_right = delay[1];
delay1_left = delay1[0];
delay1_center = delay1[1];
delay1_right = delay1[2];
delay1_sl = delay1[3];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left++ + dm_par->clev * *center - dm_par->slev * *right_sur;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++ + dm_par->slev * *right_sur++;
*s16_samples++ = (int16_t)(left_tmp + *delay_left);
*s16_samples++ = (int16_t)(right_tmp + *delay_right);
*delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center + dm_par->slev * *delay1_sl;
*delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++ + dm_par->slev * *delay1_sl++;
}
break;
case 4: // 2/1
left = samples[0];
right = samples[1];
right_sur = samples[2];
delay_left = delay[0];
delay_right = delay[1];
delay1_left = delay1[0];
delay1_right = delay1[1];
delay1_sl = delay1[2];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left++ - dm_par->slev * *right_sur;
right_tmp= dm_par->unit * *right++ + dm_par->slev * *right_sur++;
*s16_samples++ = (int16_t)(left_tmp + *delay_left);
*s16_samples++ = (int16_t)(right_tmp + *delay_right);
*delay_left++ = dm_par->unit * *delay1_left++ + dm_par->slev * *delay1_sl;
*delay_right++ = dm_par->unit * *delay1_right++ + dm_par->slev * *delay1_sl++;
}
break;
case 3: // 3/0
left = samples[0];
center = samples[1];
right = samples[2];
delay_left = delay[0];
delay_right = delay[1];
delay1_left = delay1[0];
delay1_center = delay1[1];
delay1_right = delay1[2];
for (i = 0; i < 256; i++) {
left_tmp = dm_par->unit * *left++ + dm_par->clev * *center;
right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++;
*s16_samples++ = (int16_t)(left_tmp + *delay_left);
*s16_samples++ = (int16_t)(right_tmp + *delay_right);
*delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center;
*delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++;
}
break;
case 2: // copy to output
for (i = 0; i < 256; i++) {
*s16_samples++ = (int16_t)samples[0][i];
*s16_samples++ = (int16_t)samples[1][i];
}
break;
}
}
}

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, int16_t *s16_samples, dm_par_t *dm_par);
void imdct_init(void);

View File

@ -1,548 +0,0 @@
/*
* imdct512_kni.S
*
* Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - October 2000
*
*
* imdct512_kni.S 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.
*
* imdct512_kni.S 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 __i386__
.text
.align 4
.global imdct512_pre_ifft_twiddle_kni
.type imdct512_pre_ifft_twiddle_kni, @function
imdct512_pre_ifft_twiddle_kni:
pushl %ebp
movl %esp, %ebp
addl $-4, %esp /* local variable, loop counter */
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
movl 8(%ebp), %eax /* pmt */
movl 12(%ebp), %ebx /* buf */
movl 16(%ebp), %ecx /* data */
movl 20(%ebp), %edx /* xcos_sin_sse */
movl $64, -4(%ebp)
.loop:
movl (%eax), %esi
movl 4(%eax), %edi
movss (%ecx, %esi, 8), %xmm1 /* 2j */
movss (%ecx, %edi, 8), %xmm3 /* 2(j+1) */
shll $1, %esi
shll $1, %edi
movaps (%edx, %esi, 8), %xmm0; /* -c_j | -s_j | -s_j | c_j */
movaps (%edx, %edi, 8), %xmm2; /* -c_j+1 | -s_j+1 | -s_j+1 | c_j+1 */
negl %esi
negl %edi
movss 1020(%ecx, %esi, 4), %xmm4 /* 255-2j */
addl $8, %eax
movss 1020(%ecx, %edi, 4), %xmm5 /* 255-2(j+1) */
shufps $0, %xmm1, %xmm4 /* 2j | 2j | 255-2j | 255-2j */
shufps $0, %xmm3, %xmm5 /* 2(j+1) | 2(j+1) | 255-2(j+1) | 255-2(j+1) */
mulps %xmm4, %xmm0
mulps %xmm5, %xmm2
movhlps %xmm0, %xmm1
movhlps %xmm2, %xmm3
addl $16, %ebx
addps %xmm1, %xmm0
addps %xmm3, %xmm2
movlhps %xmm2, %xmm0
movaps %xmm0, -16(%ebx)
decl -4(%ebp)
jnz .loop
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
addl $4, %esp
popl %ebp
ret
.p2align 4,0
.global imdct512_post_ifft_twiddle_kni
.type imdct512_post_ifft_twiddle_kni, @function
imdct512_post_ifft_twiddle_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
movl 8(%ebp), %eax /* buf[] */
movl 12(%ebp), %ebx /* xcos_sin_sse[] */
movl $32, %ecx /* loop counter */
.loop1:
movaps (%eax), %xmm0 /* im1 | re1 | im0 | re0 */
movaps (%ebx), %xmm2 /* -c | -s | -s | c */
movhlps %xmm0, %xmm1 /* im1 | re1 */
movaps 16(%ebx), %xmm3 /* -c1 | -s1 | -s1 | c1 */
shufps $0x50, %xmm0, %xmm0 /* im0 | im0 | re0 | re0 */
shufps $0x50, %xmm1, %xmm1 /* im1 | im1 | re1 | re1 */
movaps 16(%eax), %xmm4 /* im3 | re3 | im2 | re2 */
shufps $0x27, %xmm2, %xmm2 /* c | -s | -s | -c */
movhlps %xmm4, %xmm5 /* im3 | re3 */
shufps $0x27, %xmm3, %xmm3 /* c1 | -s1 | -s1 | -c1 */
movaps 32(%ebx), %xmm6 /* -c2 | -s2 | -s2 | c2 */
movaps 48(%ebx), %xmm7 /* -c3 | -s3 | -s3 | c3 */
shufps $0x50, %xmm4, %xmm4 /* im2 | im2 | re2 | re2 */
shufps $0x50, %xmm5, %xmm5 /* im3 | im3 | re3 | re3 */
mulps %xmm2, %xmm0
mulps %xmm3, %xmm1
shufps $0x27, %xmm6, %xmm6 /* c2 | -s2 | -s2 | -c2 */
shufps $0x27, %xmm7, %xmm7 /* c3 | -s3 | -s3 | -c3 */
movhlps %xmm0, %xmm2
movhlps %xmm1, %xmm3
mulps %xmm6, %xmm4
mulps %xmm7, %xmm5
addps %xmm2, %xmm0
addps %xmm3, %xmm1
movhlps %xmm4, %xmm6
movhlps %xmm5, %xmm7
addps %xmm6, %xmm4
addps %xmm7, %xmm5
movlhps %xmm1, %xmm0
movlhps %xmm5, %xmm4
movaps %xmm0, (%eax)
movaps %xmm4, 16(%eax)
addl $64, %ebx
addl $32, %eax
decl %ecx
jnz .loop1
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,0
.global imdct512_window_delay_kni
.type imdct512_window_delay_kni, @function
imdct512_window_delay_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
movl 20(%ebp), %ebx /* delay */
movl 16(%ebp), %edx /* window */
movl 8(%ebp), %eax /* buf */
movl $16, %ecx /* loop count */
leal 516(%eax), %esi /* buf[64].im */
leal 504(%eax), %edi /* buf[63].re */
movl 12(%ebp), %eax /* data */
.first_128_samples:
movss (%esi), %xmm0
movss 8(%esi), %xmm2
movss (%edi), %xmm1
movss -8(%edi), %xmm3
movlhps %xmm2, %xmm0 /* 0.0 | im1 | 0.0 | im0 */
movlhps %xmm3, %xmm1 /* 0.0 | re1 | 0.0 | re0 */
movaps (%edx), %xmm4 /* w3 | w2 | w1 | w0 */
movaps (%ebx), %xmm5 /* d3 | d2 | d1 | d0 */
shufps $0xb1, %xmm1, %xmm1 /* re1 | 0.0 | re0 | 0.0 */
movss 16(%esi), %xmm6 /* im2 */
movss 24(%esi), %xmm7 /* im3 */
subps %xmm1, %xmm0 /* -re1 | im1 | -re0 | im0 */
movss -16(%edi), %xmm2 /* re2 */
movss -24(%edi), %xmm3 /* re3 */
mulps %xmm4, %xmm0
movlhps %xmm7, %xmm6 /* 0.0 | im3 | 0.0 | im2 */
movlhps %xmm3, %xmm2 /* 0.0 | re3 | 0.0 | re2 */
addps %xmm5, %xmm0
shufps $0xb1, %xmm2, %xmm2 /* re3 | 0.0 | re2 | 0.0 */
movaps 16(%edx), %xmm4 /* w7 | w6 | w5 | w4 */
movaps 16(%ebx), %xmm5 /* d7 | d6 | d5 | d4 */
subps %xmm2, %xmm6 /* -re3 | im3 | -re2 | im2 */
addl $32, %edx
movaps %xmm0, (%eax)
addl $32, %ebx
mulps %xmm4, %xmm6
addl $32, %esi
addl $32, %eax
addps %xmm5, %xmm6
addl $-32, %edi
movaps %xmm6, -16(%eax)
decl %ecx
jnz .first_128_samples
movl 8(%ebp), %esi /* buf[0].re */
leal 1020(%esi), %edi /* buf[127].im */
movl $16, %ecx /* loop count */
.second_128_samples:
movss (%esi), %xmm0 /* buf[i].re */
movss 8(%esi), %xmm2 /* re1 */
movss (%edi), %xmm1 /* buf[127-i].im */
movss -8(%edi), %xmm3 /* im1 */
movlhps %xmm2, %xmm0 /* 0.0 | re1 | 0.0 | re0 */
movlhps %xmm3, %xmm1 /* 0.0 | im1 | 0.0 | im1 */
movaps (%edx), %xmm4 /* w3 | w2 | w1 | w0 */
movaps (%ebx), %xmm5 /* d3 | d2 | d1 | d0 */
shufps $0xb1, %xmm1, %xmm1 /* im1 | 0.0 | im0 | 0.0 */
movss 16(%esi), %xmm6 /* re2 */
movss 24(%esi), %xmm7 /* re3 */
movss -16(%edi), %xmm2 /* im2 */
movss -24(%edi), %xmm3 /* im3 */
subps %xmm1, %xmm0 /* -im1 | re1 | -im0 | re0 */
movlhps %xmm7, %xmm6 /* 0.0 | re3 | 0.0 | re2 */
movlhps %xmm3, %xmm2 /* 0.0 | im3 | 0.0 | im2 */
mulps %xmm4, %xmm0
shufps $0xb1, %xmm2, %xmm2 /* im3 | 0.0 | im2 | 0.0 */
movaps 16(%edx), %xmm4 /* w7 | w6 | w5 | w4 */
addl $32, %esi
subps %xmm2, %xmm6 /* -im3 | re3 | -im2 | re2 */
addps %xmm5, %xmm0
mulps %xmm4, %xmm6
addl $-32, %edi
movaps 16(%ebx), %xmm5 /* d7 | d6 | d5 | d4 */
movaps %xmm0, (%eax)
addps %xmm5, %xmm6
addl $32, %edx
addl $32, %eax
addl $32, %ebx
movaps %xmm6, -16(%eax)
decl %ecx
jnz .second_128_samples
movl 8(%ebp), %eax
leal 512(%eax), %esi /* buf[64].re */
leal 508(%eax), %edi /* buf[63].im */
movl $16, %ecx /* loop count */
movl 20(%ebp), %eax /* delay */
.first_128_delay:
movss (%esi), %xmm0
movss 8(%esi), %xmm2
movss (%edi), %xmm1
movss -8(%edi), %xmm3
movlhps %xmm2, %xmm0 /* 0.0 | re1 | 0.0 | re0 */
movlhps %xmm3, %xmm1 /* 0.0 | im1 | 0.0 | im0 */
movaps -16(%edx), %xmm4 /* w3 | w2 | w1 | w0 */
shufps $0xb1, %xmm1, %xmm1 /* im1 | 0.0 | im0 | 0.0 */
movss 16(%esi), %xmm6 /* re2 */
movss 24(%esi), %xmm7 /* re3 */
movss -16(%edi), %xmm2 /* im2 */
movss -24(%edi), %xmm3 /* im3 */
subps %xmm1, %xmm0 /* -im1 | re1 | -im0 | re0 */
addl $-32, %edx
movlhps %xmm7, %xmm6 /* 0.0 | re3 | 0.0 | re2 */
movlhps %xmm3, %xmm2 /* 0.0 | im3 | 0.0 | im2 */
mulps %xmm4, %xmm0
movaps (%edx), %xmm5 /* w7 | w6 | w5 | w4 */
shufps $0xb1, %xmm2, %xmm2 /* im3 | 0.0 | im2 | 0.0 */
movaps %xmm0, (%eax)
addl $32, %esi
subps %xmm2, %xmm6 /* -im3 | re3 | -im2 | re2 */
addl $-32, %edi
mulps %xmm5, %xmm6
addl $32, %eax
movaps %xmm6, -16(%eax)
decl %ecx
jnz .first_128_delay
movl 8(%ebp), %ebx
leal 4(%ebx), %esi /* buf[0].im */
leal 1016(%ebx), %edi /* buf[127].re */
movl $16, %ecx /* loop count */
.second_128_delay:
movss (%esi), %xmm0
movss 8(%esi), %xmm2
movss (%edi), %xmm1
movss -8(%edi), %xmm3
movlhps %xmm2, %xmm0 /* 0.0 | im1 | 0.0 | im0 */
movlhps %xmm3, %xmm1 /* 0.0 | re1 | 0.0 | re0 */
movaps -16(%edx), %xmm4 /* w3 | w2 | w1 | w0 */
shufps $0xb1, %xmm1, %xmm1 /* re1 | 0.0 | re0 | 0.0 */
movss 16(%esi), %xmm6 /* im2 */
movss 24(%esi), %xmm7 /* im3 */
movss -16(%edi), %xmm2 /* re2 */
movss -24(%edi), %xmm3 /* re3 */
subps %xmm0, %xmm1 /* re1 | -im1 | re0 | -im0 */
addl $-32, %edx
movlhps %xmm7, %xmm6 /* 0.0 | im3 | 0.0 | im2 */
movlhps %xmm3, %xmm2 /* 0.0 | re3 | 0.0 | re2 */
mulps %xmm4, %xmm1
movaps (%edx), %xmm5 /* w7 | w6 | w5 | w4 */
shufps $0xb1, %xmm2, %xmm2 /* re3 | 0.0 | re2 | 0.0 */
movaps %xmm1, (%eax)
addl $32, %esi
subps %xmm6, %xmm2 /* re | -im3 | re | -im2 */
addl $-32, %edi
mulps %xmm5, %xmm2
addl $32, %eax
movaps %xmm2, -16(%eax)
decl %ecx
jnz .second_128_delay
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,0
.global imdct512_window_delay_nol_kni
.type imdct512_window_delay_nol_kni, @function
imdct512_window_delay_nol_kni:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
/* movl 20(%ebp), %ebx delay */
movl 16(%ebp), %edx /* window */
movl 8(%ebp), %eax /* buf */
movl $16, %ecx /* loop count */
leal 516(%eax), %esi /* buf[64].im */
leal 504(%eax), %edi /* buf[63].re */
movl 12(%ebp), %eax /* data */
.first_128_sample:
movss (%esi), %xmm0
movss 8(%esi), %xmm2
movss (%edi), %xmm1
movss -8(%edi), %xmm3
movlhps %xmm2, %xmm0 /* 0.0 | im1 | 0.0 | im0 */
movlhps %xmm3, %xmm1 /* 0.0 | re1 | 0.0 | re0 */
movaps (%edx), %xmm4 /* w3 | w2 | w1 | w0 */
/* movaps (%ebx), %xmm5 d3 | d2 | d1 | d0 */
shufps $0xb1, %xmm1, %xmm1 /* re1 | 0.0 | re0 | 0.0 */
movss 16(%esi), %xmm6 /* im2 */
movss 24(%esi), %xmm7 /* im3 */
subps %xmm1, %xmm0 /* -re1 | im1 | -re0 | im0 */
movss -16(%edi), %xmm2 /* re2 */
movss -24(%edi), %xmm3 /* re3 */
mulps %xmm4, %xmm0
movlhps %xmm7, %xmm6 /* 0.0 | im3 | 0.0 | im2 */
movlhps %xmm3, %xmm2 /* 0.0 | re3 | 0.0 | re2 */
/* addps %xmm5, %xmm0 */
shufps $0xb1, %xmm2, %xmm2 /* re3 | 0.0 | re2 | 0.0 */
movaps 16(%edx), %xmm4 /* w7 | w6 | w5 | w4 */
/* movaps 16(%ebx), %xmm5 d7 | d6 | d5 | d4 */
subps %xmm2, %xmm6 /* -re3 | im3 | -re2 | im2 */
addl $32, %edx
movaps %xmm0, (%eax)
/* addl $32, %ebx */
mulps %xmm4, %xmm6
addl $32, %esi
addl $32, %eax
/* addps %xmm5, %xmm6 */
addl $-32, %edi
movaps %xmm6, -16(%eax)
decl %ecx
jnz .first_128_sample
movl 8(%ebp), %esi /* buf[0].re */
leal 1020(%esi), %edi /* buf[127].im */
movl $16, %ecx /* loop count */
.second_128_sample:
movss (%esi), %xmm0 /* buf[i].re */
movss 8(%esi), %xmm2 /* re1 */
movss (%edi), %xmm1 /* buf[127-i].im */
movss -8(%edi), %xmm3 /* im1 */
movlhps %xmm2, %xmm0 /* 0.0 | re1 | 0.0 | re0 */
movlhps %xmm3, %xmm1 /* 0.0 | im1 | 0.0 | im1 */
movaps (%edx), %xmm4 /* w3 | w2 | w1 | w0 */
/* movaps (%ebx), %xmm5 d3 | d2 | d1 | d0 */
shufps $0xb1, %xmm1, %xmm1 /* im1 | 0.0 | im0 | 0.0 */
movss 16(%esi), %xmm6 /* re2 */
movss 24(%esi), %xmm7 /* re3 */
movss -16(%edi), %xmm2 /* im2 */
movss -24(%edi), %xmm3 /* im3 */
subps %xmm1, %xmm0 /* -im1 | re1 | -im0 | re0 */
movlhps %xmm7, %xmm6 /* 0.0 | re3 | 0.0 | re2 */
movlhps %xmm3, %xmm2 /* 0.0 | im3 | 0.0 | im2 */
mulps %xmm4, %xmm0
shufps $0xb1, %xmm2, %xmm2 /* im3 | 0.0 | im2 | 0.0 */
movaps 16(%edx), %xmm4 /* w7 | w6 | w5 | w4 */
addl $32, %esi
subps %xmm2, %xmm6 /* -im3 | re3 | -im2 | re2 */
/* addps %xmm5, %xmm0 */
mulps %xmm4, %xmm6
addl $-32, %edi
/* movaps 16(%ebx), %xmm5 d7 | d6 | d5 | d4 */
movaps %xmm0, (%eax)
/* addps %xmm5, %xmm6 */
addl $32, %edx
addl $32, %eax
/* addl $32, %ebx */
movaps %xmm6, -16(%eax)
decl %ecx
jnz .second_128_sample
movl 8(%ebp), %eax
leal 512(%eax), %esi /* buf[64].re */
leal 508(%eax), %edi /* buf[63].im */
movl $16, %ecx /* loop count */
movl 20(%ebp), %eax /* delay */
.first_128_delays:
movss (%esi), %xmm0
movss 8(%esi), %xmm2
movss (%edi), %xmm1
movss -8(%edi), %xmm3
movlhps %xmm2, %xmm0 /* 0.0 | re1 | 0.0 | re0 */
movlhps %xmm3, %xmm1 /* 0.0 | im1 | 0.0 | im0 */
movaps -16(%edx), %xmm4 /* w3 | w2 | w1 | w0 */
shufps $0xb1, %xmm1, %xmm1 /* im1 | 0.0 | im0 | 0.0 */
movss 16(%esi), %xmm6 /* re2 */
movss 24(%esi), %xmm7 /* re3 */
movss -16(%edi), %xmm2 /* im2 */
movss -24(%edi), %xmm3 /* im3 */
subps %xmm1, %xmm0 /* -im1 | re1 | -im0 | re0 */
addl $-32, %edx
movlhps %xmm7, %xmm6 /* 0.0 | re3 | 0.0 | re2 */
movlhps %xmm3, %xmm2 /* 0.0 | im3 | 0.0 | im2 */
mulps %xmm4, %xmm0
movaps (%edx), %xmm5 /* w7 | w6 | w5 | w4 */
shufps $0xb1, %xmm2, %xmm2 /* im3 | 0.0 | im2 | 0.0 */
movaps %xmm0, (%eax)
addl $32, %esi
subps %xmm2, %xmm6 /* -im3 | re3 | -im2 | re2 */
addl $-32, %edi
mulps %xmm5, %xmm6
addl $32, %eax
movaps %xmm6, -16(%eax)
decl %ecx
jnz .first_128_delays
movl 8(%ebp), %ebx
leal 4(%ebx), %esi /* buf[0].im */
leal 1016(%ebx), %edi /* buf[127].re */
movl $16, %ecx /* loop count */
.second_128_delays:
movss (%esi), %xmm0
movss 8(%esi), %xmm2
movss (%edi), %xmm1
movss -8(%edi), %xmm3
movlhps %xmm2, %xmm0 /* 0.0 | im1 | 0.0 | im0 */
movlhps %xmm3, %xmm1 /* 0.0 | re1 | 0.0 | re0 */
movaps -16(%edx), %xmm4 /* w3 | w2 | w1 | w0 */
shufps $0xb1, %xmm1, %xmm1 /* re1 | 0.0 | re0 | 0.0 */
movss 16(%esi), %xmm6 /* im2 */
movss 24(%esi), %xmm7 /* im3 */
movss -16(%edi), %xmm2 /* re2 */
movss -24(%edi), %xmm3 /* re3 */
subps %xmm0, %xmm1 /* re1 | -im1 | re0 | -im0 */
addl $-32, %edx
movlhps %xmm7, %xmm6 /* 0.0 | im3 | 0.0 | im2 */
movlhps %xmm3, %xmm2 /* 0.0 | re3 | 0.0 | re2 */
mulps %xmm4, %xmm1
movaps (%edx), %xmm5 /* w7 | w6 | w5 | w4 */
shufps $0xb1, %xmm2, %xmm2 /* re3 | 0.0 | re2 | 0.0 */
movaps %xmm1, (%eax)
addl $32, %esi
subps %xmm6, %xmm2 /* re | -im3 | re | -im2 */
addl $-32, %edi
mulps %xmm5, %xmm2
addl $32, %eax
movaps %xmm2, -16(%eax)
decl %ecx
jnz .second_128_delays
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %eax
leave
ret
.p2align 4,0
#endif

View File

@ -1,218 +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 "downmix.h"
#include "imdct_c.h"
#include "srfft.h"
#define N 512
extern void (*imdct_do_512) (float data[],float delay[]);
extern void (*imdct_do_512_nol) (float data[], float delay[]);
extern void (*fft_64p) (complex_t *);
extern const int pm128[];
extern float window[];
extern complex_t buf[128];
extern void fft_64p_c (complex_t *);
extern void fft_128p_c (complex_t *);
static void imdct_do_512_c (float data[],float delay[]);
static void imdct_do_512_nol_c (float data[], float delay[]);
/* Twiddle factors for IMDCT */
static float xcos1[128] __attribute__((aligned(16)));
static float xsin1[128] __attribute__((aligned(16)));
int imdct_init_c (void)
{
int i;
float scale = 255.99609372;
imdct_do_512 = imdct_do_512_c;
imdct_do_512_nol = imdct_do_512_nol_c;
fft_64p = fft_64p_c;
/* 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)) * scale;
xsin1[i] = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
}
return 0;
}
static void imdct_do_512_c (float data[], float delay[])
{
int i, j;
float tmp_a_r, tmp_a_i;
float *data_ptr;
float *delay_ptr;
float *window_ptr;
// 512 IMDCT with source and dest data in 'data'
// Pre IFFT complex multiply plus IFFT complex conjugate
for( i=0; i < 128; i++) {
j = pm128[i];
//a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
//c = data[2*j] * xcos1[j];
//b = data[256-2*j-1] * xsin1[j];
//buf1[i].re = a - b + c;
//buf1[i].im = b + c;
buf[i].re = (data[256-2*j-1] * xcos1[j]) - (data[2*j] * xsin1[j]);
buf[i].im = -1.0 * (data[2*j] * xcos1[j] + data[256-2*j-1] * xsin1[j]);
}
fft_128p_c (&buf[0]);
// Post IFFT complex multiply plus IFFT complex conjugate
for (i=0; i < 128; i++) {
tmp_a_r = buf[i].re;
tmp_a_i = buf[i].im;
//a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
//b = tmp_a_r * xsin1[j];
//c = tmp_a_i * xcos1[j];
//buf[j].re = a - b + c;
//buf[j].im = b + c;
buf[i].re =(tmp_a_r * xcos1[i]) + (tmp_a_i * xsin1[i]);
buf[i].im =(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++ = -buf[64+i].im * *window_ptr++ + *delay_ptr++;
*data_ptr++ = buf[64-i-1].re * *window_ptr++ + *delay_ptr++;
}
for(i=0; i< 64; i++) {
*data_ptr++ = -buf[i].re * *window_ptr++ + *delay_ptr++;
*data_ptr++ = buf[128-i-1].im * *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].re * *--window_ptr;
*delay_ptr++ = buf[64-i-1].im * *--window_ptr;
}
for(i=0; i<64; i++) {
*delay_ptr++ = buf[i].im * *--window_ptr;
*delay_ptr++ = -buf[128-i-1].re * *--window_ptr;
}
}
static void imdct_do_512_nol_c (float data[], float delay[])
{
int i, j;
float tmp_a_i;
float tmp_a_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]) */
j = pm128[i];
//a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
//c = data[2*j] * xcos1[j];
//b = data[256-2*j-1] * xsin1[j];
//buf1[i].re = a - b + c;
//buf1[i].im = b + c;
buf[i].re = (data[256-2*j-1] * xcos1[j]) - (data[2*j] * xsin1[j]);
buf[i].im = -1.0 * (data[2*j] * xcos1[j] + data[256-2*j-1] * xsin1[j]);
}
fft_128p_c (&buf[0]);
/* Post IFFT complex multiply plus IFFT complex conjugate*/
for (i=0; i < 128; i++) {
/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
/* int j1 = i; */
tmp_a_r = buf[i].re;
tmp_a_i = buf[i].im;
//a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
//b = tmp_a_r * xsin1[j];
//c = tmp_a_i * xcos1[j];
//buf[j].re = a - b + c;
//buf[j].im = b + c;
buf[i].re =(tmp_a_r * xcos1[i]) + (tmp_a_i * xsin1[i]);
buf[i].im =(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, no overlap here*/
for (i=0; i< 64; i++) {
*data_ptr++ = -buf[64+i].im * *window_ptr++;
*data_ptr++ = buf[64-i-1].re * *window_ptr++;
}
for(i=0; i< 64; i++) {
*data_ptr++ = -buf[i].re * *window_ptr++;
*data_ptr++ = buf[128-i-1].im * *window_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].re * *--window_ptr;
*delay_ptr++ = buf[64-i-1].im * *--window_ptr;
}
for(i=0; i<64; i++) {
*delay_ptr++ = buf[i].im * *--window_ptr;
*delay_ptr++ = -buf[128-i-1].re * *--window_ptr;
}
}

View File

@ -1,36 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __IMDCT_C_H__
#define __IMDCT_C_H__
#include "cmplx.h"
int imdct_init_c (void);
void fft_128p_c (complex_t *);
void fft_64p_c (complex_t *);
void imdct512_pre_ifft_twiddle_c (const int *pmt, complex_t *buf, float *data, float *xcos_sin_sse);
void imdct512_post_ifft_twiddle_c (complex_t *buf, float *xcos_sin_sse);
void imdct512_window_delay_c (complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt);
void imdct512_window_delay_nol_c (complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt);
#endif

View File

@ -1,103 +0,0 @@
/*
* imdct_kni.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 __i386__
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <mm_accel.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "downmix.h"
#include "imdct_kni.h"
#include "srfft.h"
#define N 512
/* Delay buffer for time domain interleaving */
static float xcos_sin_sse[128 * 4] __attribute__((aligned(16)));
extern void (*imdct_do_512) (float data[],float delay[]);
extern void (*imdct_do_512_nol) (float data[], float delay[]);
extern void (*fft_64p) (complex_t *);
extern const int pm128[];
extern float window[];
extern complex_t buf[128];
extern void fft_64p_kni (complex_t *);
extern void fft_128p_kni (complex_t *);
static void imdct_do_512_kni (float data[], float delay[]);
static void imdct_do_512_nol_kni (float data[], float delay[]);
int imdct_init_kni (void)
{
uint32_t accel = mm_accel ();
if (accel & MM_ACCEL_X86_MMXEXT) {
int i;
float scale = 255.99609372;
fprintf (stderr, "Using SSE for IMDCT\n");
imdct_do_512 = imdct_do_512_kni;
imdct_do_512_nol = imdct_do_512_nol_kni;
fft_64p = fft_64p_kni;
for (i=0; i < 128; i++) {
float xcos_i = cos(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
float xsin_i = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
xcos_sin_sse[i * 4] = xcos_i;
xcos_sin_sse[i * 4 + 1] = -xsin_i;
xcos_sin_sse[i * 4 + 2] = -xsin_i;
xcos_sin_sse[i * 4 + 3] = -xcos_i;
}
return 0;
} else
return -1;
}
static void imdct_do_512_kni (float data[], float delay[])
{
imdct512_pre_ifft_twiddle_kni (pm128, buf, data, xcos_sin_sse);
fft_128p_kni (buf);
imdct512_post_ifft_twiddle_kni (buf, xcos_sin_sse);
imdct512_window_delay_kni (buf, data, window, delay);
}
static void imdct_do_512_nol_kni (float data[], float delay[])
{
imdct512_pre_ifft_twiddle_kni (pm128, buf, data, xcos_sin_sse);
fft_128p_kni (buf);
imdct512_post_ifft_twiddle_kni (buf, xcos_sin_sse);
imdct512_window_delay_nol_kni (buf, data, window, delay);
}
#endif

View File

@ -1,36 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __IMDCT_KNI_H__
#define __IMDCT_KNI_H__
#include "cmplx.h"
int imdct_init_kni (void);
void fft_128p_kni(complex_t *);
void fft_64p_kni(complex_t *);
void imdct512_pre_ifft_twiddle_kni(const int *pmt, complex_t *buf, float *data, float *xcos_sin_sse);
void imdct512_post_ifft_twiddle_kni(complex_t *buf, float *xcos_sin_sse);
void imdct512_window_delay_kni(complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt);
void imdct512_window_delay_nol_kni(complex_t *buf, float *data_ptr, float *window_prt, float *delay_prt);
#endif

View File

@ -1,36 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __MM_ACCEL_H__
#define __MM_ACCEL_H__
#include <inttypes.h>
// generic accelerations
#define MM_ACCEL_MLIB 0x00000001
// x86 accelerations
#define MM_ACCEL_X86_MMX 0x80000000
#define MM_ACCEL_X86_3DNOW 0x40000000
#define MM_ACCEL_X86_MMXEXT 0x20000000
uint32_t mm_accel (void);
#endif

View File

@ -1,481 +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 "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 uint16_t nfchans[8] = {2,1,2,3,3,4,4,5};
struct frmsize_s
{
uint16_t bit_rate;
uint16_t 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 } }
};
/* Parse a syncinfo structure, minus the sync word */
void parse_syncinfo(syncinfo_t *syncinfo, uint8_t *data)
{
//
// We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
// in order to determine how big the frame is
//
// Get the sampling rate
syncinfo->fscod = (data[2] >> 6) & 0x3;
if(syncinfo->fscod == 3) {
//invalid sampling rate code
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;
}
/**
* This routine fills a bsi struct from the AC3 stream
**/
void parse_bsi(bsi_t *bsi)
{
/* 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? */
if ((bsi->compre = bitstream_get(1))) {
/* Get compression gain */
bsi->compr = bitstream_get(8);
}
/* Does language code exist? */
if ((bsi->langcode = bitstream_get(1))) {
/* Get langauge code */
bsi->langcod = bitstream_get(8);
}
/* Does audio production info exist? */
if ((bsi->audprodie = bitstream_get(1))) {
/* 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) {
/* Get the dialogue normalization level two */
bsi->dialnorm2 = bitstream_get(5);
/* Does compression gain two exist? */
if ((bsi->compr2e = bitstream_get(1))) {
/* Get compression gain two */
bsi->compr2 = bitstream_get(8);
}
/* Does language code two exist? */
if ((bsi->langcod2e = bitstream_get(1))) {
/* Get langauge code two */
bsi->langcod2 = bitstream_get(8);
}
/* Does audio production info two exist? */
if ((bsi->audprodi2e = bitstream_get(1))) {
/* 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? */
if ((bsi->timecod1e = bitstream_get(1)))
bsi->timecod1 = bitstream_get(14);
/* Does timecode two exist? */
if ((bsi->timecod2e = bitstream_get(1)))
bsi->timecod2 = bitstream_get(14);
/* Does addition info exist? */
if ((bsi->addbsie = bitstream_get(1))) {
uint32_t i;
/* 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);
}
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? */
if ((audblk->dynrnge = bitstream_get(1))) {
/* 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? */
if ((audblk->dynrng2e = bitstream_get(1))) {
/* Get dynamic range info */
audblk->dynrng2 = bitstream_get(8);
}
}
/* Does coupling strategy exist? */
if ((audblk->cplstre = bitstream_get(1))) {
/* Is coupling turned on? */
if ((audblk->cplinu = bitstream_get(1))) {
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? */
if ((audblk->cplcoe[i] = bitstream_get(1))) {
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) {
if ((audblk->rematstr = bitstream_get(1))) {
if (!audblk->cplinu) {
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++) {
uint16_t 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))) {
uint16_t skip_data;
audblk->skipl = bitstream_get(9);
for (i = 0; i < audblk->skipl; i++) {
skip_data = bitstream_get(8);
}
}
stats_print_audblk(bsi,audblk);
}

View File

@ -1,26 +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(syncinfo_t *syncinfo,uint8_t *data);
void parse_audblk(bsi_t *bsi,audblk_t *audblk);
void parse_bsi(bsi_t *bsi);

View File

@ -1,91 +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 "rematrix.h"
struct rematrix_band_s
{
uint32_t start;
uint32_t end;
} rematrix_band[] = {
{13, 24},
{25, 36},
{37, 60},
{61, 252}
};
/**
*
**/
inline uint32_t min (uint32_t a, uint32_t b)
{
return (a < b) ? a : b;
}
/**
* This routine simply does stereo remartixing for the 2 channel
* stereo mode
**/
void rematrix (audblk_t *audblk, stream_samples_t samples)
{
uint32_t num_bands;
uint32_t start;
uint32_t end;
int i,j;
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++) {
float left,right;
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,124 +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;
}
/**
*
**/
int 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 **");
return -1;
}
if(bsi->magic != AC3_MAGIC_NUMBER) {
fprintf(stderr,"\n** Sanity check failed -- bsi magic number **");
return -1;
}
if(audblk->magic1 != AC3_MAGIC_NUMBER) {
fprintf(stderr,"\n** Sanity check failed -- audblk magic number 1 **");
return -1;
}
if(audblk->magic2 != AC3_MAGIC_NUMBER) {
fprintf(stderr,"\n** Sanity check failed -- audblk magic number 2 **");
return -1;
}
if(audblk->magic3 != AC3_MAGIC_NUMBER) {
fprintf(stderr,"\n** Sanity check failed -- audblk magic number 3 **");
return -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 **");
return -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 **");
return -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 **");
return -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 **");
return -1;
}
if (audblk->cpl_flt[255] !=0 || audblk->cpl_flt[254] !=0 ||
audblk->cpl_flt[253] !=0) {
fprintf(stderr,"\n** Sanity check failed -- cpl_mant out of bounds **");
return -1;
}
if ((audblk->cplinu == 1) && (audblk->cplbegf > (audblk->cplendf+2))) {
fprintf(stderr,"\n** Sanity check failed -- cpl params inconsistent **");
return -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 **");
return -1;
}
}
return 0;
}

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);
int sanity_check (syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk);

View File

@ -1,305 +0,0 @@
/*
* srfft.c
*
* Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
*
* 64 and 128 point split radix fft for ac3dec
*
* The algorithm is desribed in the book:
* "Computational Frameworks of the Fast Fourier Transform".
*
* The ideas and the the organization of code borrowed from djbfft written by
* D. J. Bernstein <djb@cr.py.to>. djbff can be found at
* http://cr.yp.to/djbfft.html.
*
* srfft.c 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.
*
* srfft.c 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 "srfft.h"
#include "srfftp.h"
void fft_8 (complex_t *x);
void fft_4(complex_t *x)
{
/* delta_p = 1 here */
/* x[k] = sum_{i=0..3} x[i] * w^{i*k}, w=e^{-2*pi/4}
*/
register float yt_r, yt_i, yb_r, yb_i, u_r, u_i, vi_r, vi_i;
yt_r = x[0].re;
yb_r = yt_r - x[2].re;
yt_r += x[2].re;
u_r = x[1].re;
vi_i = x[3].re - u_r;
u_r += x[3].re;
u_i = x[1].im;
vi_r = u_i - x[3].im;
u_i += x[3].im;
yt_i = yt_r;
yt_i += u_r;
x[0].re = yt_i;
yt_r -= u_r;
x[2].re = yt_r;
yt_i = yb_r;
yt_i += vi_r;
x[1].re = yt_i;
yb_r -= vi_r;
x[3].re = yb_r;
yt_i = x[0].im;
yb_i = yt_i - x[2].im;
yt_i += x[2].im;
yt_r = yt_i;
yt_r += u_i;
x[0].im = yt_r;
yt_i -= u_i;
x[2].im = yt_i;
yt_r = yb_i;
yt_r += vi_i;
x[1].im = yt_r;
yb_i -= vi_i;
x[3].im = yb_i;
}
void fft_8 (complex_t *x)
{
/* delta_p = diag{1, sqrt(i)} here */
/* x[k] = sum_{i=0..7} x[i] * w^{i*k}, w=e^{-2*pi/8}
*/
register float wT1_r, wT1_i, wB1_r, wB1_i, wT2_r, wT2_i, wB2_r, wB2_i;
wT1_r = x[1].re;
wT1_i = x[1].im;
wB1_r = x[3].re;
wB1_i = x[3].im;
x[1] = x[2];
x[2] = x[4];
x[3] = x[6];
fft_4(&x[0]);
/* x[0] x[4] */
wT2_r = x[5].re;
wT2_r += x[7].re;
wT2_r += wT1_r;
wT2_r += wB1_r;
wT2_i = wT2_r;
wT2_r += x[0].re;
wT2_i = x[0].re - wT2_i;
x[0].re = wT2_r;
x[4].re = wT2_i;
wT2_i = x[5].im;
wT2_i += x[7].im;
wT2_i += wT1_i;
wT2_i += wB1_i;
wT2_r = wT2_i;
wT2_r += x[0].im;
wT2_i = x[0].im - wT2_i;
x[0].im = wT2_r;
x[4].im = wT2_i;
/* x[2] x[6] */
wT2_r = x[5].im;
wT2_r -= x[7].im;
wT2_r += wT1_i;
wT2_r -= wB1_i;
wT2_i = wT2_r;
wT2_r += x[2].re;
wT2_i = x[2].re - wT2_i;
x[2].re = wT2_r;
x[6].re = wT2_i;
wT2_i = x[5].re;
wT2_i -= x[7].re;
wT2_i += wT1_r;
wT2_i -= wB1_r;
wT2_r = wT2_i;
wT2_r += x[2].im;
wT2_i = x[2].im - wT2_i;
x[2].im = wT2_i;
x[6].im = wT2_r;
/* x[1] x[5] */
wT2_r = wT1_r;
wT2_r += wB1_i;
wT2_r -= x[5].re;
wT2_r -= x[7].im;
wT2_i = wT1_i;
wT2_i -= wB1_r;
wT2_i -= x[5].im;
wT2_i += x[7].re;
wB2_r = wT2_r;
wB2_r += wT2_i;
wT2_i -= wT2_r;
wB2_r *= HSQRT2;
wT2_i *= HSQRT2;
wT2_r = wB2_r;
wB2_r += x[1].re;
wT2_r = x[1].re - wT2_r;
wB2_i = x[5].re;
x[1].re = wB2_r;
x[5].re = wT2_r;
wT2_r = wT2_i;
wT2_r += x[1].im;
wT2_i = x[1].im - wT2_i;
wB2_r = x[5].im;
x[1].im = wT2_r;
x[5].im = wT2_i;
/* x[3] x[7] */
wT1_r -= wB1_i;
wT1_i += wB1_r;
wB1_r = wB2_i - x[7].im;
wB1_i = wB2_r + x[7].re;
wT1_r -= wB1_r;
wT1_i -= wB1_i;
wB1_r = wT1_r + wT1_i;
wB1_r *= HSQRT2;
wT1_i -= wT1_r;
wT1_i *= HSQRT2;
wB2_r = x[3].re;
wB2_i = wB2_r + wT1_i;
wB2_r -= wT1_i;
x[3].re = wB2_i;
x[7].re = wB2_r;
wB2_i = x[3].im;
wB2_r = wB2_i + wB1_r;
wB2_i -= wB1_r;
x[3].im = wB2_i;
x[7].im = wB2_r;
}
void fft_asmb(int k, complex_t *x, complex_t *wTB,
const complex_t *d, const complex_t *d_3)
{
register complex_t *x2k, *x3k, *x4k, *wB;
register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i;
x2k = x + 2 * k;
x3k = x2k + 2 * k;
x4k = x3k + 2 * k;
wB = wTB + 2 * k;
TRANSZERO(x[0],x2k[0],x3k[0],x4k[0]);
TRANS(x[1],x2k[1],x3k[1],x4k[1],wTB[1],wB[1],d[1],d_3[1]);
--k;
for(;;) {
TRANS(x[2],x2k[2],x3k[2],x4k[2],wTB[2],wB[2],d[2],d_3[2]);
TRANS(x[3],x2k[3],x3k[3],x4k[3],wTB[3],wB[3],d[3],d_3[3]);
if (!--k) break;
x += 2;
x2k += 2;
x3k += 2;
x4k += 2;
d += 2;
d_3 += 2;
wTB += 2;
wB += 2;
}
}
void fft_asmb16(complex_t *x, complex_t *wTB)
{
register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i;
int k = 2;
/* transform x[0], x[8], x[4], x[12] */
TRANSZERO(x[0],x[4],x[8],x[12]);
/* transform x[1], x[9], x[5], x[13] */
TRANS(x[1],x[5],x[9],x[13],wTB[1],wTB[5],delta16[1],delta16_3[1]);
/* transform x[2], x[10], x[6], x[14] */
TRANSHALF_16(x[2],x[6],x[10],x[14]);
/* transform x[3], x[11], x[7], x[15] */
TRANS(x[3],x[7],x[11],x[15],wTB[3],wTB[7],delta16[3],delta16_3[3]);
}
void fft_64p_c (complex_t *a)
{
fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
fft_asmb16(&a[0], &a[8]);
fft_8(&a[16]), fft_8(&a[24]);
fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]);
fft_asmb16(&a[32], &a[40]);
fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]);
fft_asmb16(&a[48], &a[56]);
fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
}
void fft_128p_c (complex_t *a)
{
fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
fft_asmb16(&a[0], &a[8]);
fft_8(&a[16]), fft_8(&a[24]);
fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]);
fft_asmb16(&a[32], &a[40]);
fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]);
fft_asmb16(&a[48], &a[56]);
fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
fft_8(&a[64]); fft_4(&a[72]); fft_4(&a[76]);
/* fft_16(&a[64]); */
fft_asmb16(&a[64], &a[72]);
fft_8(&a[80]); fft_8(&a[88]);
/* fft_32(&a[64]); */
fft_asmb(4, &a[64], &a[80],&delta32[0], &delta32_3[0]);
fft_8(&a[96]); fft_4(&a[104]), fft_4(&a[108]);
/* fft_16(&a[96]); */
fft_asmb16(&a[96], &a[104]);
fft_8(&a[112]), fft_8(&a[120]);
/* fft_32(&a[96]); */
fft_asmb(4, &a[96], &a[112], &delta32[0], &delta32_3[0]);
/* fft_128(&a[0]); */
fft_asmb(16, &a[0], &a[64], &delta128[0], &delta128_3[0]);
}

View File

@ -1,39 +0,0 @@
/*
* srfft.h
*
* Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
*
* 64 and 128 point split radix fft for ac3dec
*
* The algorithm is desribed in the book:
* "Computational Frameworks of the Fast Fourier Transform".
*
* The ideas and the the organization of code borrowed from djbfft written by
* D. J. Bernstein <djb@cr.py.to>. djbff can be found at
* http://cr.yp.to/djbfft.html.
*
* srfft.h 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.
*
* srfft.h 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 SRFFT_H__
#define SRFFT_H__
#include "cmplx.h"
void fft_64p_c (complex_t *x);
void fft_128p_c (complex_t *x);
#endif /* SRFFT_H__ */

View File

@ -1,289 +0,0 @@
/*
* srfft_kni.S
*
* Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - October 2000
*
*
* srfft_kni.S 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.
*
* srfft_kni.S 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 __i386__
.section .rodata
.align 16
hsqrt2: .float 0f0.707106781188
.float 0f0.707106781188
.float 0f-0.707106781188
.float 0f-0.707106781188
C_1: .float 0f-1.0
.float 0f1.0
.float 0f-1.0
.float 0f1.0
.text
.align 4
.global fft_4_kni
.type fft_4_kni, @function
fft_4_kni:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax /* complex_t * */
movaps (%eax), %xmm0 /* x[1] | x[0] */
movaps 16(%eax), %xmm2 /* x[3] | x[2] */
movaps %xmm0, %xmm1 /* x[1] | x[0] */
addps %xmm2, %xmm0 /* x[1] + x[3] | x[0] + x[2] */
subps %xmm2, %xmm1 /* x[1] - x[3] | x[0] - x[2] */
xorps %xmm6, %xmm6
movhlps %xmm1, %xmm4 /* x[1] - x[3] */
movhlps %xmm0, %xmm3 /* x[1] + x[3] */
subss %xmm4, %xmm6 /* -(x[1] - x[3]).re */
movlhps %xmm1, %xmm0 /* x[0] - x[2] | x[0] + x[2] */
movss %xmm6, %xmm4 /* (x[1] - x[3]).im | (x[3]-x[1]).re */
movaps %xmm0, %xmm2 /* x[0] - x[2] | x[0] + x[2] */
shufps $0x14, %xmm4, %xmm3 /* -i*(x[2] - x[3] | x[2] + x[3] */
addps %xmm3, %xmm0
subps %xmm3, %xmm2
movaps %xmm0, (%eax)
movaps %xmm2, 16(%eax)
leave
ret
.align 4
.global fft_8_kni
.type fft_8_kni, @function
fft_8_kni:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax /* complext_t */
pushl %ebx
movlps (%eax), %xmm0 /* x[0] */
movlps 32(%eax), %xmm1 /* x[4] */
movhps 16(%eax), %xmm0 /* x[2] | x[0] */
movhps 48(%eax), %xmm1 /* x[6] | x[4] */
movaps %xmm0, %xmm2 /* x[2] | x[0] */
xorps %xmm3, %xmm3
addps %xmm1, %xmm0 /* x[2] + x[6] | x[0] + x[4] */
subps %xmm1, %xmm2 /* x[2] - x[6] | x[0] - x[4] */
movhlps %xmm0, %xmm5 /* x[2] + x[6] */
movhlps %xmm2, %xmm4
movlhps %xmm2, %xmm0 /* x[0] - x[4] | x[0] + x[4] */
subss %xmm4, %xmm3 /* -(x[2]-x[6]).re */
movaps %xmm0, %xmm7 /* x[0] - x[4] | x[0] + x[4] */
movss %xmm3, %xmm4 /* (x[2]-x[6]).im | -(x[2]-x[6]).re */
movlps 8(%eax), %xmm1 /* x[1] */
shufps $0x14, %xmm4, %xmm5 /* -i*(x[2] - x[6]) | x[2] + x[6] */
addps %xmm5, %xmm0 /* yt */
subps %xmm5, %xmm7 /* yb */
movhps 24(%eax), %xmm1 /* x[3] | x[1] */
movl $hsqrt2, %ebx
movlps 40(%eax), %xmm2 /* x[5] */
movhps 56(%eax), %xmm2 /* /x[7] | x[5] */
movaps %xmm1, %xmm3 /* x[3] | x[1] */
addps %xmm2, %xmm1 /* x[3] + x[7] | x[1] + x[5] */
subps %xmm2, %xmm3 /* x[3] - x[7] | x[1] - x[5] */
movaps (%ebx), %xmm4 /* -1/sqrt2 | -1/sqrt2 | 1/sqrt2 | 1/sqrt2 */
movaps %xmm3, %xmm6 /* x[3] - x[7] | x[1] - x[5] */
mulps %xmm4, %xmm3
shufps $0xc8, %xmm4, %xmm4 /* -1/sqrt2 | 1/sqrt2 | -1/sqrt2 | 1/sqrt2 */
shufps $0xb1, %xmm6, %xmm6
mulps %xmm4, %xmm6
addps %xmm3, %xmm6 /* (-1-i)/sqrt2 * (x[3]-x[7]) | (1-i)/sqrt2 * (x[1] - x[5] */
movhlps %xmm1, %xmm5 /* x[3] + x[7] */
movlhps %xmm6, %xmm1 /* (1+i)/sqrt2 * (x[1]-x[5]) | x[1]+x[5] */
shufps $0xe4, %xmm6, %xmm5 /* (-1-i)/sqrt2 * (x[3]-x[7]) | x[3]+x[7] */
movaps %xmm1, %xmm3 /* (1-i)/sqrt2 * (x[1]-x[5]) | x[1]+x[5] */
movl $C_1, %ebx
addps %xmm5, %xmm1 /* u */
subps %xmm5, %xmm3 /* v */
movaps %xmm0, %xmm2 /* yb */
movaps %xmm7, %xmm4 /* yt */
movaps (%ebx), %xmm5
mulps %xmm5, %xmm3
addps %xmm1, %xmm0 /* yt + u */
subps %xmm1, %xmm2 /* yt - u */
shufps $0xb1, %xmm3, %xmm3 /* -i * v */
movaps %xmm0, (%eax)
movaps %xmm2, 32(%eax)
addps %xmm3, %xmm4 /* yb - i*v */
subps %xmm3, %xmm7 /* yb + i*v */
movaps %xmm4, 16(%eax)
movaps %xmm7, 48(%eax)
popl %ebx
leave
ret
.align 4
.global fft_asmb_kni
.type fft_asmb, @function
fft_asmb_kni:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
movl 8(%ebp), %ecx /* k */
movl 12(%ebp), %eax /* x */
movl %ecx, -4(%ebp) /* k */
movl 16(%ebp), %ebx /* wT */
movl 20(%ebp), %edx /* d */
movl 24(%ebp), %esi /* d3 */
shll $4, %ecx /* 16k */
addl $8, %edx
leal (%eax, %ecx, 2), %edi
addl $8, %esi
/* TRANSZERO and TRANS */
movaps (%eax), %xmm0 /* x[1] | x[0] */
movaps (%ebx), %xmm1 /* wT[1] | wT[0] */
movaps (%ebx, %ecx), %xmm2 /* wB[1] | wB[0] */
movlps (%edx), %xmm3 /* d */
movlps (%esi), %xmm4 /* d3 */
movhlps %xmm1, %xmm5 /* wT[1] */
movhlps %xmm2, %xmm6 /* wB[1] */
shufps $0x50, %xmm3, %xmm3 /* d[1].im | d[1].im | d[1].re | d[1].re */
shufps $0x50, %xmm4, %xmm4 /* d3[1].im | d3[1].im | d3[i].re | d3[i].re */
movlhps %xmm5, %xmm5 /* wT[1] | wT[1] */
movlhps %xmm6, %xmm6 /* wB[1] | wB[1] */
mulps %xmm3, %xmm5
mulps %xmm4, %xmm6
movhlps %xmm5, %xmm7 /* wT[1].im * d[1].im | wT[1].re * d[1].im */
movlhps %xmm6, %xmm5 /* wB[1].im * d3[1].re | wB[1].re * d3[1].re | wT[1].im * d[1].re | wT[1].re * d[1].re */
shufps $0xb1, %xmm6, %xmm7 /* wB[1].re * d3[1].im | wB[i].im * d3[1].im | wT[1].re * d[1].im | wT[1].im * d[1].im */
movl $C_1, %edi
movaps (%edi), %xmm4
mulps %xmm4, %xmm7
addps %xmm7, %xmm5 /* wB[1] * d3[1] | wT[1] * d[1] */
movlhps %xmm5, %xmm1 /* d[1] * wT[1] | wT[0] */
shufps $0xe4, %xmm5, %xmm2 /* d3[1] * wB[1] | wB[0] */
movaps %xmm1, %xmm3 /* d[1] * wT[1] | wT[0] */
leal (%eax, %ecx, 2), %edi
addps %xmm2, %xmm1 /* u */
subps %xmm2, %xmm3 /* v */
mulps %xmm4, %xmm3
movaps (%eax, %ecx), %xmm5 /* xk[1] | xk[0] */
shufps $0xb1, %xmm3, %xmm3 /* -i * v */
movaps %xmm0, %xmm2 /* x[1] | x[0] */
movaps %xmm5, %xmm6 /* xk[1] | xk[0] */
addps %xmm1, %xmm0
subps %xmm1, %xmm2
addps %xmm3, %xmm5
subps %xmm3, %xmm6
movaps %xmm0, (%eax)
movaps %xmm2, (%edi)
movaps %xmm5, (%eax, %ecx)
movaps %xmm6, (%edi, %ecx)
addl $16, %eax
addl $16, %ebx
addl $8, %edx
addl $8, %esi
decl -4(%ebp)
.loop:
movaps (%ebx), %xmm0 /* wT[1] | wT[0] */
movaps (%edx), %xmm1 /* d[1] | d[0] */
movaps (%ebx, %ecx), %xmm4 /* wB[1] | wB[0] */
movaps (%esi), %xmm5 /* d3[1] | d3[0] */
movhlps %xmm0, %xmm2 /* wT[1] */
movhlps %xmm1, %xmm3 /* d[1] */
movhlps %xmm4, %xmm6 /* wB[1] */
movhlps %xmm5, %xmm7 /* d3[1] */
shufps $0x50, %xmm1, %xmm1 /* d[0].im | d[0].im | d[0].re | d[0].re */
shufps $0x50, %xmm3, %xmm3 /* d[1].im | d[1].im | d[1].re | d[1].re */
movlhps %xmm0, %xmm0 /* wT[0] | wT[0] */
shufps $0x50, %xmm5, %xmm5 /* d3[0].im | d3[0].im | d3[0].re | d3[0].re */
movlhps %xmm2, %xmm2 /* wT[1] | wT[1] */
shufps $0x50, %xmm7, %xmm7 /* d3[1].im | d3[1].im | d3[1].re | d3[1].re */
mulps %xmm1, %xmm0 /* d[0].im * wT[0].im | d[0].im * wT[0].re | d[0].re * wT[0].im | d[0].re * wT[0].re */
mulps %xmm3, %xmm2 /* d[1].im * wT[1].im | d[1].im * wT[1].re | d[1].re * wT[1].im | d[1].re * wT[1].re */
movlhps %xmm4, %xmm4 /* wB[0] | wB[0] */
movlhps %xmm6, %xmm6 /* wB[1] | wB[1] */
movhlps %xmm0, %xmm1 /* d[0].im * wT[0].im | d[0].im * wT[0].re */
movlhps %xmm2, %xmm0 /* d[1].re * wT[1].im | d[1].re * wT[1].re | d[0].re * wT[0].im | d[0].re * wT[0].re */
mulps %xmm5, %xmm4 /* wB[0].im * d3[0].im | wB[0].re * d3[0].im | wB[0].im * d3[0].re | wB[0].re * d3[0].re */
mulps %xmm7, %xmm6 /* wB[1].im * d3[1].im | wB[1].re * d3[1].im | wB[1].im * d3[1].re | wB[1].re * d3[1].re */
shufps $0xb1, %xmm2, %xmm1 /* d[1].im * wT[1].re | d[1].im * wT[1].im | d[0].im * wT[0].re | d[0].im * wT[0].im */
movl $C_1, %edi
movaps (%edi), %xmm3 /* 1.0 | -1.0 | 1.0 | -1.0 */
movhlps %xmm4, %xmm5 /* wB[0].im * d3[0].im | wB[0].re * d3[0].im */
mulps %xmm3, %xmm1 /* d[1].im * wT[1].re | -d[1].im * wT[1].im | d[0].im * wT[0].re | -d[0].im * wT[0].im */
movlhps %xmm6, %xmm4 /* wB[1].im * d3[1].re | wB[1].re * d3[1].re | wB[0].im * d3[0].re | wB[0].im * d3[0].re */
addps %xmm1, %xmm0 /* wT[1] * d[1] | wT[0] * d[0] */
shufps $0xb1, %xmm6, %xmm5 /* wB[1].re * d3[1].im | wB[1].im * d3[1].im | wB[0].re * d3[0].im | wB[0].im * d3[0].im */
mulps %xmm3, %xmm5 /* wB[1].re * d3[1].im | -wB[1].im * d3[1].im | wB[0].re * d3[0].im | -wB[0].im * d3[0].im */
addps %xmm5, %xmm4 /* wB[1] * d3[1] | wB[0] * d3[0] */
movaps %xmm0, %xmm1 /* wT[1] * d[1] | wT[0] * d[0] */
addps %xmm4, %xmm0 /* u */
subps %xmm4, %xmm1 /* v */
movaps (%eax), %xmm6 /* x[1] | x[0] */
leal (%eax, %ecx, 2), %edi
mulps %xmm3, %xmm1
addl $16, %ebx
addl $16, %esi
shufps $0xb1, %xmm1, %xmm1 /* -i * v */
movaps (%eax, %ecx), %xmm7 /* xk[1] | xk[0] */
movaps %xmm6, %xmm2
movaps %xmm7, %xmm4
addps %xmm0, %xmm6
subps %xmm0, %xmm2
movaps %xmm6, (%eax)
movaps %xmm2, (%edi)
addps %xmm1, %xmm7
subps %xmm1, %xmm4
addl $16, %edx
movaps %xmm7, (%eax, %ecx)
movaps %xmm4, (%edi, %ecx)
addl $16, %eax
decl -4(%ebp)
jnz .loop
.end:
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %eax
addl $4, %esp
leave
ret
#endif

View File

@ -1,30 +0,0 @@
/*****
*
* This file is part of the OMS program.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*****/
#ifndef __SRFF_KNI__
#define __SRFF_KNI__
#include "cmplx.h"
void fft_4_kni (complex_t *a);
void fft_8_kni (complex_t *a);
void fft_asmb_kni (int, complex_t*, complex_t *, complex_t *, complex_t*);
#endif

View File

@ -1,93 +0,0 @@
/*
* srfft_kni.c
*
* Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
*
* 64 and 128 point split radix fft for ac3dec
*
* The algorithm is desribed in the book:
* "Computational Frameworks of the Fast Fourier Transform".
*
* The ideas and the the organization of code borrowed from djbfft written by
* D. J. Bernstein <djb@cr.py.to>. djbff can be found at
* http://cr.yp.to/djbfft.html.
*
* srfft.c 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.
*
* srfft.c 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 __i386__
#include <stdio.h>
#include "srfft_kni.h"
#include "srfftp.h"
void fft_64p_kni(complex_t *a)
{
fft_8_kni(&a[0]); fft_4_kni(&a[8]); fft_4_kni(&a[12]);
fft_asmb_kni(2, &a[0], &a[8], &delta16[0], &delta16_3[0]);
fft_8_kni(&a[16]), fft_8_kni(&a[24]);
fft_asmb_kni(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
fft_8_kni(&a[32]); fft_4_kni(&a[40]); fft_4_kni(&a[44]);
fft_asmb_kni(2, &a[32], &a[40], &delta16[0], &delta16_3[0]);
fft_8_kni(&a[48]); fft_4_kni(&a[56]); fft_4_kni(&a[60]);
fft_asmb_kni(2, &a[48], &a[56], &delta16[0], &delta16_3[0]);
fft_asmb_kni(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
}
void fft_128p_kni(complex_t *a)
{
fft_8_kni(&a[0]); fft_4_kni(&a[8]); fft_4_kni(&a[12]);
fft_asmb_kni(2, &a[0], &a[8], &delta16[0], &delta16_3[0]);
fft_8_kni(&a[16]), fft_8_kni(&a[24]);
fft_asmb_kni(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
fft_8_kni(&a[32]); fft_4_kni(&a[40]); fft_4_kni(&a[44]);
fft_asmb_kni(2, &a[32], &a[40], &delta16[0], &delta16_3[0]);
fft_8_kni(&a[48]); fft_4_kni(&a[56]); fft_4_kni(&a[60]);
fft_asmb_kni(2, &a[48], &a[56], &delta16[0], &delta16_3[0]);
fft_asmb_kni(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
fft_8_kni(&a[64]); fft_4_kni(&a[72]); fft_4_kni(&a[76]);
/* fft_16(&a[64]); */
fft_asmb_kni(2, &a[64], &a[72], &delta16[0], &delta16_3[0]);
fft_8_kni(&a[80]); fft_8_kni(&a[88]);
/* fft_32(&a[64]); */
fft_asmb_kni(4, &a[64], &a[80],&delta32[0], &delta32_3[0]);
fft_8_kni(&a[96]); fft_4_kni(&a[104]), fft_4_kni(&a[108]);
/* fft_16(&a[96]); */
fft_asmb_kni(2, &a[96], &a[104], &delta16[0], &delta16_3[0]);
fft_8_kni(&a[112]), fft_8_kni(&a[120]);
/* fft_32(&a[96]); */
fft_asmb_kni(4, &a[96], &a[112], &delta32[0], &delta32_3[0]);
/* fft_128(&a[0]); */
fft_asmb_kni(16, &a[0], &a[64], &delta128[0], &delta128_3[0]);
}
#endif

View File

@ -1,305 +0,0 @@
/*
* srfftp.h
*
* Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
*
* 64 and 128 point split radix fft for ac3dec
*
* The algorithm is desribed in the book:
* "Computational Frameworks of the Fast Fourier Transform".
*
* The ideas and the the organization of code borrowed from djbfft written by
* D. J. Bernstein <djb@cr.py.to>. djbff can be found at
* http://cr.yp.to/djbfft.html.
*
* srfftp.h 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.
*
* srfftp.h 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 SRFFTP_H__
#define SRFFTP_H__
#include "cmplx.h"
static complex_t delta16[4] =
{ {1.00000000000000, 0.00000000000000},
{0.92387953251129, -0.38268343236509},
{0.70710678118655, -0.70710678118655},
{0.38268343236509, -0.92387953251129}};
static complex_t delta16_3[4] =
{ {1.00000000000000, 0.00000000000000},
{0.38268343236509, -0.92387953251129},
{-0.70710678118655, -0.70710678118655},
{-0.92387953251129, 0.38268343236509}};
static complex_t delta32[8] =
{ {1.00000000000000, 0.00000000000000},
{0.98078528040323, -0.19509032201613},
{0.92387953251129, -0.38268343236509},
{0.83146961230255, -0.55557023301960},
{0.70710678118655, -0.70710678118655},
{0.55557023301960, -0.83146961230255},
{0.38268343236509, -0.92387953251129},
{0.19509032201613, -0.98078528040323}};
static complex_t delta32_3[8] =
{ {1.00000000000000, 0.00000000000000},
{0.83146961230255, -0.55557023301960},
{0.38268343236509, -0.92387953251129},
{-0.19509032201613, -0.98078528040323},
{-0.70710678118655, -0.70710678118655},
{-0.98078528040323, -0.19509032201613},
{-0.92387953251129, 0.38268343236509},
{-0.55557023301960, 0.83146961230255}};
static complex_t delta64[16] =
{ {1.00000000000000, 0.00000000000000},
{0.99518472667220, -0.09801714032956},
{0.98078528040323, -0.19509032201613},
{0.95694033573221, -0.29028467725446},
{0.92387953251129, -0.38268343236509},
{0.88192126434836, -0.47139673682600},
{0.83146961230255, -0.55557023301960},
{0.77301045336274, -0.63439328416365},
{0.70710678118655, -0.70710678118655},
{0.63439328416365, -0.77301045336274},
{0.55557023301960, -0.83146961230255},
{0.47139673682600, -0.88192126434835},
{0.38268343236509, -0.92387953251129},
{0.29028467725446, -0.95694033573221},
{0.19509032201613, -0.98078528040323},
{0.09801714032956, -0.99518472667220}};
static complex_t delta64_3[16] =
{ {1.00000000000000, 0.00000000000000},
{0.95694033573221, -0.29028467725446},
{0.83146961230255, -0.55557023301960},
{0.63439328416365, -0.77301045336274},
{0.38268343236509, -0.92387953251129},
{0.09801714032956, -0.99518472667220},
{-0.19509032201613, -0.98078528040323},
{-0.47139673682600, -0.88192126434836},
{-0.70710678118655, -0.70710678118655},
{-0.88192126434835, -0.47139673682600},
{-0.98078528040323, -0.19509032201613},
{-0.99518472667220, 0.09801714032956},
{-0.92387953251129, 0.38268343236509},
{-0.77301045336274, 0.63439328416365},
{-0.55557023301960, 0.83146961230255},
{-0.29028467725446, 0.95694033573221}};
static complex_t delta128[32] =
{ {1.00000000000000, 0.00000000000000},
{0.99879545620517, -0.04906767432742},
{0.99518472667220, -0.09801714032956},
{0.98917650996478, -0.14673047445536},
{0.98078528040323, -0.19509032201613},
{0.97003125319454, -0.24298017990326},
{0.95694033573221, -0.29028467725446},
{0.94154406518302, -0.33688985339222},
{0.92387953251129, -0.38268343236509},
{0.90398929312344, -0.42755509343028},
{0.88192126434836, -0.47139673682600},
{0.85772861000027, -0.51410274419322},
{0.83146961230255, -0.55557023301960},
{0.80320753148064, -0.59569930449243},
{0.77301045336274, -0.63439328416365},
{0.74095112535496, -0.67155895484702},
{0.70710678118655, -0.70710678118655},
{0.67155895484702, -0.74095112535496},
{0.63439328416365, -0.77301045336274},
{0.59569930449243, -0.80320753148064},
{0.55557023301960, -0.83146961230255},
{0.51410274419322, -0.85772861000027},
{0.47139673682600, -0.88192126434835},
{0.42755509343028, -0.90398929312344},
{0.38268343236509, -0.92387953251129},
{0.33688985339222, -0.94154406518302},
{0.29028467725446, -0.95694033573221},
{0.24298017990326, -0.97003125319454},
{0.19509032201613, -0.98078528040323},
{0.14673047445536, -0.98917650996478},
{0.09801714032956, -0.99518472667220},
{0.04906767432742, -0.99879545620517}};
static complex_t delta128_3[32] =
{ {1.00000000000000, 0.00000000000000},
{0.98917650996478, -0.14673047445536},
{0.95694033573221, -0.29028467725446},
{0.90398929312344, -0.42755509343028},
{0.83146961230255, -0.55557023301960},
{0.74095112535496, -0.67155895484702},
{0.63439328416365, -0.77301045336274},
{0.51410274419322, -0.85772861000027},
{0.38268343236509, -0.92387953251129},
{0.24298017990326, -0.97003125319454},
{0.09801714032956, -0.99518472667220},
{-0.04906767432742, -0.99879545620517},
{-0.19509032201613, -0.98078528040323},
{-0.33688985339222, -0.94154406518302},
{-0.47139673682600, -0.88192126434836},
{-0.59569930449243, -0.80320753148065},
{-0.70710678118655, -0.70710678118655},
{-0.80320753148065, -0.59569930449243},
{-0.88192126434835, -0.47139673682600},
{-0.94154406518302, -0.33688985339222},
{-0.98078528040323, -0.19509032201613},
{-0.99879545620517, -0.04906767432742},
{-0.99518472667220, 0.09801714032956},
{-0.97003125319454, 0.24298017990326},
{-0.92387953251129, 0.38268343236509},
{-0.85772861000027, 0.51410274419322},
{-0.77301045336274, 0.63439328416365},
{-0.67155895484702, 0.74095112535496},
{-0.55557023301960, 0.83146961230255},
{-0.42755509343028, 0.90398929312344},
{-0.29028467725446, 0.95694033573221},
{-0.14673047445536, 0.98917650996478}};
#define HSQRT2 0.707106781188;
#define TRANSZERO(A0,A4,A8,A12) { \
u_r = wTB[0].re; \
v_i = u_r - wTB[k*2].re; \
u_r += wTB[k*2].re; \
u_i = wTB[0].im; \
v_r = wTB[k*2].im - u_i; \
u_i += wTB[k*2].im; \
a_r = A0.re; \
a_i = A0.im; \
a1_r = a_r; \
a1_r += u_r; \
A0.re = a1_r; \
a_r -= u_r; \
A8.re = a_r; \
a1_i = a_i; \
a1_i += u_i; \
A0.im = a1_i; \
a_i -= u_i; \
A8.im = a_i; \
a1_r = A4.re; \
a1_i = A4.im; \
a_r = a1_r; \
a_r -= v_r; \
A4.re = a_r; \
a1_r += v_r; \
A12.re = a1_r; \
a_i = a1_i; \
a_i -= v_i; \
A4.im = a_i; \
a1_i += v_i; \
A12.im = a1_i; \
}
#define TRANSHALF_16(A2,A6,A10,A14) {\
u_r = wTB[2].re; \
a_r = u_r; \
u_i = wTB[2].im; \
u_r += u_i; \
u_i -= a_r; \
a_r = wTB[6].re; \
a1_r = a_r; \
a_i = wTB[6].im; \
a_r = a_i - a_r; \
a_i += a1_r; \
v_i = u_r - a_r; \
u_r += a_r; \
v_r = u_i + a_i; \
u_i -= a_i; \
v_i *= HSQRT2; \
v_r *= HSQRT2; \
u_r *= HSQRT2; \
u_i *= HSQRT2; \
a_r = A2.re; \
a_i = A2.im; \
a1_r = a_r; \
a1_r += u_r; \
A2.re = a1_r; \
a_r -= u_r; \
A10.re = a_r; \
a1_i = a_i; \
a1_i += u_i; \
A2.im = a1_i; \
a_i -= u_i; \
A10.im = a_i; \
a1_r = A6.re; \
a1_i = A6.im; \
a_r = a1_r; \
a1_r += v_r; \
A6.re = a1_r; \
a_r -= v_r; \
A14.re = a_r; \
a_i = a1_i; \
a1_i -= v_i; \
A6.im = a1_i; \
a_i += v_i; \
A14.im = a_i; \
}
#define TRANS(A1,A5,A9,A13,WT,WB,D,D3) { \
u_r = WT.re; \
a_r = u_r; \
a_r *= D.im; \
u_r *= D.re; \
a_i = WT.im; \
a1_i = a_i; \
a1_i *= D.re; \
a_i *= D.im; \
u_r -= a_i; \
u_i = a_r; \
u_i += a1_i; \
a_r = WB.re; \
a1_r = a_r; \
a1_r *= D3.re; \
a_r *= D3.im; \
a_i = WB.im; \
a1_i = a_i; \
a_i *= D3.re; \
a1_i *= D3.im; \
a1_r -= a1_i; \
a_r += a_i; \
v_i = u_r - a1_r; \
u_r += a1_r; \
v_r = a_r - u_i; \
u_i += a_r; \
a_r = A1.re; \
a_i = A1.im; \
a1_r = a_r; \
a1_r += u_r; \
A1.re = a1_r; \
a_r -= u_r; \
A9.re = a_r; \
a1_i = a_i; \
a1_i += u_i; \
A1.im = a1_i; \
a_i -= u_i; \
A9.im = a_i; \
a1_r = A5.re; \
a1_i = A5.im; \
a_r = a1_r; \
a1_r -= v_r; \
A5.re = a1_r; \
a_r += v_r; \
A13.re = a_r; \
a_i = a1_i; \
a1_i -= v_i; \
A5.im = a1_i; \
a_i += v_i; \
A13.im = a_i; \
}
#endif

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 "stats.h"
#include "debug.h"
#if !defined (__GNUC__) || defined (DEBUG)
static const char *service_ids[8] =
{
"CM","ME","VI","HI",
"D", "C","E", "VO"
};
#endif
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) {
uint32_t 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

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 1.98 2002/02/24 11:53:14 kls Exp $
* $Id: config.h 1.99 2002/02/24 13:39:47 kls Exp $
*/
#ifndef __CONFIG_H
@ -19,7 +19,7 @@
#include "eit.h"
#include "tools.h"
#define VDRVERSION "0.99"
#define VDRVERSION "1.0.0pre1"
#define MAXPRIORITY 99
#define MAXLIFETIME 99

903
dvbapi.c
View File

@ -4,14 +4,9 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>
*
* $Id: dvbapi.c 1.151 2002/02/24 11:53:17 kls Exp $
* $Id: dvbapi.c 1.152 2002/02/24 12:53:51 kls Exp $
*/
//#define DVDDEBUG 1
#include "dvbapi.h"
#include <dirent.h>
#include <errno.h>
@ -26,13 +21,6 @@ extern "C" {
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#ifdef DVDSUPPORT
extern "C" {
#include "ac3dec/ac3.h"
}
#endif //DVDSUPPORT
#include "config.h"
#include "recording.h"
#include "remux.h"
@ -1320,865 +1308,6 @@ bool cReplayBuffer::NextFile(uchar FileNumber, int FileOffset)
return replayFile >= 0;
}
#ifdef DVDSUPPORT
#define SYSTEM_HEADER 0xBB
#define PROG_STREAM_MAP 0xBC
#ifndef PRIVATE_STREAM1
#define PRIVATE_STREAM1 0xBD
#endif
#define PADDING_STREAM 0xBE
#ifndef PRIVATE_STREAM2
#define PRIVATE_STREAM2 0xBF
#endif
#define AUDIO_STREAM_S 0xC0
#define AUDIO_STREAM_E 0xDF
#define VIDEO_STREAM_S 0xE0
#define VIDEO_STREAM_E 0xEF
#define ECM_STREAM 0xF0
#define EMM_STREAM 0xF1
#define DSM_CC_STREAM 0xF2
#define ISO13522_STREAM 0xF3
#define PROG_STREAM_DIR 0xFF
#define cOPENDVD 0
#define cOPENTITLE 1
#define cOPENCHAPTER 2
#define cOUTCELL 3
#define cREADFRAME 4
#define cOUTPACK 5
#define cOUTFRAMES 6
// --- cAC3toPCM -------------------------------------------------------------
class cAC3toPCM {
private:
enum { AC3_STOP, AC3_START, AC3_PLAY } ac3stat;
uchar *ac3data;
int ac3inp;
int ac3outp;
public:
cAC3toPCM(void);
~cAC3toPCM();
void Clear(void);
void Put(unsigned char *sector, int length);
cFrame *Get(int size, uchar PTSflags = 0, uchar *PTSdata = 0);
};
cAC3toPCM::cAC3toPCM(void)
{
ac3dec_init();
ac3data = new uchar[AC3_BUFFER_SIZE];
Clear();
}
cAC3toPCM::~cAC3toPCM()
{
delete ac3data;
}
void cAC3toPCM::Clear(void)
{
ac3stat = AC3_START;
ac3outp = ac3inp = 0;
}
void cAC3toPCM::Put(unsigned char *sector, int length)
{
ac3dec_decode_data(sector, sector + length, ac3stat == AC3_START, &ac3inp, &ac3outp, (char *)ac3data);
ac3stat = AC3_PLAY;
}
// data=PCM samples, 16 bit, LSB first, 48kHz, stereo
cFrame *cAC3toPCM::Get(int size, uchar PTSflags, uchar *PTSdata)
{
if (ac3inp == ac3outp)
return NULL;
#define MAXSIZE 2022
uchar buffer[2048];
uchar *data;
if (size > 0) {
int p_size = (size > MAXSIZE) ? MAXSIZE : size;
int length = 10; // default header bytes
int header = 0;
switch (PTSflags) {
case 2: header = 5; // additional header bytes
break;
case 3: header = 10;
break;
default: header = 0;
}
length += header;
buffer[0] = 0x00;
buffer[1] = 0x00;
buffer[2] = 0x01;
buffer[3] = PRIVATE_STREAM1;
buffer[6] = 0x80;
buffer[7] = PTSflags << 6;
buffer[8] = header;
if (header)
memcpy(&buffer[9], (void *)PTSdata, header);
// add data
data = buffer + 9 + header + 7;
int cnt = 0;
while (p_size) {
if (ac3outp != ac3inp) { // data in the buffer
data[cnt ^ 1] = ac3data[ac3outp]; // swab because ac3dec delivers wrong byteorder (the "xor" (^) is a swab!)
p_size--;
cnt++;
length++;
ac3outp = (ac3outp + 1) % AC3_BUFFER_SIZE;
}
else
break;
}
data = buffer + 9 + header;
data[0] = aLPCM; // substream ID
data[1] = 0x00; // other stuff (see DVB specs), ignored by driver
data[2] = 0x00;
data[3] = 0x00;
data[4] = 0x00;
data[5] = 0x00;
data[6] = 0x00;
buffer[4] = (length >> 8) & 0xff;
buffer[5] = length & 0xff;
length += 6;
return new cFrame(buffer, length);
}
return NULL;
}
// --- cDVDplayBuffer --------------------------------------------------------
class cDVDplayBuffer : public cPlayBuffer {
private:
cAC3toPCM AC3toPCM;
uchar audioTrack;
cDVD *dvd;//XXX necessary???
int titleid;
int chapid;
int angle;
dvd_file_t *title;
ifo_handle_t *vmg_file;
ifo_handle_t *vts_file;
int doplay;
int cyclestate;
int prevcycle;
int skipCnt;
tt_srpt_t *tt_srpt;
vts_ptt_srpt_t *vts_ptt_srpt;
pgc_t *cur_pgc;
dsi_t dsi_pack;
unsigned int next_vobu;
unsigned int prev_vobu;
unsigned int next_ilvu_start;
unsigned int cur_output_size;
unsigned int min_output_size;
unsigned int pktcnt;
int pgc_id;
int start_cell;
int next_cell;
int prev_cell;
int cur_cell;
unsigned int cur_pack;
int ttn;
int pgn;
uchar *data;
int logAudioTrack;
int maxAudioTrack;
int is_nav_pack(unsigned char *buffer);
void Close(void);
virtual void Empty(bool Block = false);
int decode_packet(unsigned char *sector, bool trickmode);
int ScanVideoPacket(const uchar *Data, int Count, uchar *PictureType);
bool PacketStart(uchar **Data, int len);
int GetPacketType(const uchar *Data);
int GetStuffingLen(const uchar *Data);
int GetPacketLength(const uchar *Data);
int GetPESHeaderLength(const uchar *Data);
void handleAC3(unsigned char *sector, int length, uchar PTSflags, uchar *PTSdata);
unsigned int getAudioStream(unsigned int StreamId);
void setChapid(void);
void NextState(int State) { prevcycle = cyclestate; cyclestate = State; }
protected:
virtual void Input(void);
public:
cDVDplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, cDVD *DvD, int title);
virtual ~cDVDplayBuffer();
virtual int SkipFrames(int Frames);
virtual void SkipSeconds(int Seconds);
virtual void Goto(int Position, bool Still = false);
virtual void GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
virtual void ToggleAudioTrack(void);
};
cDVDplayBuffer::cDVDplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, cDVD *DvD, int title)
:cPlayBuffer(DvbApi, VideoDev, AudioDev)
{
dvd = DvD;
titleid = title;
chapid = 0;
angle = 0;
cyclestate = cOPENDVD;
prevcycle = 0;
skipCnt = 0;
logAudioTrack = 0;
canToggleAudioTrack = true;//XXX determine from cDVD!
data = new uchar[1024 * DVD_VIDEO_LB_LEN];
canDoTrickMode = true;
skipAC3bytes = true;
dvbApi->SetModeReplay();
Start();
}
cDVDplayBuffer::~cDVDplayBuffer()
{
Stop();
Close();
dvbApi->SetModeNormal(false);
delete data;
}
unsigned int cDVDplayBuffer::getAudioStream(unsigned int StreamId)
{
if (cyclestate < cOPENCHAPTER || StreamId > 7)
return 0;
if (!(cur_pgc->audio_control[StreamId] & 0x8000))
return 0;
int track = (cur_pgc->audio_control[StreamId] >> 8) & 0x07;
return dvd->getAudioTrack(track) | track;
}
void cDVDplayBuffer::ToggleAudioTrack(void)
{
unsigned int newTrack;
if (CanToggleAudioTrack() && maxAudioTrack != 0) {
logAudioTrack = (logAudioTrack + 1) % maxAudioTrack;
if ((newTrack = getAudioStream(logAudioTrack)) != 0)
audioTrack = newTrack;
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVB: Audio Stream ID changed to: %x", audioTrack);
#endif
AC3toPCM.Clear();
}
}
/**
* Returns true if the pack is a NAV pack. This check is clearly insufficient,
* and sometimes we incorrectly think that valid other packs are NAV packs. I
* need to make this stronger.
*/
inline int cDVDplayBuffer::is_nav_pack(unsigned char *buffer)
{
return buffer[41] == 0xbf && buffer[1027] == 0xbf;
}
void cDVDplayBuffer::Input(void)
{
dsyslog(LOG_INFO, "input thread started (pid=%d)", getpid());
doplay = true;
while (Busy() && doplay) {
if (blockInput) {
if (blockInput > 1)
blockInput = 1;
continue;
}
//BEGIN: ripped from play_title
/**
* Playback by cell in this pgc, starting at the cell for our chapter.
*/
//dsyslog(LOG_INFO, "DVD: cyclestate: %d", cyclestate);
switch (cyclestate) {
case cOPENDVD: // open the DVD and get all the basic information
{
if (!dvd->isValid()) {
doplay = false;
break;
}
/**
* Load the video manager to find out the information about the titles on
* this disc.
*/
vmg_file = dvd->openVMG();
if (!vmg_file) {
esyslog(LOG_ERR, "ERROR: can't open VMG info");
doplay = false;
break;
}
tt_srpt = vmg_file->tt_srpt;
NextState(cOPENTITLE);
break;
}
case cOPENTITLE: // open the selected title
{
/**
* Make sure our title number is valid.
*/
isyslog(LOG_INFO, "DVD: there are %d titles on this DVD", tt_srpt->nr_of_srpts);
if (titleid < 0 || titleid >= tt_srpt->nr_of_srpts) {
esyslog(LOG_ERR, "ERROR: invalid title %d", titleid + 1);
doplay = false;
break;
}
/**
* Load the VTS information for the title set our title is in.
*/
vts_file = dvd->openVTS(tt_srpt->title[titleid].title_set_nr);
if (!vts_file) {
esyslog(LOG_ERR, "ERROR: can't open the title %d info file", tt_srpt->title[titleid].title_set_nr);
doplay = false;
break;
}
NextState(cOPENCHAPTER);
break;
}
case cOPENCHAPTER:
{
/**
* Make sure the chapter number is valid for this title.
*/
isyslog(LOG_INFO, "DVD: there are %d chapters in this title", tt_srpt->title[titleid].nr_of_ptts);
if (chapid < 0 || chapid >= tt_srpt->title[titleid].nr_of_ptts) {
esyslog(LOG_ERR, "ERROR: invalid chapter %d", chapid + 1);
doplay = false;
break;
}
/**
* Determine which program chain we want to watch. This is based on the
* chapter number.
*/
ttn = tt_srpt->title[titleid].vts_ttn;
vts_ptt_srpt = vts_file->vts_ptt_srpt;
pgc_id = vts_ptt_srpt->title[ttn - 1].ptt[chapid].pgcn;
pgn = vts_ptt_srpt->title[ttn - 1].ptt[chapid].pgn;
cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_id - 1].pgc;
start_cell = cur_pgc->program_map[pgn - 1] - 1;
/**
* setup Audio information
**/
for (maxAudioTrack = 0; maxAudioTrack < 8; maxAudioTrack++) {
if (!(cur_pgc->audio_control[maxAudioTrack] & 0x8000))
break;
}
canToggleAudioTrack = (maxAudioTrack > 0);
// init the AudioInformation
audioTrack = getAudioStream(logAudioTrack);
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: max: %d, track: %x", maxAudioTrack, audioTrack);
#endif
/**
* We've got enough info, time to open the title set data.
*/
title = dvd->openTitle(tt_srpt->title[titleid].title_set_nr, DVD_READ_TITLE_VOBS);
if (!title) {
esyslog(LOG_ERR, "ERROR: can't open title VOBS (VTS_%02d_1.VOB).", tt_srpt->title[titleid].title_set_nr);
doplay = false;
break;
}
/**
* Playback by cell in this pgc, starting at the cell for our chapter.
*/
next_cell = start_cell;
prev_cell = start_cell;
cur_cell = start_cell;
NextState(cOUTCELL);
break;
}
case cOUTCELL:
{
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: new cell: %d", cur_cell);
dsyslog(LOG_INFO, "DVD: vob_id: %x, cell_nr: %x", cur_pgc->cell_position[cur_cell].vob_id_nr, cur_pgc->cell_position[cur_cell].cell_nr);
#endif
if (cur_cell < 0) {
cur_cell = 0;
Backward();
}
doplay = (cur_cell < cur_pgc->nr_of_cells);
if (!doplay)
break;
/* Check if we're entering an angle block. */
if (cur_pgc->cell_playback[cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK) {
cur_cell += angle;
for (int i = 0; ; ++i) {
if (cur_pgc->cell_playback[cur_cell + i].block_mode == BLOCK_MODE_LAST_CELL) {
next_cell = cur_cell + i + 1;
break;
}
}
}
else {
next_cell = cur_cell + 1;
prev_cell = cur_cell - 1;
}
// init settings for next state
if (playDir == pdForward)
cur_pack = cur_pgc->cell_playback[cur_cell].first_sector;
else
cur_pack = cur_pgc->cell_playback[cur_cell].last_vobu_start_sector;
NextState(cOUTPACK);
break;
}
case cOUTPACK:
{
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: new pack: %d", cur_pack);
#endif
/**
* We loop until we're out of this cell.
*/
if (playDir == pdForward) {
if (cur_pack >= cur_pgc->cell_playback[cur_cell].last_sector) {
cur_cell = next_cell;
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: end of pack");
#endif
NextState(cOUTCELL);
break;
}
}
else {
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: prev: %d, curr: %x, next: %x, prev: %x", prevcycle, cur_pack, next_vobu, prev_vobu);
#endif
if ((cur_pack & 0x80000000) != 0) {
cur_cell = prev_cell;
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: start of pack");
#endif
NextState(cOUTCELL);
break;
}
}
/**
* Read NAV packet.
*/
int len = DVDReadBlocks(title, cur_pack, 1, data);
if (len == 0) {
esyslog(LOG_ERR, "ERROR: read failed for block %d", cur_pack);
doplay = false;
break;
}
if (!is_nav_pack(data)) {
esyslog(LOG_ERR, "ERROR: no nav_pack");
return;
}
/**
* Parse the contained dsi packet.
*/
navRead_DSI(&dsi_pack, &(data[DSI_START_BYTE]));
if (cur_pack != dsi_pack.dsi_gi.nv_pck_lbn) {
esyslog(LOG_ERR, "ERROR: cur_pack != dsi_pack.dsi_gi.nv_pck_lbn");
return;
}
// navPrint_DSI(&dsi_pack);
/**
* Determine where we go next. These values are the ones we mostly
* care about.
*/
next_ilvu_start = cur_pack + dsi_pack.sml_agli.data[angle].address;
cur_output_size = dsi_pack.dsi_gi.vobu_ea;
min_output_size = dsi_pack.dsi_gi.vobu_1stref_ea;
/**
* If we're not at the end of this cell, we can determine the next
* VOBU to display using the VOBU_SRI information section of the
* DSI. Using this value correctly follows the current angle,
* avoiding the doubled scenes in The Matrix, and makes our life
* really happy.
*
* Otherwise, we set our next address past the end of this cell to
* force the code above to go to the next cell in the program.
*/
if (dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL)
next_vobu = cur_pack + (dsi_pack.vobu_sri.next_vobu & 0x7fffffff);
else
next_vobu = cur_pack + cur_output_size + 1;
if (dsi_pack.vobu_sri.prev_vobu != SRI_END_OF_CELL)
prev_vobu = cur_pack - (dsi_pack.vobu_sri.prev_vobu & 0x7fffffff);
else {
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: cur: %x, prev: %x", cur_pack, dsi_pack.vobu_sri.prev_vobu);
#endif
prev_vobu = 0x80000000;
}
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: curr: %x, next: %x, prev: %x", cur_pack, next_vobu, prev_vobu);
#endif
if (cur_output_size >= 1024) {
esyslog(LOG_ERR, "ERROR: cur_output_size >= 1024");
return;
}
cur_pack++;
NextState(cREADFRAME);
break;
}
case cREADFRAME:
{
bool trickMode = (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward));
/* FIXME:
* the entire trickMode code relies on the assumtion
* that there is only one I-FRAME per PACK
*
* I have no clue wether that is correct or not !!!
*/
if (trickMode && (skipCnt++ % 4 != 0)) {
cur_pack = (playDir == pdForward) ? next_vobu : prev_vobu;
NextState(cOUTPACK);
break;
}
if (trickMode)
cur_output_size = min_output_size;
/**
* Read in cursize packs.
*/
#ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVD: read pack: %d", cur_pack);
#endif
int len = DVDReadBlocks(title, cur_pack, cur_output_size, data);
if (len != (int)cur_output_size) {
esyslog(LOG_ERR, "ERROR: read failed for %d blocks at %d", cur_output_size, cur_pack);
doplay = false;
break;
}
pktcnt = 0;
NextState(cOUTFRAMES);
break;
}
case cOUTFRAMES:
{
bool trickMode = (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward));
/**
* Output cursize packs.
*/
if (pktcnt >= cur_output_size) {
cur_pack = next_vobu;
NextState(cOUTPACK);
break;
}
//dsyslog(LOG_INFO, "DVD: pack: %d, frame: %d", cur_pack, pktcnt);
if (decode_packet(&data[pktcnt * DVD_VIDEO_LB_LEN], trickMode) != 1) { //we've got a video packet
if (trickMode) {
//dsyslog(LOG_INFO, "DVD: did pack: %d", pktcnt);
cur_pack = (playDir == pdForward) ? next_vobu : prev_vobu;
NextState(cOUTPACK);
break;
}
}
pktcnt++;
if (pktcnt >= cur_output_size) {
cur_pack = next_vobu;
NextState(cOUTPACK);
break;
}
break;
}
default:
{
esyslog(LOG_ERR, "ERROR: cyclestate %d not known", cyclestate);
return;
}
}
// dsyslog(LOG_INF, "DVD: new cyclestate: %d, pktcnt: %d, cur: %d", cyclestate, pktcnt, cur_output_size);
}
dsyslog(LOG_INFO, "input thread ended (pid=%d)", getpid());
}
#define NO_PICTURE 0
#define SC_PICTURE 0x00
inline bool cDVDplayBuffer::PacketStart(uchar **Data, int len)
{
while (len > 6 && !((*Data)[0] == 0x00 && (*Data)[1] == 0x00 && (*Data)[2] == 0x01))
(*Data)++;
return ((*Data)[0] == 0x00 && (*Data)[1] == 0x00 && (*Data)[2] == 0x01);
}
inline int cDVDplayBuffer::GetPacketType(const uchar *Data)
{
return Data[3];
}
inline int cDVDplayBuffer::GetStuffingLen(const uchar *Data)
{
return Data[13] & 0x07;
}
inline int cDVDplayBuffer::GetPacketLength(const uchar *Data)
{
return (Data[4] << 8) + Data[5] + 6;
}
inline int cDVDplayBuffer::GetPESHeaderLength(const uchar *Data)
{
return (Data[8]);
}
int cDVDplayBuffer::ScanVideoPacket(const uchar *Data, int Count, uchar *PictureType)
{
// Scans the video packet starting at Offset and returns its length.
// If the return value is -1 the packet was not completely in the buffer.
int Length = GetPacketLength(Data);
if (Length > 0 && Length <= Count) {
int i = 8; // the minimum length of the video packet header
i += Data[i] + 1; // possible additional header bytes
for (; i < Length; i++) {
if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1) {
switch (Data[i + 3]) {
case SC_PICTURE: *PictureType = (uchar)(Data[i + 5] >> 3) & 0x07;
return Length;
}
}
}
PictureType = NO_PICTURE;
return Length;
}
return -1;
}
void cDVDplayBuffer::handleAC3(unsigned char *sector, int length, uchar PTSflags, uchar *PTSdata)
{
#define PCM_FRAME_SIZE 1536
AC3toPCM.Put(sector, length);
cFrame *frame;
if (ac3_buffersize() <= 100) {
if ((frame = AC3toPCM.Get(PCM_FRAME_SIZE, PTSflags, PTSdata)) != NULL)
putFrame(frame);
}
while ((frame = AC3toPCM.Get(PCM_FRAME_SIZE)) != NULL)
putFrame(frame);
}
int cDVDplayBuffer::decode_packet(unsigned char *sector, bool trickMode)
{
//XXX kls 2001-11-03: do we really need all these different return values?
uchar pt = 1;
//make sure we got a PS packet header
if (!PacketStart(&sector, DVD_VIDEO_LB_LEN) && GetPacketType(sector) != 0xBA) {
esyslog(LOG_ERR, "ERROR: got unexpected packet: %x %x %x %x", sector[0], sector[1], sector[2], sector[3]);
return -1;
}
int offset = 14 + GetStuffingLen(sector);
sector += offset;
int r = DVD_VIDEO_LB_LEN - offset;
int datalen = r;
sector[6] &= 0x8f;
uchar PTSflags = sector[7] >> 6;
uchar *PTSdata = sector + 9;
uchar *data = sector;
switch (GetPacketType(sector)) {
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
{
ScanVideoPacket(sector, r, &pt);
if (trickMode && pt != 1)
return pt;
putFrame(sector, r, ftVideo);
break;
}
case AUDIO_STREAM_S ... AUDIO_STREAM_E: {
// no sound in trick mode
if (trickMode)
return 1;
if (audioTrack != GetPacketType(sector))
return 5;
putFrame(sector, r, ftAudio);
break;
}
case PRIVATE_STREAM1:
{
datalen = GetPacketLength(sector);
//skip optional Header bytes
datalen -= GetPESHeaderLength(sector);
data += GetPESHeaderLength(sector);
//skip mandatory header bytes
data += 3;
//fallthrough is intended
}
case PRIVATE_STREAM2:
{
//FIXME: Stream1 + Stream2 is ok, but is Stream2 alone also?
// no sound in trick mode
if (trickMode)
return 1;
// skip PS header bytes
data += 6;
// data now points to the beginning of the payload
if (audioTrack == *data) {
switch (audioTrack & 0xF8) {
case aAC3:
if (dolbyDev)
putFrame(sector, r, ftDolby);
data += 4;
datalen -= 13; // 3 (mandatory header) + 6 (PS header) + 4 (AC3 header) = 13
handleAC3(data, datalen, PTSflags, PTSdata);
break;
case aLPCM:
// write(audio, sector+14 , sector[19]+(sector[18]<<8)+6);
putFrame(sector, GetPacketLength(sector), ftAudio);
break;
default:
break;
}
}
return pt;
}
default:
case SYSTEM_HEADER:
case PROG_STREAM_MAP:
{
esyslog(LOG_ERR, "ERROR: don't know what to do - packetType: %x", GetPacketType(sector));
// just skip them for now,l but try to debug it
dsyslog(LOG_INFO, "DVD: curr cell: %8x, Nr of cells: %8x", cur_cell, cur_pgc->nr_of_cells);
dsyslog(LOG_INFO, "DVD: curr pack: %8x, last sector: %8x", cur_pack, cur_pgc->cell_playback[cur_cell].last_sector);
dsyslog(LOG_INFO, "DVD: curr pkt: %8x, output size: %8x", pktcnt, cur_output_size);
#if 0
// looks like my DVD is/was brocken .......
for (int n = 0; n <= 255; n++) {
dsyslog(LOG_INFO, "%4x %2x %2x %2x %2x %2x %2x %2x %2x", n * 8,
osect[n * 8 + 0], osect[n * 8 + 1], osect[n * 8 + 2], osect[n * 8 + 3],
osect[n * 8 + 4], osect[n * 8 + 5], osect[n * 8 + 6], osect[n * 8 + 7]);
}
return 0;
#endif
return pt;
}
}
return pt;
}
void cDVDplayBuffer::Empty(bool Block)
{
if (!(blockInput || blockOutput)) {
cPlayBuffer::Empty(true);
AC3toPCM.Clear();
}
if (!Block)
cPlayBuffer::Empty(false);
}
void cDVDplayBuffer::Close(void)
{
dvd->Close();
}
int cDVDplayBuffer::SkipFrames(int Frames)
{
return -1;
}
/* Figure out the correct pgN from the cell and update state. */
void cDVDplayBuffer::setChapid(void)
{
int new_pgN = 0;
while (new_pgN < cur_pgc->nr_of_programs && cur_cell >= cur_pgc->program_map[new_pgN])
new_pgN++;
if (new_pgN == cur_pgc->nr_of_programs) { /* We are at the last program */
if (cur_cell > cur_pgc->nr_of_cells)
chapid = 1; /* We are past the last cell */
}
chapid = new_pgN;
}
void cDVDplayBuffer::SkipSeconds(int Seconds)
{
if (Seconds) {
setChapid();
int newchapid = Seconds > 0 ? chapid + 1 : chapid - 1;
if (newchapid >= 0 && newchapid < tt_srpt->title[titleid].nr_of_ptts) {
Empty(true);
chapid = newchapid;
NextState(cOPENCHAPTER);
AC3toPCM.Clear();
Empty(false);
Play();
}
}
}
void cDVDplayBuffer::Goto(int Index, bool Still)
{
}
void cDVDplayBuffer::GetIndex(int &Current, int &Total, bool SnapToIFrame)
{
Current = Total = -1;
}
#endif //DVDSUPPORT
// --- cTransferBuffer -------------------------------------------------------
class cTransferBuffer : public cRingBufferLinear {
@ -3412,36 +2541,6 @@ bool cDvbApi::StartReplay(const char *FileName)
return false;
}
#ifdef DVDSUPPORT
bool cDvbApi::StartDVDplay(cDVD *dvd, int TitleID)
{
if (Recording()) {
esyslog(LOG_ERR, "ERROR: StartDVDplay() called while recording - ignored!");
return false;
}
StopTransfer();
StopReplay();
if (fd_video >= 0 && fd_audio >= 0) {
// Check DeviceName:
if (!dvd) {
esyslog(LOG_ERR, "ERROR: StartDVDplay: DVD device is (null)");
return false;
}
// Create replay buffer:
replayBuffer = new cDVDplayBuffer(this, fd_video, fd_audio, dvd, TitleID);
if (replayBuffer)
return true;
else
esyslog(LOG_ERR, "ERROR: can't allocate replaying buffer");
}
return false;
}
#endif //DVDSUPPORT
void cDvbApi::StopReplay(void)
{
if (replayBuffer) {

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbapi.h 1.62 2002/02/23 13:11:07 kls Exp $
* $Id: dvbapi.h 1.63 2002/02/24 12:38:08 kls Exp $
*/
#ifndef __DVBAPI_H
@ -29,9 +29,6 @@
#include <stdio.h>
#include "dvbosd.h"
#ifdef DVDSUPPORT
#include "dvd.h"
#endif //DVDSUPPORT
#include "eit.h"
#include "thread.h"
@ -60,9 +57,6 @@ class cChannel;
class cRecordBuffer;
class cPlayBuffer;
class cReplayBuffer;
#ifdef DVDSUPPORT
class cDVDplayBuffer;
#endif //DVDSUPPORT
class cTransferBuffer;
class cCuttingBuffer;
@ -83,9 +77,6 @@ public:
class cDvbApi {
friend class cRecordBuffer;
friend class cReplayBuffer;
#ifdef DVDSUPPORT
friend class cDVDplayBuffer;
#endif //DVDSUPPORT
friend class cTransferBuffer;
private:
FrontendType frontendType;
@ -246,10 +237,6 @@ public:
// Starts replaying the given file.
// If there is already a replay session active, it will be stopped
// and the new file will be played back.
#ifdef DVDSUPPORT
bool StartDVDplay(cDVD *dvd, int TitleID);//XXX dvd parameter necessary???
// Starts replaying the given TitleID on the DVD.
#endif //DVDSUPPORT
void StopReplay(void);
// Stops the current replay session (if any).
void Pause(void);

169
dvd.c
View File

@ -1,169 +0,0 @@
/*
* dvd.c: Functions for handling DVDs
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* Initially written by Andreas Schultz <aschultz@warp10.net>
*
* $Id: dvd.c 1.4 2001/11/10 13:38:50 kls Exp $
*/
#ifdef DVDSUPPORT
//#define DVDSUPPORTDEBUG 1
//#define DEBUG_BUFFER 1
#include <fcntl.h>
#include <linux/cdrom.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "dvd.h"
#include "tools.h"
// --- cDVD ----------------------------------------------------------------------------
const char *cDVD::deviceName = "/dev/dvd";
cDVD *cDVD::dvdInstance = NULL;
cDVD *cDVD::getDVD(void)
{
if (!dvdInstance)
new cDVD;
return dvdInstance;
}
cDVD::cDVD(void)
{
dvd = NULL;
title = NULL;
vmg_file = NULL;
vts_file = NULL;
dvdInstance = this;
}
cDVD::~cDVD()
{
Close();
}
int cDVD::Command(int Cmd)
{
int result = -1;
int f;
if ((f = open(deviceName, O_RDONLY | O_NONBLOCK)) > 0) {
result = ioctl(f, Cmd, 0);
close(f);
}
return result;
}
void cDVD::SetDeviceName(const char *DeviceName)
{
deviceName = strdup(DeviceName);
}
const char *cDVD::DeviceName(void)
{
return deviceName;
}
bool cDVD::DriveExists(void)
{
return access(deviceName, F_OK) == 0;
}
bool cDVD::DiscOk(void)
{
return Command(CDROM_DRIVE_STATUS) == CDS_DISC_OK;
}
void cDVD::Eject(void)
{
if (dvdInstance)
dvdInstance->Close();
Command(CDROMEJECT);
}
void cDVD::Open(void)
{
if (!dvd)
dvd = DVDOpen(deviceName);
}
void cDVD::Close(void)
{
#ifdef DVDSUPPORTDEBUG
dsyslog(LOG_INFO, "DVD: cDVD::Close(%p): vts: %p, vmg: %p, title: %p, dvd: %p", this, vts_file, vmg_file, title, dvd);
#endif
if (vts_file)
ifoClose(vts_file);
if (vmg_file)
ifoClose(vmg_file);
if (title)
DVDCloseFile(title);
if (dvd)
DVDClose(dvd);
vts_file = NULL;
vmg_file = NULL;
title = NULL;
dvd = NULL;
}
ifo_handle_t *cDVD::openVMG(void)
{
if (!isValid())
return NULL;
if (!vmg_file)
vmg_file = ifoOpen(dvd, 0);
return vmg_file;
}
ifo_handle_t *cDVD::openVTS(int TitleSet)
{
if (!isValid())
return NULL;
if (vts_file && (titleset != TitleSet)) {
ifoClose(vts_file);
vts_file = NULL;
}
if (!vts_file) {
titleset = TitleSet;
vts_file = ifoOpen(dvd, TitleSet);
}
return vts_file;
}
dvd_file_t *cDVD::openTitle(int Title, dvd_read_domain_t domain)
{
if (!isValid())
return NULL;
if (title)
DVDCloseFile(title);
title = DVDOpenFile(dvd, Title, domain);
return title;
}
int cDVD::getAudioTrack(int stream)
{
if (getVTS()) {
switch (getVTS()->vtsi_mat->vts_audio_attr[stream].audio_format) {
case 0: // ac3
return aAC3;
case 2: // mpeg1
case 3: // mpeg2ext
return aMPEG;
case 4: // lpcm
return aLPCM;
case 6: // dts
return aDTS;
default:
esyslog(LOG_ERR, "ERROR: unknown Audio stream info");
}
}
return 0;
}
#endif //DVDSUPPORT

62
dvd.h
View File

@ -1,62 +0,0 @@
/*
* dvd.h: Functions for handling DVDs
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* Initially written by Andreas Schultz <aschultz@warp10.net>
*
* $Id: dvd.h 1.4 2001/11/10 13:38:25 kls Exp $
*/
#ifndef __DVD_H
#define __DVD_H
#ifdef DVDSUPPORT
#include <dvdread/dvd_reader.h>
#include <dvdread/ifo_types.h>
#include <dvdread/ifo_read.h>
#include <dvdread/dvd_udf.h>
#include <dvdread/nav_read.h>
#include <dvdread/nav_print.h>
#define aAC3 0x80
#define aDTS 0x88
#define aLPCM 0xA0
#define aMPEG 0xC0
class cDVD {
private:
static cDVD *dvdInstance;
static const char *deviceName;
dvd_reader_t *dvd;
dvd_file_t *title;
ifo_handle_t *vmg_file;
ifo_handle_t *vts_file;
int titleset;
static int Command(int Cmd);
public:
cDVD(void);
~cDVD();
static void SetDeviceName(const char *DeviceName);
static const char *DeviceName(void);
static bool DriveExists(void);
static bool DiscOk(void);
static void Eject(void);
void Open(void);
void Close(void);
bool isValid(void) { return (dvd != NULL); }
ifo_handle_t *openVMG(void);
ifo_handle_t *openVTS(int TitleSet);
ifo_handle_t *getVTS() { return vts_file; }
dvd_file_t *openTitle(int Title, dvd_read_domain_t domain);
static cDVD *getDVD(void);
int getAudioNrOfTracks() { return getVTS() ? getVTS()->vtsi_mat->nr_of_vts_audio_streams : 0; }
int getAudioLanguage(int stream) { return getVTS() ? getVTS()->vtsi_mat->vts_audio_attr[stream].lang_code : 0; }
int getAudioTrack(int stream);
};
#endif //DVDSUPPORT
#endif //__DVD_H

12
i18n.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: i18n.c 1.56 2002/02/24 11:53:44 kls Exp $
* $Id: i18n.c 1.57 2002/02/24 12:54:12 kls Exp $
*
* Slovenian translations provided by Miha Setina <mihasetina@softhome.net>
* Italian translations provided by Alberto Carraro <bertocar@tin.it>
@ -120,16 +120,6 @@ const tPhrase Phrases[] = {
"Opptak",
"Nauhoitteet",
},
{ "DVD",
"DVD",
"DVD",
"DVD",
"DVD",
"DVD",
"DVD",
"DVD",
"DVD",
},
{ "Setup",
"Einstellungen",
"Nastavitve",

136
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 1.158 2002/02/24 11:54:04 kls Exp $
* $Id: menu.c 1.159 2002/02/24 12:55:49 kls Exp $
*/
#include "menu.h"
@ -1822,81 +1822,6 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
return state;
}
#ifdef DVDSUPPORT
// --- cMenuDVDItem ----------------------------------------------------------
class cMenuDVDItem : public cOsdItem {
private:
int title;
int chapters;
virtual void Set(void);
public:
cMenuDVDItem(int Title, int Chapters);
int Title(void) { return title; }
};
cMenuDVDItem::cMenuDVDItem(int Title, int Chapters)
{
title = Title;
chapters = Chapters;
Set();
}
void cMenuDVDItem::Set(void)
{
char *buffer = NULL;
asprintf(&buffer, " %2d.\tTitle - \t%2d\tChapters", title + 1, chapters);
SetText(buffer, false);
}
// --- cMenuDVD --------------------------------------------------------------
cMenuDVD::cMenuDVD(void)
:cOsdMenu(tr("DVD"), 5, 8, 3)
{
if ((dvd = cDVD::getDVD())) {
dvd->Open();
ifo_handle_t *vmg = dvd->openVMG();
if (vmg) {
int lastTitleID = cReplayControl::LastTitleID();
dsyslog(LOG_INFO, "DVD: vmg: %p", vmg);//XXX
tt_srpt_t *tt_srpt = vmg->tt_srpt;
dsyslog(LOG_INFO, "DVD: tt_srpt: %p", tt_srpt);//XXX
for (int i = 0; i < tt_srpt->nr_of_srpts; i++)
Add(new cMenuDVDItem(i, tt_srpt->title[i].nr_of_ptts), i == lastTitleID);
}
}
SetHelp(tr("Play"), NULL, NULL, NULL);
Display();
}
eOSState cMenuDVD::Play(void)
{
cMenuDVDItem *ri = (cMenuDVDItem *)Get(Current());
if (ri) {
cReplayControl::SetDVD(dvd, ri->Title());
isyslog(LOG_INFO, "DVD: playing title %d", ri->Title());
return osReplay;
}
return osContinue;
}
eOSState cMenuDVD::ProcessKey(eKeys Key)
{
eOSState state = cOsdMenu::ProcessKey(Key);
if (state == osUnknown) {
switch (Key) {
case kOk:
case kRed: return Play();
case kMenu: return osEnd;
default: break;
}
}
return state;
}
#endif //DVDSUPPORT
// --- cMenuSetup ------------------------------------------------------------
class cMenuSetup : public cOsdMenu {
@ -2059,10 +1984,6 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
Add(new cOsdItem(hk(tr("Channels")), osChannels));
Add(new cOsdItem(hk(tr("Timers")), osTimers));
Add(new cOsdItem(hk(tr("Recordings")), osRecordings));
#ifdef DVDSUPPORT
if (cDVD::DriveExists())
Add(new cOsdItem(hk(tr("DVD")), osDVD));
#endif //DVDSUPPORT
Add(new cOsdItem(hk(tr("Setup")), osSetup));
if (Commands.Count())
Add(new cOsdItem(hk(tr("Commands")), osCommands));
@ -2095,13 +2016,7 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
// Color buttons:
const char *DVDbutton =
#ifdef DVDSUPPORT
cDVD::DiscOk() ? tr("Eject") : NULL;
#else
NULL;
#endif //DVDSUPPORT
SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, DVDbutton, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, NULL, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
Display();
lastActivity = time(NULL);
SetHasHotkeys();
@ -2110,9 +2025,6 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
switch (State) {
case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break;
#ifdef DVDSUPPORT
case osDVD: AddSubMenu(new cMenuDVD); break;
#endif //DVDSUPPORT
default: break;
}
}
@ -2137,9 +2049,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
case osChannels: return AddSubMenu(new cMenuChannels);
case osTimers: return AddSubMenu(new cMenuTimers);
case osRecordings: return AddSubMenu(new cMenuRecordings);
#ifdef DVDSUPPORT
case osDVD: return AddSubMenu(new cMenuDVD);
#endif //DVDSUPPORT
case osSetup: return AddSubMenu(new cMenuSetup);
case osCommands: return AddSubMenu(new cMenuCommands);
case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) {
@ -2172,23 +2081,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
}
}
break;
#ifdef DVDSUPPORT
case kYellow: if (!HasSubMenu()) {
if (cDVD::DiscOk()) {
// We need to stop replaying a DVD before ejecting,
// otherwise the replay thread crashes. Currently
// checking LastReplayed() is pretty much the only way
// of finding out whether we are currently replaying a DVD
// (i.e. if LastReplayed() returns non-NULL, we are either
// replaying a normal recording, or nothing at all):
if (!cReplayControl::LastReplayed())
cDvbApi::PrimaryDvbApi->StopReplay();
cDVD::Eject();
state = osEnd;
}
}
break;
#endif //DVDSUPPORT
case kBlue: if (!HasSubMenu())
state = osReplay;
break;
@ -2647,10 +2539,6 @@ void cProgressBar::Mark(int x, bool Start, bool Current)
char *cReplayControl::fileName = NULL;
char *cReplayControl::title = NULL;
#ifdef DVDSUPPORT
cDVD *cReplayControl::dvd = NULL;//XXX
int cReplayControl::titleid = 0;//XXX
#endif //DVDSUPPORT
cReplayControl::cReplayControl(void)
{
@ -2664,10 +2552,6 @@ cReplayControl::cReplayControl(void)
if (!dvbApi->StartReplay(fileName))
Interface->Error(tr("Channel locked (recording)!"));
}
#ifdef DVDSUPPORT
else if (dvd)
dvbApi->StartDVDplay(dvd, titleid);//XXX
#endif //DVDSUPPORT
}
cReplayControl::~cReplayControl()
@ -2684,20 +2568,6 @@ void cReplayControl::SetRecording(const char *FileName, const char *Title)
title = Title ? strdup(Title) : NULL;
}
#ifdef DVDSUPPORT
void cReplayControl::SetDVD(cDVD *DVD, int Title)//XXX
{
SetRecording(NULL, NULL);
dvd = DVD;
titleid = Title;
}
int cReplayControl::LastTitleID(void)
{
return titleid;
}
#endif //DVDSUPPORT
const char *cReplayControl::LastReplayed(void)
{
return fileName;
@ -3065,7 +2935,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
else
Show();
break;
case kBack: return fileName ? osRecordings : osDVD;
case kBack: return osRecordings;
default: return osUnknown;
}
}

25
menu.h
View File

@ -4,16 +4,13 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.h 1.36 2002/02/17 13:40:41 kls Exp $
* $Id: menu.h 1.37 2002/02/24 12:40:37 kls Exp $
*/
#ifndef _MENU_H
#define _MENU_H
#include "dvbapi.h"
#ifdef DVDSUPPORT
#include "dvd.h"
#endif //DVDSUPPORT
#include "osd.h"
#include "recording.h"
@ -43,18 +40,6 @@ public:
virtual eOSState ProcessKey(eKeys Key);
};
#ifdef DVDSUPPORT
class cMenuDVD : public cOsdMenu {
private:
cDVD *dvd;//XXX member really necessary???
eOSState Play(void);
eOSState Eject(void);
public:
cMenuDVD(void);
virtual eOSState ProcessKey(eKeys Key);
};
#endif //DVDSUPPORT
class cMenuRecordingItem;
class cMenuRecordings : public cOsdMenu {
@ -125,10 +110,6 @@ private:
void Show(int Seconds = 0);
void Hide(void);
static char *fileName;
#ifdef DVDSUPPORT
static cDVD *dvd;//XXX member really necessary???
static int titleid;//XXX
#endif //DVDSUPPORT
static char *title;
void DisplayAtBottom(const char *s = NULL);
void ShowMode(void);
@ -144,10 +125,6 @@ public:
virtual eOSState ProcessKey(eKeys Key);
bool Visible(void) { return visible; }
static void SetRecording(const char *FileName, const char *Title);
#ifdef DVDSUPPORT
static void SetDVD(cDVD *DVD, int Title);//XXX
static int LastTitleID(void);
#endif //DVDSUPPORT
static const char *LastReplayed(void);
static void ClearLastReplayed(const char *FileName);
};

3
osd.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osd.h 1.25 2002/01/20 10:42:14 kls Exp $
* $Id: osd.h 1.26 2002/02/24 12:55:16 kls Exp $
*/
#ifndef __OSD_H
@ -27,7 +27,6 @@ enum eOSState { osUnknown,
osCommands,
osRecord,
osReplay,
osDVD,
osStopRecord,
osStopReplay,
osCancelEdit,

32
vdr.c
View File

@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
* $Id: vdr.c 1.96 2002/02/23 16:35:36 kls Exp $
* $Id: vdr.c 1.97 2002/02/24 12:55:10 kls Exp $
*/
#include <getopt.h>
@ -32,9 +32,6 @@
#include <unistd.h>
#include "config.h"
#include "dvbapi.h"
#ifdef DVDSUPPORT
#include "dvd.h"
#endif //DVDSUPPORT
#include "eit.h"
#include "i18n.h"
#include "interface.h"
@ -105,14 +102,13 @@ int main(int argc, char *argv[])
{ "shutdown", required_argument, NULL, 's' },
{ "terminal", required_argument, NULL, 't' },
{ "video", required_argument, NULL, 'v' },
{ "dvd", required_argument, NULL, 'V' },
{ "watchdog", required_argument, NULL, 'w' },
{ NULL }
};
int c;
int option_index = 0;
while ((c = getopt_long(argc, argv, "a:c:dD:E:hl:p:r:s:t:v:V:w:", long_options, &option_index)) != -1) {
while ((c = getopt_long(argc, argv, "a:c:dD:E:hl:p:r:s:t:v:w:", long_options, &option_index)) != -1) {
switch (c) {
case 'a': cDvbApi::SetAudioCommand(optarg);
break;
@ -153,7 +149,6 @@ int main(int argc, char *argv[])
" -s CMD, --shutdown=CMD call CMD to shutdown the computer\n"
" -t TTY, --terminal=TTY controlling tty\n"
" -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
" -V DEV, --dvd=DEV use DEV as the DVD device (default: %s)\n"
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
" seconds (default: %d); '0' disables the watchdog\n"
"\n"
@ -161,11 +156,6 @@ int main(int argc, char *argv[])
cSIProcessor::GetEpgDataFileName() ? cSIProcessor::GetEpgDataFileName() : "'-'",
DEFAULTSVDRPPORT,
VideoDirectory,
#ifdef DVDSUPPORT
cDVD::DeviceName(),
#else
"no DVD support",
#endif //DVDSUPPORT
DEFAULTWATCHDOG
);
return 0;
@ -197,18 +187,6 @@ int main(int argc, char *argv[])
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
optarg[strlen(optarg) - 1] = 0;
break;
case 'V':
#ifdef DVDSUPPORT
cDVD::SetDeviceName(optarg);
if (!cDVD::DriveExists()) {
fprintf(stderr, "vdr: DVD drive not found: %s\n", optarg);
return 2;
}
#else
fprintf(stderr, "vdr: DVD support has not been compiled in!");
return 2;
#endif //DVDSUPPORT
break;
case 'w': if (isnumber(optarg)) {
int t = atoi(optarg);
if (t >= 0) {
@ -409,12 +387,6 @@ int main(int argc, char *argv[])
DELETENULL(ReplayControl);
ReplayControl = new cReplayControl;
break;
#ifdef DVDSUPPORT
case osDVD: DELETENULL(Menu);
DELETENULL(ReplayControl);
Menu = new cMenuMain(ReplayControl, osDVD);
break;
#endif //DVDSUPPORT
case osStopReplay:
DELETENULL(*Interact);
DELETENULL(ReplayControl);