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:
parent
44ee59b21a
commit
715ed57ab1
9
HISTORY
9
HISTORY
@ -1031,3 +1031,12 @@ Video Disk Recorder Revision History
|
|||||||
or don't have the equipment to replay Dolby Digital audio.
|
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
|
- Reading the 'setup.conf' file no longer terminates in case of an error, but
|
||||||
rather attempts to read the rest of the file.
|
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
30
INSTALL
@ -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
|
you will have to change the definition of DVBDIR in the
|
||||||
Makefile.
|
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
|
VDR requires the Linux-DVB card driver version dated 2001-09-14 or higher
|
||||||
to work properly.
|
to work properly.
|
||||||
|
|
||||||
@ -250,19 +233,6 @@ This program must be given to VDR with the '-a' option, as in
|
|||||||
|
|
||||||
vdr -a ac3play
|
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:
|
The video data directory:
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
2
MANUAL
2
MANUAL
@ -19,7 +19,7 @@ Video Disk Recorder User's Manual
|
|||||||
Back - Menu off Main menu Main menu Discard Main menu Recordings menu
|
Back - Menu off Main menu Main menu Discard Main menu Recordings menu
|
||||||
Red - Record Edit Edit - Play Jump
|
Red - Record Edit Edit - Play Jump
|
||||||
Green - Language New New - Rewind Skip -60s
|
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
|
Blue - Resume Mark On/Off(1) - Summary Stop
|
||||||
0..9 Ch select - - - Numeric inp. - Editing
|
0..9 Ch select - - - Numeric inp. - Editing
|
||||||
|
|
||||||
|
25
Makefile
25
Makefile
@ -4,29 +4,18 @@
|
|||||||
# See the main source file 'vdr.c' for copyright information and
|
# See the main source file 'vdr.c' for copyright information and
|
||||||
# how to reach the author.
|
# 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:
|
.DELETE_ON_ERROR:
|
||||||
|
|
||||||
DVBDIR = ../DVB
|
DVBDIR = ../DVB
|
||||||
DVDDIR = ../DVD
|
|
||||||
AC3DIR = ./ac3dec
|
|
||||||
DTVDIR = ./libdtv
|
DTVDIR = ./libdtv
|
||||||
|
|
||||||
INCLUDES = -I$(DVBDIR)/ost/include
|
INCLUDES = -I$(DVBDIR)/ost/include
|
||||||
|
|
||||||
DTVLIB = $(DTVDIR)/libdtv.a
|
DTVLIB = $(DTVDIR)/libdtv.a
|
||||||
|
|
||||||
ifdef DVD
|
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o i18n.o interface.o menu.o osd.o\
|
||||||
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\
|
|
||||||
recording.o remote.o remux.o ringbuffer.o svdrp.o thread.o tools.o vdr.o\
|
recording.o remote.o remux.o ringbuffer.o svdrp.o thread.o tools.o vdr.o\
|
||||||
videodir.o
|
videodir.o
|
||||||
|
|
||||||
@ -75,8 +64,8 @@ include $(DEPFILE)
|
|||||||
|
|
||||||
# The main program:
|
# The main program:
|
||||||
|
|
||||||
vdr: $(OBJS) $(AC3LIB) $(DTVLIB)
|
vdr: $(OBJS) $(DTVLIB)
|
||||||
g++ -g -O2 $(OBJS) $(NCURSESLIB) -ljpeg -lpthread $(LIBDIRS) $(DVDLIB) $(AC3LIB) $(DTVLIB) -o vdr
|
g++ -g -O2 $(OBJS) $(NCURSESLIB) -ljpeg -lpthread $(LIBDIRS) $(DTVLIB) -o vdr
|
||||||
|
|
||||||
# The font files:
|
# The font files:
|
||||||
|
|
||||||
@ -90,11 +79,6 @@ fontosd.c:
|
|||||||
genfontfile: genfontfile.c
|
genfontfile: genfontfile.c
|
||||||
gcc -o $@ -O2 -L/usr/X11R6/lib $< -lX11
|
gcc -o $@ -O2 -L/usr/X11R6/lib $< -lX11
|
||||||
|
|
||||||
# The ac3dec library:
|
|
||||||
|
|
||||||
$(AC3LIB):
|
|
||||||
make -C $(AC3DIR) all
|
|
||||||
|
|
||||||
# The libdtv library:
|
# The libdtv library:
|
||||||
|
|
||||||
$(DTVLIB) $(DTVDIR)/libdtv.h:
|
$(DTVLIB) $(DTVDIR)/libdtv.h:
|
||||||
@ -103,7 +87,6 @@ $(DTVLIB) $(DTVDIR)/libdtv.h:
|
|||||||
# Housekeeping:
|
# Housekeeping:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C $(AC3DIR) clean
|
|
||||||
make -C $(DTVDIR) clean
|
make -C $(DTVDIR) clean
|
||||||
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~
|
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~
|
||||||
fontclean:
|
fontclean:
|
||||||
|
@ -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)
|
|
64
ac3dec/ac3.h
64
ac3dec/ac3.h
@ -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
|
|
@ -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;
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
@ -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;
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
431
ac3dec/coeff.c
431
ac3dec/coeff.c
@ -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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
@ -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
|
|
||||||
}
|
|
96
ac3dec/crc.c
96
ac3dec/crc.c
@ -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);
|
|
||||||
}
|
|
27
ac3dec/crc.h
27
ac3dec/crc.h
@ -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);
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
312
ac3dec/decode.c
312
ac3dec/decode.c
@ -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;
|
|
||||||
}
|
|
@ -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.
|
|
||||||
*
|
|
||||||
*/
|
|
114
ac3dec/dither.c
114
ac3dec/dither.c
@ -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
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 ();
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
530
ac3dec/imdct.c
530
ac3dec/imdct.c
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
@ -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
|
|
218
ac3dec/imdct_c.c
218
ac3dec/imdct_c.c
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
481
ac3dec/parse.c
481
ac3dec/parse.c
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
@ -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;
|
|
||||||
}
|
|
@ -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);
|
|
305
ac3dec/srfft.c
305
ac3dec/srfft.c
@ -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]);
|
|
||||||
}
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
305
ac3dec/srfftp.h
305
ac3dec/srfftp.h
@ -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
|
|
178
ac3dec/stats.c
178
ac3dec/stats.c
@ -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");
|
|
||||||
}
|
|
@ -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);
|
|
4
config.h
4
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __CONFIG_H
|
||||||
@ -19,7 +19,7 @@
|
|||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define VDRVERSION "0.99"
|
#define VDRVERSION "1.0.0pre1"
|
||||||
|
|
||||||
#define MAXPRIORITY 99
|
#define MAXPRIORITY 99
|
||||||
#define MAXLIFETIME 99
|
#define MAXLIFETIME 99
|
||||||
|
903
dvbapi.c
903
dvbapi.c
@ -4,14 +4,9 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* DVD support initially written by Andreas Schultz <aschultz@warp10.net>
|
* $Id: dvbapi.c 1.152 2002/02/24 12:53:51 kls Exp $
|
||||||
* 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 $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define DVDDEBUG 1
|
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -26,13 +21,6 @@ extern "C" {
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
extern "C" {
|
|
||||||
#include "ac3dec/ac3.h"
|
|
||||||
}
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
#include "remux.h"
|
#include "remux.h"
|
||||||
@ -1320,865 +1308,6 @@ bool cReplayBuffer::NextFile(uchar FileNumber, int FileOffset)
|
|||||||
return replayFile >= 0;
|
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(§or, 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 -------------------------------------------------------
|
// --- cTransferBuffer -------------------------------------------------------
|
||||||
|
|
||||||
class cTransferBuffer : public cRingBufferLinear {
|
class cTransferBuffer : public cRingBufferLinear {
|
||||||
@ -3412,36 +2541,6 @@ bool cDvbApi::StartReplay(const char *FileName)
|
|||||||
return false;
|
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)
|
void cDvbApi::StopReplay(void)
|
||||||
{
|
{
|
||||||
if (replayBuffer) {
|
if (replayBuffer) {
|
||||||
|
15
dvbapi.h
15
dvbapi.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __DVBAPI_H
|
||||||
@ -29,9 +29,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "dvbosd.h"
|
#include "dvbosd.h"
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
#include "dvd.h"
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
@ -60,9 +57,6 @@ class cChannel;
|
|||||||
class cRecordBuffer;
|
class cRecordBuffer;
|
||||||
class cPlayBuffer;
|
class cPlayBuffer;
|
||||||
class cReplayBuffer;
|
class cReplayBuffer;
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
class cDVDplayBuffer;
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
class cTransferBuffer;
|
class cTransferBuffer;
|
||||||
class cCuttingBuffer;
|
class cCuttingBuffer;
|
||||||
|
|
||||||
@ -83,9 +77,6 @@ public:
|
|||||||
class cDvbApi {
|
class cDvbApi {
|
||||||
friend class cRecordBuffer;
|
friend class cRecordBuffer;
|
||||||
friend class cReplayBuffer;
|
friend class cReplayBuffer;
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
friend class cDVDplayBuffer;
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
friend class cTransferBuffer;
|
friend class cTransferBuffer;
|
||||||
private:
|
private:
|
||||||
FrontendType frontendType;
|
FrontendType frontendType;
|
||||||
@ -246,10 +237,6 @@ public:
|
|||||||
// Starts replaying the given file.
|
// Starts replaying the given file.
|
||||||
// If there is already a replay session active, it will be stopped
|
// If there is already a replay session active, it will be stopped
|
||||||
// and the new file will be played back.
|
// 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);
|
void StopReplay(void);
|
||||||
// Stops the current replay session (if any).
|
// Stops the current replay session (if any).
|
||||||
void Pause(void);
|
void Pause(void);
|
||||||
|
169
dvd.c
169
dvd.c
@ -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
62
dvd.h
@ -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
12
i18n.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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>
|
* Slovenian translations provided by Miha Setina <mihasetina@softhome.net>
|
||||||
* Italian translations provided by Alberto Carraro <bertocar@tin.it>
|
* Italian translations provided by Alberto Carraro <bertocar@tin.it>
|
||||||
@ -120,16 +120,6 @@ const tPhrase Phrases[] = {
|
|||||||
"Opptak",
|
"Opptak",
|
||||||
"Nauhoitteet",
|
"Nauhoitteet",
|
||||||
},
|
},
|
||||||
{ "DVD",
|
|
||||||
"DVD",
|
|
||||||
"DVD",
|
|
||||||
"DVD",
|
|
||||||
"DVD",
|
|
||||||
"DVD",
|
|
||||||
"DVD",
|
|
||||||
"DVD",
|
|
||||||
"DVD",
|
|
||||||
},
|
|
||||||
{ "Setup",
|
{ "Setup",
|
||||||
"Einstellungen",
|
"Einstellungen",
|
||||||
"Nastavitve",
|
"Nastavitve",
|
||||||
|
136
menu.c
136
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "menu.h"
|
||||||
@ -1822,81 +1822,6 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
|
|||||||
return state;
|
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 ------------------------------------------------------------
|
// --- cMenuSetup ------------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSetup : public cOsdMenu {
|
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("Channels")), osChannels));
|
||||||
Add(new cOsdItem(hk(tr("Timers")), osTimers));
|
Add(new cOsdItem(hk(tr("Timers")), osTimers));
|
||||||
Add(new cOsdItem(hk(tr("Recordings")), osRecordings));
|
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));
|
Add(new cOsdItem(hk(tr("Setup")), osSetup));
|
||||||
if (Commands.Count())
|
if (Commands.Count())
|
||||||
Add(new cOsdItem(hk(tr("Commands")), osCommands));
|
Add(new cOsdItem(hk(tr("Commands")), osCommands));
|
||||||
@ -2095,13 +2016,7 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
|
|||||||
|
|
||||||
// Color buttons:
|
// Color buttons:
|
||||||
|
|
||||||
const char *DVDbutton =
|
SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, NULL, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
|
||||||
#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);
|
|
||||||
Display();
|
Display();
|
||||||
lastActivity = time(NULL);
|
lastActivity = time(NULL);
|
||||||
SetHasHotkeys();
|
SetHasHotkeys();
|
||||||
@ -2110,9 +2025,6 @@ cMenuMain::cMenuMain(bool Replaying, eOSState State)
|
|||||||
|
|
||||||
switch (State) {
|
switch (State) {
|
||||||
case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break;
|
case osRecordings: AddSubMenu(new cMenuRecordings(NULL, 0, true)); break;
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
case osDVD: AddSubMenu(new cMenuDVD); break;
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2137,9 +2049,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
|||||||
case osChannels: return AddSubMenu(new cMenuChannels);
|
case osChannels: return AddSubMenu(new cMenuChannels);
|
||||||
case osTimers: return AddSubMenu(new cMenuTimers);
|
case osTimers: return AddSubMenu(new cMenuTimers);
|
||||||
case osRecordings: return AddSubMenu(new cMenuRecordings);
|
case osRecordings: return AddSubMenu(new cMenuRecordings);
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
case osDVD: return AddSubMenu(new cMenuDVD);
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
case osSetup: return AddSubMenu(new cMenuSetup);
|
case osSetup: return AddSubMenu(new cMenuSetup);
|
||||||
case osCommands: return AddSubMenu(new cMenuCommands);
|
case osCommands: return AddSubMenu(new cMenuCommands);
|
||||||
case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) {
|
case osStopRecord: if (Interface->Confirm(tr("Stop recording?"))) {
|
||||||
@ -2172,23 +2081,6 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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())
|
case kBlue: if (!HasSubMenu())
|
||||||
state = osReplay;
|
state = osReplay;
|
||||||
break;
|
break;
|
||||||
@ -2647,10 +2539,6 @@ void cProgressBar::Mark(int x, bool Start, bool Current)
|
|||||||
|
|
||||||
char *cReplayControl::fileName = NULL;
|
char *cReplayControl::fileName = NULL;
|
||||||
char *cReplayControl::title = NULL;
|
char *cReplayControl::title = NULL;
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
cDVD *cReplayControl::dvd = NULL;//XXX
|
|
||||||
int cReplayControl::titleid = 0;//XXX
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
|
|
||||||
cReplayControl::cReplayControl(void)
|
cReplayControl::cReplayControl(void)
|
||||||
{
|
{
|
||||||
@ -2664,10 +2552,6 @@ cReplayControl::cReplayControl(void)
|
|||||||
if (!dvbApi->StartReplay(fileName))
|
if (!dvbApi->StartReplay(fileName))
|
||||||
Interface->Error(tr("Channel locked (recording)!"));
|
Interface->Error(tr("Channel locked (recording)!"));
|
||||||
}
|
}
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
else if (dvd)
|
|
||||||
dvbApi->StartDVDplay(dvd, titleid);//XXX
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cReplayControl::~cReplayControl()
|
cReplayControl::~cReplayControl()
|
||||||
@ -2684,20 +2568,6 @@ void cReplayControl::SetRecording(const char *FileName, const char *Title)
|
|||||||
title = Title ? strdup(Title) : NULL;
|
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)
|
const char *cReplayControl::LastReplayed(void)
|
||||||
{
|
{
|
||||||
return fileName;
|
return fileName;
|
||||||
@ -3065,7 +2935,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
|
|||||||
else
|
else
|
||||||
Show();
|
Show();
|
||||||
break;
|
break;
|
||||||
case kBack: return fileName ? osRecordings : osDVD;
|
case kBack: return osRecordings;
|
||||||
default: return osUnknown;
|
default: return osUnknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
menu.h
25
menu.h
@ -4,16 +4,13 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef _MENU_H
|
||||||
#define _MENU_H
|
#define _MENU_H
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
#include "dvd.h"
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
|
|
||||||
@ -43,18 +40,6 @@ public:
|
|||||||
virtual eOSState ProcessKey(eKeys Key);
|
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 cMenuRecordingItem;
|
||||||
|
|
||||||
class cMenuRecordings : public cOsdMenu {
|
class cMenuRecordings : public cOsdMenu {
|
||||||
@ -125,10 +110,6 @@ private:
|
|||||||
void Show(int Seconds = 0);
|
void Show(int Seconds = 0);
|
||||||
void Hide(void);
|
void Hide(void);
|
||||||
static char *fileName;
|
static char *fileName;
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
static cDVD *dvd;//XXX member really necessary???
|
|
||||||
static int titleid;//XXX
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
static char *title;
|
static char *title;
|
||||||
void DisplayAtBottom(const char *s = NULL);
|
void DisplayAtBottom(const char *s = NULL);
|
||||||
void ShowMode(void);
|
void ShowMode(void);
|
||||||
@ -144,10 +125,6 @@ public:
|
|||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
bool Visible(void) { return visible; }
|
bool Visible(void) { return visible; }
|
||||||
static void SetRecording(const char *FileName, const char *Title);
|
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 const char *LastReplayed(void);
|
||||||
static void ClearLastReplayed(const char *FileName);
|
static void ClearLastReplayed(const char *FileName);
|
||||||
};
|
};
|
||||||
|
3
osd.h
3
osd.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __OSD_H
|
||||||
@ -27,7 +27,6 @@ enum eOSState { osUnknown,
|
|||||||
osCommands,
|
osCommands,
|
||||||
osRecord,
|
osRecord,
|
||||||
osReplay,
|
osReplay,
|
||||||
osDVD,
|
|
||||||
osStopRecord,
|
osStopRecord,
|
||||||
osStopReplay,
|
osStopReplay,
|
||||||
osCancelEdit,
|
osCancelEdit,
|
||||||
|
32
vdr.c
32
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
* 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>
|
#include <getopt.h>
|
||||||
@ -32,9 +32,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
#include "dvd.h"
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
@ -105,14 +102,13 @@ int main(int argc, char *argv[])
|
|||||||
{ "shutdown", required_argument, NULL, 's' },
|
{ "shutdown", required_argument, NULL, 's' },
|
||||||
{ "terminal", required_argument, NULL, 't' },
|
{ "terminal", required_argument, NULL, 't' },
|
||||||
{ "video", required_argument, NULL, 'v' },
|
{ "video", required_argument, NULL, 'v' },
|
||||||
{ "dvd", required_argument, NULL, 'V' },
|
|
||||||
{ "watchdog", required_argument, NULL, 'w' },
|
{ "watchdog", required_argument, NULL, 'w' },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
int option_index = 0;
|
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) {
|
switch (c) {
|
||||||
case 'a': cDvbApi::SetAudioCommand(optarg);
|
case 'a': cDvbApi::SetAudioCommand(optarg);
|
||||||
break;
|
break;
|
||||||
@ -153,7 +149,6 @@ int main(int argc, char *argv[])
|
|||||||
" -s CMD, --shutdown=CMD call CMD to shutdown the computer\n"
|
" -s CMD, --shutdown=CMD call CMD to shutdown the computer\n"
|
||||||
" -t TTY, --terminal=TTY controlling tty\n"
|
" -t TTY, --terminal=TTY controlling tty\n"
|
||||||
" -v DIR, --video=DIR use DIR as video directory (default: %s)\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"
|
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
|
||||||
" seconds (default: %d); '0' disables the watchdog\n"
|
" seconds (default: %d); '0' disables the watchdog\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -161,11 +156,6 @@ int main(int argc, char *argv[])
|
|||||||
cSIProcessor::GetEpgDataFileName() ? cSIProcessor::GetEpgDataFileName() : "'-'",
|
cSIProcessor::GetEpgDataFileName() ? cSIProcessor::GetEpgDataFileName() : "'-'",
|
||||||
DEFAULTSVDRPPORT,
|
DEFAULTSVDRPPORT,
|
||||||
VideoDirectory,
|
VideoDirectory,
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
cDVD::DeviceName(),
|
|
||||||
#else
|
|
||||||
"no DVD support",
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
DEFAULTWATCHDOG
|
DEFAULTWATCHDOG
|
||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
@ -197,18 +187,6 @@ int main(int argc, char *argv[])
|
|||||||
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
|
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
|
||||||
optarg[strlen(optarg) - 1] = 0;
|
optarg[strlen(optarg) - 1] = 0;
|
||||||
break;
|
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)) {
|
case 'w': if (isnumber(optarg)) {
|
||||||
int t = atoi(optarg);
|
int t = atoi(optarg);
|
||||||
if (t >= 0) {
|
if (t >= 0) {
|
||||||
@ -409,12 +387,6 @@ int main(int argc, char *argv[])
|
|||||||
DELETENULL(ReplayControl);
|
DELETENULL(ReplayControl);
|
||||||
ReplayControl = new cReplayControl;
|
ReplayControl = new cReplayControl;
|
||||||
break;
|
break;
|
||||||
#ifdef DVDSUPPORT
|
|
||||||
case osDVD: DELETENULL(Menu);
|
|
||||||
DELETENULL(ReplayControl);
|
|
||||||
Menu = new cMenuMain(ReplayControl, osDVD);
|
|
||||||
break;
|
|
||||||
#endif //DVDSUPPORT
|
|
||||||
case osStopReplay:
|
case osStopReplay:
|
||||||
DELETENULL(*Interact);
|
DELETENULL(*Interact);
|
||||||
DELETENULL(ReplayControl);
|
DELETENULL(ReplayControl);
|
||||||
|
Loading…
Reference in New Issue
Block a user