mirror of https://github.com/PCSX2/pcsx2.git
GregMiscellaneous: sync with trunk (3805-3918)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/GregMiscellaneous@3919 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
0d4e02995d
commit
d84d8e8a2a
|
@ -1,60 +0,0 @@
|
||||||
# a52 library
|
|
||||||
|
|
||||||
# library name
|
|
||||||
set(Output pcsx2_a52)
|
|
||||||
|
|
||||||
set(CommonFlags
|
|
||||||
-Wall
|
|
||||||
-g
|
|
||||||
)
|
|
||||||
|
|
||||||
set(OptimizationFlags
|
|
||||||
-Os
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Debug - Build
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
||||||
# add defines
|
|
||||||
add_definitions(${CommonFlags})
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
||||||
|
|
||||||
# Devel - Build
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL Devel)
|
|
||||||
# add defines
|
|
||||||
add_definitions(${CommonFlags} ${OptimizationFlags})
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL Devel)
|
|
||||||
|
|
||||||
# Release - Build
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL Release)
|
|
||||||
# add defines
|
|
||||||
add_definitions(${CommonFlags} ${OptimizationFlags})
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL Release)
|
|
||||||
|
|
||||||
# variable with all sources of this library
|
|
||||||
set(a52Sources
|
|
||||||
bit_allocate.c
|
|
||||||
bitstream.c
|
|
||||||
downmix.c
|
|
||||||
imdct.c
|
|
||||||
parse.c)
|
|
||||||
|
|
||||||
# variable with all headers of this library
|
|
||||||
set(a52Headers
|
|
||||||
a52.h
|
|
||||||
a52_internal.h
|
|
||||||
attributes.h
|
|
||||||
bitstream.h
|
|
||||||
config.h
|
|
||||||
inttypes.h
|
|
||||||
mm_accel.h
|
|
||||||
tables.h
|
|
||||||
tendra.h)
|
|
||||||
|
|
||||||
# add library
|
|
||||||
add_library(${Output} STATIC ${a52Sources} ${a52Headers})
|
|
||||||
|
|
||||||
# User flags options
|
|
||||||
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
|
||||||
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
|
|
||||||
endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* a52.h
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef A52_H
|
|
||||||
#define A52_H
|
|
||||||
|
|
||||||
#ifndef LIBA52_DOUBLE
|
|
||||||
typedef float sample_t;
|
|
||||||
#else
|
|
||||||
typedef double sample_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct a52_state_s a52_state_t;
|
|
||||||
|
|
||||||
#define A52_CHANNEL 0
|
|
||||||
#define A52_MONO 1
|
|
||||||
#define A52_STEREO 2
|
|
||||||
#define A52_3F 3
|
|
||||||
#define A52_2F1R 4
|
|
||||||
#define A52_3F1R 5
|
|
||||||
#define A52_2F2R 6
|
|
||||||
#define A52_3F2R 7
|
|
||||||
#define A52_CHANNEL1 8
|
|
||||||
#define A52_CHANNEL2 9
|
|
||||||
#define A52_DOLBY 10
|
|
||||||
#define A52_CHANNEL_MASK 15
|
|
||||||
|
|
||||||
#define A52_LFE 16
|
|
||||||
#define A52_ADJUST_LEVEL 32
|
|
||||||
|
|
||||||
a52_state_t * a52_init (uint32_t mm_accel);
|
|
||||||
sample_t * a52_samples (a52_state_t * state);
|
|
||||||
int a52_syncinfo (uint8_t * buf, int * flags,
|
|
||||||
int * sample_rate, int * bit_rate);
|
|
||||||
int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
|
|
||||||
sample_t * level, sample_t bias);
|
|
||||||
void a52_dynrng (a52_state_t * state,
|
|
||||||
sample_t (* call) (sample_t, void *), void * data);
|
|
||||||
int a52_block (a52_state_t * state);
|
|
||||||
void a52_free (a52_state_t * state);
|
|
||||||
|
|
||||||
#endif /* A52_H */
|
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
* a52_internal.h
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t bai; /* fine SNR offset, fast gain */
|
|
||||||
uint8_t deltbae; /* delta bit allocation exists */
|
|
||||||
int8_t deltba[50]; /* per-band delta bit allocation */
|
|
||||||
} ba_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t exp[256]; /* decoded channel exponents */
|
|
||||||
int8_t bap[256]; /* derived channel bit allocation */
|
|
||||||
} expbap_t;
|
|
||||||
|
|
||||||
struct a52_state_s {
|
|
||||||
uint8_t fscod; /* sample rate */
|
|
||||||
uint8_t halfrate; /* halfrate factor */
|
|
||||||
uint8_t acmod; /* coded channels */
|
|
||||||
uint8_t lfeon; /* coded lfe channel */
|
|
||||||
sample_t clev; /* centre channel mix level */
|
|
||||||
sample_t slev; /* surround channels mix level */
|
|
||||||
|
|
||||||
int output; /* type of output */
|
|
||||||
sample_t level; /* output level */
|
|
||||||
sample_t bias; /* output bias */
|
|
||||||
|
|
||||||
int dynrnge; /* apply dynamic range */
|
|
||||||
sample_t dynrng; /* dynamic range */
|
|
||||||
void * dynrngdata; /* dynamic range callback funtion and data */
|
|
||||||
sample_t (* dynrngcall) (sample_t range, void * dynrngdata);
|
|
||||||
|
|
||||||
uint8_t chincpl; /* channel coupled */
|
|
||||||
uint8_t phsflginu; /* phase flags in use (stereo only) */
|
|
||||||
uint8_t cplstrtmant; /* coupling channel start mantissa */
|
|
||||||
uint8_t cplendmant; /* coupling channel end mantissa */
|
|
||||||
uint32_t cplbndstrc; /* coupling band structure */
|
|
||||||
sample_t cplco[5][18]; /* coupling coordinates */
|
|
||||||
|
|
||||||
/* derived information */
|
|
||||||
uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */
|
|
||||||
uint8_t ncplbnd; /* number of coupling bands */
|
|
||||||
|
|
||||||
uint8_t rematflg; /* stereo rematrixing */
|
|
||||||
|
|
||||||
uint8_t endmant[5]; /* channel end mantissa */
|
|
||||||
|
|
||||||
uint16_t bai; /* bit allocation information */
|
|
||||||
|
|
||||||
uint32_t * buffer_start;
|
|
||||||
uint16_t lfsr_state; /* dither state */
|
|
||||||
uint32_t bits_left;
|
|
||||||
uint32_t current_word;
|
|
||||||
|
|
||||||
uint8_t csnroffst; /* coarse SNR offset */
|
|
||||||
ba_t cplba; /* coupling bit allocation parameters */
|
|
||||||
ba_t ba[5]; /* channel bit allocation parameters */
|
|
||||||
ba_t lfeba; /* lfe bit allocation parameters */
|
|
||||||
|
|
||||||
uint8_t cplfleak; /* coupling fast leak init */
|
|
||||||
uint8_t cplsleak; /* coupling slow leak init */
|
|
||||||
|
|
||||||
expbap_t cpl_expbap;
|
|
||||||
expbap_t fbw_expbap[5];
|
|
||||||
expbap_t lfe_expbap;
|
|
||||||
|
|
||||||
sample_t * samples;
|
|
||||||
int downmixed;
|
|
||||||
};
|
|
||||||
|
|
||||||
// [Air]: Added sample_t casts here.
|
|
||||||
// Improves SSE2 optimization efficiency under Visual Studio 2008
|
|
||||||
|
|
||||||
#define LEVEL_PLUS6DB ((sample_t)2.0)
|
|
||||||
#define LEVEL_PLUS3DB ((sample_t)1.4142135623730951)
|
|
||||||
#define LEVEL_3DB ((sample_t)0.7071067811865476)
|
|
||||||
#define LEVEL_45DB ((sample_t)0.5946035575013605)
|
|
||||||
#define LEVEL_6DB ((sample_t)0.5)
|
|
||||||
|
|
||||||
#define EXP_REUSE (0)
|
|
||||||
#define EXP_D15 (1)
|
|
||||||
#define EXP_D25 (2)
|
|
||||||
#define EXP_D45 (3)
|
|
||||||
|
|
||||||
#define DELTA_BIT_REUSE (0)
|
|
||||||
#define DELTA_BIT_NEW (1)
|
|
||||||
#define DELTA_BIT_NONE (2)
|
|
||||||
#define DELTA_BIT_RESERVED (3)
|
|
||||||
|
|
||||||
void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
|
|
||||||
int start, int end, int fastleak, int slowleak,
|
|
||||||
expbap_t * expbap);
|
|
||||||
|
|
||||||
int a52_downmix_init (int input, int flags, sample_t * level,
|
|
||||||
sample_t clev, sample_t slev);
|
|
||||||
int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
|
|
||||||
sample_t clev, sample_t slev);
|
|
||||||
void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
|
|
||||||
sample_t clev, sample_t slev);
|
|
||||||
void a52_upmix (sample_t * samples, int acmod, int output);
|
|
||||||
|
|
||||||
void a52_imdct_init (uint32_t mm_accel);
|
|
||||||
void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias);
|
|
||||||
void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias);
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* attributes.h
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* use gcc attribs to align critical data structures */
|
|
||||||
#ifdef ATTRIBUTE_ALIGNED_MAX
|
|
||||||
#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
|
|
||||||
#else
|
|
||||||
#define ATTR_ALIGN(align)
|
|
||||||
#endif
|
|
|
@ -1,265 +0,0 @@
|
||||||
/*
|
|
||||||
* bit_allocate.c
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "inttypes.h"
|
|
||||||
|
|
||||||
#include "a52.h"
|
|
||||||
#include "a52_internal.h"
|
|
||||||
|
|
||||||
static int hthtab[3][50] = {
|
|
||||||
{0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
|
|
||||||
0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890,
|
|
||||||
0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900,
|
|
||||||
0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0,
|
|
||||||
0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0},
|
|
||||||
{0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860,
|
|
||||||
0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880,
|
|
||||||
0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0,
|
|
||||||
0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820,
|
|
||||||
0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0},
|
|
||||||
{0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850,
|
|
||||||
0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860,
|
|
||||||
0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0,
|
|
||||||
0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0,
|
|
||||||
0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int8_t baptab[305] = {
|
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, /* 93 padding elems */
|
|
||||||
|
|
||||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14,
|
|
||||||
14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
|
|
||||||
9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5,
|
|
||||||
5, 4, 4, -3, -3, 3, 3, 3, -2, -2, -1, -1, -1, -1, -1, 0,
|
|
||||||
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0 /* 148 padding elems */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int bndtab[30] = {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, 253};
|
|
||||||
|
|
||||||
static int8_t latab[256] = {
|
|
||||||
-64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53,
|
|
||||||
-52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44,
|
|
||||||
-43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35,
|
|
||||||
-35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28,
|
|
||||||
-28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22,
|
|
||||||
-22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18,
|
|
||||||
-17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14,
|
|
||||||
-13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11,
|
|
||||||
-10, -10, -10, -10, -10, -9, -9, -9, -9, -9, -8, -8,
|
|
||||||
-8, -8, -8, -8, -7, -7, -7, -7, -7, -7, -6, -6,
|
|
||||||
-6, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5,
|
|
||||||
-5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
|
|
||||||
-4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
|
|
||||||
-3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2,
|
|
||||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -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, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#define UPDATE_LEAK() \
|
|
||||||
do { \
|
|
||||||
fastleak += fdecay; \
|
|
||||||
if (fastleak > psd + fgain) \
|
|
||||||
fastleak = psd + fgain; \
|
|
||||||
slowleak += sdecay; \
|
|
||||||
if (slowleak > psd + sgain) \
|
|
||||||
slowleak = psd + sgain; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define COMPUTE_MASK() \
|
|
||||||
do { \
|
|
||||||
if (psd > dbknee) \
|
|
||||||
mask -= (psd - dbknee) >> 2; \
|
|
||||||
if (mask > hth [i >> halfrate]) \
|
|
||||||
mask = hth [i >> halfrate]; \
|
|
||||||
mask -= snroffset + 128 * deltba[i]; \
|
|
||||||
mask = (mask > 0) ? 0 : ((-mask) >> 5); \
|
|
||||||
mask -= floor; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
|
|
||||||
int start, int end, int fastleak, int slowleak,
|
|
||||||
expbap_t * expbap)
|
|
||||||
{
|
|
||||||
static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
|
|
||||||
static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100};
|
|
||||||
static int floortab[8] = {0x910, 0x950, 0x990, 0x9d0,
|
|
||||||
0xa10, 0xa90, 0xb10, 0x1400};
|
|
||||||
|
|
||||||
int i, j;
|
|
||||||
uint8_t * exp;
|
|
||||||
int8_t * bap;
|
|
||||||
int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset;
|
|
||||||
int psd, mask;
|
|
||||||
int8_t * deltba;
|
|
||||||
int * hth;
|
|
||||||
int halfrate;
|
|
||||||
|
|
||||||
halfrate = state->halfrate;
|
|
||||||
fdecay = (63 + 20 * ((state->bai >> 7) & 3)) >> halfrate; /* fdcycod */
|
|
||||||
fgain = 128 + 128 * (ba->bai & 7); /* fgaincod */
|
|
||||||
sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate; /* sdcycod */
|
|
||||||
sgain = slowgain[(state->bai >> 5) & 3]; /* sgaincod */
|
|
||||||
dbknee = dbpbtab[(state->bai >> 3) & 3]; /* dbpbcod */
|
|
||||||
hth = hthtab[state->fscod];
|
|
||||||
/*
|
|
||||||
* if there is no delta bit allocation, make deltba point to an area
|
|
||||||
* known to contain zeroes. baptab+156 here.
|
|
||||||
*/
|
|
||||||
deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
|
|
||||||
floor = floortab[state->bai & 7]; /* floorcod */
|
|
||||||
snroffset = 960 - 64 * state->csnroffst - 4 * (ba->bai >> 3) + floor;
|
|
||||||
floor >>= 5;
|
|
||||||
|
|
||||||
exp = expbap->exp;
|
|
||||||
bap = expbap->bap;
|
|
||||||
|
|
||||||
i = bndstart;
|
|
||||||
j = start;
|
|
||||||
if (start == 0) { /* not the coupling channel */
|
|
||||||
int lowcomp;
|
|
||||||
|
|
||||||
lowcomp = 0;
|
|
||||||
j = end - 1;
|
|
||||||
do {
|
|
||||||
if (i < j) {
|
|
||||||
if (exp[i+1] == exp[i] - 2)
|
|
||||||
lowcomp = 384;
|
|
||||||
else if (lowcomp && (exp[i+1] > exp[i]))
|
|
||||||
lowcomp -= 64;
|
|
||||||
}
|
|
||||||
psd = 128 * exp[i];
|
|
||||||
mask = psd + fgain + lowcomp;
|
|
||||||
COMPUTE_MASK ();
|
|
||||||
bap[i] = (baptab+156)[mask + 4 * exp[i]];
|
|
||||||
i++;
|
|
||||||
} while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1])));
|
|
||||||
fastleak = psd + fgain;
|
|
||||||
slowleak = psd + sgain;
|
|
||||||
|
|
||||||
while (i < 7) {
|
|
||||||
if (i < j) {
|
|
||||||
if (exp[i+1] == exp[i] - 2)
|
|
||||||
lowcomp = 384;
|
|
||||||
else if (lowcomp && (exp[i+1] > exp[i]))
|
|
||||||
lowcomp -= 64;
|
|
||||||
}
|
|
||||||
psd = 128 * exp[i];
|
|
||||||
UPDATE_LEAK ();
|
|
||||||
mask = ((fastleak + lowcomp < slowleak) ?
|
|
||||||
fastleak + lowcomp : slowleak);
|
|
||||||
COMPUTE_MASK ();
|
|
||||||
bap[i] = (baptab+156)[mask + 4 * exp[i]];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end == 7) /* lfe channel */
|
|
||||||
return;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (exp[i+1] == exp[i] - 2)
|
|
||||||
lowcomp = 320;
|
|
||||||
else if (lowcomp && (exp[i+1] > exp[i]))
|
|
||||||
lowcomp -= 64;
|
|
||||||
psd = 128 * exp[i];
|
|
||||||
UPDATE_LEAK ();
|
|
||||||
mask = ((fastleak + lowcomp < slowleak) ?
|
|
||||||
fastleak + lowcomp : slowleak);
|
|
||||||
COMPUTE_MASK ();
|
|
||||||
bap[i] = (baptab+156)[mask + 4 * exp[i]];
|
|
||||||
i++;
|
|
||||||
} while (i < 20);
|
|
||||||
|
|
||||||
while (lowcomp > 128) { /* two iterations maximum */
|
|
||||||
lowcomp -= 128;
|
|
||||||
psd = 128 * exp[i];
|
|
||||||
UPDATE_LEAK ();
|
|
||||||
mask = ((fastleak + lowcomp < slowleak) ?
|
|
||||||
fastleak + lowcomp : slowleak);
|
|
||||||
COMPUTE_MASK ();
|
|
||||||
bap[i] = (baptab+156)[mask + 4 * exp[i]];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
j = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
int startband, endband;
|
|
||||||
|
|
||||||
startband = j;
|
|
||||||
endband = ((bndtab-20)[i] < end) ? (bndtab-20)[i] : end;
|
|
||||||
psd = 128 * exp[j++];
|
|
||||||
while (j < endband) {
|
|
||||||
int next, delta;
|
|
||||||
|
|
||||||
next = 128 * exp[j++];
|
|
||||||
delta = next - psd;
|
|
||||||
switch (delta >> 9) {
|
|
||||||
case -6: case -5: case -4: case -3: case -2:
|
|
||||||
psd = next;
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
psd = next + latab[(-delta) >> 1];
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
psd += latab[delta >> 1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* minpsd = -289 */
|
|
||||||
UPDATE_LEAK ();
|
|
||||||
mask = (fastleak < slowleak) ? fastleak : slowleak;
|
|
||||||
COMPUTE_MASK ();
|
|
||||||
i++;
|
|
||||||
j = startband;
|
|
||||||
do {
|
|
||||||
/* max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp */
|
|
||||||
/* min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 */
|
|
||||||
bap[j] = (baptab+156)[mask + 4 * exp[j]];
|
|
||||||
} while (++j < endband);
|
|
||||||
} while (j < end);
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
* bitstream.c
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "inttypes.h"
|
|
||||||
|
|
||||||
#include "a52.h"
|
|
||||||
#include "a52_internal.h"
|
|
||||||
#include "bitstream.h"
|
|
||||||
|
|
||||||
#define BUFFER_SIZE 4096
|
|
||||||
|
|
||||||
void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf)
|
|
||||||
{
|
|
||||||
int align;
|
|
||||||
|
|
||||||
align = (long)buf & 3;
|
|
||||||
state->buffer_start = (uint32_t *) (buf - align);
|
|
||||||
state->bits_left = 0;
|
|
||||||
bitstream_get (state, align * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bitstream_fill_current (a52_state_t * state)
|
|
||||||
{
|
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
tmp = *(state->buffer_start++);
|
|
||||||
state->current_word = swab32 (tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The fast paths for _get is in the
|
|
||||||
* bitstream.h header file so it can be inlined.
|
|
||||||
*
|
|
||||||
* The "bottom half" of this routine is suffixed _bh
|
|
||||||
*
|
|
||||||
* -ah
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
num_bits -= state->bits_left;
|
|
||||||
result = ((state->current_word << (32 - state->bits_left)) >>
|
|
||||||
(32 - state->bits_left));
|
|
||||||
|
|
||||||
bitstream_fill_current (state);
|
|
||||||
|
|
||||||
if (num_bits != 0)
|
|
||||||
result = (result << num_bits) | (state->current_word >> (32 - num_bits));
|
|
||||||
|
|
||||||
state->bits_left = 32 - num_bits;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
num_bits -= state->bits_left;
|
|
||||||
result = ((((int32_t)state->current_word) << (32 - state->bits_left)) >>
|
|
||||||
(32 - state->bits_left));
|
|
||||||
|
|
||||||
bitstream_fill_current(state);
|
|
||||||
|
|
||||||
if (num_bits != 0)
|
|
||||||
result = (result << num_bits) | (state->current_word >> (32 - num_bits));
|
|
||||||
|
|
||||||
state->bits_left = 32 - num_bits;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
* bitstream.h
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* (stolen from the kernel) */
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
|
|
||||||
# define swab32(x) (x)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
# if 0 && defined (__i386__)
|
|
||||||
|
|
||||||
# define swab32(x) __i386_swab32(x)
|
|
||||||
static inline const uint32_t __i386_swab32(uint32_t x)
|
|
||||||
{
|
|
||||||
__asm__("bswap %0" : "=r" (x) : "0" (x));
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
# else
|
|
||||||
|
|
||||||
# define swab32(x)\
|
|
||||||
((((uint8_t*)&x)[0] << 24) | (((uint8_t*)&x)[1] << 16) | \
|
|
||||||
(((uint8_t*)&x)[2] << 8) | (((uint8_t*)&x)[3]))
|
|
||||||
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf);
|
|
||||||
uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits);
|
|
||||||
int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits);
|
|
||||||
|
|
||||||
static inline uint32_t bitstream_get (a52_state_t * state, uint32_t num_bits)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
if (num_bits < state->bits_left) {
|
|
||||||
result = (state->current_word << (32 - state->bits_left)) >> (32 - num_bits);
|
|
||||||
state->bits_left -= num_bits;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a52_bitstream_get_bh (state, num_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t bitstream_get_2 (a52_state_t * state, uint32_t num_bits)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
if (num_bits < state->bits_left) {
|
|
||||||
result = (((int32_t)state->current_word) << (32 - state->bits_left)) >> (32 - num_bits);
|
|
||||||
state->bits_left -= num_bits;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a52_bitstream_get_bh_2 (state, num_bits);
|
|
||||||
}
|
|
|
@ -1,124 +0,0 @@
|
||||||
/* vc++/config.h - manually adapted from include/config.h.in */
|
|
||||||
|
|
||||||
/* maximum supported data alignment */
|
|
||||||
/* #undef ATTRIBUTE_ALIGNED_MAX */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
|
||||||
/* #undef HAVE_DLFCN_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `ftime' function. */
|
|
||||||
#define HAVE_FTIME 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `gettimeofday' function. */
|
|
||||||
/* #undef HAVE_GETTIMEOFDAY */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
|
||||||
/* #undef HAVE_INTTYPES_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <io.h> header file. */
|
|
||||||
#define HAVE_IO_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `memalign' function. */
|
|
||||||
/* #undef HAVE_MEMALIGN */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
|
||||||
#define HAVE_MEMORY_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
|
||||||
/* #undef HAVE_STDINT_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
|
||||||
#define HAVE_STDLIB_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <strings.h> header file. */
|
|
||||||
/* #undef HAVE_STRINGS_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> header file. */
|
|
||||||
#define HAVE_STRING_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#define HAVE_SYS_STAT_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/timeb.h> header file. */
|
|
||||||
#define HAVE_SYS_TIMEB_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
|
||||||
/* #undef HAVE_SYS_TIME_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#define HAVE_SYS_TYPES_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
/* #undef HAVE_UNISTD_H */
|
|
||||||
|
|
||||||
/* liba52 djbfft support */
|
|
||||||
/* #undef LIBA52_DJBFFT */
|
|
||||||
|
|
||||||
/* a52 sample precision */
|
|
||||||
/* #undef LIBA52_DOUBLE */
|
|
||||||
|
|
||||||
/* libao al support */
|
|
||||||
/* #undef LIBAO_AL */
|
|
||||||
|
|
||||||
/* libao OSS support */
|
|
||||||
/* #undef LIBAO_OSS */
|
|
||||||
|
|
||||||
/* libao solaris support */
|
|
||||||
/* #undef LIBAO_SOLARIS */
|
|
||||||
|
|
||||||
/* libao win support */
|
|
||||||
#define LIBAO_WIN
|
|
||||||
|
|
||||||
/* Name of package */
|
|
||||||
#define PACKAGE "a52dec"
|
|
||||||
|
|
||||||
/* Define to the address where bug reports for this package should be sent. */
|
|
||||||
#define PACKAGE_BUGREPORT ""
|
|
||||||
|
|
||||||
/* Define to the full name of this package. */
|
|
||||||
#define PACKAGE_NAME ""
|
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
|
||||||
#define PACKAGE_STRING ""
|
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
|
||||||
#define PACKAGE_TARNAME ""
|
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
|
||||||
#define PACKAGE_VERSION ""
|
|
||||||
|
|
||||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
|
||||||
#define RETSIGTYPE void
|
|
||||||
|
|
||||||
/* The size of a `char', as computed by sizeof. */
|
|
||||||
#define SIZEOF_CHAR 1
|
|
||||||
|
|
||||||
/* The size of a `int', as computed by sizeof. */
|
|
||||||
#define SIZEOF_INT 4
|
|
||||||
|
|
||||||
/* The size of a `short', as computed by sizeof. */
|
|
||||||
#define SIZEOF_SHORT 2
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
|
||||||
#define STDC_HEADERS 1
|
|
||||||
|
|
||||||
/* Version number of package */
|
|
||||||
#define VERSION "0.7.4-cvs"
|
|
||||||
|
|
||||||
/* Define to 1 if your processor stores words with the most significant byte
|
|
||||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
|
||||||
/* #undef WORDS_BIGENDIAN */
|
|
||||||
|
|
||||||
/* Define to empty if `const' does not conform to ANSI C. */
|
|
||||||
/* #undef const */
|
|
||||||
|
|
||||||
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
|
|
||||||
if it is not supported. */
|
|
||||||
#define inline __inline
|
|
||||||
|
|
||||||
/* Define as `__restrict' if that's what the C compiler calls it, or to
|
|
||||||
nothing if it is not supported. */
|
|
||||||
#define restrict /*__restrict*/
|
|
||||||
|
|
||||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
|
||||||
/* #undef size_t */
|
|
|
@ -1,19 +0,0 @@
|
||||||
AC_SUBST([LIBA52_CFLAGS])
|
|
||||||
AC_SUBST([LIBA52_LIBS])
|
|
||||||
|
|
||||||
dnl avoid -fPIC when possible
|
|
||||||
LIBA52_CFLAGS="$LIBA52_CFLAGS -prefer-non-pic"
|
|
||||||
|
|
||||||
AC_ARG_ENABLE([double],
|
|
||||||
[ --enable-double use double-precision samples])
|
|
||||||
if test x"$enable_double" = x"yes"; then
|
|
||||||
AC_DEFINE([LIBA52_DOUBLE],,[a52 sample precision])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl check for djbttf
|
|
||||||
AC_ARG_ENABLE([djbfft],
|
|
||||||
[ --enable-djbfft make a version using djbfft])
|
|
||||||
if test x"$enable_djbfft" = x"yes"; then
|
|
||||||
AC_DEFINE([LIBA52_DJBFFT],,[liba52 djbfft support])
|
|
||||||
LIBA52_LIBS="$LIBA52_LIBS -ldjbfft"
|
|
||||||
fi
|
|
|
@ -1,655 +0,0 @@
|
||||||
/*
|
|
||||||
* downmix.c
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#pragma warning(disable:4244)
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "inttypes.h"
|
|
||||||
|
|
||||||
#include "a52.h"
|
|
||||||
#include "a52_internal.h"
|
|
||||||
|
|
||||||
#define CONVERT(acmod,output) (((output) << 3) + (acmod))
|
|
||||||
|
|
||||||
int a52_downmix_init (int input, int flags, sample_t * level,
|
|
||||||
sample_t clev, sample_t slev)
|
|
||||||
{
|
|
||||||
static uint8_t table[11][8] = {
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
|
|
||||||
A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO},
|
|
||||||
{A52_MONO, A52_MONO, A52_MONO, A52_MONO,
|
|
||||||
A52_MONO, A52_MONO, A52_MONO, A52_MONO},
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
|
|
||||||
A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO},
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
|
|
||||||
A52_STEREO, A52_3F, A52_STEREO, A52_3F},
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
|
|
||||||
A52_2F1R, A52_2F1R, A52_2F1R, A52_2F1R},
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO,
|
|
||||||
A52_2F1R, A52_3F1R, A52_2F1R, A52_3F1R},
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
|
|
||||||
A52_2F2R, A52_2F2R, A52_2F2R, A52_2F2R},
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F,
|
|
||||||
A52_2F2R, A52_3F2R, A52_2F2R, A52_3F2R},
|
|
||||||
{A52_CHANNEL1, A52_MONO, A52_MONO, A52_MONO,
|
|
||||||
A52_MONO, A52_MONO, A52_MONO, A52_MONO},
|
|
||||||
{A52_CHANNEL2, A52_MONO, A52_MONO, A52_MONO,
|
|
||||||
A52_MONO, A52_MONO, A52_MONO, A52_MONO},
|
|
||||||
{A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_DOLBY,
|
|
||||||
A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY}
|
|
||||||
};
|
|
||||||
int output;
|
|
||||||
|
|
||||||
output = flags & A52_CHANNEL_MASK;
|
|
||||||
if (output > A52_DOLBY)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
output = table[output][input & 7];
|
|
||||||
|
|
||||||
if ((output == A52_STEREO) &&
|
|
||||||
((input == A52_DOLBY) || ((input == A52_3F) && (clev == LEVEL_3DB))))
|
|
||||||
output = A52_DOLBY;
|
|
||||||
|
|
||||||
if (flags & A52_ADJUST_LEVEL)
|
|
||||||
switch (CONVERT (input & 7, output)) {
|
|
||||||
|
|
||||||
case CONVERT (A52_3F, A52_MONO):
|
|
||||||
*level *= LEVEL_3DB / (1 + clev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_STEREO, A52_MONO):
|
|
||||||
case CONVERT (A52_2F2R, A52_2F1R):
|
|
||||||
case CONVERT (A52_3F2R, A52_3F1R):
|
|
||||||
level_3db:
|
|
||||||
*level *= LEVEL_3DB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_2F1R):
|
|
||||||
if (clev < LEVEL_PLUS3DB - 1)
|
|
||||||
goto level_3db;
|
|
||||||
/* break thru */
|
|
||||||
case CONVERT (A52_3F, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F1R, A52_2F1R):
|
|
||||||
case CONVERT (A52_3F1R, A52_2F2R):
|
|
||||||
case CONVERT (A52_3F2R, A52_2F2R):
|
|
||||||
*level /= 1 + clev;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_MONO):
|
|
||||||
*level *= LEVEL_PLUS3DB / (2 + slev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F1R, A52_3F):
|
|
||||||
*level /= 1 + slev * LEVEL_3DB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_MONO):
|
|
||||||
*level *= LEVEL_3DB / (1 + clev + 0.5 * slev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_STEREO):
|
|
||||||
*level /= 1 + clev + slev * LEVEL_3DB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_MONO):
|
|
||||||
*level *= LEVEL_3DB / (1 + slev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F2R, A52_3F):
|
|
||||||
*level /= 1 + slev;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_MONO):
|
|
||||||
*level *= LEVEL_3DB / (1 + clev + slev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_STEREO):
|
|
||||||
*level /= 1 + clev + slev;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_MONO, A52_DOLBY):
|
|
||||||
*level *= LEVEL_PLUS3DB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F, A52_DOLBY):
|
|
||||||
case CONVERT (A52_2F1R, A52_DOLBY):
|
|
||||||
*level *= 1 / (1 + LEVEL_3DB);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_DOLBY):
|
|
||||||
case CONVERT (A52_2F2R, A52_DOLBY):
|
|
||||||
*level *= 1 / (1 + 2 * LEVEL_3DB);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_DOLBY):
|
|
||||||
*level *= 1 / (1 + 3 * LEVEL_3DB);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level,
|
|
||||||
sample_t clev, sample_t slev)
|
|
||||||
{
|
|
||||||
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
|
|
||||||
|
|
||||||
case CONVERT (A52_CHANNEL, A52_CHANNEL):
|
|
||||||
case CONVERT (A52_MONO, A52_MONO):
|
|
||||||
case CONVERT (A52_STEREO, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F, A52_3F):
|
|
||||||
case CONVERT (A52_2F1R, A52_2F1R):
|
|
||||||
case CONVERT (A52_3F1R, A52_3F1R):
|
|
||||||
case CONVERT (A52_2F2R, A52_2F2R):
|
|
||||||
case CONVERT (A52_3F2R, A52_3F2R):
|
|
||||||
case CONVERT (A52_STEREO, A52_DOLBY):
|
|
||||||
coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case CONVERT (A52_CHANNEL, A52_MONO):
|
|
||||||
coeff[0] = coeff[1] = level * LEVEL_6DB;
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
case CONVERT (A52_STEREO, A52_MONO):
|
|
||||||
coeff[0] = coeff[1] = level * LEVEL_3DB;
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F, A52_MONO):
|
|
||||||
coeff[0] = coeff[2] = level * LEVEL_3DB;
|
|
||||||
coeff[1] = level * clev * LEVEL_PLUS3DB;
|
|
||||||
return 7;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_MONO):
|
|
||||||
coeff[0] = coeff[1] = level * LEVEL_3DB;
|
|
||||||
coeff[2] = level * slev * LEVEL_3DB;
|
|
||||||
return 7;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_MONO):
|
|
||||||
coeff[0] = coeff[1] = level * LEVEL_3DB;
|
|
||||||
coeff[2] = coeff[3] = level * slev * LEVEL_3DB;
|
|
||||||
return 15;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_MONO):
|
|
||||||
coeff[0] = coeff[2] = level * LEVEL_3DB;
|
|
||||||
coeff[1] = level * clev * LEVEL_PLUS3DB;
|
|
||||||
coeff[3] = level * slev * LEVEL_3DB;
|
|
||||||
return 15;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_MONO):
|
|
||||||
coeff[0] = coeff[2] = level * LEVEL_3DB;
|
|
||||||
coeff[1] = level * clev * LEVEL_PLUS3DB;
|
|
||||||
coeff[3] = coeff[4] = level * slev * LEVEL_3DB;
|
|
||||||
return 31;
|
|
||||||
|
|
||||||
case CONVERT (A52_MONO, A52_DOLBY):
|
|
||||||
coeff[0] = level * LEVEL_3DB;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F, A52_DOLBY):
|
|
||||||
clev = LEVEL_3DB;
|
|
||||||
case CONVERT (A52_3F, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F1R, A52_2F1R):
|
|
||||||
case CONVERT (A52_3F2R, A52_2F2R):
|
|
||||||
coeff[0] = coeff[2] = coeff[3] = coeff[4] = level;
|
|
||||||
coeff[1] = level * clev;
|
|
||||||
return 7;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_DOLBY):
|
|
||||||
slev = 1;
|
|
||||||
case CONVERT (A52_2F1R, A52_STEREO):
|
|
||||||
coeff[0] = coeff[1] = level;
|
|
||||||
coeff[2] = level * slev * LEVEL_3DB;
|
|
||||||
return 7;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_DOLBY):
|
|
||||||
clev = LEVEL_3DB;
|
|
||||||
slev = 1;
|
|
||||||
case CONVERT (A52_3F1R, A52_STEREO):
|
|
||||||
coeff[0] = coeff[2] = level;
|
|
||||||
coeff[1] = level * clev;
|
|
||||||
coeff[3] = level * slev * LEVEL_3DB;
|
|
||||||
return 15;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_DOLBY):
|
|
||||||
slev = LEVEL_3DB;
|
|
||||||
case CONVERT (A52_2F2R, A52_STEREO):
|
|
||||||
coeff[0] = coeff[1] = level;
|
|
||||||
coeff[2] = coeff[3] = level * slev;
|
|
||||||
return 15;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_DOLBY):
|
|
||||||
clev = LEVEL_3DB;
|
|
||||||
case CONVERT (A52_3F2R, A52_2F1R):
|
|
||||||
slev = LEVEL_3DB;
|
|
||||||
case CONVERT (A52_3F2R, A52_STEREO):
|
|
||||||
coeff[0] = coeff[2] = level;
|
|
||||||
coeff[1] = level * clev;
|
|
||||||
coeff[3] = coeff[4] = level * slev;
|
|
||||||
return 31;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_3F):
|
|
||||||
coeff[0] = coeff[1] = coeff[2] = level;
|
|
||||||
coeff[3] = level * slev * LEVEL_3DB;
|
|
||||||
return 13;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_3F):
|
|
||||||
coeff[0] = coeff[1] = coeff[2] = level;
|
|
||||||
coeff[3] = coeff[4] = level * slev;
|
|
||||||
return 29;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_2F1R):
|
|
||||||
coeff[0] = coeff[1] = level;
|
|
||||||
coeff[2] = coeff[3] = level * LEVEL_3DB;
|
|
||||||
return 12;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_3F1R):
|
|
||||||
coeff[0] = coeff[1] = coeff[2] = level;
|
|
||||||
coeff[3] = coeff[4] = level * LEVEL_3DB;
|
|
||||||
return 24;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_2F2R):
|
|
||||||
coeff[0] = coeff[1] = level;
|
|
||||||
coeff[2] = level * LEVEL_3DB;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_2F2R):
|
|
||||||
coeff[0] = coeff[2] = level;
|
|
||||||
coeff[1] = level * clev;
|
|
||||||
coeff[3] = level * LEVEL_3DB;
|
|
||||||
return 7;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_3F2R):
|
|
||||||
coeff[0] = coeff[1] = coeff[2] = level;
|
|
||||||
coeff[3] = level * LEVEL_3DB;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case CONVERT (A52_CHANNEL, A52_CHANNEL1):
|
|
||||||
coeff[0] = level;
|
|
||||||
coeff[1] = 0;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case CONVERT (A52_CHANNEL, A52_CHANNEL2):
|
|
||||||
coeff[0] = 0;
|
|
||||||
coeff[1] = level;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1; /* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
dest[i] += src[i] + bias;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix3to1 (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
samples[i] += samples[i + 256] + samples[i + 512] + bias;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix4to1 (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
samples[i] += (samples[i + 256] + samples[i + 512] +
|
|
||||||
samples[i + 768] + bias);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix5to1 (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
samples[i] += (samples[i + 256] + samples[i + 512] +
|
|
||||||
samples[i + 768] + samples[i + 1024] + bias);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix3to2 (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t common;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
common = samples[i + 256] + bias;
|
|
||||||
samples[i] += common;
|
|
||||||
samples[i + 256] = samples[i + 512] + common;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix21to2 (sample_t * left, sample_t * right, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t common;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
common = right[i + 256] + bias;
|
|
||||||
left[i] += common;
|
|
||||||
right[i] += common;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix21toS (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t surround;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
surround = samples[i + 512];
|
|
||||||
samples[i] += bias - surround;
|
|
||||||
samples[i + 256] += bias + surround;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix31to2 (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t common;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
common = samples[i + 256] + samples[i + 768] + bias;
|
|
||||||
samples[i] += common;
|
|
||||||
samples[i + 256] = samples[i + 512] + common;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix31toS (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t common, surround;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
common = samples[i + 256] + bias;
|
|
||||||
surround = samples[i + 768];
|
|
||||||
samples[i] += common - surround;
|
|
||||||
samples[i + 256] = samples[i + 512] + common + surround;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix22toS (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t surround;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
surround = samples[i + 512] + samples[i + 768];
|
|
||||||
samples[i] += bias - surround;
|
|
||||||
samples[i + 256] += bias + surround;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix32to2 (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t common;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
common = samples[i + 256] + bias;
|
|
||||||
samples[i] += common + samples[i + 768];
|
|
||||||
samples[i + 256] = common + samples[i + 512] + samples[i + 1024];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mix32toS (sample_t * samples, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sample_t common, surround;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
common = samples[i + 256] + bias;
|
|
||||||
surround = samples[i + 768] + samples[i + 1024];
|
|
||||||
samples[i] += common - surround;
|
|
||||||
samples[i + 256] = samples[i + 512] + common + surround;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void move2to1 (sample_t * src, sample_t * dest, sample_t bias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
dest[i] = src[i] + src[i + 256] + bias;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zero (sample_t * samples)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
samples[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
|
|
||||||
sample_t clev, sample_t slev)
|
|
||||||
{
|
|
||||||
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
|
|
||||||
|
|
||||||
case CONVERT (A52_CHANNEL, A52_CHANNEL2):
|
|
||||||
memcpy (samples, samples + 256, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_CHANNEL, A52_MONO):
|
|
||||||
case CONVERT (A52_STEREO, A52_MONO):
|
|
||||||
mix_2to1:
|
|
||||||
mix2to1 (samples, samples + 256, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_MONO):
|
|
||||||
if (slev == 0)
|
|
||||||
goto mix_2to1;
|
|
||||||
case CONVERT (A52_3F, A52_MONO):
|
|
||||||
mix_3to1:
|
|
||||||
mix3to1 (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_MONO):
|
|
||||||
if (slev == 0)
|
|
||||||
goto mix_3to1;
|
|
||||||
case CONVERT (A52_2F2R, A52_MONO):
|
|
||||||
if (slev == 0)
|
|
||||||
goto mix_2to1;
|
|
||||||
mix4to1 (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_MONO):
|
|
||||||
if (slev == 0)
|
|
||||||
goto mix_3to1;
|
|
||||||
mix5to1 (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_MONO, A52_DOLBY):
|
|
||||||
memcpy (samples + 256, samples, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F, A52_DOLBY):
|
|
||||||
mix_3to2:
|
|
||||||
mix3to2 (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_STEREO):
|
|
||||||
if (slev == 0)
|
|
||||||
break;
|
|
||||||
mix21to2 (samples, samples + 256, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_DOLBY):
|
|
||||||
mix21toS (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_STEREO):
|
|
||||||
if (slev == 0)
|
|
||||||
goto mix_3to2;
|
|
||||||
mix31to2 (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_DOLBY):
|
|
||||||
mix31toS (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_STEREO):
|
|
||||||
if (slev == 0)
|
|
||||||
break;
|
|
||||||
mix2to1 (samples, samples + 512, bias);
|
|
||||||
mix2to1 (samples + 256, samples + 768, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_DOLBY):
|
|
||||||
mix22toS (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_STEREO):
|
|
||||||
if (slev == 0)
|
|
||||||
goto mix_3to2;
|
|
||||||
mix32to2 (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_DOLBY):
|
|
||||||
mix32toS (samples, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_3F):
|
|
||||||
if (slev == 0)
|
|
||||||
break;
|
|
||||||
mix21to2 (samples, samples + 512, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_3F):
|
|
||||||
if (slev == 0)
|
|
||||||
break;
|
|
||||||
mix2to1 (samples, samples + 768, bias);
|
|
||||||
mix2to1 (samples + 512, samples + 1024, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_2F1R):
|
|
||||||
mix3to2 (samples, bias);
|
|
||||||
memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_2F1R):
|
|
||||||
mix2to1 (samples + 512, samples + 768, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_2F1R):
|
|
||||||
mix3to2 (samples, bias);
|
|
||||||
move2to1 (samples + 768, samples + 512, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_3F1R):
|
|
||||||
mix2to1 (samples + 768, samples + 1024, bias);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F1R, A52_2F2R):
|
|
||||||
memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_2F2R):
|
|
||||||
mix3to2 (samples, bias);
|
|
||||||
memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_2F2R):
|
|
||||||
mix3to2 (samples, bias);
|
|
||||||
memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
|
|
||||||
memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F1R, A52_3F2R):
|
|
||||||
memcpy (samples + 1027, samples + 768, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void a52_upmix (sample_t * samples, int acmod, int output)
|
|
||||||
{
|
|
||||||
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
|
|
||||||
|
|
||||||
case CONVERT (A52_CHANNEL, A52_CHANNEL2):
|
|
||||||
memcpy (samples + 256, samples, 256 * sizeof (sample_t));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_MONO):
|
|
||||||
zero (samples + 1024);
|
|
||||||
case CONVERT (A52_3F1R, A52_MONO):
|
|
||||||
case CONVERT (A52_2F2R, A52_MONO):
|
|
||||||
zero (samples + 768);
|
|
||||||
case CONVERT (A52_3F, A52_MONO):
|
|
||||||
case CONVERT (A52_2F1R, A52_MONO):
|
|
||||||
zero (samples + 512);
|
|
||||||
case CONVERT (A52_CHANNEL, A52_MONO):
|
|
||||||
case CONVERT (A52_STEREO, A52_MONO):
|
|
||||||
zero (samples + 256);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F2R, A52_DOLBY):
|
|
||||||
zero (samples + 1024);
|
|
||||||
case CONVERT (A52_3F1R, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F1R, A52_DOLBY):
|
|
||||||
zero (samples + 768);
|
|
||||||
case CONVERT (A52_3F, A52_STEREO):
|
|
||||||
case CONVERT (A52_3F, A52_DOLBY):
|
|
||||||
mix_3to2:
|
|
||||||
memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t));
|
|
||||||
zero (samples + 256);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_2F2R, A52_STEREO):
|
|
||||||
case CONVERT (A52_2F2R, A52_DOLBY):
|
|
||||||
zero (samples + 768);
|
|
||||||
case CONVERT (A52_2F1R, A52_STEREO):
|
|
||||||
case CONVERT (A52_2F1R, A52_DOLBY):
|
|
||||||
zero (samples + 512);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_3F):
|
|
||||||
zero (samples + 1024);
|
|
||||||
case CONVERT (A52_3F1R, A52_3F):
|
|
||||||
case CONVERT (A52_2F2R, A52_2F1R):
|
|
||||||
zero (samples + 768);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_3F1R):
|
|
||||||
zero (samples + 1024);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_2F1R):
|
|
||||||
zero (samples + 1024);
|
|
||||||
case CONVERT (A52_3F1R, A52_2F1R):
|
|
||||||
mix_31to21:
|
|
||||||
memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
|
|
||||||
goto mix_3to2;
|
|
||||||
|
|
||||||
case CONVERT (A52_3F2R, A52_2F2R):
|
|
||||||
memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
|
|
||||||
goto mix_31to21;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,432 +0,0 @@
|
||||||
/*
|
|
||||||
* imdct.c
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* The ifft algorithms in this file have been largely inspired by Dan
|
|
||||||
* Bernstein's work, djbfft, available at http://cr.yp.to/djbfft.html
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#pragma warning(disable:4244)
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#ifdef LIBA52_DJBFFT
|
|
||||||
#include <fftc4.h>
|
|
||||||
#endif
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.1415926535897932384626433832795029
|
|
||||||
#endif
|
|
||||||
#include "inttypes.h"
|
|
||||||
|
|
||||||
#include "a52.h"
|
|
||||||
#include "a52_internal.h"
|
|
||||||
#include "mm_accel.h"
|
|
||||||
|
|
||||||
typedef struct complex_s {
|
|
||||||
sample_t real;
|
|
||||||
sample_t imag;
|
|
||||||
} complex_t;
|
|
||||||
|
|
||||||
static uint8_t fftorder[] = {
|
|
||||||
0,128, 64,192, 32,160,224, 96, 16,144, 80,208,240,112, 48,176,
|
|
||||||
8,136, 72,200, 40,168,232,104,248,120, 56,184, 24,152,216, 88,
|
|
||||||
4,132, 68,196, 36,164,228,100, 20,148, 84,212,244,116, 52,180,
|
|
||||||
252,124, 60,188, 28,156,220, 92, 12,140, 76,204,236,108, 44,172,
|
|
||||||
2,130, 66,194, 34,162,226, 98, 18,146, 82,210,242,114, 50,178,
|
|
||||||
10,138, 74,202, 42,170,234,106,250,122, 58,186, 26,154,218, 90,
|
|
||||||
254,126, 62,190, 30,158,222, 94, 14,142, 78,206,238,110, 46,174,
|
|
||||||
6,134, 70,198, 38,166,230,102,246,118, 54,182, 22,150,214, 86
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Root values for IFFT */
|
|
||||||
static sample_t roots16[3];
|
|
||||||
static sample_t roots32[7];
|
|
||||||
static sample_t roots64[15];
|
|
||||||
static sample_t roots128[31];
|
|
||||||
|
|
||||||
/* Twiddle factors for IMDCT */
|
|
||||||
static complex_t pre1[128];
|
|
||||||
static complex_t post1[64];
|
|
||||||
static complex_t pre2[64];
|
|
||||||
static complex_t post2[32];
|
|
||||||
|
|
||||||
static sample_t a52_imdct_window[256];
|
|
||||||
|
|
||||||
static void (* ifft128) (complex_t * buf);
|
|
||||||
static void (* ifft64) (complex_t * buf);
|
|
||||||
|
|
||||||
static inline void ifft2 (complex_t * buf)
|
|
||||||
{
|
|
||||||
double r, i;
|
|
||||||
|
|
||||||
r = buf[0].real;
|
|
||||||
i = buf[0].imag;
|
|
||||||
buf[0].real += buf[1].real;
|
|
||||||
buf[0].imag += buf[1].imag;
|
|
||||||
buf[1].real = r - buf[1].real;
|
|
||||||
buf[1].imag = i - buf[1].imag;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ifft4 (complex_t * buf)
|
|
||||||
{
|
|
||||||
double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
|
|
||||||
|
|
||||||
tmp1 = buf[0].real + buf[1].real;
|
|
||||||
tmp2 = buf[3].real + buf[2].real;
|
|
||||||
tmp3 = buf[0].imag + buf[1].imag;
|
|
||||||
tmp4 = buf[2].imag + buf[3].imag;
|
|
||||||
tmp5 = buf[0].real - buf[1].real;
|
|
||||||
tmp6 = buf[0].imag - buf[1].imag;
|
|
||||||
tmp7 = buf[2].imag - buf[3].imag;
|
|
||||||
tmp8 = buf[3].real - buf[2].real;
|
|
||||||
|
|
||||||
buf[0].real = tmp1 + tmp2;
|
|
||||||
buf[0].imag = tmp3 + tmp4;
|
|
||||||
buf[2].real = tmp1 - tmp2;
|
|
||||||
buf[2].imag = tmp3 - tmp4;
|
|
||||||
buf[1].real = tmp5 + tmp7;
|
|
||||||
buf[1].imag = tmp6 + tmp8;
|
|
||||||
buf[3].real = tmp5 - tmp7;
|
|
||||||
buf[3].imag = tmp6 - tmp8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the basic split-radix ifft butterfly */
|
|
||||||
|
|
||||||
#define BUTTERFLY(a0,a1,a2,a3,wr,wi) do { \
|
|
||||||
tmp5 = a2.real * wr + a2.imag * wi; \
|
|
||||||
tmp6 = a2.imag * wr - a2.real * wi; \
|
|
||||||
tmp7 = a3.real * wr - a3.imag * wi; \
|
|
||||||
tmp8 = a3.imag * wr + a3.real * wi; \
|
|
||||||
tmp1 = tmp5 + tmp7; \
|
|
||||||
tmp2 = tmp6 + tmp8; \
|
|
||||||
tmp3 = tmp6 - tmp8; \
|
|
||||||
tmp4 = tmp7 - tmp5; \
|
|
||||||
a2.real = a0.real - tmp1; \
|
|
||||||
a2.imag = a0.imag - tmp2; \
|
|
||||||
a3.real = a1.real - tmp3; \
|
|
||||||
a3.imag = a1.imag - tmp4; \
|
|
||||||
a0.real += tmp1; \
|
|
||||||
a0.imag += tmp2; \
|
|
||||||
a1.real += tmp3; \
|
|
||||||
a1.imag += tmp4; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* split-radix ifft butterfly, specialized for wr=1 wi=0 */
|
|
||||||
|
|
||||||
#define BUTTERFLY_ZERO(a0,a1,a2,a3) do { \
|
|
||||||
tmp1 = a2.real + a3.real; \
|
|
||||||
tmp2 = a2.imag + a3.imag; \
|
|
||||||
tmp3 = a2.imag - a3.imag; \
|
|
||||||
tmp4 = a3.real - a2.real; \
|
|
||||||
a2.real = a0.real - tmp1; \
|
|
||||||
a2.imag = a0.imag - tmp2; \
|
|
||||||
a3.real = a1.real - tmp3; \
|
|
||||||
a3.imag = a1.imag - tmp4; \
|
|
||||||
a0.real += tmp1; \
|
|
||||||
a0.imag += tmp2; \
|
|
||||||
a1.real += tmp3; \
|
|
||||||
a1.imag += tmp4; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* split-radix ifft butterfly, specialized for wr=wi */
|
|
||||||
|
|
||||||
#define BUTTERFLY_HALF(a0,a1,a2,a3,w) do { \
|
|
||||||
tmp5 = (a2.real + a2.imag) * w; \
|
|
||||||
tmp6 = (a2.imag - a2.real) * w; \
|
|
||||||
tmp7 = (a3.real - a3.imag) * w; \
|
|
||||||
tmp8 = (a3.imag + a3.real) * w; \
|
|
||||||
tmp1 = tmp5 + tmp7; \
|
|
||||||
tmp2 = tmp6 + tmp8; \
|
|
||||||
tmp3 = tmp6 - tmp8; \
|
|
||||||
tmp4 = tmp7 - tmp5; \
|
|
||||||
a2.real = a0.real - tmp1; \
|
|
||||||
a2.imag = a0.imag - tmp2; \
|
|
||||||
a3.real = a1.real - tmp3; \
|
|
||||||
a3.imag = a1.imag - tmp4; \
|
|
||||||
a0.real += tmp1; \
|
|
||||||
a0.imag += tmp2; \
|
|
||||||
a1.real += tmp3; \
|
|
||||||
a1.imag += tmp4; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
static inline void ifft8 (complex_t * buf)
|
|
||||||
{
|
|
||||||
double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
|
|
||||||
|
|
||||||
ifft4 (buf);
|
|
||||||
ifft2 (buf + 4);
|
|
||||||
ifft2 (buf + 6);
|
|
||||||
BUTTERFLY_ZERO (buf[0], buf[2], buf[4], buf[6]);
|
|
||||||
BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], roots16[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ifft_pass (complex_t * buf, sample_t * weight, int n)
|
|
||||||
{
|
|
||||||
complex_t * buf1;
|
|
||||||
complex_t * buf2;
|
|
||||||
complex_t * buf3;
|
|
||||||
double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
buf++;
|
|
||||||
buf1 = buf + n;
|
|
||||||
buf2 = buf + 2 * n;
|
|
||||||
buf3 = buf + 3 * n;
|
|
||||||
|
|
||||||
BUTTERFLY_ZERO (buf[-1], buf1[-1], buf2[-1], buf3[-1]);
|
|
||||||
|
|
||||||
i = n - 1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
BUTTERFLY (buf[0], buf1[0], buf2[0], buf3[0], weight[n], weight[2*i]);
|
|
||||||
buf++;
|
|
||||||
buf1++;
|
|
||||||
buf2++;
|
|
||||||
buf3++;
|
|
||||||
weight++;
|
|
||||||
} while (--i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ifft16 (complex_t * buf)
|
|
||||||
{
|
|
||||||
ifft8 (buf);
|
|
||||||
ifft4 (buf + 8);
|
|
||||||
ifft4 (buf + 12);
|
|
||||||
ifft_pass (buf, roots16 - 4, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ifft32 (complex_t * buf)
|
|
||||||
{
|
|
||||||
ifft16 (buf);
|
|
||||||
ifft8 (buf + 16);
|
|
||||||
ifft8 (buf + 24);
|
|
||||||
ifft_pass (buf, roots32 - 8, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ifft64_c (complex_t * buf)
|
|
||||||
{
|
|
||||||
ifft32 (buf);
|
|
||||||
ifft16 (buf + 32);
|
|
||||||
ifft16 (buf + 48);
|
|
||||||
ifft_pass (buf, roots64 - 16, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ifft128_c (complex_t * buf)
|
|
||||||
{
|
|
||||||
ifft32 (buf);
|
|
||||||
ifft16 (buf + 32);
|
|
||||||
ifft16 (buf + 48);
|
|
||||||
ifft_pass (buf, roots64 - 16, 16);
|
|
||||||
|
|
||||||
ifft32 (buf + 64);
|
|
||||||
ifft32 (buf + 96);
|
|
||||||
ifft_pass (buf, roots128 - 32, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias)
|
|
||||||
{
|
|
||||||
int i, k;
|
|
||||||
sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2;
|
|
||||||
const sample_t * window = a52_imdct_window;
|
|
||||||
complex_t buf[128];
|
|
||||||
|
|
||||||
for (i = 0; i < 128; i++) {
|
|
||||||
k = fftorder[i];
|
|
||||||
t_r = pre1[i].real;
|
|
||||||
t_i = pre1[i].imag;
|
|
||||||
|
|
||||||
buf[i].real = t_i * data[255-k] + t_r * data[k];
|
|
||||||
buf[i].imag = t_r * data[255-k] - t_i * data[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
ifft128 (buf);
|
|
||||||
|
|
||||||
/* Post IFFT complex multiply plus IFFT complex conjugate*/
|
|
||||||
/* Window and convert to real valued signal */
|
|
||||||
for (i = 0; i < 64; i++) {
|
|
||||||
/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
|
|
||||||
t_r = post1[i].real;
|
|
||||||
t_i = post1[i].imag;
|
|
||||||
|
|
||||||
a_r = t_r * buf[i].real + t_i * buf[i].imag;
|
|
||||||
a_i = t_i * buf[i].real - t_r * buf[i].imag;
|
|
||||||
b_r = t_i * buf[127-i].real + t_r * buf[127-i].imag;
|
|
||||||
b_i = t_r * buf[127-i].real - t_i * buf[127-i].imag;
|
|
||||||
|
|
||||||
w_1 = window[2*i];
|
|
||||||
w_2 = window[255-2*i];
|
|
||||||
data[2*i] = delay[2*i] * w_2 - a_r * w_1 + bias;
|
|
||||||
data[255-2*i] = delay[2*i] * w_1 + a_r * w_2 + bias;
|
|
||||||
delay[2*i] = a_i;
|
|
||||||
|
|
||||||
w_1 = window[2*i+1];
|
|
||||||
w_2 = window[254-2*i];
|
|
||||||
data[2*i+1] = delay[2*i+1] * w_2 + b_r * w_1 + bias;
|
|
||||||
data[254-2*i] = delay[2*i+1] * w_1 - b_r * w_2 + bias;
|
|
||||||
delay[2*i+1] = b_i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void a52_imdct_256(sample_t * data, sample_t * delay, sample_t bias)
|
|
||||||
{
|
|
||||||
int i, k;
|
|
||||||
sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2;
|
|
||||||
const sample_t * window = a52_imdct_window;
|
|
||||||
complex_t buf1[64], buf2[64];
|
|
||||||
|
|
||||||
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
|
|
||||||
for (i = 0; i < 64; i++) {
|
|
||||||
k = fftorder[i];
|
|
||||||
t_r = pre2[i].real;
|
|
||||||
t_i = pre2[i].imag;
|
|
||||||
|
|
||||||
buf1[i].real = t_i * data[254-k] + t_r * data[k];
|
|
||||||
buf1[i].imag = t_r * data[254-k] - t_i * data[k];
|
|
||||||
|
|
||||||
buf2[i].real = t_i * data[255-k] + t_r * data[k+1];
|
|
||||||
buf2[i].imag = t_r * data[255-k] - t_i * data[k+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
ifft64 (buf1);
|
|
||||||
ifft64 (buf2);
|
|
||||||
|
|
||||||
/* Post IFFT complex multiply */
|
|
||||||
/* Window and convert to real valued signal */
|
|
||||||
for (i = 0; i < 32; i++) {
|
|
||||||
/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
|
|
||||||
t_r = post2[i].real;
|
|
||||||
t_i = post2[i].imag;
|
|
||||||
|
|
||||||
a_r = t_r * buf1[i].real + t_i * buf1[i].imag;
|
|
||||||
a_i = t_i * buf1[i].real - t_r * buf1[i].imag;
|
|
||||||
b_r = t_i * buf1[63-i].real + t_r * buf1[63-i].imag;
|
|
||||||
b_i = t_r * buf1[63-i].real - t_i * buf1[63-i].imag;
|
|
||||||
|
|
||||||
c_r = t_r * buf2[i].real + t_i * buf2[i].imag;
|
|
||||||
c_i = t_i * buf2[i].real - t_r * buf2[i].imag;
|
|
||||||
d_r = t_i * buf2[63-i].real + t_r * buf2[63-i].imag;
|
|
||||||
d_i = t_r * buf2[63-i].real - t_i * buf2[63-i].imag;
|
|
||||||
|
|
||||||
w_1 = window[2*i];
|
|
||||||
w_2 = window[255-2*i];
|
|
||||||
data[2*i] = delay[2*i] * w_2 - a_r * w_1 + bias;
|
|
||||||
data[255-2*i] = delay[2*i] * w_1 + a_r * w_2 + bias;
|
|
||||||
delay[2*i] = c_i;
|
|
||||||
|
|
||||||
w_1 = window[128+2*i];
|
|
||||||
w_2 = window[127-2*i];
|
|
||||||
data[128+2*i] = delay[127-2*i] * w_2 + a_i * w_1 + bias;
|
|
||||||
data[127-2*i] = delay[127-2*i] * w_1 - a_i * w_2 + bias;
|
|
||||||
delay[127-2*i] = c_r;
|
|
||||||
|
|
||||||
w_1 = window[2*i+1];
|
|
||||||
w_2 = window[254-2*i];
|
|
||||||
data[2*i+1] = delay[2*i+1] * w_2 - b_i * w_1 + bias;
|
|
||||||
data[254-2*i] = delay[2*i+1] * w_1 + b_i * w_2 + bias;
|
|
||||||
delay[2*i+1] = d_r;
|
|
||||||
|
|
||||||
w_1 = window[129+2*i];
|
|
||||||
w_2 = window[126-2*i];
|
|
||||||
data[129+2*i] = delay[126-2*i] * w_2 + b_r * w_1 + bias;
|
|
||||||
data[126-2*i] = delay[126-2*i] * w_1 - b_r * w_2 + bias;
|
|
||||||
delay[126-2*i] = d_i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static double besselI0 (double x)
|
|
||||||
{
|
|
||||||
double bessel = 1;
|
|
||||||
int i = 100;
|
|
||||||
|
|
||||||
do
|
|
||||||
bessel = bessel * x / (i * i) + 1;
|
|
||||||
while (--i);
|
|
||||||
return bessel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void a52_imdct_init (uint32_t mm_accel)
|
|
||||||
{
|
|
||||||
int i, k;
|
|
||||||
double sum;
|
|
||||||
|
|
||||||
/* compute imdct window - kaiser-bessel derived window, alpha = 5.0 */
|
|
||||||
sum = 0;
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
sum += besselI0 (i * (256 - i) * (5 * M_PI / 256) * (5 * M_PI / 256));
|
|
||||||
a52_imdct_window[i] = sum;
|
|
||||||
}
|
|
||||||
sum++;
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
a52_imdct_window[i] = sqrt (a52_imdct_window[i] / sum);
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
roots16[i] = cos ((M_PI / 8) * (i + 1));
|
|
||||||
|
|
||||||
for (i = 0; i < 7; i++)
|
|
||||||
roots32[i] = cos ((M_PI / 16) * (i + 1));
|
|
||||||
|
|
||||||
for (i = 0; i < 15; i++)
|
|
||||||
roots64[i] = cos ((M_PI / 32) * (i + 1));
|
|
||||||
|
|
||||||
for (i = 0; i < 31; i++)
|
|
||||||
roots128[i] = cos ((M_PI / 64) * (i + 1));
|
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
|
||||||
k = fftorder[i] / 2 + 64;
|
|
||||||
pre1[i].real = cos ((M_PI / 256) * (k - 0.25));
|
|
||||||
pre1[i].imag = sin ((M_PI / 256) * (k - 0.25));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 64; i < 128; i++) {
|
|
||||||
k = fftorder[i] / 2 + 64;
|
|
||||||
pre1[i].real = -cos ((M_PI / 256) * (k - 0.25));
|
|
||||||
pre1[i].imag = -sin ((M_PI / 256) * (k - 0.25));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
|
||||||
post1[i].real = cos ((M_PI / 256) * (i + 0.5));
|
|
||||||
post1[i].imag = sin ((M_PI / 256) * (i + 0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
|
||||||
k = fftorder[i] / 4;
|
|
||||||
pre2[i].real = cos ((M_PI / 128) * (k - 0.25));
|
|
||||||
pre2[i].imag = sin ((M_PI / 128) * (k - 0.25));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
|
||||||
post2[i].real = cos ((M_PI / 128) * (i + 0.5));
|
|
||||||
post2[i].imag = sin ((M_PI / 128) * (i + 0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LIBA52_DJBFFT
|
|
||||||
if (mm_accel & MM_ACCEL_DJBFFT) {
|
|
||||||
fprintf (stderr, "Using djbfft for IMDCT transform\n");
|
|
||||||
ifft128 = (void (*) (complex_t *)) fftc4_un128;
|
|
||||||
ifft64 = (void (*) (complex_t *)) fftc4_un64;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "No accelerated IMDCT transform found\n");
|
|
||||||
ifft128 = ifft128_c;
|
|
||||||
ifft64 = ifft64_c;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef signed int int32_t;
|
|
||||||
#ifdef ARCH_X86
|
|
||||||
typedef signed long long int64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#ifdef ARCH_X86
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
#endif
|
|
|
@ -1,66 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
|
||||||
<CodeBlocks_project_file>
|
|
||||||
<FileVersion major="1" minor="6" />
|
|
||||||
<Project>
|
|
||||||
<Option title="liba52" />
|
|
||||||
<Option pch_mode="2" />
|
|
||||||
<Option compiler="gcc" />
|
|
||||||
<Build>
|
|
||||||
<Target title="Debug">
|
|
||||||
<Option output="../../deps/debug/liba52" prefix_auto="1" extension_auto="1" />
|
|
||||||
<Option working_dir="" />
|
|
||||||
<Option object_output="obj/Debug/" />
|
|
||||||
<Option type="2" />
|
|
||||||
<Option compiler="gcc" />
|
|
||||||
<Option createDefFile="1" />
|
|
||||||
<Compiler>
|
|
||||||
<Add option="-Wall" />
|
|
||||||
<Add option="-g" />
|
|
||||||
</Compiler>
|
|
||||||
</Target>
|
|
||||||
<Target title="Release">
|
|
||||||
<Option output="../../deps/release/liba52" prefix_auto="1" extension_auto="1" />
|
|
||||||
<Option working_dir="" />
|
|
||||||
<Option object_output="obj/Release/" />
|
|
||||||
<Option type="2" />
|
|
||||||
<Option compiler="gcc" />
|
|
||||||
<Option createDefFile="1" />
|
|
||||||
<Compiler>
|
|
||||||
<Add option="-Wall" />
|
|
||||||
<Add option="-O2" />
|
|
||||||
</Compiler>
|
|
||||||
<Linker>
|
|
||||||
<Add option="-s" />
|
|
||||||
</Linker>
|
|
||||||
</Target>
|
|
||||||
</Build>
|
|
||||||
<Unit filename="./a52.h" />
|
|
||||||
<Unit filename="./a52_internal.h" />
|
|
||||||
<Unit filename="./attributes.h" />
|
|
||||||
<Unit filename="./bit_allocate.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="./bitstream.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="./bitstream.h" />
|
|
||||||
<Unit filename="./config.h" />
|
|
||||||
<Unit filename="./downmix.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="./imdct.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="./inttypes.h" />
|
|
||||||
<Unit filename="./mm_accel.h" />
|
|
||||||
<Unit filename="./parse.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="./tables.h" />
|
|
||||||
<Unit filename="./tendra.h" />
|
|
||||||
<Extensions>
|
|
||||||
<code_completion />
|
|
||||||
<debugger />
|
|
||||||
</Extensions>
|
|
||||||
</Project>
|
|
||||||
</CodeBlocks_project_file>
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* mm_accel.h
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MM_ACCEL_H
|
|
||||||
#define MM_ACCEL_H
|
|
||||||
|
|
||||||
/* generic accelerations */
|
|
||||||
#define MM_ACCEL_DJBFFT 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 /* MM_ACCEL_H */
|
|
|
@ -1,903 +0,0 @@
|
||||||
/*
|
|
||||||
* parse.c
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#pragma warning(disable:4305)
|
|
||||||
#pragma warning(disable:4244)
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "inttypes.h"
|
|
||||||
|
|
||||||
#include "a52.h"
|
|
||||||
#include "a52_internal.h"
|
|
||||||
#include "bitstream.h"
|
|
||||||
#include "tables.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_MEMALIGN
|
|
||||||
/* some systems have memalign() but no declaration for it */
|
|
||||||
void * memalign (size_t align, size_t size);
|
|
||||||
#else
|
|
||||||
/* assume malloc alignment is sufficient */
|
|
||||||
#define memalign(align,size) malloc (size)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
sample_t q1[2];
|
|
||||||
sample_t q2[2];
|
|
||||||
sample_t q4;
|
|
||||||
int q1_ptr;
|
|
||||||
int q2_ptr;
|
|
||||||
int q4_ptr;
|
|
||||||
} quantizer_t;
|
|
||||||
|
|
||||||
static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
|
|
||||||
|
|
||||||
a52_state_t * a52_init (uint32_t mm_accel)
|
|
||||||
{
|
|
||||||
a52_state_t * state;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
state = malloc (sizeof (a52_state_t));
|
|
||||||
if (state == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
state->samples = memalign (16, 256 * 12 * sizeof (sample_t));
|
|
||||||
if (state->samples == NULL) {
|
|
||||||
free (state);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 256 * 12; i++)
|
|
||||||
state->samples[i] = 0;
|
|
||||||
|
|
||||||
state->downmixed = 1;
|
|
||||||
|
|
||||||
state->lfsr_state = 1;
|
|
||||||
|
|
||||||
a52_imdct_init (mm_accel);
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
sample_t * a52_samples (a52_state_t * state)
|
|
||||||
{
|
|
||||||
return state->samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
int a52_syncinfo (uint8_t * buf, int * flags,
|
|
||||||
int * sample_rate, int * bit_rate)
|
|
||||||
{
|
|
||||||
static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
|
|
||||||
128, 160, 192, 224, 256, 320, 384, 448,
|
|
||||||
512, 576, 640};
|
|
||||||
static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01};
|
|
||||||
int frmsizecod;
|
|
||||||
int bitrate;
|
|
||||||
int half;
|
|
||||||
int acmod;
|
|
||||||
|
|
||||||
if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (buf[5] >= 0x60) /* bsid >= 12 */
|
|
||||||
return 0;
|
|
||||||
half = halfrate[buf[5] >> 3];
|
|
||||||
|
|
||||||
/* acmod, dsurmod and lfeon */
|
|
||||||
acmod = buf[6] >> 5;
|
|
||||||
*flags = ((((buf[6] & 0xf8) == 0x50) ? A52_DOLBY : acmod) |
|
|
||||||
((buf[6] & lfeon[acmod]) ? A52_LFE : 0));
|
|
||||||
|
|
||||||
frmsizecod = buf[4] & 63;
|
|
||||||
if (frmsizecod >= 38)
|
|
||||||
return 0;
|
|
||||||
bitrate = rate [frmsizecod >> 1];
|
|
||||||
*bit_rate = (bitrate * 1000) >> half;
|
|
||||||
|
|
||||||
switch (buf[4] & 0xc0) {
|
|
||||||
case 0:
|
|
||||||
*sample_rate = 48000 >> half;
|
|
||||||
return 4 * bitrate;
|
|
||||||
case 0x40:
|
|
||||||
*sample_rate = 44100 >> half;
|
|
||||||
return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
|
|
||||||
case 0x80:
|
|
||||||
*sample_rate = 32000 >> half;
|
|
||||||
return 6 * bitrate;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int a52_frame (a52_state_t * state, uint8_t * buf, int * flags,
|
|
||||||
sample_t * level, sample_t bias)
|
|
||||||
{
|
|
||||||
static sample_t clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB};
|
|
||||||
static sample_t slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB};
|
|
||||||
int chaninfo;
|
|
||||||
int acmod;
|
|
||||||
|
|
||||||
state->fscod = buf[4] >> 6;
|
|
||||||
state->halfrate = halfrate[buf[5] >> 3];
|
|
||||||
state->acmod = acmod = buf[6] >> 5;
|
|
||||||
|
|
||||||
a52_bitstream_set_ptr (state, buf + 6);
|
|
||||||
bitstream_get (state, 3); /* skip acmod we already parsed */
|
|
||||||
|
|
||||||
if ((acmod == 2) && (bitstream_get (state, 2) == 2)) /* dsurmod */
|
|
||||||
acmod = A52_DOLBY;
|
|
||||||
|
|
||||||
if ((acmod & 1) && (acmod != 1))
|
|
||||||
state->clev = clev[bitstream_get (state, 2)]; /* cmixlev */
|
|
||||||
|
|
||||||
if (acmod & 4)
|
|
||||||
state->slev = slev[bitstream_get (state, 2)]; /* surmixlev */
|
|
||||||
|
|
||||||
state->lfeon = bitstream_get (state, 1);
|
|
||||||
|
|
||||||
state->output = a52_downmix_init (acmod, *flags, level,
|
|
||||||
state->clev, state->slev);
|
|
||||||
if (state->output < 0)
|
|
||||||
return 1;
|
|
||||||
if (state->lfeon && (*flags & A52_LFE))
|
|
||||||
state->output |= A52_LFE;
|
|
||||||
*flags = state->output;
|
|
||||||
/* the 2* compensates for differences in imdct */
|
|
||||||
state->dynrng = state->level = 2 * *level;
|
|
||||||
state->bias = bias;
|
|
||||||
state->dynrnge = 1;
|
|
||||||
state->dynrngcall = NULL;
|
|
||||||
state->cplba.deltbae = DELTA_BIT_NONE;
|
|
||||||
state->ba[0].deltbae = state->ba[1].deltbae = state->ba[2].deltbae =
|
|
||||||
state->ba[3].deltbae = state->ba[4].deltbae = DELTA_BIT_NONE;
|
|
||||||
|
|
||||||
chaninfo = !acmod;
|
|
||||||
do {
|
|
||||||
bitstream_get (state, 5); /* dialnorm */
|
|
||||||
if (bitstream_get (state, 1)) /* compre */
|
|
||||||
bitstream_get (state, 8); /* compr */
|
|
||||||
if (bitstream_get (state, 1)) /* langcode */
|
|
||||||
bitstream_get (state, 8); /* langcod */
|
|
||||||
if (bitstream_get (state, 1)) /* audprodie */
|
|
||||||
bitstream_get (state, 7); /* mixlevel + roomtyp */
|
|
||||||
} while (chaninfo--);
|
|
||||||
|
|
||||||
bitstream_get (state, 2); /* copyrightb + origbs */
|
|
||||||
|
|
||||||
if (bitstream_get (state, 1)) /* timecod1e */
|
|
||||||
bitstream_get (state, 14); /* timecod1 */
|
|
||||||
if (bitstream_get (state, 1)) /* timecod2e */
|
|
||||||
bitstream_get (state, 14); /* timecod2 */
|
|
||||||
|
|
||||||
if (bitstream_get (state, 1)) { /* addbsie */
|
|
||||||
int addbsil;
|
|
||||||
|
|
||||||
addbsil = bitstream_get (state, 6);
|
|
||||||
do {
|
|
||||||
bitstream_get (state, 8); /* addbsi */
|
|
||||||
} while (addbsil--);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void a52_dynrng (a52_state_t * state,
|
|
||||||
sample_t (* call) (sample_t, void *), void * data)
|
|
||||||
{
|
|
||||||
state->dynrnge = 0;
|
|
||||||
if (call) {
|
|
||||||
state->dynrnge = 1;
|
|
||||||
state->dynrngcall = call;
|
|
||||||
state->dynrngdata = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_exponents (a52_state_t * state, int expstr, int ngrps,
|
|
||||||
uint8_t exponent, uint8_t * dest)
|
|
||||||
{
|
|
||||||
int exps;
|
|
||||||
|
|
||||||
while (ngrps--) {
|
|
||||||
exps = bitstream_get (state, 7);
|
|
||||||
|
|
||||||
exponent += exp_1[exps];
|
|
||||||
if (exponent > 24)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
switch (expstr) {
|
|
||||||
case EXP_D45:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
*(dest++) = exponent;
|
|
||||||
case EXP_D25:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
case EXP_D15:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
exponent += exp_2[exps];
|
|
||||||
if (exponent > 24)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
switch (expstr) {
|
|
||||||
case EXP_D45:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
*(dest++) = exponent;
|
|
||||||
case EXP_D25:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
case EXP_D15:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
exponent += exp_3[exps];
|
|
||||||
if (exponent > 24)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
switch (expstr) {
|
|
||||||
case EXP_D45:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
*(dest++) = exponent;
|
|
||||||
case EXP_D25:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
case EXP_D15:
|
|
||||||
*(dest++) = exponent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_deltba (a52_state_t * state, int8_t * deltba)
|
|
||||||
{
|
|
||||||
int deltnseg, deltlen, delta, j;
|
|
||||||
|
|
||||||
memset (deltba, 0, 50);
|
|
||||||
|
|
||||||
deltnseg = bitstream_get (state, 3);
|
|
||||||
j = 0;
|
|
||||||
do {
|
|
||||||
j += bitstream_get (state, 5);
|
|
||||||
deltlen = bitstream_get (state, 4);
|
|
||||||
delta = bitstream_get (state, 3);
|
|
||||||
delta -= (delta >= 4) ? 3 : 4;
|
|
||||||
if (!deltlen)
|
|
||||||
continue;
|
|
||||||
if (j + deltlen >= 50)
|
|
||||||
return 1;
|
|
||||||
while (deltlen--)
|
|
||||||
deltba[j++] = delta;
|
|
||||||
} while (deltnseg--);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int zero_snr_offsets (int nfchans, a52_state_t * state)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((state->csnroffst) ||
|
|
||||||
(state->chincpl && state->cplba.bai >> 3) || /* cplinu, fsnroffst */
|
|
||||||
(state->lfeon && state->lfeba.bai >> 3)) /* fsnroffst */
|
|
||||||
return 0;
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
if (state->ba[i].bai >> 3) /* fsnroffst */
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int16_t dither_gen (a52_state_t * state)
|
|
||||||
{
|
|
||||||
int16_t nstate;
|
|
||||||
|
|
||||||
nstate = dither_lut[state->lfsr_state >> 8] ^ (state->lfsr_state << 8);
|
|
||||||
|
|
||||||
state->lfsr_state = (uint16_t) nstate;
|
|
||||||
|
|
||||||
return nstate;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void coeff_get (a52_state_t * state, sample_t * coeff,
|
|
||||||
expbap_t * expbap, quantizer_t * quantizer,
|
|
||||||
sample_t level, int dither, int end)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint8_t * exp;
|
|
||||||
int8_t * bap;
|
|
||||||
sample_t factor[25];
|
|
||||||
|
|
||||||
for (i = 0; i <= 24; i++)
|
|
||||||
factor[i] = scale_factor[i] * level;
|
|
||||||
|
|
||||||
exp = expbap->exp;
|
|
||||||
bap = expbap->bap;
|
|
||||||
|
|
||||||
for (i = 0; i < end; i++) {
|
|
||||||
int bapi;
|
|
||||||
|
|
||||||
bapi = bap[i];
|
|
||||||
switch (bapi) {
|
|
||||||
case 0:
|
|
||||||
if (dither) {
|
|
||||||
coeff[i] = dither_gen (state) * LEVEL_3DB * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
coeff[i] = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
case -1:
|
|
||||||
if (quantizer->q1_ptr >= 0) {
|
|
||||||
coeff[i] = quantizer->q1[quantizer->q1_ptr--] * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
int code;
|
|
||||||
|
|
||||||
code = bitstream_get (state, 5);
|
|
||||||
|
|
||||||
quantizer->q1_ptr = 1;
|
|
||||||
quantizer->q1[0] = q_1_2[code];
|
|
||||||
quantizer->q1[1] = q_1_1[code];
|
|
||||||
coeff[i] = q_1_0[code] * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
case -2:
|
|
||||||
if (quantizer->q2_ptr >= 0) {
|
|
||||||
coeff[i] = quantizer->q2[quantizer->q2_ptr--] * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
int code;
|
|
||||||
|
|
||||||
code = bitstream_get (state, 7);
|
|
||||||
|
|
||||||
quantizer->q2_ptr = 1;
|
|
||||||
quantizer->q2[0] = q_2_2[code];
|
|
||||||
quantizer->q2[1] = q_2_1[code];
|
|
||||||
coeff[i] = q_2_0[code] * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
coeff[i] = q_3[bitstream_get (state, 3)] * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case -3:
|
|
||||||
if (quantizer->q4_ptr == 0) {
|
|
||||||
quantizer->q4_ptr = -1;
|
|
||||||
coeff[i] = quantizer->q4 * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
int code;
|
|
||||||
|
|
||||||
code = bitstream_get (state, 7);
|
|
||||||
|
|
||||||
quantizer->q4_ptr = 0;
|
|
||||||
quantizer->q4 = q_4_1[code];
|
|
||||||
coeff[i] = q_4_0[code] * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
coeff[i] = q_5[bitstream_get (state, 4)] * factor[exp[i]];
|
|
||||||
continue;
|
|
||||||
|
|
||||||
default:
|
|
||||||
coeff[i] = ((bitstream_get_2 (state, bapi) << (16 - bapi)) *
|
|
||||||
factor[exp[i]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void coeff_get_coupling (a52_state_t * state, int nfchans,
|
|
||||||
sample_t * coeff, sample_t (* samples)[256],
|
|
||||||
quantizer_t * quantizer, uint8_t dithflag[5])
|
|
||||||
{
|
|
||||||
int cplbndstrc, bnd, i, i_end, ch;
|
|
||||||
uint8_t * exp;
|
|
||||||
int8_t * bap;
|
|
||||||
sample_t cplco[5];
|
|
||||||
|
|
||||||
exp = state->cpl_expbap.exp;
|
|
||||||
bap = state->cpl_expbap.bap;
|
|
||||||
bnd = 0;
|
|
||||||
cplbndstrc = state->cplbndstrc;
|
|
||||||
i = state->cplstrtmant;
|
|
||||||
while (i < state->cplendmant) {
|
|
||||||
i_end = i + 12;
|
|
||||||
while (cplbndstrc & 1) {
|
|
||||||
cplbndstrc >>= 1;
|
|
||||||
i_end += 12;
|
|
||||||
}
|
|
||||||
cplbndstrc >>= 1;
|
|
||||||
for (ch = 0; ch < nfchans; ch++)
|
|
||||||
cplco[ch] = state->cplco[ch][bnd] * coeff[ch];
|
|
||||||
bnd++;
|
|
||||||
|
|
||||||
while (i < i_end) {
|
|
||||||
sample_t cplcoeff;
|
|
||||||
int bapi;
|
|
||||||
|
|
||||||
bapi = bap[i];
|
|
||||||
switch (bapi) {
|
|
||||||
case 0:
|
|
||||||
cplcoeff = LEVEL_3DB * scale_factor[exp[i]];
|
|
||||||
for (ch = 0; ch < nfchans; ch++)
|
|
||||||
if ((state->chincpl >> ch) & 1) {
|
|
||||||
if (dithflag[ch])
|
|
||||||
samples[ch][i] = (cplcoeff * cplco[ch] *
|
|
||||||
dither_gen (state));
|
|
||||||
else
|
|
||||||
samples[ch][i] = 0;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case -1:
|
|
||||||
if (quantizer->q1_ptr >= 0) {
|
|
||||||
cplcoeff = quantizer->q1[quantizer->q1_ptr--];
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
int code;
|
|
||||||
|
|
||||||
code = bitstream_get (state, 5);
|
|
||||||
|
|
||||||
quantizer->q1_ptr = 1;
|
|
||||||
quantizer->q1[0] = q_1_2[code];
|
|
||||||
quantizer->q1[1] = q_1_1[code];
|
|
||||||
cplcoeff = q_1_0[code];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case -2:
|
|
||||||
if (quantizer->q2_ptr >= 0) {
|
|
||||||
cplcoeff = quantizer->q2[quantizer->q2_ptr--];
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
int code;
|
|
||||||
|
|
||||||
code = bitstream_get (state, 7);
|
|
||||||
|
|
||||||
quantizer->q2_ptr = 1;
|
|
||||||
quantizer->q2[0] = q_2_2[code];
|
|
||||||
quantizer->q2[1] = q_2_1[code];
|
|
||||||
cplcoeff = q_2_0[code];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
cplcoeff = q_3[bitstream_get (state, 3)];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case -3:
|
|
||||||
if (quantizer->q4_ptr == 0) {
|
|
||||||
quantizer->q4_ptr = -1;
|
|
||||||
cplcoeff = quantizer->q4;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
int code;
|
|
||||||
|
|
||||||
code = bitstream_get (state, 7);
|
|
||||||
|
|
||||||
quantizer->q4_ptr = 0;
|
|
||||||
quantizer->q4 = q_4_1[code];
|
|
||||||
cplcoeff = q_4_0[code];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
cplcoeff = q_5[bitstream_get (state, 4)];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
cplcoeff = bitstream_get_2 (state, bapi) << (16 - bapi);
|
|
||||||
}
|
|
||||||
|
|
||||||
cplcoeff *= scale_factor[exp[i]];
|
|
||||||
for (ch = 0; ch < nfchans; ch++)
|
|
||||||
if ((state->chincpl >> ch) & 1)
|
|
||||||
samples[ch][i] = cplcoeff * cplco[ch];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int a52_block (a52_state_t * state)
|
|
||||||
{
|
|
||||||
static const uint8_t nfchans_tbl[] = {2, 1, 2, 3, 3, 4, 4, 5, 1, 1, 2};
|
|
||||||
static int rematrix_band[4] = {25, 37, 61, 253};
|
|
||||||
int i, nfchans, chaninfo;
|
|
||||||
uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc, done_cpl;
|
|
||||||
uint8_t blksw[5], dithflag[5];
|
|
||||||
sample_t coeff[5];
|
|
||||||
int chanbias;
|
|
||||||
quantizer_t quantizer;
|
|
||||||
sample_t * samples;
|
|
||||||
|
|
||||||
nfchans = nfchans_tbl[state->acmod];
|
|
||||||
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
blksw[i] = bitstream_get (state, 1);
|
|
||||||
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
dithflag[i] = bitstream_get (state, 1);
|
|
||||||
|
|
||||||
chaninfo = !state->acmod;
|
|
||||||
do {
|
|
||||||
if (bitstream_get (state, 1)) { /* dynrnge */
|
|
||||||
int dynrng;
|
|
||||||
|
|
||||||
dynrng = bitstream_get_2 (state, 8);
|
|
||||||
if (state->dynrnge) {
|
|
||||||
sample_t range;
|
|
||||||
|
|
||||||
range = ((((dynrng & 0x1f) | 0x20) << 13) *
|
|
||||||
scale_factor[3 - (dynrng >> 5)]);
|
|
||||||
if (state->dynrngcall)
|
|
||||||
range = state->dynrngcall (range, state->dynrngdata);
|
|
||||||
state->dynrng = state->level * range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (chaninfo--);
|
|
||||||
|
|
||||||
if (bitstream_get (state, 1)) { /* cplstre */
|
|
||||||
state->chincpl = 0;
|
|
||||||
if (bitstream_get (state, 1)) { /* cplinu */
|
|
||||||
static uint8_t bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44,
|
|
||||||
45, 45, 46, 46, 47, 47, 48, 48};
|
|
||||||
int cplbegf;
|
|
||||||
int cplendf;
|
|
||||||
int ncplsubnd;
|
|
||||||
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
state->chincpl |= bitstream_get (state, 1) << i;
|
|
||||||
switch (state->acmod) {
|
|
||||||
case 0: case 1:
|
|
||||||
return 1;
|
|
||||||
case 2:
|
|
||||||
state->phsflginu = bitstream_get (state, 1);
|
|
||||||
}
|
|
||||||
cplbegf = bitstream_get (state, 4);
|
|
||||||
cplendf = bitstream_get (state, 4);
|
|
||||||
|
|
||||||
if (cplendf + 3 - cplbegf < 0)
|
|
||||||
return 1;
|
|
||||||
state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf;
|
|
||||||
state->cplstrtbnd = bndtab[cplbegf];
|
|
||||||
state->cplstrtmant = cplbegf * 12 + 37;
|
|
||||||
state->cplendmant = cplendf * 12 + 73;
|
|
||||||
|
|
||||||
state->cplbndstrc = 0;
|
|
||||||
for (i = 0; i < ncplsubnd - 1; i++)
|
|
||||||
if (bitstream_get (state, 1)) {
|
|
||||||
state->cplbndstrc |= 1 << i;
|
|
||||||
state->ncplbnd--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->chincpl) { /* cplinu */
|
|
||||||
int j, cplcoe;
|
|
||||||
|
|
||||||
cplcoe = 0;
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
if ((state->chincpl) >> i & 1)
|
|
||||||
if (bitstream_get (state, 1)) { /* cplcoe */
|
|
||||||
int mstrcplco, cplcoexp, cplcomant;
|
|
||||||
|
|
||||||
cplcoe = 1;
|
|
||||||
mstrcplco = 3 * bitstream_get (state, 2);
|
|
||||||
for (j = 0; j < state->ncplbnd; j++) {
|
|
||||||
cplcoexp = bitstream_get (state, 4);
|
|
||||||
cplcomant = bitstream_get (state, 4);
|
|
||||||
if (cplcoexp == 15)
|
|
||||||
cplcomant <<= 14;
|
|
||||||
else
|
|
||||||
cplcomant = (cplcomant | 0x10) << 13;
|
|
||||||
state->cplco[i][j] =
|
|
||||||
cplcomant * scale_factor[cplcoexp + mstrcplco];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((state->acmod == 2) && state->phsflginu && cplcoe)
|
|
||||||
for (j = 0; j < state->ncplbnd; j++)
|
|
||||||
if (bitstream_get (state, 1)) /* phsflg */
|
|
||||||
state->cplco[1][j] = -state->cplco[1][j];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((state->acmod == 2) && (bitstream_get (state, 1))) { /* rematstr */
|
|
||||||
int end;
|
|
||||||
|
|
||||||
state->rematflg = 0;
|
|
||||||
end = (state->chincpl) ? state->cplstrtmant : 253; /* cplinu */
|
|
||||||
i = 0;
|
|
||||||
do
|
|
||||||
state->rematflg |= bitstream_get (state, 1) << i;
|
|
||||||
while (rematrix_band[i++] < end);
|
|
||||||
}
|
|
||||||
|
|
||||||
cplexpstr = EXP_REUSE;
|
|
||||||
lfeexpstr = EXP_REUSE;
|
|
||||||
if (state->chincpl) /* cplinu */
|
|
||||||
cplexpstr = bitstream_get (state, 2);
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
chexpstr[i] = bitstream_get (state, 2);
|
|
||||||
if (state->lfeon)
|
|
||||||
lfeexpstr = bitstream_get (state, 1);
|
|
||||||
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
if (chexpstr[i] != EXP_REUSE) {
|
|
||||||
if ((state->chincpl >> i) & 1)
|
|
||||||
state->endmant[i] = state->cplstrtmant;
|
|
||||||
else {
|
|
||||||
int chbwcod;
|
|
||||||
|
|
||||||
chbwcod = bitstream_get (state, 6);
|
|
||||||
if (chbwcod > 60)
|
|
||||||
return 1;
|
|
||||||
state->endmant[i] = chbwcod * 3 + 73;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do_bit_alloc = 0;
|
|
||||||
|
|
||||||
if (cplexpstr != EXP_REUSE) {
|
|
||||||
int cplabsexp, ncplgrps;
|
|
||||||
|
|
||||||
do_bit_alloc = 64;
|
|
||||||
ncplgrps = ((state->cplendmant - state->cplstrtmant) /
|
|
||||||
(3 << (cplexpstr - 1)));
|
|
||||||
cplabsexp = bitstream_get (state, 4) << 1;
|
|
||||||
if (parse_exponents (state, cplexpstr, ncplgrps, cplabsexp,
|
|
||||||
state->cpl_expbap.exp + state->cplstrtmant))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
if (chexpstr[i] != EXP_REUSE) {
|
|
||||||
int grp_size, nchgrps;
|
|
||||||
|
|
||||||
do_bit_alloc |= 1 << i;
|
|
||||||
grp_size = 3 << (chexpstr[i] - 1);
|
|
||||||
nchgrps = (state->endmant[i] + grp_size - 4) / grp_size;
|
|
||||||
state->fbw_expbap[i].exp[0] = bitstream_get (state, 4);
|
|
||||||
if (parse_exponents (state, chexpstr[i], nchgrps,
|
|
||||||
state->fbw_expbap[i].exp[0],
|
|
||||||
state->fbw_expbap[i].exp + 1))
|
|
||||||
return 1;
|
|
||||||
bitstream_get (state, 2); /* gainrng */
|
|
||||||
}
|
|
||||||
if (lfeexpstr != EXP_REUSE) {
|
|
||||||
do_bit_alloc |= 32;
|
|
||||||
state->lfe_expbap.exp[0] = bitstream_get (state, 4);
|
|
||||||
if (parse_exponents (state, lfeexpstr, 2, state->lfe_expbap.exp[0],
|
|
||||||
state->lfe_expbap.exp + 1))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bitstream_get (state, 1)) { /* baie */
|
|
||||||
do_bit_alloc = -1;
|
|
||||||
state->bai = bitstream_get (state, 11);
|
|
||||||
}
|
|
||||||
if (bitstream_get (state, 1)) { /* snroffste */
|
|
||||||
do_bit_alloc = -1;
|
|
||||||
state->csnroffst = bitstream_get (state, 6);
|
|
||||||
if (state->chincpl) /* cplinu */
|
|
||||||
state->cplba.bai = bitstream_get (state, 7);
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
state->ba[i].bai = bitstream_get (state, 7);
|
|
||||||
if (state->lfeon)
|
|
||||||
state->lfeba.bai = bitstream_get (state, 7);
|
|
||||||
}
|
|
||||||
if ((state->chincpl) && (bitstream_get (state, 1))) { /* cplleake */
|
|
||||||
do_bit_alloc |= 64;
|
|
||||||
state->cplfleak = 9 - bitstream_get (state, 3);
|
|
||||||
state->cplsleak = 9 - bitstream_get (state, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bitstream_get (state, 1)) { /* deltbaie */
|
|
||||||
do_bit_alloc = -1;
|
|
||||||
if (state->chincpl) /* cplinu */
|
|
||||||
state->cplba.deltbae = bitstream_get (state, 2);
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
state->ba[i].deltbae = bitstream_get (state, 2);
|
|
||||||
if (state->chincpl && /* cplinu */
|
|
||||||
(state->cplba.deltbae == DELTA_BIT_NEW) &&
|
|
||||||
parse_deltba (state, state->cplba.deltba))
|
|
||||||
return 1;
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
if ((state->ba[i].deltbae == DELTA_BIT_NEW) &&
|
|
||||||
parse_deltba (state, state->ba[i].deltba))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_bit_alloc) {
|
|
||||||
if (zero_snr_offsets (nfchans, state)) {
|
|
||||||
memset (state->cpl_expbap.bap, 0, sizeof (state->cpl_expbap.bap));
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
memset (state->fbw_expbap[i].bap, 0,
|
|
||||||
sizeof (state->fbw_expbap[i].bap));
|
|
||||||
memset (state->lfe_expbap.bap, 0, sizeof (state->lfe_expbap.bap));
|
|
||||||
} else {
|
|
||||||
if (state->chincpl && (do_bit_alloc & 64)) /* cplinu */
|
|
||||||
a52_bit_allocate (state, &state->cplba, state->cplstrtbnd,
|
|
||||||
state->cplstrtmant, state->cplendmant,
|
|
||||||
state->cplfleak << 8, state->cplsleak << 8,
|
|
||||||
&state->cpl_expbap);
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
if (do_bit_alloc & (1 << i))
|
|
||||||
a52_bit_allocate (state, state->ba + i, 0, 0,
|
|
||||||
state->endmant[i], 0, 0,
|
|
||||||
state->fbw_expbap +i);
|
|
||||||
if (state->lfeon && (do_bit_alloc & 32)) {
|
|
||||||
state->lfeba.deltbae = DELTA_BIT_NONE;
|
|
||||||
a52_bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0,
|
|
||||||
&state->lfe_expbap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bitstream_get (state, 1)) { /* skiple */
|
|
||||||
i = bitstream_get (state, 9); /* skipl */
|
|
||||||
while (i--)
|
|
||||||
bitstream_get (state, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
samples = state->samples;
|
|
||||||
if (state->output & A52_LFE)
|
|
||||||
samples += 256; /* shift for LFE channel */
|
|
||||||
|
|
||||||
chanbias = a52_downmix_coeff (coeff, state->acmod, state->output,
|
|
||||||
state->dynrng, state->clev, state->slev);
|
|
||||||
|
|
||||||
quantizer.q1_ptr = quantizer.q2_ptr = quantizer.q4_ptr = -1;
|
|
||||||
done_cpl = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nfchans; i++) {
|
|
||||||
int j;
|
|
||||||
|
|
||||||
coeff_get (state, samples + 256 * i, state->fbw_expbap +i, &quantizer,
|
|
||||||
coeff[i], dithflag[i], state->endmant[i]);
|
|
||||||
|
|
||||||
if ((state->chincpl >> i) & 1) {
|
|
||||||
if (!done_cpl) {
|
|
||||||
done_cpl = 1;
|
|
||||||
coeff_get_coupling (state, nfchans, coeff,
|
|
||||||
(sample_t (*)[256])samples, &quantizer,
|
|
||||||
dithflag);
|
|
||||||
}
|
|
||||||
j = state->cplendmant;
|
|
||||||
} else
|
|
||||||
j = state->endmant[i];
|
|
||||||
do
|
|
||||||
(samples + 256 * i)[j] = 0;
|
|
||||||
while (++j < 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->acmod == 2) {
|
|
||||||
int j, end, band, rematflg;
|
|
||||||
|
|
||||||
end = ((state->endmant[0] < state->endmant[1]) ?
|
|
||||||
state->endmant[0] : state->endmant[1]);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
j = 13;
|
|
||||||
rematflg = state->rematflg;
|
|
||||||
do {
|
|
||||||
if (! (rematflg & 1)) {
|
|
||||||
rematflg >>= 1;
|
|
||||||
j = rematrix_band[i++];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
rematflg >>= 1;
|
|
||||||
band = rematrix_band[i++];
|
|
||||||
if (band > end)
|
|
||||||
band = end;
|
|
||||||
do {
|
|
||||||
sample_t tmp0, tmp1;
|
|
||||||
|
|
||||||
tmp0 = samples[j];
|
|
||||||
tmp1 = (samples+256)[j];
|
|
||||||
samples[j] = tmp0 + tmp1;
|
|
||||||
(samples+256)[j] = tmp0 - tmp1;
|
|
||||||
} while (++j < band);
|
|
||||||
} while (j < end);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->lfeon) {
|
|
||||||
if (state->output & A52_LFE) {
|
|
||||||
coeff_get (state, samples - 256, &state->lfe_expbap, &quantizer,
|
|
||||||
state->dynrng, 0, 7);
|
|
||||||
for (i = 7; i < 256; i++)
|
|
||||||
(samples-256)[i] = 0;
|
|
||||||
a52_imdct_512 (samples - 256, samples + 1536 - 256, state->bias);
|
|
||||||
} else {
|
|
||||||
/* just skip the LFE coefficients */
|
|
||||||
coeff_get (state, samples + 1280, &state->lfe_expbap, &quantizer,
|
|
||||||
0, 0, 7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
if (nfchans_tbl[state->output & A52_CHANNEL_MASK] < nfchans)
|
|
||||||
for (i = 1; i < nfchans; i++)
|
|
||||||
if (blksw[i] != blksw[0])
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i < nfchans) {
|
|
||||||
if (state->downmixed) {
|
|
||||||
state->downmixed = 0;
|
|
||||||
a52_upmix (samples + 1536, state->acmod, state->output);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nfchans; i++) {
|
|
||||||
sample_t bias;
|
|
||||||
|
|
||||||
bias = 0;
|
|
||||||
if (!(chanbias & (1 << i)))
|
|
||||||
bias = state->bias;
|
|
||||||
|
|
||||||
if (coeff[i]) {
|
|
||||||
if (blksw[i])
|
|
||||||
a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
|
|
||||||
bias);
|
|
||||||
else
|
|
||||||
a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
|
|
||||||
bias);
|
|
||||||
} else {
|
|
||||||
int j;
|
|
||||||
|
|
||||||
for (j = 0; j < 256; j++)
|
|
||||||
(samples + 256 * i)[j] = bias;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a52_downmix (samples, state->acmod, state->output, state->bias,
|
|
||||||
state->clev, state->slev);
|
|
||||||
} else {
|
|
||||||
nfchans = nfchans_tbl[state->output & A52_CHANNEL_MASK];
|
|
||||||
|
|
||||||
a52_downmix (samples, state->acmod, state->output, 0,
|
|
||||||
state->clev, state->slev);
|
|
||||||
|
|
||||||
if (!state->downmixed) {
|
|
||||||
state->downmixed = 1;
|
|
||||||
a52_downmix (samples + 1536, state->acmod, state->output, 0,
|
|
||||||
state->clev, state->slev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blksw[0])
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i,
|
|
||||||
state->bias);
|
|
||||||
else
|
|
||||||
for (i = 0; i < nfchans; i++)
|
|
||||||
a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i,
|
|
||||||
state->bias);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void a52_free (a52_state_t * state)
|
|
||||||
{
|
|
||||||
free (state->samples);
|
|
||||||
free (state);
|
|
||||||
}
|
|
|
@ -1,246 +0,0 @@
|
||||||
/*
|
|
||||||
* tables.h
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
static const int8_t exp_1[128] = {
|
|
||||||
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
||||||
-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,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
||||||
25,25,25
|
|
||||||
};
|
|
||||||
static const int8_t exp_2[128] = {
|
|
||||||
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
|
|
||||||
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
|
|
||||||
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
|
|
||||||
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
|
|
||||||
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
|
|
||||||
25,25,25
|
|
||||||
};
|
|
||||||
static const int8_t exp_3[128] = {
|
|
||||||
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
|
|
||||||
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
|
|
||||||
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
|
|
||||||
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
|
|
||||||
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
|
|
||||||
25,25,25
|
|
||||||
};
|
|
||||||
|
|
||||||
#define Q0 ((-2 << 15) / 3.0)
|
|
||||||
#define Q1 (0)
|
|
||||||
#define Q2 ((2 << 15) / 3.0)
|
|
||||||
|
|
||||||
static const sample_t 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 sample_t 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 sample_t 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 sample_t 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 sample_t 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 sample_t 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 sample_t q_3[8] = {
|
|
||||||
(-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0, 0,
|
|
||||||
( 2 << 15)/7.0, ( 4 << 15)/7.0, ( 6 << 15)/7.0, 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 sample_t 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 sample_t 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 sample_t q_5[16] = {
|
|
||||||
(-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 ,( 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,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const sample_t scale_factor[25] = {
|
|
||||||
0.000030517578125,
|
|
||||||
0.0000152587890625,
|
|
||||||
0.00000762939453125,
|
|
||||||
0.000003814697265625,
|
|
||||||
0.0000019073486328125,
|
|
||||||
0.00000095367431640625,
|
|
||||||
0.000000476837158203125,
|
|
||||||
0.0000002384185791015625,
|
|
||||||
0.00000011920928955078125,
|
|
||||||
0.000000059604644775390625,
|
|
||||||
0.0000000298023223876953125,
|
|
||||||
0.00000001490116119384765625,
|
|
||||||
0.000000007450580596923828125,
|
|
||||||
0.0000000037252902984619140625,
|
|
||||||
0.00000000186264514923095703125,
|
|
||||||
0.000000000931322574615478515625,
|
|
||||||
0.0000000004656612873077392578125,
|
|
||||||
0.00000000023283064365386962890625,
|
|
||||||
0.000000000116415321826934814453125,
|
|
||||||
0.0000000000582076609134674072265625,
|
|
||||||
0.00000000002910383045673370361328125,
|
|
||||||
0.000000000014551915228366851806640625,
|
|
||||||
0.0000000000072759576141834259033203125,
|
|
||||||
0.00000000000363797880709171295166015625,
|
|
||||||
0.000000000001818989403545856475830078125
|
|
||||||
};
|
|
||||||
|
|
||||||
static 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
|
|
||||||
};
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* tendra.h
|
|
||||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
||||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
||||||
*
|
|
||||||
* This file is part of a52dec, a free ATSC A-52 stream decoder.
|
|
||||||
* See http://liba52.sourceforge.net/ for updates.
|
|
||||||
*
|
|
||||||
* a52dec is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* a52dec is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma TenDRA begin
|
|
||||||
#pragma TenDRA longlong type warning
|
|
||||||
|
|
||||||
#ifdef TenDRA_check
|
|
||||||
|
|
||||||
#pragma TenDRA conversion analysis (pointer-int explicit) off
|
|
||||||
#pragma TenDRA implicit function declaration off
|
|
||||||
|
|
||||||
/* avoid the "No declarations in translation unit" problem */
|
|
||||||
int TenDRA;
|
|
||||||
|
|
||||||
#endif /* TenDRA_check */
|
|
|
@ -46,3 +46,5 @@ PaWasapi_GetDeviceRole @57
|
||||||
PaWasapi_ThreadPriorityBoost @58
|
PaWasapi_ThreadPriorityBoost @58
|
||||||
PaWasapi_ThreadPriorityRevert @59
|
PaWasapi_ThreadPriorityRevert @59
|
||||||
PaWasapi_GetFramesPerHostBuffer @60
|
PaWasapi_GetFramesPerHostBuffer @60
|
||||||
|
PaWasapi_GetJackDescription @61
|
||||||
|
PaWasapi_GetJackCount @62
|
|
@ -42,3 +42,5 @@ PaWasapi_GetDeviceRole @57
|
||||||
PaWasapi_ThreadPriorityBoost @58
|
PaWasapi_ThreadPriorityBoost @58
|
||||||
PaWasapi_ThreadPriorityRevert @59
|
PaWasapi_ThreadPriorityRevert @59
|
||||||
PaWasapi_GetFramesPerHostBuffer @60
|
PaWasapi_GetFramesPerHostBuffer @60
|
||||||
|
PaWasapi_GetJackDescription @61
|
||||||
|
PaWasapi_GetJackCount @62
|
|
@ -0,0 +1,109 @@
|
||||||
|
Hello
|
||||||
|
|
||||||
|
This is a small list of steps in order to build portaudio
|
||||||
|
(Currently v19-devel) into a VC6 DLL and lib file.
|
||||||
|
This DLL contains all 3 current win32 PA APIS (MM/DS/ASIO)
|
||||||
|
|
||||||
|
1)Copy the source dirs that comes with the ASIO SDK inside src\hostapi\asio\ASIOSDK
|
||||||
|
so you should now have example:
|
||||||
|
|
||||||
|
portaudio19svn\src\hostapi\asio\ASIOSDK\common
|
||||||
|
portaudio19svn\src\hostapi\asio\ASIOSDK\host
|
||||||
|
portaudio19svn\src\hostapi\asio\ASIOSDK\host\sample
|
||||||
|
portaudio19svn\src\hostapi\asio\ASIOSDK\host\pc
|
||||||
|
portaudio19svn\src\hostapi\asio\ASIOSDK\host\mac (not needed)
|
||||||
|
|
||||||
|
You dont need "driver"
|
||||||
|
|
||||||
|
To build without ASIO (or another Host API) see the "Building without ASIO support" section below.
|
||||||
|
|
||||||
|
2)
|
||||||
|
*If you have Visual Studio 6.0*, please make sure you have it updated with the latest (and final)
|
||||||
|
microsoft libraries for it, namely:
|
||||||
|
|
||||||
|
Service pack 5:
|
||||||
|
Latest known URL:
|
||||||
|
http://msdn2.microsoft.com/en-us/vstudio/aa718363.aspx
|
||||||
|
Yes there EXISTS a service pack 6 , but the processor pack (below) isnt compatible with it.
|
||||||
|
|
||||||
|
Processor Pack(only works with above SP5)
|
||||||
|
Latest known URL:
|
||||||
|
http://msdn2.microsoft.com/en-us/vstudio/Aa718349.aspx
|
||||||
|
This isnt absolutely required for portaudio, but if you plan on using SSE intrinsics and similar things.
|
||||||
|
Up to you to decide upon Service pack 5 or 6 depending on your need for intrinsics.
|
||||||
|
|
||||||
|
Platform SDK (Feb 2003) :
|
||||||
|
Latest known URL:
|
||||||
|
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
|
||||||
|
(This will allow your code base to be x64 friendly, with correct defines
|
||||||
|
for LONG_PTR and such)
|
||||||
|
NOTE A) Yes you have to use IE activex scripts to install that - wont work in Firefox, you
|
||||||
|
may have to temporarily change tyour default browser(aint life unfair)
|
||||||
|
NOTE B) Dont forget to hit "Register PSDK Directories with Visual Studio".
|
||||||
|
you can make sure its right in VC6 if you open tools/options/directories/include files and you see SDK 2003 as the FIRST entry
|
||||||
|
(it must be the same for libs)
|
||||||
|
|
||||||
|
DirectX 9.0 SDK Update - (Summer 2003)
|
||||||
|
Latest known URL:
|
||||||
|
http://www.microsoft.com/downloads/details.aspx?familyid=9216652f-51e0-402e-b7b5-feb68d00f298&displaylang=en
|
||||||
|
Again register the links in VC6, and check inside vc6 if headers are in second place right after SDk 2003
|
||||||
|
|
||||||
|
*If you have 7.0(VC.NET/2001) or 7.1(VC.2003) *
|
||||||
|
then I suggest you open portaudio.dsp (and convert if needed)
|
||||||
|
|
||||||
|
*If you have Visual Studio 2005*, I suggest you open the portaudio.sln file
|
||||||
|
which contains 4 configurations. Win32/x64 in both Release and Debug variants
|
||||||
|
|
||||||
|
hit compile and hope for the best.
|
||||||
|
|
||||||
|
3)Now in any project, in which you require portaudio,
|
||||||
|
you can just link with portaudio_x86.lib, (or _x64) and of course include the
|
||||||
|
relevant headers
|
||||||
|
(portaudio.h, and/or pa_asio.h , pa_x86_plain_converters.h) See (*)
|
||||||
|
|
||||||
|
4) Your new exe should now use portaudio_xXX.dll.
|
||||||
|
|
||||||
|
|
||||||
|
Have fun!
|
||||||
|
|
||||||
|
(*): you may want to add/remove some DLL entry points.
|
||||||
|
Right now those 6 entries are _not_ from portaudio.h
|
||||||
|
|
||||||
|
(from portaudio.def)
|
||||||
|
(...)
|
||||||
|
PaAsio_GetAvailableLatencyValues @50
|
||||||
|
PaAsio_ShowControlPanel @51
|
||||||
|
PaUtil_InitializeX86PlainConverters @52
|
||||||
|
PaAsio_GetInputChannelName @53
|
||||||
|
PaAsio_GetOutputChannelName @54
|
||||||
|
PaUtil_SetLogPrintFunction @55
|
||||||
|
|
||||||
|
|
||||||
|
*** Building without ASIO support ***
|
||||||
|
|
||||||
|
To build PortAudio without ASIO support you need to:
|
||||||
|
A. Make sure your project doesn't try to build any ASIO SDK files.
|
||||||
|
If you're using one of the shipped projects, remove the ASIO related files
|
||||||
|
from the project.
|
||||||
|
|
||||||
|
B. Make sure your project doesn't try to build the PortAudio ASIO
|
||||||
|
implementation files:
|
||||||
|
src/hostapi/pa_asio.cpp src/hostapi/iasiothiscallresolver.cpp
|
||||||
|
If you're using one of the shipped projects remove them from the project.
|
||||||
|
|
||||||
|
C. Define the PA_NO_ASIO preprocessor symbol in the project properties.
|
||||||
|
In VS2005 this can be added under
|
||||||
|
Project Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions
|
||||||
|
|
||||||
|
Defining PA_NO_ASIO stops src/os/win/pa_win_hostapis.c
|
||||||
|
from trying to initialize the PA ASIO implementation.
|
||||||
|
|
||||||
|
D. Remove PaAsio_* entry points from portaudio.def
|
||||||
|
|
||||||
|
A similar procedure can be used to omit any of the other host APIs from the
|
||||||
|
build. The relevant preprocessor symbols used by pa_win_hostapis.c are:
|
||||||
|
PA_NO_WMME, PA_NO_DS, PA_NO_ASIO, PA_NO_WASAPI and PA_NO_WDMKS
|
||||||
|
|
||||||
|
|
||||||
|
-----
|
||||||
|
David Viens, davidv@plogue.com
|
|
@ -109,6 +109,70 @@ typedef enum PaWasapiDeviceRole
|
||||||
PaWasapiDeviceRole;
|
PaWasapiDeviceRole;
|
||||||
|
|
||||||
|
|
||||||
|
/* Jack connection type */
|
||||||
|
typedef enum PaWasapiJackConnectionType
|
||||||
|
{
|
||||||
|
eJackConnTypeUnknown,
|
||||||
|
eJackConnType3Point5mm,
|
||||||
|
eJackConnTypeQuarter,
|
||||||
|
eJackConnTypeAtapiInternal,
|
||||||
|
eJackConnTypeRCA,
|
||||||
|
eJackConnTypeOptical,
|
||||||
|
eJackConnTypeOtherDigital,
|
||||||
|
eJackConnTypeOtherAnalog,
|
||||||
|
eJackConnTypeMultichannelAnalogDIN,
|
||||||
|
eJackConnTypeXlrProfessional,
|
||||||
|
eJackConnTypeRJ11Modem,
|
||||||
|
eJackConnTypeCombination
|
||||||
|
}
|
||||||
|
PaWasapiJackConnectionType;
|
||||||
|
|
||||||
|
|
||||||
|
/* Jack geometric location */
|
||||||
|
typedef enum PaWasapiJackGeoLocation
|
||||||
|
{
|
||||||
|
eJackGeoLocUnk = 0,
|
||||||
|
eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */
|
||||||
|
eJackGeoLocFront,
|
||||||
|
eJackGeoLocLeft,
|
||||||
|
eJackGeoLocRight,
|
||||||
|
eJackGeoLocTop,
|
||||||
|
eJackGeoLocBottom,
|
||||||
|
eJackGeoLocRearPanel,
|
||||||
|
eJackGeoLocRiser,
|
||||||
|
eJackGeoLocInsideMobileLid,
|
||||||
|
eJackGeoLocDrivebay,
|
||||||
|
eJackGeoLocHDMI,
|
||||||
|
eJackGeoLocOutsideMobileLid,
|
||||||
|
eJackGeoLocATAPI,
|
||||||
|
eJackGeoLocReserved5,
|
||||||
|
eJackGeoLocReserved6,
|
||||||
|
}
|
||||||
|
PaWasapiJackGeoLocation;
|
||||||
|
|
||||||
|
|
||||||
|
/* Jack general location */
|
||||||
|
typedef enum PaWasapiJackGenLocation
|
||||||
|
{
|
||||||
|
eJackGenLocPrimaryBox = 0,
|
||||||
|
eJackGenLocInternal,
|
||||||
|
eJackGenLocSeparate,
|
||||||
|
eJackGenLocOther
|
||||||
|
}
|
||||||
|
PaWasapiJackGenLocation;
|
||||||
|
|
||||||
|
|
||||||
|
/* Jack's type of port */
|
||||||
|
typedef enum PaWasapiJackPortConnection
|
||||||
|
{
|
||||||
|
eJackPortConnJack = 0,
|
||||||
|
eJackPortConnIntegratedDevice,
|
||||||
|
eJackPortConnBothIntegratedAndJack,
|
||||||
|
eJackPortConnUnknown
|
||||||
|
}
|
||||||
|
PaWasapiJackPortConnection;
|
||||||
|
|
||||||
|
|
||||||
/* Thread priority */
|
/* Thread priority */
|
||||||
typedef enum PaWasapiThreadPriority
|
typedef enum PaWasapiThreadPriority
|
||||||
{
|
{
|
||||||
|
@ -124,6 +188,20 @@ typedef enum PaWasapiThreadPriority
|
||||||
PaWasapiThreadPriority;
|
PaWasapiThreadPriority;
|
||||||
|
|
||||||
|
|
||||||
|
/* Stream descriptor. */
|
||||||
|
typedef struct PaWasapiJackDescription
|
||||||
|
{
|
||||||
|
unsigned long channelMapping;
|
||||||
|
unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */
|
||||||
|
PaWasapiJackConnectionType connectionType;
|
||||||
|
PaWasapiJackGeoLocation geoLocation;
|
||||||
|
PaWasapiJackGenLocation genLocation;
|
||||||
|
PaWasapiJackPortConnection portConnection;
|
||||||
|
unsigned int isConnected;
|
||||||
|
}
|
||||||
|
PaWasapiJackDescription;
|
||||||
|
|
||||||
|
|
||||||
/* Stream descriptor. */
|
/* Stream descriptor. */
|
||||||
typedef struct PaWasapiStreamInfo
|
typedef struct PaWasapiStreamInfo
|
||||||
{
|
{
|
||||||
|
@ -223,6 +301,31 @@ PaError PaWasapi_ThreadPriorityRevert( void *hTask );
|
||||||
PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput );
|
PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput );
|
||||||
|
|
||||||
|
|
||||||
|
/** Get number of jacks associated with a WASAPI device. Use this method to determine if
|
||||||
|
there are any jacks associated with the provided WASAPI device. Not all audio devices
|
||||||
|
will support this capability. This is valid for both input and output devices.
|
||||||
|
@param nDevice device index.
|
||||||
|
@param jcount Number of jacks is returned in this variable
|
||||||
|
@return Error code indicating success or failure
|
||||||
|
@see PaWasapi_GetJackDescription
|
||||||
|
*/
|
||||||
|
PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount);
|
||||||
|
|
||||||
|
|
||||||
|
/** Get the jack description associated with a WASAPI device and jack number
|
||||||
|
Before this function is called, use PaWasapi_GetJackCount to determine the
|
||||||
|
number of jacks associated with device. If jcount is greater than zero, then
|
||||||
|
each jack from 0 to jcount can be queried with this function to get the jack
|
||||||
|
description.
|
||||||
|
@param nDevice device index.
|
||||||
|
@param jindex Which jack to return information
|
||||||
|
@param KSJACK_DESCRIPTION This structure filled in on success.
|
||||||
|
@return Error code indicating success or failure
|
||||||
|
@see PaWasapi_GetJackCount
|
||||||
|
*/
|
||||||
|
PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
IMPORTANT:
|
IMPORTANT:
|
||||||
|
|
||||||
|
@ -243,8 +346,8 @@ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput
|
||||||
1) Event-Driven:
|
1) Event-Driven:
|
||||||
This is the most powerful WASAPI implementation which provides glitch-free
|
This is the most powerful WASAPI implementation which provides glitch-free
|
||||||
audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is
|
audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is
|
||||||
usually - 1.4(Vista only)-3ms(Windows 7+) for HD Audio class audio chips. For the
|
3 ms for HD Audio class audio chips. For the Shared mode latency can not be
|
||||||
Shared mode latency can not be lower than 20ms.
|
lower than 20 ms.
|
||||||
|
|
||||||
2) Poll-Driven:
|
2) Poll-Driven:
|
||||||
Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
|
Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: pa_process.c 1408 2009-03-13 16:41:39Z rossb $
|
* $Id: pa_process.c 1523 2010-07-10 17:41:25Z dmitrykos $
|
||||||
* Portable Audio I/O Library
|
* Portable Audio I/O Library
|
||||||
* streamCallback <-> host buffer processing adapter
|
* streamCallback <-> host buffer processing adapter
|
||||||
*
|
*
|
||||||
|
@ -264,6 +264,9 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
|
||||||
|
|
||||||
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
|
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
|
||||||
|
|
||||||
|
bp->hostInputIsInterleaved = (hostInputSampleFormat & paNonInterleaved)?0:1;
|
||||||
|
|
||||||
|
bp->userInputSampleFormatIsEqualToHost = ((userInputSampleFormat & ~paNonInterleaved) == (hostInputSampleFormat & ~paNonInterleaved));
|
||||||
|
|
||||||
tempInputBufferSize =
|
tempInputBufferSize =
|
||||||
bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;
|
bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;
|
||||||
|
@ -331,6 +334,10 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
|
||||||
|
|
||||||
bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1;
|
bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1;
|
||||||
|
|
||||||
|
bp->hostOutputIsInterleaved = (hostOutputSampleFormat & paNonInterleaved)?0:1;
|
||||||
|
|
||||||
|
bp->userOutputSampleFormatIsEqualToHost = ((userOutputSampleFormat & ~paNonInterleaved) == (hostOutputSampleFormat & ~paNonInterleaved));
|
||||||
|
|
||||||
tempOutputBufferSize =
|
tempOutputBufferSize =
|
||||||
bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount;
|
bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount;
|
||||||
|
|
||||||
|
@ -495,6 +502,7 @@ void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp,
|
||||||
|
|
||||||
assert( firstChannel < bp->inputChannelCount );
|
assert( firstChannel < bp->inputChannelCount );
|
||||||
assert( firstChannel + channelCount <= bp->inputChannelCount );
|
assert( firstChannel + channelCount <= bp->inputChannelCount );
|
||||||
|
assert( bp->hostInputIsInterleaved );
|
||||||
|
|
||||||
for( i=0; i< channelCount; ++i )
|
for( i=0; i< channelCount; ++i )
|
||||||
{
|
{
|
||||||
|
@ -509,6 +517,7 @@ void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
|
||||||
unsigned int channel, void *data )
|
unsigned int channel, void *data )
|
||||||
{
|
{
|
||||||
assert( channel < bp->inputChannelCount );
|
assert( channel < bp->inputChannelCount );
|
||||||
|
assert( !bp->hostInputIsInterleaved );
|
||||||
|
|
||||||
bp->hostInputChannels[0][channel].data = data;
|
bp->hostInputChannels[0][channel].data = data;
|
||||||
bp->hostInputChannels[0][channel].stride = 1;
|
bp->hostInputChannels[0][channel].stride = 1;
|
||||||
|
@ -544,6 +553,7 @@ void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp,
|
||||||
|
|
||||||
assert( firstChannel < bp->inputChannelCount );
|
assert( firstChannel < bp->inputChannelCount );
|
||||||
assert( firstChannel + channelCount <= bp->inputChannelCount );
|
assert( firstChannel + channelCount <= bp->inputChannelCount );
|
||||||
|
assert( bp->hostInputIsInterleaved );
|
||||||
|
|
||||||
for( i=0; i< channelCount; ++i )
|
for( i=0; i< channelCount; ++i )
|
||||||
{
|
{
|
||||||
|
@ -558,6 +568,7 @@ void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
|
||||||
unsigned int channel, void *data )
|
unsigned int channel, void *data )
|
||||||
{
|
{
|
||||||
assert( channel < bp->inputChannelCount );
|
assert( channel < bp->inputChannelCount );
|
||||||
|
assert( !bp->hostInputIsInterleaved );
|
||||||
|
|
||||||
bp->hostInputChannels[1][channel].data = data;
|
bp->hostInputChannels[1][channel].data = data;
|
||||||
bp->hostInputChannels[1][channel].stride = 1;
|
bp->hostInputChannels[1][channel].stride = 1;
|
||||||
|
@ -605,6 +616,7 @@ void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp,
|
||||||
|
|
||||||
assert( firstChannel < bp->outputChannelCount );
|
assert( firstChannel < bp->outputChannelCount );
|
||||||
assert( firstChannel + channelCount <= bp->outputChannelCount );
|
assert( firstChannel + channelCount <= bp->outputChannelCount );
|
||||||
|
assert( bp->hostOutputIsInterleaved );
|
||||||
|
|
||||||
for( i=0; i< channelCount; ++i )
|
for( i=0; i< channelCount; ++i )
|
||||||
{
|
{
|
||||||
|
@ -618,6 +630,7 @@ void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
|
||||||
unsigned int channel, void *data )
|
unsigned int channel, void *data )
|
||||||
{
|
{
|
||||||
assert( channel < bp->outputChannelCount );
|
assert( channel < bp->outputChannelCount );
|
||||||
|
assert( !bp->hostOutputIsInterleaved );
|
||||||
|
|
||||||
PaUtil_SetOutputChannel( bp, channel, data, 1 );
|
PaUtil_SetOutputChannel( bp, channel, data, 1 );
|
||||||
}
|
}
|
||||||
|
@ -653,6 +666,7 @@ void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp,
|
||||||
|
|
||||||
assert( firstChannel < bp->outputChannelCount );
|
assert( firstChannel < bp->outputChannelCount );
|
||||||
assert( firstChannel + channelCount <= bp->outputChannelCount );
|
assert( firstChannel + channelCount <= bp->outputChannelCount );
|
||||||
|
assert( bp->hostOutputIsInterleaved );
|
||||||
|
|
||||||
for( i=0; i< channelCount; ++i )
|
for( i=0; i< channelCount; ++i )
|
||||||
{
|
{
|
||||||
|
@ -666,6 +680,7 @@ void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
|
||||||
unsigned int channel, void *data )
|
unsigned int channel, void *data )
|
||||||
{
|
{
|
||||||
assert( channel < bp->outputChannelCount );
|
assert( channel < bp->outputChannelCount );
|
||||||
|
assert( !bp->hostOutputIsInterleaved );
|
||||||
|
|
||||||
PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );
|
PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );
|
||||||
}
|
}
|
||||||
|
@ -722,6 +737,8 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
unsigned long frameCount;
|
unsigned long frameCount;
|
||||||
unsigned long framesToGo = framesToProcess;
|
unsigned long framesToGo = framesToProcess;
|
||||||
unsigned long framesProcessed = 0;
|
unsigned long framesProcessed = 0;
|
||||||
|
int skipOutputConvert = 0;
|
||||||
|
int skipInputConvert = 0;
|
||||||
|
|
||||||
|
|
||||||
if( *streamCallbackResult == paContinue )
|
if( *streamCallbackResult == paContinue )
|
||||||
|
@ -738,10 +755,6 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
}
|
}
|
||||||
else /* there are input channels */
|
else /* there are input channels */
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
could use more elaborate logic here and sometimes process
|
|
||||||
buffers in-place.
|
|
||||||
*/
|
|
||||||
|
|
||||||
destBytePtr = (unsigned char *)bp->tempInputBuffer;
|
destBytePtr = (unsigned char *)bp->tempInputBuffer;
|
||||||
|
|
||||||
|
@ -749,19 +762,41 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
{
|
{
|
||||||
destSampleStrideSamples = bp->inputChannelCount;
|
destSampleStrideSamples = bp->inputChannelCount;
|
||||||
destChannelStrideBytes = bp->bytesPerUserInputSample;
|
destChannelStrideBytes = bp->bytesPerUserInputSample;
|
||||||
|
|
||||||
|
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
|
||||||
|
if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved )
|
||||||
|
{
|
||||||
|
userInput = hostInputChannels[0].data;
|
||||||
|
destBytePtr = (unsigned char *)hostInputChannels[0].data;
|
||||||
|
skipInputConvert = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
userInput = bp->tempInputBuffer;
|
userInput = bp->tempInputBuffer;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else /* user input is not interleaved */
|
else /* user input is not interleaved */
|
||||||
{
|
{
|
||||||
destSampleStrideSamples = 1;
|
destSampleStrideSamples = 1;
|
||||||
destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample;
|
destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample;
|
||||||
|
|
||||||
/* setup non-interleaved ptrs */
|
/* setup non-interleaved ptrs */
|
||||||
|
if( bp->userInputSampleFormatIsEqualToHost && !bp->hostInputIsInterleaved )
|
||||||
|
{
|
||||||
|
for( i=0; i<bp->inputChannelCount; ++i )
|
||||||
|
{
|
||||||
|
bp->tempInputBufferPtrs[i] = hostInputChannels[i].data;
|
||||||
|
}
|
||||||
|
skipInputConvert = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for( i=0; i<bp->inputChannelCount; ++i )
|
for( i=0; i<bp->inputChannelCount; ++i )
|
||||||
{
|
{
|
||||||
bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
|
bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
|
||||||
i * bp->bytesPerUserInputSample * frameCount;
|
i * bp->bytesPerUserInputSample * frameCount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
userInput = bp->tempInputBufferPtrs;
|
userInput = bp->tempInputBufferPtrs;
|
||||||
}
|
}
|
||||||
|
@ -777,6 +812,17 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
destBytePtr += destChannelStrideBytes; /* skip to next destination channel */
|
destBytePtr += destChannelStrideBytes; /* skip to next destination channel */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( skipInputConvert )
|
||||||
|
{
|
||||||
|
for( i=0; i<bp->inputChannelCount; ++i )
|
||||||
|
{
|
||||||
|
/* advance src ptr for next iteration */
|
||||||
|
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
|
||||||
|
frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( i=0; i<bp->inputChannelCount; ++i )
|
for( i=0; i<bp->inputChannelCount; ++i )
|
||||||
|
@ -794,6 +840,7 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* configure user output buffer */
|
/* configure user output buffer */
|
||||||
if( bp->outputChannelCount == 0 )
|
if( bp->outputChannelCount == 0 )
|
||||||
|
@ -804,16 +851,36 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
else /* there are output channels */
|
else /* there are output channels */
|
||||||
{
|
{
|
||||||
if( bp->userOutputIsInterleaved )
|
if( bp->userOutputIsInterleaved )
|
||||||
|
{
|
||||||
|
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
|
||||||
|
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved )
|
||||||
|
{
|
||||||
|
userOutput = hostOutputChannels[0].data;
|
||||||
|
skipOutputConvert = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
userOutput = bp->tempOutputBuffer;
|
userOutput = bp->tempOutputBuffer;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else /* user output is not interleaved */
|
else /* user output is not interleaved */
|
||||||
|
{
|
||||||
|
if( bp->userOutputSampleFormatIsEqualToHost && !bp->hostOutputIsInterleaved )
|
||||||
|
{
|
||||||
|
for( i=0; i<bp->outputChannelCount; ++i )
|
||||||
|
{
|
||||||
|
bp->tempOutputBufferPtrs[i] = hostOutputChannels[i].data;
|
||||||
|
}
|
||||||
|
skipOutputConvert = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
for( i=0; i<bp->outputChannelCount; ++i )
|
for( i=0; i<bp->outputChannelCount; ++i )
|
||||||
{
|
{
|
||||||
bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
|
bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
|
||||||
i * bp->bytesPerUserOutputSample * frameCount;
|
i * bp->bytesPerUserOutputSample * frameCount;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
userOutput = bp->tempOutputBufferPtrs;
|
userOutput = bp->tempOutputBufferPtrs;
|
||||||
}
|
}
|
||||||
|
@ -836,10 +903,17 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
|
|
||||||
if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
|
if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
|
||||||
{
|
{
|
||||||
/*
|
if( skipOutputConvert )
|
||||||
could use more elaborate logic here and sometimes process
|
{
|
||||||
buffers in-place.
|
for( i=0; i<bp->outputChannelCount; ++i )
|
||||||
*/
|
{
|
||||||
|
/* advance dest ptr for next iteration */
|
||||||
|
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
|
||||||
|
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
|
srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
|
||||||
|
|
||||||
|
@ -868,6 +942,7 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
||||||
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
|
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
framesProcessed += frameCount;
|
framesProcessed += frameCount;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef PA_PROCESS_H
|
#ifndef PA_PROCESS_H
|
||||||
#define PA_PROCESS_H
|
#define PA_PROCESS_H
|
||||||
/*
|
/*
|
||||||
* $Id: pa_process.h 1097 2006-08-26 08:27:53Z rossb $
|
* $Id: pa_process.h 1523 2010-07-10 17:41:25Z dmitrykos $
|
||||||
* Portable Audio I/O Library callback buffer processing adapters
|
* Portable Audio I/O Library callback buffer processing adapters
|
||||||
*
|
*
|
||||||
* Based on the Open Source API proposed by Ross Bencina
|
* Based on the Open Source API proposed by Ross Bencina
|
||||||
|
@ -256,6 +256,8 @@ typedef struct {
|
||||||
|
|
||||||
PaUtilHostBufferSizeMode hostBufferSizeMode;
|
PaUtilHostBufferSizeMode hostBufferSizeMode;
|
||||||
int useNonAdaptingProcess;
|
int useNonAdaptingProcess;
|
||||||
|
int userOutputSampleFormatIsEqualToHost;
|
||||||
|
int userInputSampleFormatIsEqualToHost;
|
||||||
unsigned long framesPerTempBuffer;
|
unsigned long framesPerTempBuffer;
|
||||||
|
|
||||||
unsigned int inputChannelCount;
|
unsigned int inputChannelCount;
|
||||||
|
@ -287,12 +289,14 @@ typedef struct {
|
||||||
|
|
||||||
PaStreamCallbackFlags callbackStatusFlags;
|
PaStreamCallbackFlags callbackStatusFlags;
|
||||||
|
|
||||||
|
int hostInputIsInterleaved;
|
||||||
unsigned long hostInputFrameCount[2];
|
unsigned long hostInputFrameCount[2];
|
||||||
PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors.
|
PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors.
|
||||||
pointers are NULL for half-duplex output processing.
|
pointers are NULL for half-duplex output processing.
|
||||||
hostInputChannels[i].data is NULL when the caller
|
hostInputChannels[i].data is NULL when the caller
|
||||||
calls PaUtil_SetNoInput()
|
calls PaUtil_SetNoInput()
|
||||||
*/
|
*/
|
||||||
|
int hostOutputIsInterleaved;
|
||||||
unsigned long hostOutputFrameCount[2];
|
unsigned long hostOutputFrameCount[2];
|
||||||
PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors.
|
PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors.
|
||||||
pointers are NULL for half-duplex input processing.
|
pointers are NULL for half-duplex input processing.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: pa_linux_alsa.c 1415 2009-06-03 18:57:56Z aknudsen $
|
* $Id: pa_linux_alsa.c 1540 2010-09-20 16:23:30Z dmitrykos $
|
||||||
* PortAudio Portable Real-Time Audio Library
|
* PortAudio Portable Real-Time Audio Library
|
||||||
* Latest Version at: http://www.portaudio.com
|
* Latest Version at: http://www.portaudio.com
|
||||||
* ALSA implementation by Joshua Haberman and Arve Knudsen
|
* ALSA implementation by Joshua Haberman and Arve Knudsen
|
||||||
|
@ -1257,6 +1257,10 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se
|
||||||
/* test if MMAP supported */
|
/* test if MMAP supported */
|
||||||
self->canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
|
self->canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
|
||||||
snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
|
snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
|
||||||
|
|
||||||
|
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO")));
|
||||||
|
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO")));
|
||||||
|
|
||||||
if (!self->canMmap)
|
if (!self->canMmap)
|
||||||
{
|
{
|
||||||
accessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
|
accessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||||
|
@ -1271,12 +1275,17 @@ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *se
|
||||||
/* test if MMAP supported */
|
/* test if MMAP supported */
|
||||||
self->canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
|
self->canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ||
|
||||||
snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
|
snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0;
|
||||||
|
|
||||||
|
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO")));
|
||||||
|
PA_DEBUG(("%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, (snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO")));
|
||||||
|
|
||||||
if (!self->canMmap)
|
if (!self->canMmap)
|
||||||
{
|
{
|
||||||
accessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED;
|
accessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED;
|
||||||
alternateAccessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
|
alternateAccessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PA_DEBUG(("%s: device can MMAP: %s\n", __FUNCTION__, (self->canMmap ? "YES" : "NO")));
|
PA_DEBUG(("%s: device can MMAP: %s\n", __FUNCTION__, (self->canMmap ? "YES" : "NO")));
|
||||||
|
|
||||||
/* If requested access mode fails, try alternate mode */
|
/* If requested access mode fails, try alternate mode */
|
||||||
|
@ -1465,6 +1474,40 @@ static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frame
|
||||||
return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate );
|
return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Align value in backward direction.
|
||||||
|
*
|
||||||
|
* @param v: Value to align.
|
||||||
|
* @param align: Alignment.
|
||||||
|
*/
|
||||||
|
static unsigned long PaAlsa_AlignBackward(unsigned long v, unsigned long align)
|
||||||
|
{
|
||||||
|
return ((v - (align ? v % align : 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Align value in forward direction.
|
||||||
|
*
|
||||||
|
* @param v: Value to align.
|
||||||
|
* @param align: Alignment.
|
||||||
|
*/
|
||||||
|
static unsigned long PaAlsa_AlignForward(unsigned long v, unsigned long align)
|
||||||
|
{
|
||||||
|
unsigned long remainder = (align ? (v % align) : 0);
|
||||||
|
return (remainder != 0 ? v + (align - remainder) : v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get size of host buffer maintained from the number of user frames, sample rate and suggested latency. Minimum double buffering
|
||||||
|
* is maintained to allow 100% CPU usage inside user callback.
|
||||||
|
*
|
||||||
|
* @param userFramesPerBuffer: User buffer size in number of frames.
|
||||||
|
* @param suggestedLatency: User provided desired latency.
|
||||||
|
* @param sampleRate: Sample rate.
|
||||||
|
*/
|
||||||
|
static unsigned long PaAlsa_GetFramesPerHostBuffer(unsigned long userFramesPerBuffer, PaTime suggestedLatency, double sampleRate)
|
||||||
|
{
|
||||||
|
unsigned long frames = userFramesPerBuffer + PA_MAX( userFramesPerBuffer, (unsigned long)(suggestedLatency * sampleRate) );
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
/** Determine size per host buffer.
|
/** Determine size per host buffer.
|
||||||
*
|
*
|
||||||
* During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size
|
* During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size
|
||||||
|
@ -1475,18 +1518,20 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
|
||||||
unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate )
|
unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate )
|
||||||
{
|
{
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
unsigned long bufferSize = params->suggestedLatency * sampleRate, framesPerHostBuffer;
|
unsigned long bufferSize, framesPerHostBuffer;
|
||||||
int dir = 0;
|
int dir = 0;
|
||||||
|
|
||||||
{
|
/* Calculate host buffer size */
|
||||||
snd_pcm_uframes_t tmp;
|
bufferSize = PaAlsa_GetFramesPerHostBuffer(framesPerUserBuffer, params->suggestedLatency, sampleRate);
|
||||||
snd_pcm_hw_params_get_buffer_size_min( hwParams, &tmp );
|
|
||||||
bufferSize = PA_MAX( bufferSize, tmp );
|
|
||||||
snd_pcm_hw_params_get_buffer_size_max( hwParams, &tmp );
|
|
||||||
bufferSize = PA_MIN( bufferSize, tmp );
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( bufferSize > 0 );
|
/* Log */
|
||||||
|
PA_DEBUG(( "%s: user-buffer (frames) = %lu\n", __FUNCTION__, framesPerUserBuffer ));
|
||||||
|
PA_DEBUG(( "%s: user-buffer (sec) = %f\n", __FUNCTION__, (double)(framesPerUserBuffer / sampleRate) ));
|
||||||
|
PA_DEBUG(( "%s: suggested latency (sec) = %f\n", __FUNCTION__, params->suggestedLatency ));
|
||||||
|
PA_DEBUG(( "%s: suggested host buffer (frames) = %lu\n", __FUNCTION__, bufferSize ));
|
||||||
|
PA_DEBUG(( "%s: suggested host buffer (sec) = %f\n", __FUNCTION__, (double)(bufferSize / sampleRate) ));
|
||||||
|
|
||||||
|
#ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
|
||||||
|
|
||||||
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
|
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
|
||||||
{
|
{
|
||||||
|
@ -1528,15 +1573,62 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Using the base number of periods, we try to approximate the suggested latency (+1 period),
|
#endif
|
||||||
finding a combination of period/buffer size which best fits these constraints */
|
|
||||||
{
|
{
|
||||||
unsigned numPeriods = numPeriods_, maxPeriods = 0;
|
unsigned numPeriods = numPeriods_, maxPeriods = 0, minPeriods = numPeriods_;
|
||||||
|
|
||||||
/* It may be that the device only supports 2 periods for instance */
|
/* It may be that the device only supports 2 periods for instance */
|
||||||
dir = 0;
|
dir = 0;
|
||||||
|
ENSURE_( snd_pcm_hw_params_get_periods_min( hwParams, &minPeriods, &dir ), paUnanticipatedHostError )
|
||||||
ENSURE_( snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError );
|
ENSURE_( snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError );
|
||||||
assert( maxPeriods > 1 );
|
assert( maxPeriods > 1 );
|
||||||
numPeriods = PA_MIN( maxPeriods, numPeriods );
|
|
||||||
|
/* Clamp to min/max */
|
||||||
|
numPeriods = PA_MIN(maxPeriods, PA_MAX(minPeriods, numPeriods));
|
||||||
|
|
||||||
|
PA_DEBUG(( "%s: periods min = %lu, max = %lu, req = %lu \n", __FUNCTION__, minPeriods, maxPeriods, numPeriods ));
|
||||||
|
|
||||||
|
#ifndef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
|
||||||
|
|
||||||
|
/* Calculate period size */
|
||||||
|
framesPerHostBuffer = (bufferSize / numPeriods);
|
||||||
|
|
||||||
|
/* Align & test size */
|
||||||
|
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
|
||||||
|
{
|
||||||
|
/* Align to user buffer size */
|
||||||
|
framesPerHostBuffer = PaAlsa_AlignForward(framesPerHostBuffer, framesPerUserBuffer);
|
||||||
|
|
||||||
|
/* Test (borrowed from older implementation) */
|
||||||
|
if( framesPerHostBuffer < framesPerUserBuffer )
|
||||||
|
{
|
||||||
|
assert( framesPerUserBuffer % framesPerHostBuffer == 0 );
|
||||||
|
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
|
||||||
|
{
|
||||||
|
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 )
|
||||||
|
framesPerHostBuffer *= 2;
|
||||||
|
else
|
||||||
|
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 )
|
||||||
|
framesPerHostBuffer /= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert( framesPerHostBuffer % framesPerUserBuffer == 0 );
|
||||||
|
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
|
||||||
|
{
|
||||||
|
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 )
|
||||||
|
framesPerHostBuffer += framesPerUserBuffer;
|
||||||
|
else
|
||||||
|
if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 )
|
||||||
|
framesPerHostBuffer -= framesPerUserBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC
|
||||||
|
|
||||||
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
|
if( framesPerUserBuffer != paFramesPerBufferUnspecified )
|
||||||
{
|
{
|
||||||
|
@ -1594,41 +1686,49 @@ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamCompo
|
||||||
{
|
{
|
||||||
framesPerHostBuffer = bufferSize / numPeriods;
|
framesPerHostBuffer = bufferSize / numPeriods;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* non-mmap mode needs a reasonably-sized buffer or it'll stutter */
|
/* non-mmap mode needs a reasonably-sized buffer or it'll stutter */
|
||||||
if( !self->canMmap && framesPerHostBuffer < 2048 )
|
if( !self->canMmap && framesPerHostBuffer < 2048 )
|
||||||
framesPerHostBuffer = 2048;
|
framesPerHostBuffer = 2048;
|
||||||
|
#endif
|
||||||
|
PA_DEBUG(( "%s: suggested host buffer period = %lu \n", __FUNCTION__, framesPerHostBuffer ));
|
||||||
|
}
|
||||||
|
|
||||||
assert( framesPerHostBuffer > 0 );
|
|
||||||
{
|
{
|
||||||
snd_pcm_uframes_t min = 0, max = 0;
|
/* Get min/max period sizes and adjust our chosen */
|
||||||
|
snd_pcm_uframes_t min = 0, max = 0, minmax_diff;
|
||||||
ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError );
|
ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError );
|
||||||
ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError );
|
ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError );
|
||||||
|
minmax_diff = max - min;
|
||||||
|
|
||||||
if( framesPerHostBuffer < min )
|
if( framesPerHostBuffer < min )
|
||||||
{
|
{
|
||||||
PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__,
|
PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__, framesPerHostBuffer, min ));
|
||||||
framesPerHostBuffer, min ));
|
framesPerHostBuffer = ((minmax_diff == 2) ? min + 1 : min);
|
||||||
framesPerHostBuffer = min;
|
|
||||||
}
|
}
|
||||||
else if( framesPerHostBuffer > max )
|
else
|
||||||
|
if( framesPerHostBuffer > max )
|
||||||
{
|
{
|
||||||
PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__,
|
PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__, framesPerHostBuffer, max ));
|
||||||
framesPerHostBuffer, max ));
|
framesPerHostBuffer = ((minmax_diff == 2) ? max - 1 : max);
|
||||||
framesPerHostBuffer = max;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( framesPerHostBuffer >= min && framesPerHostBuffer <= max );
|
PA_DEBUG(( "%s: device period minimum = %lu\n", __FUNCTION__, min ));
|
||||||
|
PA_DEBUG(( "%s: device period maximum = %lu\n", __FUNCTION__, max ));
|
||||||
|
PA_DEBUG(( "%s: host buffer period = %lu\n", __FUNCTION__, framesPerHostBuffer ));
|
||||||
|
PA_DEBUG(( "%s: host buffer period latency = %f\n", __FUNCTION__, (double)(framesPerHostBuffer / sampleRate) ));
|
||||||
|
|
||||||
|
/* Try setting period size */
|
||||||
dir = 0;
|
dir = 0;
|
||||||
ENSURE_( snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ),
|
ENSURE_( snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ), paUnanticipatedHostError );
|
||||||
paUnanticipatedHostError );
|
|
||||||
if( dir != 0 )
|
if( dir != 0 )
|
||||||
{
|
{
|
||||||
PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir ));
|
PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir ));
|
||||||
*accurate = 0;
|
*accurate = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set result */
|
||||||
self->framesPerBuffer = framesPerHostBuffer;
|
self->framesPerBuffer = framesPerHostBuffer;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1996,8 +2096,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
|
|
||||||
PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer,
|
PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer,
|
||||||
&inputLatency, &outputLatency, &hostBufferSizeMode ) );
|
&inputLatency, &outputLatency, &hostBufferSizeMode ) );
|
||||||
hostInputSampleFormat = stream->capture.hostSampleFormat;
|
hostInputSampleFormat = stream->capture.hostSampleFormat | (!stream->capture.hostInterleaved ? paNonInterleaved : 0);
|
||||||
hostOutputSampleFormat = stream->playback.hostSampleFormat;
|
hostOutputSampleFormat = stream->playback.hostSampleFormat | (!stream->playback.hostInterleaved ? paNonInterleaved : 0);
|
||||||
|
|
||||||
PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
|
PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
|
||||||
numInputChannels, inputSampleFormat, hostInputSampleFormat,
|
numInputChannels, inputSampleFormat, hostInputSampleFormat,
|
||||||
|
@ -2013,6 +2113,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)(
|
stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)(
|
||||||
PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor ) / sampleRate);
|
PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor ) / sampleRate);
|
||||||
|
|
||||||
|
PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency = i(%f)/o(%f), \n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency));
|
||||||
|
|
||||||
*s = (PaStream*)stream;
|
*s = (PaStream*)stream;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -2032,9 +2134,6 @@ static PaError CloseStream( PaStream* s )
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
PaAlsaStream *stream = (PaAlsaStream*)s;
|
PaAlsaStream *stream = (PaAlsaStream*)s;
|
||||||
|
|
||||||
free(stream->playback.nonMmapBuffer);
|
|
||||||
free(stream->capture.nonMmapBuffer);
|
|
||||||
|
|
||||||
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
|
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
|
||||||
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
|
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
|
||||||
|
|
||||||
|
@ -2345,6 +2444,7 @@ static double GetStreamCpuLoad( PaStream* s )
|
||||||
|
|
||||||
static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate )
|
static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate )
|
||||||
{
|
{
|
||||||
|
PaError result = paNoError;
|
||||||
unsigned long approx = (unsigned long) sampleRate;
|
unsigned long approx = (unsigned long) sampleRate;
|
||||||
int dir = 0;
|
int dir = 0;
|
||||||
double fraction = sampleRate - approx;
|
double fraction = sampleRate - approx;
|
||||||
|
@ -2362,7 +2462,24 @@ static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwPara
|
||||||
dir = 1;
|
dir = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir );
|
if( snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir ) < 0)
|
||||||
|
result = paInvalidSampleRate;
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
/* Log */
|
||||||
|
{
|
||||||
|
unsigned int _min = 0, _max = 0; int _dir = 0;
|
||||||
|
ENSURE_( snd_pcm_hw_params_get_rate_min( hwParams, &_min, &_dir ), paUnanticipatedHostError );
|
||||||
|
ENSURE_( snd_pcm_hw_params_get_rate_max( hwParams, &_max, &_dir ), paUnanticipatedHostError );
|
||||||
|
PA_DEBUG(( "%s: SR min = %d, max = %d, req = %lu\n", __FUNCTION__, _min, _max, approx ));
|
||||||
|
}
|
||||||
|
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return exact sample rate in param sampleRate */
|
/* Return exact sample rate in param sampleRate */
|
||||||
|
@ -2987,6 +3104,8 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
|
||||||
/* not else ! */
|
/* not else ! */
|
||||||
if (timeouts >= 64) /* audio device not working, shall return error to notify waiters */
|
if (timeouts >= 64) /* audio device not working, shall return error to notify waiters */
|
||||||
{
|
{
|
||||||
|
*framesAvail = 0; /* no frames available for processing */
|
||||||
|
|
||||||
PA_DEBUG(( "%s: poll timed out, returning error\n", __FUNCTION__, timeouts ));
|
PA_DEBUG(( "%s: poll timed out, returning error\n", __FUNCTION__, timeouts ));
|
||||||
PA_ENSURE( paTimedOut );
|
PA_ENSURE( paTimedOut );
|
||||||
}
|
}
|
||||||
|
@ -3113,11 +3232,7 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* using realloc for optimisation
|
unsigned int bufferSize = self->numHostChannels * snd_pcm_format_size( self->nativeFormat, *numFrames );
|
||||||
free( self->nonMmapBuffer );
|
|
||||||
self->nonMmapBuffer = calloc( self->numHostChannels, snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 ) );
|
|
||||||
*/
|
|
||||||
unsigned int bufferSize = self->numHostChannels * snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
|
|
||||||
if (bufferSize > self->nonMmapBufferSize)
|
if (bufferSize > self->nonMmapBufferSize)
|
||||||
{
|
{
|
||||||
self->nonMmapBuffer = realloc(self->nonMmapBuffer, (self->nonMmapBufferSize = bufferSize));
|
self->nonMmapBuffer = realloc(self->nonMmapBuffer, (self->nonMmapBufferSize = bufferSize));
|
||||||
|
@ -3144,20 +3259,22 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( self->canMmap )
|
if( self->canMmap )
|
||||||
|
{
|
||||||
for( i = 0; i < self->numUserChannels; ++i )
|
for( i = 0; i < self->numUserChannels; ++i )
|
||||||
{
|
{
|
||||||
area = areas + i;
|
area = areas + i;
|
||||||
buffer = ExtractAddress( area, self->offset );
|
buffer = ExtractAddress( area, self->offset );
|
||||||
setChannel( bp, i, buffer, 1 );
|
setChannel( bp, i, buffer, 1 );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bufsize = snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
|
unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels;
|
||||||
buffer = self->nonMmapBuffer;
|
buffer = self->nonMmapBuffer;
|
||||||
for( i = 0; i < self->numUserChannels; ++i )
|
for( i = 0; i < self->numUserChannels; ++i )
|
||||||
{
|
{
|
||||||
setChannel( bp, i, buffer, 1 );
|
setChannel( bp, i, buffer, 1 );
|
||||||
buffer += bufsize;
|
buffer += buf_per_ch_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3171,13 +3288,13 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
void *bufs[self->numHostChannels];
|
void *bufs[self->numHostChannels];
|
||||||
int bufsize = snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
|
unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels;
|
||||||
unsigned char *buffer = self->nonMmapBuffer;
|
unsigned char *buffer = self->nonMmapBuffer;
|
||||||
int i;
|
int i;
|
||||||
for( i = 0; i < self->numHostChannels; ++i )
|
for( i = 0; i < self->numHostChannels; ++i )
|
||||||
{
|
{
|
||||||
bufs[i] = buffer;
|
bufs[i] = buffer;
|
||||||
buffer += bufsize;
|
buffer += buf_per_ch_size;
|
||||||
}
|
}
|
||||||
res = snd_pcm_readn( self->pcm, bufs, *numFrames );
|
res = snd_pcm_readn( self->pcm, bufs, *numFrames );
|
||||||
}
|
}
|
||||||
|
@ -3185,11 +3302,6 @@ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* se
|
||||||
{
|
{
|
||||||
*xrun = 1;
|
*xrun = 1;
|
||||||
*numFrames = 0;
|
*numFrames = 0;
|
||||||
|
|
||||||
/* using realloc for optimisation
|
|
||||||
free( self->nonMmapBuffer );
|
|
||||||
self->nonMmapBuffer = NULL;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: pa_asio.cpp 1436 2009-12-10 08:09:21Z rossb $
|
* $Id: pa_asio.cpp 1525 2010-07-14 06:45:25Z rossb $
|
||||||
* Portable Audio I/O Library for ASIO Drivers
|
* Portable Audio I/O Library for ASIO Drivers
|
||||||
*
|
*
|
||||||
* Author: Stephane Letz
|
* Author: Stephane Letz
|
||||||
|
@ -169,6 +169,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* winmm.lib is needed for timeGetTime() (this is in winmm.a if you're using gcc) */
|
||||||
|
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
|
||||||
|
#pragma comment(lib, "winmm.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* external reference to ASIO SDK's asioDrivers.
|
/* external reference to ASIO SDK's asioDrivers.
|
||||||
|
|
||||||
This is a bit messy because we want to explicitly manage
|
This is a bit messy because we want to explicitly manage
|
||||||
|
@ -2528,8 +2534,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
else /* Using callback interface... */
|
else /* Using callback interface... */
|
||||||
{
|
{
|
||||||
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
|
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
|
||||||
inputChannelCount, inputSampleFormat, hostInputSampleFormat,
|
inputChannelCount, inputSampleFormat, (hostInputSampleFormat | paNonInterleaved),
|
||||||
outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
|
outputChannelCount, outputSampleFormat, (hostOutputSampleFormat | paNonInterleaved),
|
||||||
sampleRate, streamFlags, framesPerBuffer,
|
sampleRate, streamFlags, framesPerBuffer,
|
||||||
framesPerHostBuffer, paUtilFixedHostBufferSize,
|
framesPerHostBuffer, paUtilFixedHostBufferSize,
|
||||||
streamCallback, userData );
|
streamCallback, userData );
|
||||||
|
|
|
@ -249,7 +249,6 @@ static PaError AbortStream( PaStream *stream );
|
||||||
static PaError IsStreamStopped( PaStream *s );
|
static PaError IsStreamStopped( PaStream *s );
|
||||||
static PaError IsStreamActive( PaStream *stream );
|
static PaError IsStreamActive( PaStream *stream );
|
||||||
static PaTime GetStreamTime( PaStream *stream );
|
static PaTime GetStreamTime( PaStream *stream );
|
||||||
static void setStreamStartTime( PaStream *stream );
|
|
||||||
static OSStatus AudioIOProc( void *inRefCon,
|
static OSStatus AudioIOProc( void *inRefCon,
|
||||||
AudioUnitRenderActionFlags *ioActionFlags,
|
AudioUnitRenderActionFlags *ioActionFlags,
|
||||||
const AudioTimeStamp *inTimeStamp,
|
const AudioTimeStamp *inTimeStamp,
|
||||||
|
@ -798,6 +797,75 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
return paFormatIsSupported;
|
return paFormatIsSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( PaMacCoreStream *stream )
|
||||||
|
{
|
||||||
|
/* FIXME: not sure if this should be the sample rate of the output device or the output unit */
|
||||||
|
Float64 actualOutputSampleRate = stream->outDeviceSampleRate;
|
||||||
|
UInt32 propSize = sizeof(Float64);
|
||||||
|
OSStatus osErr = AudioDeviceGetProperty( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate, &propSize, &actualOutputSampleRate);
|
||||||
|
if( osErr != noErr || actualOutputSampleRate < .01 ) // avoid divide by zero if there's an error
|
||||||
|
actualOutputSampleRate = stream->outDeviceSampleRate;
|
||||||
|
|
||||||
|
stream->recipricalOfActualOutputSampleRate = 1. / actualOutputSampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OSStatus AudioDevicePropertyActualSampleRateListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
|
||||||
|
{
|
||||||
|
PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
|
||||||
|
|
||||||
|
pthread_mutex_lock( &stream->timingInformationMutex );
|
||||||
|
UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( stream );
|
||||||
|
pthread_mutex_unlock( &stream->timingInformationMutex );
|
||||||
|
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateOutputLatencySamplesFromDeviceProperty( PaMacCoreStream *stream )
|
||||||
|
{
|
||||||
|
UInt32 deviceOutputLatencySamples = 0;
|
||||||
|
UInt32 propSize = sizeof(UInt32);
|
||||||
|
OSStatus osErr = AudioDeviceGetProperty( stream->outputDevice, 0, /* isInput= */ FALSE, kAudioDevicePropertyLatency, &propSize, &deviceOutputLatencySamples);
|
||||||
|
if( osErr != noErr )
|
||||||
|
deviceOutputLatencySamples = 0;
|
||||||
|
|
||||||
|
stream->deviceOutputLatencySamples = deviceOutputLatencySamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OSStatus AudioDevicePropertyOutputLatencySamplesListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
|
||||||
|
{
|
||||||
|
PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
|
||||||
|
|
||||||
|
pthread_mutex_lock( &stream->timingInformationMutex );
|
||||||
|
UpdateOutputLatencySamplesFromDeviceProperty( stream );
|
||||||
|
pthread_mutex_unlock( &stream->timingInformationMutex );
|
||||||
|
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateInputLatencySamplesFromDeviceProperty( PaMacCoreStream *stream )
|
||||||
|
{
|
||||||
|
UInt32 deviceInputLatencySamples = 0;
|
||||||
|
UInt32 propSize = sizeof(UInt32);
|
||||||
|
OSStatus osErr = AudioDeviceGetProperty( stream->inputDevice, 0, /* isInput= */ TRUE, kAudioDevicePropertyLatency, &propSize, &deviceInputLatencySamples);
|
||||||
|
if( osErr != noErr )
|
||||||
|
deviceInputLatencySamples = 0;
|
||||||
|
|
||||||
|
stream->deviceInputLatencySamples = deviceInputLatencySamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OSStatus AudioDevicePropertyInputLatencySamplesListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData )
|
||||||
|
{
|
||||||
|
PaMacCoreStream *stream = (PaMacCoreStream*)inClientData;
|
||||||
|
|
||||||
|
pthread_mutex_lock( &stream->timingInformationMutex );
|
||||||
|
UpdateInputLatencySamplesFromDeviceProperty( stream );
|
||||||
|
pthread_mutex_unlock( &stream->timingInformationMutex );
|
||||||
|
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PaError OpenAndSetupOneAudioUnit(
|
static PaError OpenAndSetupOneAudioUnit(
|
||||||
const PaMacCoreStream *stream,
|
const PaMacCoreStream *stream,
|
||||||
const PaStreamParameters *inStreamParams,
|
const PaStreamParameters *inStreamParams,
|
||||||
|
@ -1356,6 +1424,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
stream->inputFramesPerBuffer = 0;
|
stream->inputFramesPerBuffer = 0;
|
||||||
stream->outputFramesPerBuffer = 0;
|
stream->outputFramesPerBuffer = 0;
|
||||||
stream->bufferProcessorIsInitialized = FALSE;
|
stream->bufferProcessorIsInitialized = FALSE;
|
||||||
|
stream->timingInformationMutexIsInitialized = 0;
|
||||||
|
|
||||||
/* assert( streamCallback ) ; */ /* only callback mode is implemented */
|
/* assert( streamCallback ) ; */ /* only callback mode is implemented */
|
||||||
if( streamCallback )
|
if( streamCallback )
|
||||||
|
@ -1656,7 +1725,39 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
stream->userInChan = inputChannelCount;
|
stream->userInChan = inputChannelCount;
|
||||||
stream->userOutChan = outputChannelCount;
|
stream->userOutChan = outputChannelCount;
|
||||||
|
|
||||||
stream->isTimeSet = FALSE;
|
pthread_mutex_init( &stream->timingInformationMutex, NULL );
|
||||||
|
stream->timingInformationMutexIsInitialized = 1;
|
||||||
|
|
||||||
|
if( stream->outputUnit ) {
|
||||||
|
UpdateReciprocalOfActualOutputSampleRateFromDeviceProperty( stream );
|
||||||
|
stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
|
||||||
|
|
||||||
|
AudioDeviceAddPropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate,
|
||||||
|
AudioDevicePropertyActualSampleRateListenerProc, stream );
|
||||||
|
|
||||||
|
UpdateOutputLatencySamplesFromDeviceProperty( stream );
|
||||||
|
stream->deviceOutputLatencySamples_ioProcCopy = stream->deviceOutputLatencySamples;
|
||||||
|
|
||||||
|
AudioDeviceAddPropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency,
|
||||||
|
AudioDevicePropertyOutputLatencySamplesListenerProc, stream );
|
||||||
|
|
||||||
|
}else{
|
||||||
|
stream->recipricalOfActualOutputSampleRate = 1.;
|
||||||
|
stream->recipricalOfActualOutputSampleRate_ioProcCopy = 0.;
|
||||||
|
stream->deviceOutputLatencySamples_ioProcCopy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stream->inputUnit ) {
|
||||||
|
UpdateInputLatencySamplesFromDeviceProperty( stream );
|
||||||
|
stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples;
|
||||||
|
|
||||||
|
AudioDeviceAddPropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency,
|
||||||
|
AudioDevicePropertyInputLatencySamplesListenerProc, stream );
|
||||||
|
}else{
|
||||||
|
stream->deviceInputLatencySamples = 0;
|
||||||
|
stream->deviceInputLatencySamples_ioProcCopy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
stream->state = STOPPED;
|
stream->state = STOPPED;
|
||||||
stream->xrunFlags = 0;
|
stream->xrunFlags = 0;
|
||||||
|
|
||||||
|
@ -1669,56 +1770,12 @@ error:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define HOST_TIME_TO_PA_TIME( x ) ( AudioConvertHostTimeToNanos( (x) ) * 1.0E-09) /* convert to nanoseconds and then to seconds */
|
||||||
|
|
||||||
PaTime GetStreamTime( PaStream *s )
|
PaTime GetStreamTime( PaStream *s )
|
||||||
{
|
{
|
||||||
/* FIXME: I am not at all sure this timing info stuff is right.
|
return HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() );
|
||||||
patest_sine_time reports negative latencies, which is wierd.*/
|
|
||||||
PaMacCoreStream *stream = (PaMacCoreStream*)s;
|
|
||||||
AudioTimeStamp timeStamp;
|
|
||||||
|
|
||||||
VVDBUG(("GetStreamTime()\n"));
|
|
||||||
|
|
||||||
if ( !stream->isTimeSet )
|
|
||||||
return (PaTime)0;
|
|
||||||
|
|
||||||
if ( stream->outputDevice ) {
|
|
||||||
AudioDeviceGetCurrentTime( stream->outputDevice, &timeStamp);
|
|
||||||
return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->outDeviceSampleRate;
|
|
||||||
} else if ( stream->inputDevice ) {
|
|
||||||
AudioDeviceGetCurrentTime( stream->inputDevice, &timeStamp);
|
|
||||||
return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->inDeviceSampleRate;
|
|
||||||
} else {
|
|
||||||
return (PaTime)0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setStreamStartTime( PaStream *stream )
|
|
||||||
{
|
|
||||||
/* FIXME: I am not at all sure this timing info stuff is right.
|
|
||||||
patest_sine_time reports negative latencies, which is wierd.*/
|
|
||||||
PaMacCoreStream *s = (PaMacCoreStream *) stream;
|
|
||||||
VVDBUG(("setStreamStartTime()\n"));
|
|
||||||
if( s->outputDevice )
|
|
||||||
AudioDeviceGetCurrentTime( s->outputDevice, &s->startTime);
|
|
||||||
else if( s->inputDevice )
|
|
||||||
AudioDeviceGetCurrentTime( s->inputDevice, &s->startTime);
|
|
||||||
else
|
|
||||||
bzero( &s->startTime, sizeof( s->startTime ) );
|
|
||||||
|
|
||||||
//FIXME: we need a memory barier here
|
|
||||||
|
|
||||||
s->isTimeSet = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PaTime TimeStampToSecs(PaMacCoreStream *stream, const AudioTimeStamp* timeStamp)
|
|
||||||
{
|
|
||||||
VVDBUG(("TimeStampToSecs()\n"));
|
|
||||||
//printf( "ATS: %lu, %g, %g\n", timeStamp->mFlags, timeStamp->mSampleTime, timeStamp->mRateScalar );
|
|
||||||
if (timeStamp->mFlags & kAudioTimeStampSampleTimeValid)
|
|
||||||
return (timeStamp->mSampleTime / stream->sampleRate);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RING_BUFFER_EMPTY (1000)
|
#define RING_BUFFER_EMPTY (1000)
|
||||||
|
@ -1799,22 +1856,66 @@ static OSStatus AudioIOProc( void *inRefCon,
|
||||||
}
|
}
|
||||||
----------------------------------------------------------------- */
|
----------------------------------------------------------------- */
|
||||||
|
|
||||||
if( !stream->isTimeSet )
|
/* compute PaStreamCallbackTimeInfo */
|
||||||
setStreamStartTime( stream );
|
|
||||||
|
|
||||||
if( isRender ) {
|
if( pthread_mutex_trylock( &stream->timingInformationMutex ) == 0 ){
|
||||||
AudioTimeStamp currentTime;
|
/* snapshot the ioproc copy of timing information */
|
||||||
timeInfo.outputBufferDacTime = TimeStampToSecs(stream, inTimeStamp);
|
stream->deviceOutputLatencySamples_ioProcCopy = stream->deviceOutputLatencySamples;
|
||||||
AudioDeviceGetCurrentTime(stream->outputDevice, ¤tTime);
|
stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
|
||||||
timeInfo.currentTime = TimeStampToSecs(stream, ¤tTime);
|
stream->deviceInputLatencySamples_ioProcCopy = stream->deviceInputLatencySamples;
|
||||||
|
pthread_mutex_unlock( &stream->timingInformationMutex );
|
||||||
}
|
}
|
||||||
if( isRender && stream->inputUnit == stream->outputUnit )
|
|
||||||
timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
|
/* For timeInfo.currentTime we could calculate current time backwards from the HAL audio
|
||||||
if( !isRender ) {
|
output time to give a more accurate impression of the current timeslice but it doesn't
|
||||||
AudioTimeStamp currentTime;
|
seem worth it at the moment since other PA host APIs don't do any better.
|
||||||
timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);
|
*/
|
||||||
AudioDeviceGetCurrentTime(stream->inputDevice, ¤tTime);
|
timeInfo.currentTime = HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() );
|
||||||
timeInfo.currentTime = TimeStampToSecs(stream, ¤tTime);
|
|
||||||
|
/*
|
||||||
|
For an input HAL AU, inTimeStamp is the time the samples are received from the hardware,
|
||||||
|
for an output HAL AU inTimeStamp is the time the samples are sent to the hardware.
|
||||||
|
PA expresses timestamps in terms of when the samples enter the ADC or leave the DAC
|
||||||
|
so we add or subtract kAudioDevicePropertyLatency below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FIXME: not sure what to do below if the host timestamps aren't valid (kAudioTimeStampHostTimeValid isn't set)
|
||||||
|
Could ask on CA mailing list if it is possible for it not to be set. If so, could probably grab a now timestamp
|
||||||
|
at the top and compute from there (modulo scheduling jitter) or ask on mailing list for other options. */
|
||||||
|
|
||||||
|
if( isRender )
|
||||||
|
{
|
||||||
|
if( stream->inputUnit ) /* full duplex */
|
||||||
|
{
|
||||||
|
if( stream->inputUnit == stream->outputUnit ) /* full duplex AUHAL IOProc */
|
||||||
|
{
|
||||||
|
/* FIXME: review. i'm not sure this computation of inputBufferAdcTime is correct for a full-duplex AUHAL */
|
||||||
|
timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
|
||||||
|
- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
|
||||||
|
timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
|
||||||
|
+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
|
||||||
|
}
|
||||||
|
else /* full duplex with ring-buffer from a separate input AUHAL ioproc */
|
||||||
|
{
|
||||||
|
/* FIXME: review. this computation of inputBufferAdcTime is definitely wrong since it doesn't take the ring buffer latency into account */
|
||||||
|
timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
|
||||||
|
- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
|
||||||
|
timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
|
||||||
|
+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* output only */
|
||||||
|
{
|
||||||
|
timeInfo.inputBufferAdcTime = 0;
|
||||||
|
timeInfo.outputBufferDacTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
|
||||||
|
+ stream->deviceOutputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* input only */
|
||||||
|
{
|
||||||
|
timeInfo.inputBufferAdcTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime)
|
||||||
|
- stream->deviceInputLatencySamples_ioProcCopy * stream->recipricalOfActualOutputSampleRate_ioProcCopy; // FIXME should be using input sample rate here?
|
||||||
|
timeInfo.outputBufferDacTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime );
|
//printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime );
|
||||||
|
@ -2128,7 +2229,6 @@ static OSStatus AudioIOProc( void *inRefCon,
|
||||||
case paContinue: break;
|
case paContinue: break;
|
||||||
case paComplete:
|
case paComplete:
|
||||||
case paAbort:
|
case paAbort:
|
||||||
stream->isTimeSet = FALSE;
|
|
||||||
stream->state = CALLBACK_STOPPED ;
|
stream->state = CALLBACK_STOPPED ;
|
||||||
if( stream->outputUnit )
|
if( stream->outputUnit )
|
||||||
AudioOutputUnitStop(stream->outputUnit);
|
AudioOutputUnitStop(stream->outputUnit);
|
||||||
|
@ -2157,6 +2257,19 @@ static PaError CloseStream( PaStream* s )
|
||||||
VDBUG( ( "Closing stream.\n" ) );
|
VDBUG( ( "Closing stream.\n" ) );
|
||||||
|
|
||||||
if( stream ) {
|
if( stream ) {
|
||||||
|
|
||||||
|
if( stream->outputUnit ) {
|
||||||
|
AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyActualSampleRate,
|
||||||
|
AudioDevicePropertyActualSampleRateListenerProc );
|
||||||
|
AudioDeviceRemovePropertyListener( stream->outputDevice, 0, /* isInput = */ FALSE, kAudioDevicePropertyLatency,
|
||||||
|
AudioDevicePropertyOutputLatencySamplesListenerProc );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stream->inputUnit ) {
|
||||||
|
AudioDeviceRemovePropertyListener( stream->inputDevice, 0, /* isInput = */ TRUE, kAudioDevicePropertyLatency,
|
||||||
|
AudioDevicePropertyInputLatencySamplesListenerProc );
|
||||||
|
}
|
||||||
|
|
||||||
if( stream->outputUnit ) {
|
if( stream->outputUnit ) {
|
||||||
int count = removeFromXRunListenerList( stream );
|
int count = removeFromXRunListenerList( stream );
|
||||||
if( count == 0 )
|
if( count == 0 )
|
||||||
|
@ -2203,6 +2316,10 @@ static PaError CloseStream( PaStream* s )
|
||||||
return result;
|
return result;
|
||||||
if( stream->bufferProcessorIsInitialized )
|
if( stream->bufferProcessorIsInitialized )
|
||||||
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
|
PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
|
||||||
|
|
||||||
|
if( stream->timingInformationMutexIsInitialized )
|
||||||
|
pthread_mutex_destroy( &stream->timingInformationMutex );
|
||||||
|
|
||||||
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
|
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
|
||||||
PaUtil_FreeMemory( stream );
|
PaUtil_FreeMemory( stream );
|
||||||
}
|
}
|
||||||
|
@ -2233,9 +2350,6 @@ static PaError StartStream( PaStream *s )
|
||||||
ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) );
|
ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//setStreamStartTime( stream );
|
|
||||||
//stream->isTimeSet = TRUE;
|
|
||||||
|
|
||||||
return paNoError;
|
return paNoError;
|
||||||
#undef ERR_WRAP
|
#undef ERR_WRAP
|
||||||
}
|
}
|
||||||
|
@ -2266,7 +2380,6 @@ static PaError StopStream( PaStream *s )
|
||||||
waitUntilBlioWriteBufferIsFlushed( &stream->blio );
|
waitUntilBlioWriteBufferIsFlushed( &stream->blio );
|
||||||
VDBUG( ( "Stopping stream.\n" ) );
|
VDBUG( ( "Stopping stream.\n" ) );
|
||||||
|
|
||||||
stream->isTimeSet = FALSE;
|
|
||||||
stream->state = STOPPING;
|
stream->state = STOPPING;
|
||||||
|
|
||||||
#define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0)
|
#define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0)
|
||||||
|
@ -2314,10 +2427,6 @@ static PaError StopStream( PaStream *s )
|
||||||
if( paErr )
|
if( paErr )
|
||||||
return paErr;
|
return paErr;
|
||||||
|
|
||||||
/*
|
|
||||||
//stream->isTimeSet = FALSE;
|
|
||||||
*/
|
|
||||||
|
|
||||||
VDBUG( ( "Stream Stopped.\n" ) );
|
VDBUG( ( "Stream Stopped.\n" ) );
|
||||||
return paNoError;
|
return paNoError;
|
||||||
#undef ERR_WRAP
|
#undef ERR_WRAP
|
||||||
|
|
|
@ -142,7 +142,6 @@ typedef struct PaMacCoreStream
|
||||||
AudioTimeStamp startTime;
|
AudioTimeStamp startTime;
|
||||||
/* FIXME: instead of volatile, these should be properly memory barriered */
|
/* FIXME: instead of volatile, these should be properly memory barriered */
|
||||||
volatile PaStreamCallbackFlags xrunFlags;
|
volatile PaStreamCallbackFlags xrunFlags;
|
||||||
volatile bool isTimeSet;
|
|
||||||
volatile enum {
|
volatile enum {
|
||||||
STOPPED = 0, /* playback is completely stopped,
|
STOPPED = 0, /* playback is completely stopped,
|
||||||
and the user has called StopStream(). */
|
and the user has called StopStream(). */
|
||||||
|
@ -159,6 +158,18 @@ typedef struct PaMacCoreStream
|
||||||
//these may be different from the stream sample rate due to SR conversion:
|
//these may be different from the stream sample rate due to SR conversion:
|
||||||
double outDeviceSampleRate;
|
double outDeviceSampleRate;
|
||||||
double inDeviceSampleRate;
|
double inDeviceSampleRate;
|
||||||
|
|
||||||
|
/* data updated by main thread and notifications, protected by timingInformationMutex */
|
||||||
|
int timingInformationMutexIsInitialized;
|
||||||
|
pthread_mutex_t timingInformationMutex;
|
||||||
|
Float64 recipricalOfActualOutputSampleRate;
|
||||||
|
UInt32 deviceOutputLatencySamples;
|
||||||
|
UInt32 deviceInputLatencySamples;
|
||||||
|
|
||||||
|
/* while the io proc is active, the following values are only accessed and manipulated by the ioproc */
|
||||||
|
Float64 recipricalOfActualOutputSampleRate_ioProcCopy;
|
||||||
|
UInt32 deviceOutputLatencySamples_ioProcCopy;
|
||||||
|
UInt32 deviceInputLatencySamples_ioProcCopy;
|
||||||
}
|
}
|
||||||
PaMacCoreStream;
|
PaMacCoreStream;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: pa_win_ds.c 1450 2010-02-03 00:28:29Z rossb $
|
* $Id: pa_win_ds.c 1534 2010-08-03 21:02:52Z dmitrykos $
|
||||||
* Portable Audio I/O Library DirectSound implementation
|
* Portable Audio I/O Library DirectSound implementation
|
||||||
*
|
*
|
||||||
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina
|
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina
|
||||||
|
@ -244,7 +244,7 @@ typedef struct PaWinDsStream
|
||||||
/* Try to detect play buffer underflows. */
|
/* Try to detect play buffer underflows. */
|
||||||
LARGE_INTEGER perfCounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */
|
LARGE_INTEGER perfCounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */
|
||||||
LARGE_INTEGER previousPlayTime;
|
LARGE_INTEGER previousPlayTime;
|
||||||
UINT previousPlayCursor;
|
DWORD previousPlayCursor;
|
||||||
UINT outputUnderflowCount;
|
UINT outputUnderflowCount;
|
||||||
BOOL outputIsRunning;
|
BOOL outputIsRunning;
|
||||||
INT finalZeroBytesWritten; /* used to determine when we've flushed the whole buffer */
|
INT finalZeroBytesWritten; /* used to determine when we've flushed the whole buffer */
|
||||||
|
@ -1502,10 +1502,10 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
|
|
||||||
/* retrieve the pre ds 8 buffer interfaces which are used by the rest of the code */
|
/* retrieve the pre ds 8 buffer interfaces which are used by the rest of the code */
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface( pCaptureBuffer8, &IID_IDirectSoundCaptureBuffer, &stream->pDirectSoundInputBuffer );
|
hr = IUnknown_QueryInterface( pCaptureBuffer8, &IID_IDirectSoundCaptureBuffer, (LPVOID *)&stream->pDirectSoundInputBuffer );
|
||||||
|
|
||||||
if( hr == DS_OK )
|
if( hr == DS_OK )
|
||||||
hr = IUnknown_QueryInterface( pRenderBuffer8, &IID_IDirectSoundBuffer, &stream->pDirectSoundOutputBuffer );
|
hr = IUnknown_QueryInterface( pRenderBuffer8, &IID_IDirectSoundBuffer, (LPVOID *)&stream->pDirectSoundOutputBuffer );
|
||||||
|
|
||||||
/* release the ds 8 interfaces, we don't need them */
|
/* release the ds 8 interfaces, we don't need them */
|
||||||
IUnknown_Release( pCaptureBuffer8 );
|
IUnknown_Release( pCaptureBuffer8 );
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: pa_jack.c 1346 2008-02-20 10:09:20Z rossb $
|
* $Id: pa_jack.c 1541 2010-09-22 06:33:47Z dmitrykos $
|
||||||
* PortAudio Portable Real-Time Audio Library
|
* PortAudio Portable Real-Time Audio Library
|
||||||
* Latest Version at: http://www.portaudio.com
|
* Latest Version at: http://www.portaudio.com
|
||||||
* JACK Implementation by Joshua Haberman
|
* JACK Implementation by Joshua Haberman
|
||||||
|
@ -71,8 +71,6 @@
|
||||||
#include "pa_ringbuffer.h"
|
#include "pa_ringbuffer.h"
|
||||||
#include "pa_debugprint.h"
|
#include "pa_debugprint.h"
|
||||||
|
|
||||||
static int aErr_;
|
|
||||||
static PaError paErr_; /* For use with ENSURE_PA */
|
|
||||||
static pthread_t mainThread_;
|
static pthread_t mainThread_;
|
||||||
static char *jackErr_ = NULL;
|
static char *jackErr_ = NULL;
|
||||||
static const char* clientName_ = "PortAudio";
|
static const char* clientName_ = "PortAudio";
|
||||||
|
@ -83,15 +81,17 @@ static const char* clientName_ = "PortAudio";
|
||||||
/* Check PaError */
|
/* Check PaError */
|
||||||
#define ENSURE_PA(expr) \
|
#define ENSURE_PA(expr) \
|
||||||
do { \
|
do { \
|
||||||
if( (paErr_ = (expr)) < paNoError ) \
|
PaError paErr; \
|
||||||
|
if( (paErr = (expr)) < paNoError ) \
|
||||||
{ \
|
{ \
|
||||||
if( (paErr_) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
|
if( (paErr) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
|
||||||
{ \
|
{ \
|
||||||
if (! jackErr_ ) jackErr_ = "unknown error";\
|
const char *err = jackErr_; \
|
||||||
PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
|
if (! err ) err = "unknown error"; \
|
||||||
|
PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \
|
||||||
} \
|
} \
|
||||||
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
|
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
|
||||||
result = paErr_; \
|
result = paErr; \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
} while( 0 )
|
} while( 0 )
|
||||||
|
@ -102,8 +102,9 @@ static const char* clientName_ = "PortAudio";
|
||||||
{ \
|
{ \
|
||||||
if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
|
if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
|
||||||
{ \
|
{ \
|
||||||
if (!jackErr_) jackErr_ = "unknown error";\
|
const char *err = jackErr_; \
|
||||||
PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
|
if (!err) err = "unknown error"; \
|
||||||
|
PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \
|
||||||
} \
|
} \
|
||||||
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
|
PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
|
||||||
result = (code); \
|
result = (code); \
|
||||||
|
@ -112,8 +113,10 @@ static const char* clientName_ = "PortAudio";
|
||||||
} while( 0 )
|
} while( 0 )
|
||||||
|
|
||||||
#define ASSERT_CALL(expr, success) \
|
#define ASSERT_CALL(expr, success) \
|
||||||
aErr_ = (expr); \
|
do { \
|
||||||
assert( aErr_ == success );
|
int err = (expr); \
|
||||||
|
assert( err == success ); \
|
||||||
|
} while( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions that directly map to the PortAudio stream interface
|
* Functions that directly map to the PortAudio stream interface
|
||||||
|
@ -826,6 +829,7 @@ static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
|
||||||
PaUtil_FreeMemory( jackHostApi );
|
PaUtil_FreeMemory( jackHostApi );
|
||||||
|
|
||||||
free( jackErr_ );
|
free( jackErr_ );
|
||||||
|
jackErr_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
|
@ -1000,7 +1004,7 @@ static PaError WaitCondition( PaJackHostApiRepresentation *hostApi )
|
||||||
PaTime pt = PaUtil_GetTime();
|
PaTime pt = PaUtil_GetTime();
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
ts.tv_sec = (time_t) floor( pt + 1 );
|
ts.tv_sec = (time_t) floor( pt + 10 * 60 /* 10 minutes */ );
|
||||||
ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000);
|
ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000);
|
||||||
/* XXX: Best enclose in loop, in case of spurious wakeups? */
|
/* XXX: Best enclose in loop, in case of spurious wakeups? */
|
||||||
err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts );
|
err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts );
|
||||||
|
@ -1276,10 +1280,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
&stream->bufferProcessor,
|
&stream->bufferProcessor,
|
||||||
inputChannelCount,
|
inputChannelCount,
|
||||||
inputSampleFormat,
|
inputSampleFormat,
|
||||||
paFloat32, /* hostInputSampleFormat */
|
paFloat32 | paNonInterleaved, /* hostInputSampleFormat */
|
||||||
outputChannelCount,
|
outputChannelCount,
|
||||||
outputSampleFormat,
|
outputSampleFormat,
|
||||||
paFloat32, /* hostOutputSampleFormat */
|
paFloat32 | paNonInterleaved, /* hostOutputSampleFormat */
|
||||||
jackSr,
|
jackSr,
|
||||||
streamFlags,
|
streamFlags,
|
||||||
framesPerBuffer,
|
framesPerBuffer,
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: pa_unix_oss.c 1385 2008-06-05 21:13:54Z aknudsen $
|
* $Id: pa_unix_oss.c 1509 2010-06-06 17:36:33Z dmitrykos $
|
||||||
* PortAudio Portable Real-Time Audio Library
|
* PortAudio Portable Real-Time Audio Library
|
||||||
* Latest Version at: http://www.portaudio.com
|
* Latest Version at: http://www.portaudio.com
|
||||||
* OSS implementation by:
|
* OSS implementation by:
|
||||||
|
@ -185,7 +185,7 @@ typedef struct PaOssStream
|
||||||
double sampleRate;
|
double sampleRate;
|
||||||
|
|
||||||
int callbackMode;
|
int callbackMode;
|
||||||
int callbackStop, callbackAbort;
|
volatile int callbackStop, callbackAbort;
|
||||||
|
|
||||||
PaOssStreamComponent *capture, *playback;
|
PaOssStreamComponent *capture, *playback;
|
||||||
unsigned long pollTimeout;
|
unsigned long pollTimeout;
|
||||||
|
@ -1317,7 +1317,17 @@ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *fr
|
||||||
|
|
||||||
while( pollPlayback || pollCapture )
|
while( pollPlayback || pollCapture )
|
||||||
{
|
{
|
||||||
|
#ifdef PTHREAD_CANCELED
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
|
#else
|
||||||
|
/* avoid indefinite waiting on thread not supporting cancelation */
|
||||||
|
if( stream->callbackStop || stream->callbackAbort )
|
||||||
|
{
|
||||||
|
PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" ));
|
||||||
|
(*frames) = 0;
|
||||||
|
return paNoError;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* select may modify the timeout parameter */
|
/* select may modify the timeout parameter */
|
||||||
selectTimeval.tv_usec = timeout;
|
selectTimeval.tv_usec = timeout;
|
||||||
|
@ -1341,8 +1351,17 @@ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *fr
|
||||||
ENSURE_( -1, paUnanticipatedHostError );
|
ENSURE_( -1, paUnanticipatedHostError );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#ifdef PTHREAD_CANCELED
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
|
#else
|
||||||
|
/* avoid indefinite waiting on thread not supporting cancelation */
|
||||||
|
if( stream->callbackStop || stream->callbackAbort )
|
||||||
|
{
|
||||||
|
PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" ));
|
||||||
|
(*frames) = 0;
|
||||||
|
return paNoError;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if( pollCapture )
|
if( pollCapture )
|
||||||
{
|
{
|
||||||
if( FD_ISSET( captureFd, &readFds ) )
|
if( FD_ISSET( captureFd, &readFds ) )
|
||||||
|
@ -1603,8 +1622,15 @@ static void *PaOSS_AudioThreadProc( void *userData )
|
||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
|
#ifdef PTHREAD_CANCELED
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
|
#else
|
||||||
|
if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */
|
||||||
|
{
|
||||||
|
PA_DEBUG(( "Aborting callback thread\n" ));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if( stream->callbackStop && callbackResult == paContinue )
|
if( stream->callbackStop && callbackResult == paContinue )
|
||||||
{
|
{
|
||||||
PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
|
PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
|
||||||
|
@ -1631,8 +1657,21 @@ static void *PaOSS_AudioThreadProc( void *userData )
|
||||||
{
|
{
|
||||||
unsigned long frames = framesAvail;
|
unsigned long frames = framesAvail;
|
||||||
|
|
||||||
|
#ifdef PTHREAD_CANCELED
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
|
#else
|
||||||
|
if( stream->callbackStop )
|
||||||
|
{
|
||||||
|
PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
|
||||||
|
callbackResult = paComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */
|
||||||
|
{
|
||||||
|
PA_DEBUG(( "Aborting callback thread\n" ));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
|
PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
|
||||||
|
|
||||||
/* Read data */
|
/* Read data */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: pa_unix_util.c 1419 2009-10-22 17:28:35Z bjornroche $
|
* $Id: pa_unix_util.c 1510 2010-06-10 08:05:29Z dmitrykos $
|
||||||
* Portable Audio I/O Library
|
* Portable Audio I/O Library
|
||||||
* UNIX platform-specific support functions
|
* UNIX platform-specific support functions
|
||||||
*
|
*
|
||||||
|
@ -193,9 +193,15 @@ PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *e
|
||||||
if( exitResult )
|
if( exitResult )
|
||||||
*exitResult = paNoError;
|
*exitResult = paNoError;
|
||||||
|
|
||||||
|
/* If pthread_cancel is not supported (Android platform) whole this function can lead to indefinite waiting if
|
||||||
|
working thread (callbackThread) has'n received any stop signals from outside, please keep
|
||||||
|
this in mind when considering using PaUtil_CancelThreading
|
||||||
|
*/
|
||||||
|
#ifdef PTHREAD_CANCELED
|
||||||
/* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
|
/* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
|
||||||
if( !wait )
|
if( !wait )
|
||||||
pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */
|
pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */
|
||||||
|
#endif
|
||||||
pthread_join( threading->callbackThread, &pret );
|
pthread_join( threading->callbackThread, &pret );
|
||||||
|
|
||||||
#ifdef PTHREAD_CANCELED
|
#ifdef PTHREAD_CANCELED
|
||||||
|
@ -427,12 +433,19 @@ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResul
|
||||||
{
|
{
|
||||||
PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread ));
|
PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread ));
|
||||||
/* XXX: Safe to call this if the thread has exited on its own? */
|
/* XXX: Safe to call this if the thread has exited on its own? */
|
||||||
|
#ifdef PTHREAD_CANCELED
|
||||||
pthread_cancel( self->thread );
|
pthread_cancel( self->thread );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread ));
|
PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread ));
|
||||||
PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 );
|
PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 );
|
||||||
|
|
||||||
|
#ifdef PTHREAD_CANCELED
|
||||||
if( pret && PTHREAD_CANCELED != pret )
|
if( pret && PTHREAD_CANCELED != pret )
|
||||||
|
#else
|
||||||
|
/* !wait means the thread may have been canceled */
|
||||||
|
if( pret && wait )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if( exitResult )
|
if( exitResult )
|
||||||
{
|
{
|
||||||
|
@ -506,9 +519,11 @@ PaError PaUnixMutex_Terminate( PaUnixMutex* self )
|
||||||
PaError PaUnixMutex_Lock( PaUnixMutex* self )
|
PaError PaUnixMutex_Lock( PaUnixMutex* self )
|
||||||
{
|
{
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
int oldState;
|
|
||||||
|
|
||||||
|
#ifdef PTHREAD_CANCEL
|
||||||
|
int oldState;
|
||||||
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 );
|
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 );
|
||||||
|
#endif
|
||||||
PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 );
|
PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 );
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -522,10 +537,12 @@ error:
|
||||||
PaError PaUnixMutex_Unlock( PaUnixMutex* self )
|
PaError PaUnixMutex_Unlock( PaUnixMutex* self )
|
||||||
{
|
{
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
int oldState;
|
|
||||||
|
|
||||||
PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 );
|
PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 );
|
||||||
|
#ifdef PTHREAD_CANCEL
|
||||||
|
int oldState;
|
||||||
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 );
|
PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -37,6 +37,16 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmreg.h>
|
#include <mmreg.h>
|
||||||
|
#ifndef WAVE_FORMAT_IEEE_FLOAT
|
||||||
|
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this
|
||||||
|
#endif
|
||||||
|
#ifndef _WAVEFORMATEXTENSIBLE_
|
||||||
|
#define _WAVEFORMATEXTENSIBLE_ // MinGW32 does not define this
|
||||||
|
#endif
|
||||||
|
#ifndef _INC_MMREG
|
||||||
|
#define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||||
|
#endif
|
||||||
|
#include <winioctl.h> // MinGW32 does not define this automatically
|
||||||
#include <ks.h>
|
#include <ks.h>
|
||||||
#include <ksmedia.h>
|
#include <ksmedia.h>
|
||||||
#include <stdio.h> // just for some development printfs
|
#include <stdio.h> // just for some development printfs
|
||||||
|
@ -45,13 +55,10 @@
|
||||||
#include "pa_util.h"
|
#include "pa_util.h"
|
||||||
#include "pa_win_wdmks_utils.h"
|
#include "pa_win_wdmks_utils.h"
|
||||||
|
|
||||||
|
#if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB)
|
||||||
#ifndef PA_WDMKS_NO_KSGUID_LIB
|
|
||||||
|
|
||||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
|
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
|
||||||
#pragma comment( lib, "ksguid.lib" )
|
#pragma comment( lib, "ksguid.lib" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
|
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
|
||||||
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||||
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
|
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
|
||||||
|
@ -59,9 +66,7 @@
|
||||||
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
|
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
|
||||||
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
|
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
|
||||||
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
|
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
|
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
|
||||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
|
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
|
||||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
|
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
|
||||||
|
@ -69,7 +74,6 @@ static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_
|
||||||
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
|
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
|
||||||
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
|
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
|
||||||
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
|
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -102,10 +102,18 @@ ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei)
|
||||||
* routine. We need to cleanup before letting the exception
|
* routine. We need to cleanup before letting the exception
|
||||||
* out of thread scope.
|
* out of thread scope.
|
||||||
*/
|
*/
|
||||||
pthread_t self = pthread_self ();
|
|
||||||
|
|
||||||
(void) pthread_mutex_destroy (&((ptw32_thread_t *)self.p)->cancelLock);
|
// Air Says: No we don't. If a structured exception makes it this far, the program is
|
||||||
ptw32_callUserDestroyRoutines (self);
|
// screwed anyway (will cause a GPF / close program dialog to the user) and so a little lost
|
||||||
|
// cleanup isn't going to matter anyway. Furthermore, no other stack objects are
|
||||||
|
// getting unwound, so if anything in the User destroy routines are dependent on other
|
||||||
|
// stack objects being unwound, it'll cause a secondary premature crash which can confuse
|
||||||
|
// debugging efforts. There is a reason microsoft recommends *not* doing much of anything
|
||||||
|
// from the context of an exception filter... --air
|
||||||
|
|
||||||
|
//pthread_t self = pthread_self ();
|
||||||
|
//(void) pthread_mutex_destroy (&((ptw32_thread_t *)self.p)->cancelLock);
|
||||||
|
//ptw32_callUserDestroyRoutines (self);
|
||||||
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1179,6 +1179,9 @@ wxRenameFile(const wxString& file1, const wxString& file2, bool overwrite)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
return ::MoveFileEx(file1,file2, MOVEFILE_REPLACE_EXISTING) != 0;
|
||||||
|
#else
|
||||||
#if !defined(__WXWINCE__) && !defined(__WXPALMOS__)
|
#if !defined(__WXWINCE__) && !defined(__WXPALMOS__)
|
||||||
// Normal system call
|
// Normal system call
|
||||||
if ( wxRename (file1, file2) == 0 )
|
if ( wxRename (file1, file2) == 0 )
|
||||||
|
@ -1192,6 +1195,7 @@ wxRenameFile(const wxString& file1, const wxString& file2, bool overwrite)
|
||||||
}
|
}
|
||||||
// Give up
|
// Give up
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxRemoveFile(const wxString& file)
|
bool wxRemoveFile(const wxString& file)
|
||||||
|
|
|
@ -85,7 +85,8 @@ bool wxDbgHelpDLL::BindFunctions(const wxDynamicLibrary& dllDbgHelp)
|
||||||
// of WinDbgHlp (v6.5 or later). If it binds as NULL, that's ok. Its only needed in
|
// of WinDbgHlp (v6.5 or later). If it binds as NULL, that's ok. Its only needed in
|
||||||
// order to reload symbols for apps that dynamically unload/reload plugins.
|
// order to reload symbols for apps that dynamically unload/reload plugins.
|
||||||
|
|
||||||
SymRefreshModuleList = (SymRefreshModuleList_t)dllDbgHelp.GetSymbol(_T("SymRefreshModuleList"));
|
SymRefreshModuleList = (SymRefreshModuleList_t) (dllDbgHelp.HasSymbol(_T("SymRefreshModuleList")) ?
|
||||||
|
dllDbgHelp.GetSymbol(_T("SymRefreshModuleList")) : NULL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,24 +0,0 @@
|
||||||
# Try to find A52
|
|
||||||
# Once done, this will define
|
|
||||||
#
|
|
||||||
# A52_FOUND - system has A52
|
|
||||||
# A52_INCLUDE_DIR - the A52 include directories
|
|
||||||
# A52_LIBRARIES - link these to use A52
|
|
||||||
|
|
||||||
if(A52_INCLUDE_DIR AND A52_LIBRARIES)
|
|
||||||
set(A52_FIND_QUIETLY TRUE)
|
|
||||||
endif(A52_INCLUDE_DIR AND A52_LIBRARIES)
|
|
||||||
|
|
||||||
# include dir
|
|
||||||
find_path(A52_INCLUDE_DIR a52dec/a52.h)
|
|
||||||
|
|
||||||
# finally the library itself
|
|
||||||
find_library(libA52 NAMES a52)
|
|
||||||
set(A52_LIBRARIES ${libA52})
|
|
||||||
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set A52_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(A52 DEFAULT_MSG A52_LIBRARIES A52_INCLUDE_DIR)
|
|
||||||
|
|
||||||
mark_as_advanced(A52_LIBRARIES A52_INCLUDE_DIR)
|
|
|
@ -42,7 +42,6 @@ if(NOT FORCE_INTERNAL_ZLIB)
|
||||||
endif(NOT FORCE_INTERNAL_ZLIB)
|
endif(NOT FORCE_INTERNAL_ZLIB)
|
||||||
|
|
||||||
## Use pcsx2 package to find module
|
## Use pcsx2 package to find module
|
||||||
include(FindA52)
|
|
||||||
include(FindCg)
|
include(FindCg)
|
||||||
include(FindGlew)
|
include(FindGlew)
|
||||||
include(FindPortAudio)
|
include(FindPortAudio)
|
||||||
|
@ -96,11 +95,6 @@ if(Linux)
|
||||||
endif(X11_FOUND)
|
endif(X11_FOUND)
|
||||||
endif(Linux)
|
endif(Linux)
|
||||||
|
|
||||||
# A52
|
|
||||||
if(A52_FOUND)
|
|
||||||
include_directories(${A52_INCLUDE_DIR})
|
|
||||||
endif(A52_FOUND)
|
|
||||||
|
|
||||||
# ALSA
|
# ALSA
|
||||||
if(ALSA_FOUND)
|
if(ALSA_FOUND)
|
||||||
include_directories(${ALSA_INCLUDE_DIRS})
|
include_directories(${ALSA_INCLUDE_DIRS})
|
||||||
|
|
|
@ -8,7 +8,7 @@ set(msg_dep_zerogs "check these libraries -> glew (>=1.5), opengl, X11, nvi
|
||||||
set(msg_dep_zzogl "check these libraries -> glew (>=1.5), jpeg (>=6.2), opengl, X11, nvidia-cg-toolkit (>=2.1), pcsx2 common libs")
|
set(msg_dep_zzogl "check these libraries -> glew (>=1.5), jpeg (>=6.2), opengl, X11, nvidia-cg-toolkit (>=2.1), pcsx2 common libs")
|
||||||
set(msg_dep_onepad "check these libraries -> sdl (>=1.2)")
|
set(msg_dep_onepad "check these libraries -> sdl (>=1.2)")
|
||||||
set(msg_dep_zeropad "check these libraries -> sdl (>=1.2)")
|
set(msg_dep_zeropad "check these libraries -> sdl (>=1.2)")
|
||||||
set(msg_dep_spu2x "check these libraries -> soundtouch (>=1.5), alsa, portaudio (>=1.9), a52 (>= 0.7.4), pcsx2 common libs")
|
set(msg_dep_spu2x "check these libraries -> soundtouch (>=1.5), alsa, portaudio (>=1.9), pcsx2 common libs")
|
||||||
set(msg_dep_zerospu2 "check these libraries -> soundtouch (>=1.5), alsa")
|
set(msg_dep_zerospu2 "check these libraries -> soundtouch (>=1.5), alsa")
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
@ -186,16 +186,15 @@ set(SPU2null TRUE)
|
||||||
# requires: -SoundTouch
|
# requires: -SoundTouch
|
||||||
# -ALSA
|
# -ALSA
|
||||||
# -Portaudio
|
# -Portaudio
|
||||||
# -A52
|
|
||||||
# -common_libs
|
# -common_libs
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
if(A52_FOUND AND ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND common_libs)
|
if(ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND common_libs)
|
||||||
set(spu2-x TRUE)
|
set(spu2-x TRUE)
|
||||||
else(A52_FOUND AND ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND common_libs)
|
else(ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND common_libs)
|
||||||
set(spu2-x FALSE)
|
set(spu2-x FALSE)
|
||||||
message(STATUS "Skip build of spu2-x: miss some dependencies")
|
message(STATUS "Skip build of spu2-x: miss some dependencies")
|
||||||
message(STATUS "${msg_dep_spu2x}")
|
message(STATUS "${msg_dep_spu2x}")
|
||||||
endif(A52_FOUND AND ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND common_libs)
|
endif(ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND common_libs)
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
|
|
|
@ -161,7 +161,7 @@ union u128
|
||||||
|
|
||||||
bool operator!=( const u128& right ) const
|
bool operator!=( const u128& right ) const
|
||||||
{
|
{
|
||||||
return (lo != right.lo) && (hi != right.hi);
|
return (lo != right.lo) || (hi != right.hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In order for the following ToString() and WriteTo methods to be available, you must
|
// In order for the following ToString() and WriteTo methods to be available, you must
|
||||||
|
@ -206,7 +206,7 @@ struct s128
|
||||||
|
|
||||||
bool operator!=( const s128& right ) const
|
bool operator!=( const s128& right ) const
|
||||||
{
|
{
|
||||||
return (lo != right.lo) && (hi != right.hi);
|
return (lo != right.lo) || (hi != right.hi);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -107,14 +107,32 @@ struct ParsedAssignmentString
|
||||||
ParsedAssignmentString( const wxString& src );
|
ParsedAssignmentString( const wxString& src );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ======================================================================================
|
||||||
|
// FastFormatAscii / FastFormatUnicode (overview!)
|
||||||
|
// ======================================================================================
|
||||||
|
// Fast formatting of ASCII or Unicode text. These classes uses a series of thread-local
|
||||||
|
// format buffers that are allocated only once and grown to accommodate string formatting
|
||||||
|
// needs. Because the buffers are thread-local, no thread synch objects are required in
|
||||||
|
// order to format strings, allowing for multi-threaded string formatting operations to be
|
||||||
|
// performed with maximum efficiency. This class also reduces the overhead typically required
|
||||||
|
// to allocate string buffers off the heap.
|
||||||
|
//
|
||||||
|
// Drawbacks:
|
||||||
|
// * Some overhead is added to the creation and destruction of threads, however since thread
|
||||||
|
// construction is a typically slow process, and often avoided to begin with, this should
|
||||||
|
// be a sound trade-off.
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// * conversion to wxString requires a heap allocation.
|
||||||
|
// * FastFormatUnicode can accept either UTF8 or UTF16/32 (wchar_t) input, but FastFormatAscii
|
||||||
|
// accepts Ascii/UTF8 only.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// FastFormatAscii
|
// FastFormatAscii
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Fast formatting of ASCII text. This class uses a process-wide format buffer that is
|
|
||||||
// allocated only once and grown to accommodate string formatting needs. The buffer is
|
|
||||||
// thread-safe. This technique reduces the overhead of formatting strings by eliminating
|
|
||||||
// most or all heap allocation actions.
|
|
||||||
//
|
|
||||||
class FastFormatAscii
|
class FastFormatAscii
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -127,6 +145,7 @@ public:
|
||||||
FastFormatAscii& Write( const char* fmt, ... );
|
FastFormatAscii& Write( const char* fmt, ... );
|
||||||
FastFormatAscii& WriteV( const char* fmt, va_list argptr );
|
FastFormatAscii& WriteV( const char* fmt, va_list argptr );
|
||||||
|
|
||||||
|
void Clear();
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
|
|
||||||
const char* c_str() const { return m_dest->GetPtr(); }
|
const char* c_str() const { return m_dest->GetPtr(); }
|
||||||
|
@ -136,6 +155,9 @@ public:
|
||||||
//operator wxString() const;
|
//operator wxString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// FastFormatUnicode
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
class FastFormatUnicode
|
class FastFormatUnicode
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -151,6 +173,7 @@ public:
|
||||||
FastFormatUnicode& WriteV( const char* fmt, va_list argptr );
|
FastFormatUnicode& WriteV( const char* fmt, va_list argptr );
|
||||||
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr );
|
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr );
|
||||||
|
|
||||||
|
void Clear();
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
|
|
||||||
const wxChar* c_str() const { return (const wxChar*)m_dest->GetPtr(); }
|
const wxChar* c_str() const { return (const wxChar*)m_dest->GetPtr(); }
|
||||||
|
|
|
@ -56,10 +56,7 @@ void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp )
|
||||||
}
|
}
|
||||||
|
|
||||||
const_cast<IConsoleWriter&>(Console) = writer;
|
const_cast<IConsoleWriter&>(Console) = writer;
|
||||||
|
const_cast<IConsoleWriter&>(DevConWriter) = writer;
|
||||||
#ifdef PCSX2_DEVBUILD
|
|
||||||
const_cast<IConsoleWriter&>(DevCon) = writer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PCSX2_DEBUG
|
#ifdef PCSX2_DEBUG
|
||||||
const_cast<IConsoleWriter&>(DbgCon) = writer;
|
const_cast<IConsoleWriter&>(DbgCon) = writer;
|
||||||
|
|
|
@ -39,12 +39,17 @@ static const int MaxFormattedStringLength = 0x80000;
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// FastFormatBuffers
|
// FastFormatBuffers
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
template< typename CharType >
|
// This class provides a series of pre-allocated thread-local buffers for use by string
|
||||||
|
// formatting tools. These buffers are handed out in round-robin style and require *no*
|
||||||
|
// thread sync objects and avoid multi-thread contention completely -- allowing multiple
|
||||||
|
// threads to format complicated strings concurrently with maximum efficiency.
|
||||||
|
//
|
||||||
class FastFormatBuffers
|
class FastFormatBuffers
|
||||||
{
|
{
|
||||||
DeclareNoncopyableObject(FastFormatBuffers);
|
DeclareNoncopyableObject(FastFormatBuffers);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
typedef char CharType;
|
||||||
typedef SafeAlignedArray<CharType,16> BufferType;
|
typedef SafeAlignedArray<CharType,16> BufferType;
|
||||||
|
|
||||||
static const uint BufferCount = 4;
|
static const uint BufferCount = 4;
|
||||||
|
@ -62,7 +67,7 @@ public:
|
||||||
for (uint i=0; i<BufferCount; ++i)
|
for (uint i=0; i<BufferCount; ++i)
|
||||||
{
|
{
|
||||||
m_buffers[i].Name = wxsFormat(L"%s Formatting Buffer (slot%d)",
|
m_buffers[i].Name = wxsFormat(L"%s Formatting Buffer (slot%d)",
|
||||||
(sizeof(CharType)==1) ? L"Ascii" : L"Unicode", i);
|
(sizeof(CharType)==1) ? L"UTF8/Ascii" : L"Wide-char", i);
|
||||||
m_buffers[i].MakeRoomFor(1024);
|
m_buffers[i].MakeRoomFor(1024);
|
||||||
m_buffers[i].ChunkSize = 2048;
|
m_buffers[i].ChunkSize = 2048;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +77,11 @@ public:
|
||||||
|
|
||||||
virtual ~FastFormatBuffers() throw()
|
virtual ~FastFormatBuffers() throw()
|
||||||
{
|
{
|
||||||
pxAssumeDev(m_curslot==0, "Dangling Ascii formatting buffer detected!");
|
pxAssumeDev(m_curslot==0,
|
||||||
|
wxsFormat(L"Dangling %s formatting buffer detected!",
|
||||||
|
(sizeof(CharType)==1) ? L"UTF8/Ascii" : L"Wide-char"
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasFreeBuffer() const
|
bool HasFreeBuffer() const
|
||||||
|
@ -139,7 +148,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool buffer_is_avail = false;
|
static bool buffer_is_avail = false;
|
||||||
static GlobalBufferManager< BaseTlsVariable< FastFormatBuffers< char > > > m_buffer_tls(buffer_is_avail);
|
static GlobalBufferManager< BaseTlsVariable< FastFormatBuffers > > m_buffer_tls(buffer_is_avail);
|
||||||
|
|
||||||
static __ri void format_that_ascii_mess( SafeArray<char>& buffer, uint writepos, const char* fmt, va_list argptr )
|
static __ri void format_that_ascii_mess( SafeArray<char>& buffer, uint writepos, const char* fmt, va_list argptr )
|
||||||
{
|
{
|
||||||
|
@ -218,10 +227,16 @@ SafeArray<char>* GetFormatBuffer( bool& deleteDest )
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// FastFormatUnicode (implementations)
|
// FastFormatUnicode (implementations)
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
// [TODO] This class should actually be renamed to FastFormatNative or FastFormatString, and
|
||||||
|
// adopted to properly support 1-byte wxChar types (mostly requiring some changes to the
|
||||||
|
// WriteV functions). The current implementation is fine for wx2.8, which always defaults
|
||||||
|
// to wide-varieties of wxChar -- but wx3.0 will use UTF8 for linux distros, which will break
|
||||||
|
// this class nicely in its current state. --air
|
||||||
|
|
||||||
FastFormatUnicode::FastFormatUnicode()
|
FastFormatUnicode::FastFormatUnicode()
|
||||||
{
|
{
|
||||||
m_dest = GetFormatBuffer(m_deleteDest);
|
m_dest = GetFormatBuffer(m_deleteDest);
|
||||||
((wxChar*)m_dest->GetPtr())[0] = 0;
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFormatUnicode::~FastFormatUnicode() throw()
|
FastFormatUnicode::~FastFormatUnicode() throw()
|
||||||
|
@ -232,6 +247,11 @@ FastFormatUnicode::~FastFormatUnicode() throw()
|
||||||
m_buffer_tls.Get()->ReleaseBuffer();
|
m_buffer_tls.Get()->ReleaseBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FastFormatUnicode::Clear()
|
||||||
|
{
|
||||||
|
((wxChar*)m_dest->GetPtr())[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
FastFormatUnicode& FastFormatUnicode::WriteV( const char* fmt, va_list argptr )
|
FastFormatUnicode& FastFormatUnicode::WriteV( const char* fmt, va_list argptr )
|
||||||
{
|
{
|
||||||
wxString converted( fromUTF8(FastFormatAscii().WriteV( fmt, argptr )) );
|
wxString converted( fromUTF8(FastFormatAscii().WriteV( fmt, argptr )) );
|
||||||
|
@ -278,7 +298,7 @@ bool FastFormatUnicode::IsEmpty() const
|
||||||
FastFormatAscii::FastFormatAscii()
|
FastFormatAscii::FastFormatAscii()
|
||||||
{
|
{
|
||||||
m_dest = GetFormatBuffer(m_deleteDest);
|
m_dest = GetFormatBuffer(m_deleteDest);
|
||||||
m_dest->GetPtr()[0] = 0;
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFormatAscii::~FastFormatAscii() throw()
|
FastFormatAscii::~FastFormatAscii() throw()
|
||||||
|
@ -289,16 +309,16 @@ FastFormatAscii::~FastFormatAscii() throw()
|
||||||
m_buffer_tls.Get()->ReleaseBuffer();
|
m_buffer_tls.Get()->ReleaseBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FastFormatAscii::Clear()
|
||||||
|
{
|
||||||
|
m_dest->GetPtr()[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
const wxString FastFormatAscii::GetString() const
|
const wxString FastFormatAscii::GetString() const
|
||||||
{
|
{
|
||||||
return fromAscii(m_dest->GetPtr());
|
return fromAscii(m_dest->GetPtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*FastFormatAscii::operator wxString() const
|
|
||||||
{
|
|
||||||
return fromAscii(m_dest->GetPtr());
|
|
||||||
}*/
|
|
||||||
|
|
||||||
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr )
|
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr )
|
||||||
{
|
{
|
||||||
format_that_ascii_mess( *m_dest, strlen(m_dest->GetPtr()), fmt, argptr );
|
format_that_ascii_mess( *m_dest, strlen(m_dest->GetPtr()), fmt, argptr );
|
||||||
|
|
|
@ -12,7 +12,6 @@ Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
||||||
libwxbase2.8-dev (>= 2.8.10), libwxbase2.8-dev (<< 2.8.11),
|
libwxbase2.8-dev (>= 2.8.10), libwxbase2.8-dev (<< 2.8.11),
|
||||||
libwxgtk2.8-dev (>= 2.8.10), libwxgtk2.8-dev (<< 2.8.11),
|
libwxgtk2.8-dev (>= 2.8.10), libwxgtk2.8-dev (<< 2.8.11),
|
||||||
libgtk2.0-dev (>= 2.16),
|
libgtk2.0-dev (>= 2.16),
|
||||||
liba52-0.7.4-dev,
|
|
||||||
libasound2-dev | lib32asound2-dev [amd64],
|
libasound2-dev | lib32asound2-dev [amd64],
|
||||||
portaudio19-dev,
|
portaudio19-dev,
|
||||||
# version not yet in debian
|
# version not yet in debian
|
||||||
|
|
|
@ -10,7 +10,6 @@ Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
||||||
libwxbase2.8-dev (>= 2.8.10), libwxbase2.8-dev (<< 2.8.11),
|
libwxbase2.8-dev (>= 2.8.10), libwxbase2.8-dev (<< 2.8.11),
|
||||||
libwxgtk2.8-dev (>= 2.8.10), libwxgtk2.8-dev (<< 2.8.11),
|
libwxgtk2.8-dev (>= 2.8.10), libwxgtk2.8-dev (<< 2.8.11),
|
||||||
libgtk2.0-dev (>= 2.16),
|
libgtk2.0-dev (>= 2.16),
|
||||||
liba52-0.7.4-dev,
|
|
||||||
libasound2-dev,
|
libasound2-dev,
|
||||||
portaudio19-dev,
|
portaudio19-dev,
|
||||||
# version not yet in debian
|
# version not yet in debian
|
||||||
|
|
|
@ -155,9 +155,11 @@ License: BSD (3 clause)
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
SUCH DAMAGE.
|
SUCH DAMAGE.
|
||||||
|
|
||||||
Files: plugins/zzogl-pg/opengl/ZeroGSShaders/* plugins/zzogl-pg/opengl/zpipe* plugins/zzogl-pg/opengl/zerogsmath.h plugins/zzogl-pg/opengl/memcpy_amd.cpp
|
Files: plugins/zzogl-pg/opengl/zpipe.cpp
|
||||||
Copyright: Unknown
|
Copyright: public domain
|
||||||
|
|
||||||
|
Files: plugins/zzogl-pg/opengl/ZeroGSShaders/zerogsshaders*
|
||||||
|
Copyright: Unknown
|
||||||
|
|
||||||
The Debian packaging is:
|
The Debian packaging is:
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,9 @@ rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/Win32"
|
||||||
rm -fr "${NEW_DIR}/tools/GSDumpGUI"
|
rm -fr "${NEW_DIR}/tools/GSDumpGUI"
|
||||||
rm -fr "${NEW_DIR}/common/vsprops"
|
rm -fr "${NEW_DIR}/common/vsprops"
|
||||||
echo "Remove useless files (copyright issues)"
|
echo "Remove useless files (copyright issues)"
|
||||||
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders/zlib"
|
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders"
|
||||||
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
||||||
|
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/memcpy_amd.cpp"
|
||||||
|
|
||||||
## BUILD
|
## BUILD
|
||||||
echo "Build the tar.gz file"
|
echo "Build the tar.gz file"
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
pcsx2 for debian
|
||||||
|
=========================
|
||||||
|
|
||||||
|
* This version has some major modifications against the default upstream version.
|
||||||
|
-> documents are stored in $XDG_CONFIG_HOME instead of $HOME/pcsx2
|
||||||
|
-> some features were removed so it could compile against libsound 1.3.
|
||||||
|
Pcsx2 needs at least soundtouch 1.5.
|
||||||
|
|
||||||
|
* This package is highly experimental.
|
||||||
|
|
||||||
|
* Documentation needs some love. Feel free to help.
|
||||||
|
|
||||||
|
* -fPIC option was removed for multiple reason.
|
||||||
|
- Code only support x86 architecture.
|
||||||
|
- Upstream code uses the ebx register so it's not compliant with PIC.
|
||||||
|
- Impacts the performance too much.
|
||||||
|
- Only plugins. No package will link to them.
|
||||||
|
|
||||||
|
-- Gregory Hainaut <gregory.hainaut@gmail.com> Sat, 24 Apr 2010 23:11:10 +0200
|
|
@ -0,0 +1,40 @@
|
||||||
|
need libsoundtouch v1.5
|
||||||
|
|
||||||
|
* policy bin2cpp tool ??
|
||||||
|
May be we could pregenerate the file in the upstream tar ball!!
|
||||||
|
|
||||||
|
* copyright and doc stuff
|
||||||
|
Lots of work to do here....
|
||||||
|
|
||||||
|
# only a stub
|
||||||
|
plugins/zzogl-pg/opengl/memcpy_amd.cpp: UNKNOWN
|
||||||
|
|
||||||
|
# need zerofrog confirmation of gpl v2
|
||||||
|
plugins/zzogl-pg/opengl/zpipe.h: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/shaders.sh: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/common.h: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/ZeroGSShaders/zpipe.h: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/ZeroGSShaders/zerogsshaders.cpp: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/ZeroGSShaders/zerogsshaders.h: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/ZeroGSShaders/zpipe.cpp: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/zerogsmath.h: *No copyright* UNKNOWN
|
||||||
|
plugins/zzogl-pg/opengl/zpipe.cpp: *No copyright* UNKNOWN
|
||||||
|
|
||||||
|
## 64 bit
|
||||||
|
nvidia-cg-toolkit: propably need a special package for 32 bits version
|
||||||
|
ia32-libs: add libportaudio, libsoundtouch, libglew
|
||||||
|
ia32-libs: add .so symlink for compilation
|
||||||
|
ia32-libs-gtk: add libwxbase2.8 and libwxgtk2.8 (warning a architecture dependant include file (in -dev package) is also needed)
|
||||||
|
ia32-libs-gtk: add .so symlink for compilation
|
||||||
|
|
||||||
|
|
||||||
|
== Multi-Arch support in APT ==
|
||||||
|
by David Kalnischkies, mentored by Michael Vogt
|
||||||
|
|
||||||
|
Hardware like 64bit processors are perfectly able to execute 32bit
|
||||||
|
opcode but until now this potentiality is disregard as the
|
||||||
|
infrastructure tools like dpkg and APT are not able to install and/or
|
||||||
|
solve dependencies across multiple architectures. The project
|
||||||
|
therefore focuses on enabling APT to work out good solutions in a
|
||||||
|
MultiArch aware environments without the need of hacky and partly
|
||||||
|
working biarch packages currently in use.
|
|
@ -0,0 +1,6 @@
|
||||||
|
pcsx2 (3351-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
||||||
|
-- Gregory Hainaut <gregory.hainaut@gmail.com> Thu, 13 May 2010 14:27:56 +0200
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
pcsx2 (3351-0ubuntu1) lucid; urgency=low
|
||||||
|
|
||||||
|
* Initial release
|
||||||
|
|
||||||
|
-- Gregory Hainaut <gregory.hainaut@gmail.com> Thu, 13 May 2010 14:27:56 +0200
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
7
|
|
@ -0,0 +1,117 @@
|
||||||
|
Source: pcsx2
|
||||||
|
Section: games
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Gregory Hainaut <gregory.hainaut@gmail.com>
|
||||||
|
# WARNING we need dpkg-dev 1.15.7 to support dpkg-buildflags but ubunutu 10.04 have only 1.15.5.6...
|
||||||
|
Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
||||||
|
gcc-multilib [amd64], g++-multilib [amd64],
|
||||||
|
zlib1g-dev (>= 1:1.2.3.3) | lib32z1-dev (>= 1.2.3.3) [amd64],
|
||||||
|
libbz2-dev (>= 1.0.4),
|
||||||
|
libsdl1.2-dev,
|
||||||
|
libjpeg-dev,
|
||||||
|
libwxbase2.8-dev (>= 2.8.10), libwxbase2.8-dev (<< 2.8.11),
|
||||||
|
libwxgtk2.8-dev (>= 2.8.10), libwxgtk2.8-dev (<< 2.8.11),
|
||||||
|
libgtk2.0-dev (>= 2.16),
|
||||||
|
libasound2-dev | lib32asound2-dev [amd64],
|
||||||
|
portaudio19-dev,
|
||||||
|
# version not yet in debian
|
||||||
|
# libsoundtouch1-dev (>= 1.5),
|
||||||
|
# I patch the source (remove feature) to compile with version 1.3
|
||||||
|
libsoundtouch1-dev (>= 1.3),
|
||||||
|
libsparsehash-dev (>= 1.6),
|
||||||
|
libx11-dev,
|
||||||
|
libglew1.5-dev (>= 1.5.1),
|
||||||
|
libgl1-mesa-dev,
|
||||||
|
libglu1-mesa-dev,
|
||||||
|
# my nmu: add 32bits packages
|
||||||
|
# nvidia-cg-toolkit (>= 2.1.0017.deb1) | nvidia-cg-toolkit (>= 2.1.0017.deb1+nmu2) [amd64],
|
||||||
|
nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1), ia32-nvidia-cg-toolkit-pcsx2 [amd64],
|
||||||
|
ia32-libs (>= 20090808+nmu7) [amd64], ia32-libs-gtk (= 20100503+local1) [amd64]
|
||||||
|
Standards-Version: 3.9.1
|
||||||
|
Homepage: http://pcsx2.net/
|
||||||
|
|
||||||
|
Package: pcsx2
|
||||||
|
# Warning amd64 need additional ia32libs
|
||||||
|
Architecture: i386 amd64
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||||
|
pcsx2-data (>= ${binary:Version}),
|
||||||
|
pcsx2-plugins (>= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-unstable
|
||||||
|
Description: Playstation 2 emulator
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package includes the main binary file.
|
||||||
|
|
||||||
|
|
||||||
|
Package: pcsx2-data
|
||||||
|
Architecture: all
|
||||||
|
Depends: ${misc:Depends}
|
||||||
|
Recommends: pcsx2 (>= ${binary:Version}), pcsx2-plugins (>= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-data-unstable
|
||||||
|
Description: data for pcsx2
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package includes data files.
|
||||||
|
|
||||||
|
Package: pcsx2-plugins
|
||||||
|
# Warning amd64 need additional ia32libs
|
||||||
|
Architecture: i386 amd64
|
||||||
|
# manually add nvidia-cg-toolkit for zzogl. Do not why is not found by shlibs !!!
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||||
|
nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1), ia32-nvidia-cg-toolkit-pcsx2 [amd64]
|
||||||
|
Recommends: pcsx2 (>= ${binary:Version}),
|
||||||
|
pcsx2-data (>= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-plugins-unstable
|
||||||
|
Description: Various plugins for pcsx2
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package includes the plugins for PCSX2.
|
||||||
|
|
||||||
|
Package: pcsx2-dbg
|
||||||
|
Section: debug
|
||||||
|
Priority: extra
|
||||||
|
# Warning amd64 need additional ia32libs
|
||||||
|
Architecture: i386 amd64
|
||||||
|
Depends: ${misc:Depends}, pcsx2 (= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-unstable-dbg
|
||||||
|
Description: Debug symbols for pcsx2
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package contains the debug symbol of pcsx2.
|
||||||
|
|
||||||
|
Package: pcsx2-plugins-dbg
|
||||||
|
Section: debug
|
||||||
|
Priority: extra
|
||||||
|
# Warning amd64 need additional ia32libs
|
||||||
|
Architecture: i386 amd64
|
||||||
|
Depends: ${misc:Depends}, pcsx2-plugins (= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-plugins-unstable-dbg
|
||||||
|
Description: Debug symbols of the pcsx2-plugins
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package contains the debug symbols of the pcsx2 plugins.
|
|
@ -0,0 +1,108 @@
|
||||||
|
Source: pcsx2
|
||||||
|
Section: games
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Gregory Hainaut <gregory.hainaut@gmail.com>
|
||||||
|
Build-Depends: debhelper (>= 7.0.50), dpkg-dev (>= 1.15.5.6), cmake (>=2.8),
|
||||||
|
zlib1g-dev (>= 1:1.2.3.3),
|
||||||
|
libbz2-dev (>= 1.0.4),
|
||||||
|
libsdl1.2-dev,
|
||||||
|
libjpeg-dev,
|
||||||
|
libwxbase2.8-dev (>= 2.8.10), libwxbase2.8-dev (<< 2.8.11),
|
||||||
|
libwxgtk2.8-dev (>= 2.8.10), libwxgtk2.8-dev (<< 2.8.11),
|
||||||
|
libgtk2.0-dev (>= 2.16),
|
||||||
|
libasound2-dev,
|
||||||
|
portaudio19-dev,
|
||||||
|
# version not yet in debian
|
||||||
|
# libsoundtouch1-dev (>= 1.5),
|
||||||
|
# I patch the source (remove feature) to compile with version 1.3
|
||||||
|
libsoundtouch1-dev (>= 1.3),
|
||||||
|
libsparsehash-dev (>= 1.6),
|
||||||
|
libx11-dev,
|
||||||
|
libglew1.5-dev (>= 1.5.1),
|
||||||
|
libgl1-mesa-dev,
|
||||||
|
libglu1-mesa-dev,
|
||||||
|
nvidia-cg-toolkit-pcsx2
|
||||||
|
Standards-Version: 3.9.1
|
||||||
|
Homepage: http://pcsx2.net/
|
||||||
|
|
||||||
|
Package: pcsx2
|
||||||
|
Architecture: i386
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||||
|
pcsx2-data (>= ${binary:Version}),
|
||||||
|
pcsx2-plugins (>= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-unstable
|
||||||
|
Description: Playstation 2 emulator
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package includes the main binary file.
|
||||||
|
|
||||||
|
|
||||||
|
Package: pcsx2-data
|
||||||
|
Architecture: all
|
||||||
|
Depends: ${misc:Depends}
|
||||||
|
Recommends: pcsx2 (>= ${binary:Version}), pcsx2-plugins (>= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-data-unstable
|
||||||
|
Description: data for pcsx2
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package includes data files.
|
||||||
|
|
||||||
|
Package: pcsx2-plugins
|
||||||
|
Architecture: i386
|
||||||
|
# manually add nvidia-cg-toolkit for zzogl. Do not why is not found by shlibs !!!
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends},
|
||||||
|
nvidia-cg-toolkit-pcsx2 | nvidia-cg-toolkit (>= 2.1)
|
||||||
|
Recommends: pcsx2 (>= ${binary:Version}),
|
||||||
|
pcsx2-data (>= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-plugins-unstable
|
||||||
|
Description: Various plugins for pcsx2
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package includes the plugins for PCSX2.
|
||||||
|
|
||||||
|
Package: pcsx2-dbg
|
||||||
|
Section: debug
|
||||||
|
Priority: extra
|
||||||
|
Architecture: i386
|
||||||
|
Depends: ${misc:Depends}, pcsx2 (= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-unstable-dbg
|
||||||
|
Description: Debug symbols for pcsx2
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package contains the debug symbol of pcsx2.
|
||||||
|
|
||||||
|
Package: pcsx2-plugins-dbg
|
||||||
|
Section: debug
|
||||||
|
Priority: extra
|
||||||
|
Architecture: i386
|
||||||
|
Depends: ${misc:Depends}, pcsx2-plugins (= ${binary:Version})
|
||||||
|
Conflicts: pcsx2-plugins-unstable-dbg
|
||||||
|
Description: Debug symbols of the pcsx2-plugins
|
||||||
|
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same
|
||||||
|
team that brought you PCSX (a Sony PlayStation 1 emulator).
|
||||||
|
.
|
||||||
|
WARNING: It requires a CPU with SSE2 instructions. If your CPU does not support
|
||||||
|
this instruction set, it does not have enough horse power to run this emulator
|
||||||
|
anyway.
|
||||||
|
.
|
||||||
|
This package contains the debug symbols of the pcsx2 plugins.
|
|
@ -0,0 +1,168 @@
|
||||||
|
This work was packaged for Debian by:
|
||||||
|
|
||||||
|
Gregory Hainaut <gregory.hainaut@gmail.com> on Sat, 24 Apr 2010 23:11:10 +0200
|
||||||
|
|
||||||
|
It was downloaded from:
|
||||||
|
|
||||||
|
http://pcsx2.googlecode.com/svn/
|
||||||
|
|
||||||
|
Upstream Author(s):
|
||||||
|
|
||||||
|
PCSX2 Dev Team
|
||||||
|
|
||||||
|
Copyright:
|
||||||
|
|
||||||
|
Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||||
|
|
||||||
|
Files: pcsx2/*, common/*, plugins/spu2-x/*, plugins/PadNull/Pad*, plugins/USBnull/*, plugins/FWnull/*, plugins/CDVDnull/CDVD*, plugins/GSnull/*, plugins/dev9null/DEV9.cpp
|
||||||
|
License: LGPL-3+
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This package is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
On Debian systems, the complete text of the GNU Lesser General
|
||||||
|
Public License version 3 can be found in "/usr/share/common-licenses/LGPL-3".
|
||||||
|
|
||||||
|
|
||||||
|
Files: pcsx2/Mdec.cpp, pcsx2/Mdec.h, pcsx2/RDebug/deci2_drfp.cpp, pcsx2/IPU/mpeg2lib/*, pcsx2/cheatscpp.h, common/include/api/*, plugins/onepad/*, plugins/PadNull/Linux/*, plugins/SPU2null/*, plugins/FWnull/FW.cpp, plugins/zerospu2/*, plugins/zzogl-pg/*, plugins/GSnull/Registers.h, plugins/GSnull/Linux/Linux*, plugins/GSnull/Linux/Config*, plugins/dev9null/DEV9.h, plugins/dev9null/Config.*
|
||||||
|
License: GPL-2+
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This package is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
On Debian systems, the complete text of the GNU General
|
||||||
|
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||||
|
|
||||||
|
|
||||||
|
Files: plugins/spu2-x/src/Spu2replay.*, plugins/spu2-x/src/Decode*, plugins/spu2-x/src/Linux/ConfigSoundTouch.cpp, plugins/spu2-x/src/spdif.h, plugins/spu2-x/src/Debug.h
|
||||||
|
|
||||||
|
License: LGPL-2.1+
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This package is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
On Debian systems, the complete text of the GNU Lesser General
|
||||||
|
Public License version 2.1 can be found in "/usr/share/common-licenses/LGPL-2.1".
|
||||||
|
|
||||||
|
Files: plugins/zzogl-pg/opengl/glprocs.*
|
||||||
|
Copyright: 1991-2000, Silicon Graphics, Inc
|
||||||
|
License: MIT/X11 (BSD like)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice including the dates of first publication and
|
||||||
|
either this permission notice or a reference to
|
||||||
|
http://oss.sgi.com/projects/FreeB/
|
||||||
|
shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||||
|
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of Silicon Graphics, Inc.
|
||||||
|
shall not be used in advertising or otherwise to promote the sale, use or
|
||||||
|
other dealings in this Software without prior written authorization from
|
||||||
|
Silicon Graphics, Inc.
|
||||||
|
|
||||||
|
|
||||||
|
Files: common/include/intrin_x86.h
|
||||||
|
Copyright: 2006, KJK::Hyperion <hackbunny@reactos.com>
|
||||||
|
License: MIT/X11 (BSD like)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
Files: common/src/Utilities/vssprintf.cpp
|
||||||
|
Copyright: 2002, Michael Ringgaard
|
||||||
|
License: BSD (3 clause)
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the project nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
Files: plugins/zzogl-pg/opengl/zpipe.cpp
|
||||||
|
Copyright: public domain
|
||||||
|
|
||||||
|
Files: plugins/zzogl-pg/opengl/ZeroGSShaders/zerogsshaders*
|
||||||
|
Copyright: Unknown
|
||||||
|
|
||||||
|
The Debian packaging is:
|
||||||
|
|
||||||
|
Copyright (C) 2010 Gregory Hainaut <gregory.hainaut@gmail.com>
|
||||||
|
|
||||||
|
and is licensed under the Lesser GPL version 3, see above.
|
|
@ -0,0 +1,145 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# copyright (c) 2010 Gregory Hainaut
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This package is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Global Parameters
|
||||||
|
######################################################################
|
||||||
|
# Svn parameter
|
||||||
|
if [ -n "$1" ] ; then
|
||||||
|
SVN_CO_VERSION=$1;
|
||||||
|
else
|
||||||
|
echo "Please provide the subversion revision number as the first parameter"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
if [ -n "$2" ] ; then
|
||||||
|
# Use branch argument
|
||||||
|
SVN_TRUNK="http://pcsx2.googlecode.com/svn/branches/$2"
|
||||||
|
else
|
||||||
|
# by default take the trunk
|
||||||
|
SVN_TRUNK="http://pcsx2.googlecode.com/svn/trunk"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Debian name of package and tarball
|
||||||
|
PKG_NAME="pcsx2-${SVN_CO_VERSION}"
|
||||||
|
TAR_NAME="pcsx2_${SVN_CO_VERSION}.orig.tar"
|
||||||
|
|
||||||
|
# Directory
|
||||||
|
TMP_DIR=/tmp
|
||||||
|
ROOT_DIR=${TMP_DIR}/subversion_pcsx2_${SVN_CO_VERSION}
|
||||||
|
NEW_DIR=${TMP_DIR}/$PKG_NAME
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Basic functions
|
||||||
|
######################################################################
|
||||||
|
get_svn_dir()
|
||||||
|
{
|
||||||
|
for directory in $* ; do
|
||||||
|
# Print the directory without /
|
||||||
|
echo " $directory" | sed -e 's/\//\ /g'
|
||||||
|
if [ -e `basename ${directory}` ] ; then
|
||||||
|
# Directory already exist so only update
|
||||||
|
svn up --quiet ${SVN_TRUNK}/${directory} -r $SVN_CO_VERSION;
|
||||||
|
else
|
||||||
|
svn co --quiet ${SVN_TRUNK}/${directory} -r $SVN_CO_VERSION;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
get_svn_file()
|
||||||
|
{
|
||||||
|
for file in $* ; do
|
||||||
|
if [ ! -e `basename ${file}` ] ; then
|
||||||
|
# Versioning information is not supported for a single file
|
||||||
|
# therefore you can't use svn co
|
||||||
|
svn export --quiet ${SVN_TRUNK}/${file} -r $SVN_CO_VERSION;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Main script
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
## Download the svn repository (only the useful things)
|
||||||
|
echo "Downloading pcsx2 source revision ${SVN_CO_VERSION}"
|
||||||
|
mkdir -p $ROOT_DIR;
|
||||||
|
(cd $ROOT_DIR;
|
||||||
|
get_svn_file CMakeLists.txt;
|
||||||
|
get_svn_dir bin common cmake pcsx2 tools;
|
||||||
|
get_svn_dir debian-upstream;
|
||||||
|
echo "Done")
|
||||||
|
|
||||||
|
echo "Downloading Linux compatible plugins for revision ${SVN_CO_VERSION}"
|
||||||
|
# Note: Other plugins exist but they are not 100% copyright free.
|
||||||
|
mkdir -p $ROOT_DIR/plugins
|
||||||
|
(cd $ROOT_DIR/plugins;
|
||||||
|
get_svn_file plugins/CMakeLists.txt;
|
||||||
|
# DVD
|
||||||
|
get_svn_dir plugins/CDVDnull;
|
||||||
|
# Copyright issue
|
||||||
|
# get_svn_dir plugins/CDVDnull plugins/CDVDiso;
|
||||||
|
# PAD
|
||||||
|
get_svn_dir plugins/PadNull plugins/onepad;
|
||||||
|
# AUDIO
|
||||||
|
get_svn_dir plugins/SPU2null plugins/spu2-x plugins/zerospu2;
|
||||||
|
# Graphics
|
||||||
|
get_svn_dir plugins/GSnull plugins/zzogl-pg;
|
||||||
|
# Misc
|
||||||
|
get_svn_dir plugins/dev9null plugins/FWnull plugins/USBnull;
|
||||||
|
echo "Note: some plugins are more or less deprecated CDVDisoEFP, CDVDlinuz, Zerogs, Zeropad ...";
|
||||||
|
echo "Done")
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
echo "Copy the subversion repository to a temporary directory"
|
||||||
|
# Copy the dir
|
||||||
|
rm -fr $NEW_DIR
|
||||||
|
cp -r $ROOT_DIR $NEW_DIR
|
||||||
|
|
||||||
|
echo "Remove .svn directories"
|
||||||
|
find $NEW_DIR -name ".svn" -type d -exec rm -fr {} \; 2> /dev/null
|
||||||
|
echo "Remove old build system (scripts and autotools)"
|
||||||
|
find $NEW_DIR -name "build.sh" -exec rm -f {} \;
|
||||||
|
find $NEW_DIR -name "install-sh" -exec rm -f {} \;
|
||||||
|
find $NEW_DIR -name "depcomp" -exec rm -f {} \;
|
||||||
|
find $NEW_DIR -name "missing" -exec rm -f {} \;
|
||||||
|
find $NEW_DIR -name "aclocal.m4" -exec rm -f {} \;
|
||||||
|
find $NEW_DIR -name "configure.ac" -exec rm -f {} \;
|
||||||
|
find $NEW_DIR -name "Makefile.am" -exec rm -f {} \;
|
||||||
|
echo "Remove 3rd party directories"
|
||||||
|
find $NEW_DIR -name "3rdparty" -exec rm -fr {} \; 2> /dev/null
|
||||||
|
# I really need to clean this mess one day
|
||||||
|
# echo "Remove plugins/zzogl-pg/opengl/ZeroGSShaders (some zlib source in the middle)"
|
||||||
|
# rm -fr $NEW_DIR/plugins/zzogl-pg/opengl/ZeroGSShaders
|
||||||
|
echo "Remove windows file (useless & copyright issue)"
|
||||||
|
find $NEW_DIR -iname "windows" -type d -exec rm -fr {} \; 2> /dev/null
|
||||||
|
find $NEW_DIR -name "Win32" -type d -exec rm -fr {} \; 2> /dev/null
|
||||||
|
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/Win32"
|
||||||
|
rm -fr "${NEW_DIR}/tools/GSDumpGUI"
|
||||||
|
rm -fr "${NEW_DIR}/common/vsprops"
|
||||||
|
echo "Remove useless files (copyright issues)"
|
||||||
|
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders"
|
||||||
|
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
||||||
|
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/memcpy_amd.cpp"
|
||||||
|
|
||||||
|
## BUILD
|
||||||
|
echo "Build the tar.gz file"
|
||||||
|
tar -C $TMP_DIR -czf ${TAR_NAME}.gz $PKG_NAME
|
||||||
|
|
||||||
|
## Clean
|
||||||
|
rm -fr $NEW_DIR
|
||||||
|
rm -fr $ROOT_DIR
|
|
@ -0,0 +1,24 @@
|
||||||
|
Debian specific
|
||||||
|
Always uses the same executable name for the build. Easier for the install script
|
||||||
|
Index: pcsx2-3567/pcsx2/CMakeLists.txt
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3567.orig/pcsx2/CMakeLists.txt
|
||||||
|
+++ pcsx2-3567/pcsx2/CMakeLists.txt
|
||||||
|
@@ -72,7 +72,7 @@
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
|
|
||||||
|
# executable name
|
||||||
|
- set(Output pcsx2-dbg)
|
||||||
|
+ set(Output pcsx2)
|
||||||
|
|
||||||
|
# add defines
|
||||||
|
add_definitions(${CommonFlags} ${DebugFlags} -DPCSX2_DEVBUILD -DPCSX2_DEBUG -DWX_PRECOMP)
|
||||||
|
@@ -82,7 +82,7 @@
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL Devel)
|
||||||
|
|
||||||
|
# executable name
|
||||||
|
- set(Output pcsx2-dev)
|
||||||
|
+ set(Output pcsx2)
|
||||||
|
|
||||||
|
# add defines
|
||||||
|
add_definitions(${CommonFlags} ${OptimizationFlags} -DPCSX2_DEVBUILD -DWX_PRECOMP -DNDEBUG)
|
|
@ -0,0 +1,58 @@
|
||||||
|
Debian policy.
|
||||||
|
This patch updates default plugin path and config path.
|
||||||
|
It also updates the pcsx2 game db path and shaders data path.
|
||||||
|
AppInit.cpp:93 could be probably updated
|
||||||
|
Index: pcsx2-3369/pcsx2/gui/AppConfig.cpp
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3369.orig/pcsx2/gui/AppConfig.cpp
|
||||||
|
+++ pcsx2-3369/pcsx2/gui/AppConfig.cpp
|
||||||
|
@@ -162,7 +162,8 @@
|
||||||
|
|
||||||
|
wxDirName GetPlugins()
|
||||||
|
{
|
||||||
|
- return AppRoot() + Base::Plugins();
|
||||||
|
+ // return AppRoot() + Base::Plugins();
|
||||||
|
+ return wxDirName( L"/usr/lib/games/pcsx2" ) + Base::Plugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDirName GetSettings()
|
||||||
|
Index: pcsx2-3369/plugins/zzogl-pg/opengl/ZZoglCreate.cpp
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3369.orig/plugins/zzogl-pg/opengl/ZZoglCreate.cpp
|
||||||
|
+++ pcsx2-3369/plugins/zzogl-pg/opengl/ZZoglCreate.cpp
|
||||||
|
@@ -347,17 +347,12 @@
|
||||||
|
assert(hShaderGlob != NULL);
|
||||||
|
s_lpShaderResources = (u8*)LockResource(hShaderGlob);
|
||||||
|
# else // not _WIN32
|
||||||
|
- FILE* fres = fopen("ps2hw.dat", "rb");
|
||||||
|
+ FILE* fres = fopen("/usr/share/games/pcsx2/shaders/ps2hw.dat", "rb");
|
||||||
|
|
||||||
|
if (fres == NULL)
|
||||||
|
{
|
||||||
|
- fres = fopen("plugins/ps2hw.dat", "rb");
|
||||||
|
-
|
||||||
|
- if (fres == NULL)
|
||||||
|
- {
|
||||||
|
- ZZLog::Error_Log("Cannot find ps2hw.dat in working directory. Exiting.");
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
+ ZZLog::Error_Log("Cannot find ps2hw.dat in working directory. Exiting.");
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fres, 0, SEEK_END);
|
||||||
|
Index: pcsx2-3369/pcsx2/gui/AppGameDatabase.h
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3369.orig/pcsx2/gui/AppGameDatabase.h
|
||||||
|
+++ pcsx2-3369/pcsx2/gui/AppGameDatabase.h
|
||||||
|
@@ -51,8 +51,8 @@
|
||||||
|
Console.WriteLn( "(GameDB) Unloading..." );
|
||||||
|
}
|
||||||
|
|
||||||
|
- AppGameDatabase& LoadFromFile(const wxString& file = L"GameIndex.dbf", const wxString& key = L"Serial" );
|
||||||
|
- void SaveToFile(const wxString& file = L"GameIndex.dbf");
|
||||||
|
+ AppGameDatabase& LoadFromFile(const wxString& file = L"/var/games/pcsx2/GameIndex.dbf", const wxString& key = L"Serial" );
|
||||||
|
+ void SaveToFile(const wxString& file = L"/var/games/pcsx2/GameIndex.dbf");
|
||||||
|
};
|
||||||
|
|
||||||
|
static wxString compatToStringWX(int compat) {
|
|
@ -0,0 +1,17 @@
|
||||||
|
Index: pcsx2-3369/pcsx2/gui/AppConfig.cpp
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3369.orig/pcsx2/gui/AppConfig.cpp
|
||||||
|
+++ pcsx2-3369/pcsx2/gui/AppConfig.cpp
|
||||||
|
@@ -125,7 +125,12 @@
|
||||||
|
{
|
||||||
|
switch( mode )
|
||||||
|
{
|
||||||
|
+#ifdef __LINUX__
|
||||||
|
+ // By default on linux move all user data file into central configuration directory
|
||||||
|
+ case DocsFolder_User: return GetUserLocalDataDir();
|
||||||
|
+#else
|
||||||
|
case DocsFolder_User: return (wxDirName)Path::Combine( wxStandardPaths::Get().GetDocumentsDir(), pxGetAppName() );
|
||||||
|
+#endif
|
||||||
|
//case DocsFolder_CWD: return (wxDirName)wxGetCwd();
|
||||||
|
case DocsFolder_Custom: return CustomDocumentsFolder;
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
This patch removes recording feature beacause it needs libsoundtouch > 1.4.
|
||||||
|
Howerever only the version 1.3 is in debian. Unfortunately the package seems
|
||||||
|
to be not actively maintained.
|
||||||
|
Note it also correct the inlude path.
|
||||||
|
Index: pcsx2-3369/plugins/spu2-x/src/Wavedump_wav.cpp
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3369.orig/plugins/spu2-x/src/Wavedump_wav.cpp
|
||||||
|
+++ pcsx2-3369/plugins/spu2-x/src/Wavedump_wav.cpp
|
||||||
|
@@ -16,16 +16,22 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Global.h"
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
#include "soundtouch/WavFile.h"
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
static WavOutFile* _new_WavOutFile( const char* destfile )
|
||||||
|
{
|
||||||
|
return new WavOutFile( destfile, 48000, 16, 2 );
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
namespace WaveDump
|
||||||
|
{
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
static WavOutFile* m_CoreWav[2][CoreSrc_Count] = { NULL };
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
static const char* m_tbl_CoreOutputTypeNames[CoreSrc_Count] =
|
||||||
|
{
|
||||||
|
@@ -42,6 +48,7 @@
|
||||||
|
if( !IsDevBuild ) return;
|
||||||
|
if( !WaveLog() ) return;
|
||||||
|
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
char wavfilename[256];
|
||||||
|
|
||||||
|
for( uint cidx=0; cidx<2; cidx++ )
|
||||||
|
@@ -68,11 +75,13 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Close()
|
||||||
|
{
|
||||||
|
if( !IsDevBuild ) return;
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
for( uint cidx=0; cidx<2; cidx++ )
|
||||||
|
{
|
||||||
|
for( int srcidx=0; srcidx<CoreSrc_Count; srcidx++ )
|
||||||
|
@@ -80,13 +89,16 @@
|
||||||
|
safe_delete( m_CoreWav[cidx][srcidx] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteCore( uint coreidx, CoreSourceType src, const StereoOut16& sample )
|
||||||
|
{
|
||||||
|
if( !IsDevBuild ) return;
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
if( m_CoreWav[coreidx][src] != NULL )
|
||||||
|
m_CoreWav[coreidx][src]->write( (s16*)&sample, 2 );
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteCore( uint coreidx, CoreSourceType src, s16 left, s16 right )
|
||||||
|
@@ -101,11 +113,14 @@
|
||||||
|
|
||||||
|
bool WavRecordEnabled = false;
|
||||||
|
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
static WavOutFile* m_wavrecord = NULL;
|
||||||
|
+#endif
|
||||||
|
static Mutex WavRecordMutex;
|
||||||
|
|
||||||
|
void RecordStart()
|
||||||
|
{
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
WavRecordEnabled = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
@@ -120,18 +135,23 @@
|
||||||
|
m_wavrecord = NULL; // not needed, but what the heck. :)
|
||||||
|
SysMessage("SPU2-X couldn't open file for recording: %s.\nRecording to wavfile disabled.", "recording.wav");
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecordStop()
|
||||||
|
{
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
WavRecordEnabled = false;
|
||||||
|
ScopedLock lock( WavRecordMutex );
|
||||||
|
safe_delete( m_wavrecord );
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecordWrite( const StereoOut16& sample )
|
||||||
|
{
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
ScopedLock lock( WavRecordMutex );
|
||||||
|
if( m_wavrecord == NULL ) return;
|
||||||
|
m_wavrecord->write( (s16*)&sample, 2 );
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
Index: pcsx2-3369/plugins/zerospu2/zerospu2.cpp
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3369.orig/plugins/zerospu2/zerospu2.cpp
|
||||||
|
+++ pcsx2-3369/plugins/zerospu2/zerospu2.cpp
|
||||||
|
@@ -28,7 +28,9 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "soundtouch/SoundTouch.h"
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
#include "soundtouch/WavFile.h"
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
char libraryName[256];
|
||||||
|
|
||||||
|
@@ -74,7 +76,9 @@
|
||||||
|
|
||||||
|
// time stretch variables
|
||||||
|
soundtouch::SoundTouch* pSoundTouch=NULL;
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
extern WavOutFile* g_pWavRecord; // used for recording
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
u64 s_GlobalTimeStamp = 0;
|
||||||
|
s32 s_nDurations[64]={0};
|
||||||
|
@@ -361,7 +365,9 @@
|
||||||
|
|
||||||
|
RemoveSound();
|
||||||
|
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
delete g_pWavRecord; g_pWavRecord = NULL;
|
||||||
|
+#endif
|
||||||
|
delete pSoundTouch; pSoundTouch = NULL;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < ArraySize(s_pAudioBuffers); ++i)
|
||||||
|
Index: pcsx2-3369/plugins/zerospu2/zeroworker.cpp
|
||||||
|
===================================================================
|
||||||
|
--- pcsx2-3369.orig/plugins/zerospu2/zeroworker.cpp
|
||||||
|
+++ pcsx2-3369/plugins/zerospu2/zeroworker.cpp
|
||||||
|
@@ -19,10 +19,14 @@
|
||||||
|
#include "zerospu2.h"
|
||||||
|
#include "zeroworker.h"
|
||||||
|
#include "soundtouch/SoundTouch.h"
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
#include "soundtouch/WavFile.h"
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
s32 g_logsound = 0;
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
WavOutFile* g_pWavRecord=NULL; // used for recording
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
const s32 f[5][2] = {
|
||||||
|
{ 0, 0 },
|
||||||
|
@@ -302,6 +306,7 @@
|
||||||
|
|
||||||
|
void LogRawSound(void* pleft, s32 leftstride, void* pright, s32 rightstride, s32 numsamples)
|
||||||
|
{
|
||||||
|
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
|
||||||
|
if (g_pWavRecord == NULL )
|
||||||
|
g_pWavRecord = new WavOutFile(RECORD_FILENAME, SAMPLE_RATE, 16, 2);
|
||||||
|
|
||||||
|
@@ -320,4 +325,5 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pWavRecord->write(&tempbuf[0], numsamples*2);
|
||||||
|
+#endif
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
01_rename_binary_generated.patch
|
||||||
|
02_update_default_path.patch
|
||||||
|
05_move_data_to_config.patch
|
||||||
|
21_use_legacy_soundtouch_13.patch
|
|
@ -0,0 +1,2 @@
|
||||||
|
usr/share/games/pcsx2/shaders
|
||||||
|
var/games/pcsx2/
|
|
@ -0,0 +1,2 @@
|
||||||
|
bin/plugins/ps2hw.dat usr/share/games/pcsx2/shaders/
|
||||||
|
bin/GameIndex.dbf var/games/pcsx2/
|
|
@ -0,0 +1 @@
|
||||||
|
usr/lib/games/pcsx2/plugins
|
|
@ -0,0 +1 @@
|
||||||
|
bin/plugins/lib* usr/lib/games/pcsx2/plugins
|
|
@ -0,0 +1,6 @@
|
||||||
|
#* -fPIC option was removed for multiple reason.
|
||||||
|
# - Code only support x86 architecture.
|
||||||
|
# - Upstream code uses the ebx register so it's not compliant with PIC.
|
||||||
|
# - Impacts the performance too much.
|
||||||
|
# - Only plugins. No package will link to them.
|
||||||
|
pcsx2-plugins-unstable: shlib-with-non-pic-code
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Name=PCSX2
|
||||||
|
GenericName=Playstation 2 Emulator
|
||||||
|
Comment=Sony Playstation 2 emulator
|
||||||
|
Exec=pcsx2
|
||||||
|
Icon=pcsx2
|
||||||
|
Categories=Game;Emulator;GTK;
|
|
@ -0,0 +1,3 @@
|
||||||
|
usr/games
|
||||||
|
usr/share/pixmaps
|
||||||
|
usr/share/applications
|
|
@ -0,0 +1,3 @@
|
||||||
|
bin/pcsx2 usr/games
|
||||||
|
debian/pcsx2.desktop usr/share/applications
|
||||||
|
debian/pcsx2.xpm usr/share/pixmaps
|
|
@ -0,0 +1 @@
|
||||||
|
bin/docs/pcsx2.man
|
|
@ -0,0 +1,6 @@
|
||||||
|
?package(pcsx2): \
|
||||||
|
needs="X11" \
|
||||||
|
section="Applications/Emulators" \
|
||||||
|
title="pcsx2" \
|
||||||
|
longtitle="A playstation 2 emulators" \
|
||||||
|
command="/usr/games/pcsx2"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,87 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
# export DH_VERBOSE=1
|
||||||
|
|
||||||
|
ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
|
||||||
|
CMAKE_BUILD_TYPE=Debug
|
||||||
|
else
|
||||||
|
CMAKE_BUILD_TYPE=Release
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
||||||
|
NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
||||||
|
MAKEFLAGS += -j$(NUMJOBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
USER_CFLAGS=$(shell dpkg-buildflags --get CFLAGS)
|
||||||
|
USER_CXXFLAGS=$(shell dpkg-buildflags --get CXXFLAGS)
|
||||||
|
|
||||||
|
build: build-stamp
|
||||||
|
build-stamp:
|
||||||
|
dh_testdir
|
||||||
|
|
||||||
|
# backup orig makefile
|
||||||
|
for makefile in `find ./ -name "Makefile"` ; do [ -f $${makefile}.orig ] || mv $${makefile} $${makefile}.orig ; done
|
||||||
|
|
||||||
|
# Cmake based makefile
|
||||||
|
cmake CMakeLists.txt \
|
||||||
|
-DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
|
||||||
|
-DCMAKE_BUILD_STRIP=FALSE \
|
||||||
|
-DFORCE_INTERNAL_SOUNDTOUCH=FALSE \
|
||||||
|
-DUSER_CMAKE_C_FLAGS:STRING="$(USER_CFLAGS)" \
|
||||||
|
-DUSER_CMAKE_CXX_FLAGS:STRING="$(USER_CXXFLAGS)"
|
||||||
|
$(MAKE) $(MAKEFLAGS)
|
||||||
|
|
||||||
|
touch build-stamp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dh_testdir
|
||||||
|
dh_testroot
|
||||||
|
rm -f build-stamp
|
||||||
|
|
||||||
|
# Backup some orig makefile if it's not already done.
|
||||||
|
# I hope that some will be delete by upstream when the cmake port is over.
|
||||||
|
# Note: In case that we do not dl all the plugins, the test [ -f $${makefile} ] ensures it works
|
||||||
|
for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \
|
||||||
|
plugins/CDVDiso/src/Linux/Makefile \
|
||||||
|
plugins/CDVDiso/src/Windows/Makefile \
|
||||||
|
plugins/USBnull/Windows/Makefile \
|
||||||
|
plugins/FWnull/Windows/Makefile \
|
||||||
|
plugins/PeopsSPU2/Makefile \
|
||||||
|
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
||||||
|
[ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done
|
||||||
|
|
||||||
|
# Add here the commands to clean up after the build process.
|
||||||
|
[ -f Makefile ] && $(MAKE) clean || true
|
||||||
|
# Remove cmake stuff
|
||||||
|
rm -fr $$(find . -type d -name CMakeFiles)
|
||||||
|
rm -f $$(find . -type f -name CMakeCache.txt) $$(find . -type f -name cmake_install.cmake)
|
||||||
|
rm -f $$(find . -type f -name Makefile)
|
||||||
|
# Files generated by bin2cpp
|
||||||
|
cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h
|
||||||
|
# leftover of cmake
|
||||||
|
rm -f bin/plugins/ps2hw.dat
|
||||||
|
rm -f pcsx2/svnrev.h
|
||||||
|
# Restore orig makefile
|
||||||
|
for makefile_orig in `find ./ -name "Makefile.orig"` ; do [ -f $${makefile_orig} ] && mv $${makefile_orig} `echo $${makefile_orig} | sed -e 's/.orig//'` ; done
|
||||||
|
|
||||||
|
dh_clean
|
||||||
|
|
||||||
|
## Uncomment this, if fglrx driver is installed
|
||||||
|
#override_dh_shlibdeps:
|
||||||
|
# dh_shlibdeps -- --ignore-missing-info
|
||||||
|
|
||||||
|
override_dh_strip:
|
||||||
|
dh_strip --package=pcsx2 --dbg-package=pcsx2-dbg
|
||||||
|
dh_strip --package=pcsx2-plugins --dbg-package=pcsx2-plugins-dbg
|
||||||
|
|
||||||
|
# Avoid to relaunch the compilation twice. (build and dh_auto_build target)
|
||||||
|
override_dh_auto_build:
|
||||||
|
# Do nothing
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --parallel
|
||||||
|
|
||||||
|
.PHONY: build clean install
|
|
@ -0,0 +1,87 @@
|
||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
# export DH_VERBOSE=1
|
||||||
|
|
||||||
|
ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
|
||||||
|
CMAKE_BUILD_TYPE=Debug
|
||||||
|
else
|
||||||
|
CMAKE_BUILD_TYPE=Release
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
||||||
|
NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
|
||||||
|
MAKEFLAGS += -j$(NUMJOBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
USER_CFLAGS=$(shell dpkg-buildflags --get CFLAGS)
|
||||||
|
USER_CXXFLAGS=$(shell dpkg-buildflags --get CXXFLAGS)
|
||||||
|
|
||||||
|
build: build-stamp
|
||||||
|
build-stamp:
|
||||||
|
dh_testdir
|
||||||
|
|
||||||
|
# backup orig makefile
|
||||||
|
for makefile in `find ./ -name "Makefile"` ; do [ -f $${makefile}.orig ] || mv $${makefile} $${makefile}.orig ; done
|
||||||
|
|
||||||
|
# Cmake based makefile
|
||||||
|
cmake CMakeLists.txt \
|
||||||
|
-DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
|
||||||
|
-DCMAKE_BUILD_STRIP=FALSE \
|
||||||
|
-DFORCE_INTERNAL_SOUNDTOUCH=FALSE \
|
||||||
|
-DUSER_CMAKE_C_FLAGS:STRING="$(USER_CFLAGS)" \
|
||||||
|
-DUSER_CMAKE_CXX_FLAGS:STRING="$(USER_CXXFLAGS)"
|
||||||
|
$(MAKE) $(MAKEFLAGS)
|
||||||
|
|
||||||
|
touch build-stamp
|
||||||
|
|
||||||
|
clean:
|
||||||
|
dh_testdir
|
||||||
|
dh_testroot
|
||||||
|
rm -f build-stamp
|
||||||
|
|
||||||
|
# Backup some orig makefile if it's not already done.
|
||||||
|
# I hope that some will be delete by upstream when the cmake port is over.
|
||||||
|
# Note: In case that we do not dl all the plugins, the test [ -f $${makefile} ] ensures it works
|
||||||
|
for makefile in plugins/CDVDlinuz/Src/Linux/Makefile \
|
||||||
|
plugins/CDVDiso/src/Linux/Makefile \
|
||||||
|
plugins/CDVDiso/src/Windows/Makefile \
|
||||||
|
plugins/USBnull/Windows/Makefile \
|
||||||
|
plugins/FWnull/Windows/Makefile \
|
||||||
|
plugins/PeopsSPU2/Makefile \
|
||||||
|
plugins/CDVDisoEFP/src/Linux/Makefile ; do \
|
||||||
|
[ -f $${makefile}.orig ] || ( [ -f $${makefile} ] && mv $${makefile} $${makefile}.orig ) || true ; done
|
||||||
|
|
||||||
|
# Add here the commands to clean up after the build process.
|
||||||
|
[ -f Makefile ] && $(MAKE) clean || true
|
||||||
|
# Remove cmake stuff
|
||||||
|
rm -fr $$(find . -type d -name CMakeFiles)
|
||||||
|
rm -f $$(find . -type f -name CMakeCache.txt) $$(find . -type f -name cmake_install.cmake)
|
||||||
|
rm -f $$(find . -type f -name Makefile)
|
||||||
|
# Files generated by bin2cpp
|
||||||
|
cd pcsx2/gui/Resources/ && rm -f App*.h Config*.h BackgroundLogo.h ButtonIcon_Camera.h Dualshock.h
|
||||||
|
# leftover of cmake
|
||||||
|
rm -f bin/plugins/ps2hw.dat
|
||||||
|
rm -f pcsx2/svnrev.h
|
||||||
|
# Restore orig makefile
|
||||||
|
for makefile_orig in `find ./ -name "Makefile.orig"` ; do [ -f $${makefile_orig} ] && mv $${makefile_orig} `echo $${makefile_orig} | sed -e 's/.orig//'` ; done
|
||||||
|
|
||||||
|
dh_clean
|
||||||
|
|
||||||
|
# Allow compilation when fglrx is installed
|
||||||
|
override_dh_shlibdeps:
|
||||||
|
dh_shlibdeps -- --ignore-missing-info
|
||||||
|
|
||||||
|
override_dh_strip:
|
||||||
|
dh_strip --package=pcsx2 --dbg-package=pcsx2-dbg
|
||||||
|
dh_strip --package=pcsx2-plugins --dbg-package=pcsx2-plugins-dbg
|
||||||
|
|
||||||
|
# Avoid to relaunch the compilation twice. (build and dh_auto_build target)
|
||||||
|
override_dh_auto_build:
|
||||||
|
# Do nothing
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --parallel
|
||||||
|
|
||||||
|
.PHONY: build clean install
|
|
@ -0,0 +1 @@
|
||||||
|
3.0 (quilt)
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Example watch control file for uscan
|
||||||
|
# Rename this file to "watch" and then you can run the "uscan" command
|
||||||
|
# to check for upstream updates and more.
|
||||||
|
# See uscan(1) for format
|
||||||
|
|
||||||
|
# Compulsory line, this is a version 3 file
|
||||||
|
version=3
|
||||||
|
|
||||||
|
# Note: Upstream does not release prepackaged source files.
|
||||||
|
# It's adviced to get them from their subversion repository.
|
||||||
|
# http://pcsx2.googlecode.com/files/Pcsx2-linux-beta-(.*).tar.gz
|
|
@ -36,6 +36,11 @@
|
||||||
|
|
||||||
!insertmacro UNINSTALL.LOG_CLOSE_INSTALL
|
!insertmacro UNINSTALL.LOG_CLOSE_INSTALL
|
||||||
|
|
||||||
|
SetOutPath "$INSTDIR\Cheats"
|
||||||
|
!insertmacro UNINSTALL.LOG_OPEN_INSTALL
|
||||||
|
File ..\bin\Cheats\*
|
||||||
|
!insertmacro UNINSTALL.LOG_CLOSE_INSTALL
|
||||||
|
|
||||||
SetOutPath "$INSTDIR\Docs"
|
SetOutPath "$INSTDIR\Docs"
|
||||||
!insertmacro UNINSTALL.LOG_OPEN_INSTALL
|
!insertmacro UNINSTALL.LOG_OPEN_INSTALL
|
||||||
File ..\bin\docs\*
|
File ..\bin\docs\*
|
||||||
|
|
|
@ -19,6 +19,7 @@ Section "Un.Exes and Plugins ${APP_NAME}"
|
||||||
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\Langs"
|
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\Langs"
|
||||||
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\Plugins"
|
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\Plugins"
|
||||||
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\Docs"
|
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\Docs"
|
||||||
|
!insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\Cheats"
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,9 @@ Function un.onUninstSuccess
|
||||||
StrCpy $0 "$INSTDIR\docs"
|
StrCpy $0 "$INSTDIR\docs"
|
||||||
Call un.DeleteDirIfEmpty
|
Call un.DeleteDirIfEmpty
|
||||||
|
|
||||||
|
StrCpy $0 "$INSTDIR\Cheats"
|
||||||
|
Call un.DeleteDirIfEmpty
|
||||||
|
|
||||||
StrCpy $0 "$INSTDIR"
|
StrCpy $0 "$INSTDIR"
|
||||||
Call un.DeleteDirIfEmpty
|
Call un.DeleteDirIfEmpty
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
<Project filename="common/build/x86emitter/x86emitter.cbp" />
|
<Project filename="common/build/x86emitter/x86emitter.cbp" />
|
||||||
<Project filename="common/build/Utilities/Utilities.cbp" />
|
<Project filename="common/build/Utilities/Utilities.cbp" />
|
||||||
<Project filename="3rdparty/SoundTouch/SoundTouch.cbp" />
|
<Project filename="3rdparty/SoundTouch/SoundTouch.cbp" />
|
||||||
<Project filename="3rdparty/liba52/liba52.cbp" />
|
|
||||||
<Project filename="plugins/FWnull/Linux/FWnull.cbp" />
|
<Project filename="plugins/FWnull/Linux/FWnull.cbp" />
|
||||||
<Project filename="plugins/USBnull/Linux/USBnull.cbp" />
|
<Project filename="plugins/USBnull/Linux/USBnull.cbp" />
|
||||||
<Project filename="plugins/dev9null/Linux/Dev9null.cbp" />
|
<Project filename="plugins/dev9null/Linux/Dev9null.cbp" />
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
<Depends filename="common/build/x86emitter/x86emitter.cbp" />
|
<Depends filename="common/build/x86emitter/x86emitter.cbp" />
|
||||||
<Depends filename="common/build/Utilities/Utilities.cbp" />
|
<Depends filename="common/build/Utilities/Utilities.cbp" />
|
||||||
<Depends filename="3rdparty/SoundTouch/SoundTouch.cbp" />
|
<Depends filename="3rdparty/SoundTouch/SoundTouch.cbp" />
|
||||||
<Depends filename="3rdparty/liba52/liba52.cbp" />
|
|
||||||
</Project>
|
</Project>
|
||||||
<Project filename="plugins/zerospu2/Linux/ZeroSPU2.cbp">
|
<Project filename="plugins/zerospu2/Linux/ZeroSPU2.cbp">
|
||||||
<Depends filename="3rdparty/SoundTouch/SoundTouch.cbp" />
|
<Depends filename="3rdparty/SoundTouch/SoundTouch.cbp" />
|
||||||
|
|
|
@ -83,22 +83,20 @@ static int mg_BIToffset(u8 *buffer)
|
||||||
|
|
||||||
FILE *_cdvdOpenMechaVer()
|
FILE *_cdvdOpenMechaVer()
|
||||||
{
|
{
|
||||||
FILE* fd;
|
|
||||||
|
|
||||||
// get the name of the bios file
|
// get the name of the bios file
|
||||||
|
|
||||||
wxFileName mecfile(EmuConfig.BiosFilename);
|
wxFileName mecfile(EmuConfig.BiosFilename);
|
||||||
mecfile.SetExt( L"mec" );
|
mecfile.SetExt( L"mec" );
|
||||||
const wxCharBuffer file( mecfile.GetFullPath().ToUTF8() );
|
const wxString fname( mecfile.GetFullPath() );
|
||||||
|
|
||||||
// if file doesnt exist, create empty one
|
// if file doesnt exist, create empty one
|
||||||
fd = fopen(file, "r+b");
|
FILE* fd = wxFopen(fname, L"r+b");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
Console.Warning("MEC File Not Found , Creating Blank File");
|
Console.Warning("MEC File Not Found, creating substitute...");
|
||||||
fd = fopen(file, "wb");
|
fd = wxFopen(fname, L"wb");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
throw Exception::CannotCreateStream(mecfile.GetFullPath());
|
throw Exception::CannotCreateStream(fname);
|
||||||
|
|
||||||
fputc(0x03, fd);
|
fputc(0x03, fd);
|
||||||
fputc(0x06, fd);
|
fputc(0x06, fd);
|
||||||
|
@ -108,32 +106,30 @@ FILE *_cdvdOpenMechaVer()
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdGetMechaVer(u8* ver)
|
static void cdvdGetMechaVer(u8* ver)
|
||||||
{
|
{
|
||||||
FILE* fd = _cdvdOpenMechaVer();
|
FILE* fd = _cdvdOpenMechaVer();
|
||||||
if (fd == NULL) return 1;
|
|
||||||
fseek(fd, 0, SEEK_SET);
|
fseek(fd, 0, SEEK_SET);
|
||||||
fread(ver, 1, 4, fd);
|
fread(ver, 1, 4, fd);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Throws Exception::CannotCreateStream if the file cannot be opened for reading, or cannot
|
||||||
|
// be created for some reason.
|
||||||
FILE* _cdvdOpenNVM()
|
FILE* _cdvdOpenNVM()
|
||||||
{
|
{
|
||||||
FILE* fd;
|
|
||||||
|
|
||||||
wxFileName nvmfile(EmuConfig.BiosFilename);
|
wxFileName nvmfile(EmuConfig.BiosFilename);
|
||||||
nvmfile.SetExt( L"nvm" );
|
nvmfile.SetExt( L"nvm" );
|
||||||
const wxCharBuffer file( nvmfile.GetFullPath().ToUTF8() );
|
const wxString fname( nvmfile.GetFullPath() );
|
||||||
|
|
||||||
// if file doesn't exist, create empty one
|
// if file doesn't exist, create empty one
|
||||||
fd = fopen(file, "r+b");
|
FILE* fd = wxFopen(fname, L"r+b");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
Console.Warning("NVM File Not Found, Creating Blank File");
|
Console.Warning("NVM File Not Found, Creating Blank File");
|
||||||
fd = fopen(file, "wb");
|
fd = wxFopen(fname, L"wb");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
throw Exception::CannotCreateStream(nvmfile.GetFullPath());
|
throw Exception::CannotCreateStream(fname);
|
||||||
|
|
||||||
for (int i=0; i<1024; i++) fputc(0, fd);
|
for (int i=0; i<1024; i++) fputc(0, fd);
|
||||||
}
|
}
|
||||||
|
@ -144,28 +140,23 @@ FILE *_cdvdOpenNVM()
|
||||||
// the following 'cdvd' functions all return 0 if successful
|
// the following 'cdvd' functions all return 0 if successful
|
||||||
//
|
//
|
||||||
|
|
||||||
s32 cdvdReadNVM(u8 *dst, int offset, int bytes) {
|
static void cdvdReadNVM(u8 *dst, int offset, int bytes) {
|
||||||
FILE* fd = _cdvdOpenNVM();
|
FILE* fd = _cdvdOpenNVM();
|
||||||
if (fd == NULL) return 1;
|
|
||||||
|
|
||||||
fseek(fd, offset, SEEK_SET);
|
fseek(fd, offset, SEEK_SET);
|
||||||
fread(dst, 1, bytes, fd);
|
fread(dst, 1, bytes, fd);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
s32 cdvdWriteNVM(const u8 *src, int offset, int bytes) {
|
|
||||||
|
static void cdvdWriteNVM(const u8 *src, int offset, int bytes) {
|
||||||
FILE* fd = _cdvdOpenNVM();
|
FILE* fd = _cdvdOpenNVM();
|
||||||
if (fd == NULL) return 1;
|
|
||||||
|
|
||||||
fseek(fd, offset, SEEK_SET);
|
fseek(fd, offset, SEEK_SET);
|
||||||
fwrite(src, 1, bytes, fd);
|
fwrite(src, 1, bytes, fd);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NVMLayout* getNvmLayout(void)
|
NVMLayout* getNvmLayout()
|
||||||
{
|
{
|
||||||
NVMLayout* nvmLayout = NULL;
|
NVMLayout* nvmLayout = NULL;
|
||||||
s32 nvmIdx;
|
s32 nvmIdx;
|
||||||
|
@ -178,70 +169,67 @@ NVMLayout* getNvmLayout(void)
|
||||||
return nvmLayout;
|
return nvmLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 getNvmData(u8* buffer, s32 offset, s32 size, s32 fmtOffset)
|
void getNvmData(u8* buffer, s32 offset, s32 size, s32 fmtOffset)
|
||||||
{
|
{
|
||||||
// find the correct bios version
|
// find the correct bios version
|
||||||
NVMLayout* nvmLayout = getNvmLayout();
|
NVMLayout* nvmLayout = getNvmLayout();
|
||||||
if (nvmLayout == NULL) return 1;
|
|
||||||
|
|
||||||
// get data from eeprom
|
// get data from eeprom
|
||||||
return cdvdReadNVM(buffer, *(s32*)(((u8*)nvmLayout)+fmtOffset) + offset, size);
|
cdvdReadNVM(buffer, *(s32*)(((u8*)nvmLayout)+fmtOffset) + offset, size);
|
||||||
}
|
}
|
||||||
s32 setNvmData(const u8* buffer, s32 offset, s32 size, s32 fmtOffset)
|
|
||||||
|
void setNvmData(const u8* buffer, s32 offset, s32 size, s32 fmtOffset)
|
||||||
{
|
{
|
||||||
// find the correct bios version
|
// find the correct bios version
|
||||||
NVMLayout* nvmLayout = getNvmLayout();
|
NVMLayout* nvmLayout = getNvmLayout();
|
||||||
if (nvmLayout == NULL) return 1;
|
|
||||||
|
|
||||||
// set data in eeprom
|
// set data in eeprom
|
||||||
return cdvdWriteNVM(buffer, *(s32*)(((u8*)nvmLayout)+fmtOffset) + offset, size);
|
cdvdWriteNVM(buffer, *(s32*)(((u8*)nvmLayout)+fmtOffset) + offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdReadConsoleID(u8* id)
|
static void cdvdReadConsoleID(u8* id)
|
||||||
{
|
{
|
||||||
return getNvmData(id, 0, 8, offsetof(NVMLayout, consoleId));
|
getNvmData(id, 0, 8, offsetof(NVMLayout, consoleId));
|
||||||
}
|
}
|
||||||
s32 cdvdWriteConsoleID(const u8* id)
|
static void cdvdWriteConsoleID(const u8* id)
|
||||||
{
|
{
|
||||||
return setNvmData(id, 0, 8, offsetof(NVMLayout, consoleId));
|
setNvmData(id, 0, 8, offsetof(NVMLayout, consoleId));
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdReadILinkID(u8* id)
|
static void cdvdReadILinkID(u8* id)
|
||||||
{
|
{
|
||||||
return getNvmData(id, 0, 8, offsetof(NVMLayout, ilinkId));
|
getNvmData(id, 0, 8, offsetof(NVMLayout, ilinkId));
|
||||||
}
|
}
|
||||||
s32 cdvdWriteILinkID(const u8* id)
|
static void cdvdWriteILinkID(const u8* id)
|
||||||
{
|
{
|
||||||
return setNvmData(id, 0, 8, offsetof(NVMLayout, ilinkId));
|
setNvmData(id, 0, 8, offsetof(NVMLayout, ilinkId));
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdReadModelNumber(u8* num, s32 part)
|
static void cdvdReadModelNumber(u8* num, s32 part)
|
||||||
{
|
{
|
||||||
return getNvmData(num, part, 8, offsetof(NVMLayout, modelNum));
|
getNvmData(num, part, 8, offsetof(NVMLayout, modelNum));
|
||||||
}
|
}
|
||||||
s32 cdvdWriteModelNumber(const u8* num, s32 part)
|
static void cdvdWriteModelNumber(const u8* num, s32 part)
|
||||||
{
|
{
|
||||||
return setNvmData(num, part, 8, offsetof(NVMLayout, modelNum));
|
setNvmData(num, part, 8, offsetof(NVMLayout, modelNum));
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdReadRegionParams(u8* num)
|
static void cdvdReadRegionParams(u8* num)
|
||||||
{
|
{
|
||||||
return getNvmData(num, 0, 8, offsetof(NVMLayout,regparams));
|
getNvmData(num, 0, 8, offsetof(NVMLayout,regparams));
|
||||||
|
}
|
||||||
|
static void cdvdWriteRegionParams(const u8* num)
|
||||||
|
{
|
||||||
|
setNvmData(num, 0, 8, offsetof(NVMLayout,regparams));
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdWriteRegionParams(const u8* num)
|
static void cdvdReadMAC(u8* num)
|
||||||
{
|
{
|
||||||
return setNvmData(num, 0, 8, offsetof(NVMLayout,regparams));
|
getNvmData(num, 0, 8, offsetof(NVMLayout,mac));
|
||||||
}
|
}
|
||||||
|
static void cdvdWriteMAC(const u8* num)
|
||||||
s32 cdvdReadMAC(u8* num)
|
|
||||||
{
|
{
|
||||||
return getNvmData(num, 0, 8, offsetof(NVMLayout,mac));
|
setNvmData(num, 0, 8, offsetof(NVMLayout,mac));
|
||||||
}
|
|
||||||
|
|
||||||
s32 cdvdWriteMAC(const u8* num)
|
|
||||||
{
|
|
||||||
return setNvmData(num, 0, 8, offsetof(NVMLayout,mac));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 cdvdReadConfig(u8* config)
|
s32 cdvdReadConfig(u8* config)
|
||||||
|
@ -270,14 +258,15 @@ s32 cdvdReadConfig(u8* config)
|
||||||
switch (cdvd.COffset)
|
switch (cdvd.COffset)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0));
|
getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2));
|
getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1));
|
getNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1));
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
s32 cdvdWriteConfig(const u8* config)
|
s32 cdvdWriteConfig(const u8* config)
|
||||||
{
|
{
|
||||||
|
@ -295,14 +284,15 @@ s32 cdvdWriteConfig(const u8* config)
|
||||||
switch (cdvd.COffset)
|
switch (cdvd.COffset)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0));
|
setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config0));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2));
|
setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config2));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1));
|
setNvmData(config, (cdvd.CBlockIndex++)*16, 16, offsetof(NVMLayout, config1));
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MutexRecursive Mutex_NewDiskCB;
|
static MutexRecursive Mutex_NewDiskCB;
|
||||||
|
@ -1431,6 +1421,8 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
CDVD_LOG("cdvdWrite16: SCMD %s (%x) (ParamP = %x)", sCmdName[rt], rt, cdvd.ParamP);
|
CDVD_LOG("cdvdWrite16: SCMD %s (%x) (ParamP = %x)", sCmdName[rt], rt, cdvd.ParamP);
|
||||||
|
|
||||||
cdvd.sCommand = rt;
|
cdvd.sCommand = rt;
|
||||||
|
cdvd.Result[0] = 0; // assume success -- failures will overwrite this with an error code.
|
||||||
|
|
||||||
switch (rt) {
|
switch (rt) {
|
||||||
// case 0x01: // GetDiscType - from cdvdman (0:1)
|
// case 0x01: // GetDiscType - from cdvdman (0:1)
|
||||||
// SetResultSize(1);
|
// SetResultSize(1);
|
||||||
|
@ -1452,12 +1444,12 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
|
|
||||||
case 0x44: // write console ID (9:1)
|
case 0x44: // write console ID (9:1)
|
||||||
SetResultSize(1);
|
SetResultSize(1);
|
||||||
cdvd.Result[0] = cdvdWriteConsoleID(&cdvd.Param[1]);
|
cdvdWriteConsoleID(&cdvd.Param[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x45: // read console ID (1:9)
|
case 0x45: // read console ID (1:9)
|
||||||
SetResultSize(9);
|
SetResultSize(9);
|
||||||
cdvd.Result[0] = cdvdReadConsoleID(&cdvd.Result[1]);
|
cdvdReadConsoleID(&cdvd.Result[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFD: // _sceCdReadRenewalDate (1:6) BCD
|
case 0xFD: // _sceCdReadRenewalDate (1:6) BCD
|
||||||
|
@ -1538,7 +1530,7 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
if (address < 512)
|
if (address < 512)
|
||||||
{
|
{
|
||||||
SetResultSize(3);
|
SetResultSize(3);
|
||||||
cdvd.Result[0] = cdvdReadNVM(&cdvd.Result[1], address*2, 2);
|
cdvdReadNVM(&cdvd.Result[1], address*2, 2);
|
||||||
// swap bytes around
|
// swap bytes around
|
||||||
tmp = cdvd.Result[1];
|
tmp = cdvd.Result[1];
|
||||||
cdvd.Result[1] = cdvd.Result[2];
|
cdvd.Result[1] = cdvd.Result[2];
|
||||||
|
@ -1561,7 +1553,7 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
tmp = cdvd.Param[2];
|
tmp = cdvd.Param[2];
|
||||||
cdvd.Param[2] = cdvd.Param[3];
|
cdvd.Param[2] = cdvd.Param[3];
|
||||||
cdvd.Param[3] = tmp;
|
cdvd.Param[3] = tmp;
|
||||||
cdvd.Result[0] = cdvdWriteNVM(&cdvd.Param[2], address*2, 2);
|
cdvdWriteNVM(&cdvd.Param[2], address*2, 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1580,12 +1572,12 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
|
|
||||||
case 0x12: // sceCdReadILinkId (0:9)
|
case 0x12: // sceCdReadILinkId (0:9)
|
||||||
SetResultSize(9);
|
SetResultSize(9);
|
||||||
cdvd.Result[0] = cdvdReadILinkID(&cdvd.Result[1]);
|
cdvdReadILinkID(&cdvd.Result[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x13: // sceCdWriteILinkID (8:1)
|
case 0x13: // sceCdWriteILinkID (8:1)
|
||||||
SetResultSize(1);
|
SetResultSize(1);
|
||||||
cdvd.Result[0] = cdvdWriteILinkID(&cdvd.Param[1]);
|
cdvdWriteILinkID(&cdvd.Param[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x14: // CdCtrlAudioDigitalOut (1:1)
|
case 0x14: // CdCtrlAudioDigitalOut (1:1)
|
||||||
|
@ -1607,12 +1599,12 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
|
|
||||||
case 0x17: // CdReadModelNumber (1:9) - from xcdvdman
|
case 0x17: // CdReadModelNumber (1:9) - from xcdvdman
|
||||||
SetResultSize(9);
|
SetResultSize(9);
|
||||||
cdvd.Result[0] = cdvdReadModelNumber(&cdvd.Result[1], cdvd.Param[0]);
|
cdvdReadModelNumber(&cdvd.Result[1], cdvd.Param[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18: // CdWriteModelNumber (9:1) - from xcdvdman
|
case 0x18: // CdWriteModelNumber (9:1) - from xcdvdman
|
||||||
SetResultSize(1);
|
SetResultSize(1);
|
||||||
cdvd.Result[0] = cdvdWriteModelNumber(&cdvd.Param[1], cdvd.Param[0]);
|
cdvdWriteModelNumber(&cdvd.Param[1], cdvd.Param[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case 0x19: // sceCdForbidRead (0:1) - from xcdvdman
|
// case 0x19: // sceCdForbidRead (0:1) - from xcdvdman
|
||||||
|
@ -1728,7 +1720,7 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
SetResultSize(15);
|
SetResultSize(15);
|
||||||
|
|
||||||
cdvdGetMechaVer(&cdvd.Result[1]);
|
cdvdGetMechaVer(&cdvd.Result[1]);
|
||||||
cdvd.Result[0] = cdvdReadRegionParams(&cdvd.Result[3]);//size==8
|
cdvdReadRegionParams(&cdvd.Result[3]);//size==8
|
||||||
Console.WriteLn("REGION PARAMS = %s %s", mg_zones[cdvd.Result[1]], &cdvd.Result[3]);
|
Console.WriteLn("REGION PARAMS = %s %s", mg_zones[cdvd.Result[1]], &cdvd.Result[3]);
|
||||||
cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers
|
cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
@ -1750,17 +1742,17 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
|
|
||||||
case 0x37: //called from EECONF [sceCdReadMAC - made up name] (0:9)
|
case 0x37: //called from EECONF [sceCdReadMAC - made up name] (0:9)
|
||||||
SetResultSize(9);
|
SetResultSize(9);
|
||||||
cdvd.Result[0] = cdvdReadMAC(&cdvd.Result[1]);
|
cdvdReadMAC(&cdvd.Result[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x38: //used to fix the MAC back after accidentally trashed it :D [sceCdWriteMAC - made up name] (8:1)
|
case 0x38: //used to fix the MAC back after accidentally trashed it :D [sceCdWriteMAC - made up name] (8:1)
|
||||||
SetResultSize(1);
|
SetResultSize(1);
|
||||||
cdvd.Result[0] = cdvdWriteMAC(&cdvd.Param[0]);
|
cdvdWriteMAC(&cdvd.Param[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3E: //[__sceCdWriteRegionParams - made up name] (15:1) [Florin: hum, i was expecting 14:1]
|
case 0x3E: //[__sceCdWriteRegionParams - made up name] (15:1) [Florin: hum, i was expecting 14:1]
|
||||||
SetResultSize(1);
|
SetResultSize(1);
|
||||||
cdvd.Result[0] = cdvdWriteRegionParams(&cdvd.Param[2]);
|
cdvdWriteRegionParams(&cdvd.Param[2]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x40: // CdOpenConfig (3:1)
|
case 0x40: // CdOpenConfig (3:1)
|
||||||
|
@ -1779,7 +1771,7 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
|
||||||
|
|
||||||
case 0x42: // CdWriteConfig (16:1)
|
case 0x42: // CdWriteConfig (16:1)
|
||||||
SetResultSize(1);
|
SetResultSize(1);
|
||||||
cdvd.Result[0] = cdvdWriteConfig(&cdvd.Param[0]);
|
cdvdWriteConfig(&cdvd.Param[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x43: // CdCloseConfig (0:1)
|
case 0x43: // CdCloseConfig (0:1)
|
||||||
|
|
|
@ -36,6 +36,9 @@ __ri void cpuUpdateOperationMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall WriteCP0Status(u32 value) {
|
void __fastcall WriteCP0Status(u32 value) {
|
||||||
|
|
||||||
|
DMA_LOG("COP0 Status write = 0x%08x", value);
|
||||||
|
|
||||||
cpuRegs.CP0.n.Status.val = value;
|
cpuRegs.CP0.n.Status.val = value;
|
||||||
cpuUpdateOperationMode();
|
cpuUpdateOperationMode();
|
||||||
cpuSetNextEventDelta(4);
|
cpuSetNextEventDelta(4);
|
||||||
|
|
|
@ -240,7 +240,7 @@ struct Pcsx2Config
|
||||||
return !OpEqu( bitset );
|
return !OpEqu( bitset );
|
||||||
}
|
}
|
||||||
|
|
||||||
} Recompiler;
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
struct CpuOptions
|
struct CpuOptions
|
||||||
|
@ -338,9 +338,9 @@ struct Pcsx2Config
|
||||||
OPHFlagHack :1; // Skips MPEG videos (Katamari and other games need this)
|
OPHFlagHack :1; // Skips MPEG videos (Katamari and other games need this)
|
||||||
BITFIELD_END
|
BITFIELD_END
|
||||||
|
|
||||||
// all gamefixes are disabled by default.
|
GamefixOptions();
|
||||||
GamefixOptions() : bitset( 0 ) {}
|
|
||||||
void LoadSave( IniInterface& conf );
|
void LoadSave( IniInterface& conf );
|
||||||
|
GamefixOptions& DisableAll();
|
||||||
|
|
||||||
void Set( const wxString& list, bool enabled=true );
|
void Set( const wxString& list, bool enabled=true );
|
||||||
void Clear( const wxString& list ) { Set( list, false ); }
|
void Clear( const wxString& list ) { Set( list, false ); }
|
||||||
|
@ -378,6 +378,7 @@ struct Pcsx2Config
|
||||||
|
|
||||||
SpeedhackOptions();
|
SpeedhackOptions();
|
||||||
void LoadSave( IniInterface& conf );
|
void LoadSave( IniInterface& conf );
|
||||||
|
SpeedhackOptions& DisableAll();
|
||||||
|
|
||||||
bool operator ==( const SpeedhackOptions& right ) const
|
bool operator ==( const SpeedhackOptions& right ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -347,7 +347,8 @@ static __fi void VSyncStart(u32 sCycle)
|
||||||
GetCoreThread().VsyncInThread();
|
GetCoreThread().VsyncInThread();
|
||||||
Cpu->CheckExecutionState();
|
Cpu->CheckExecutionState();
|
||||||
|
|
||||||
EECNT_LOG( "///////// EE COUNTER VSYNC START (frame: %6d) \\\\\\\\\\\\\\\\\\\\ ", g_FrameCount );
|
if(EmuConfig.Trace.Enabled && EmuConfig.Trace.EE.m_EnableAll)
|
||||||
|
SysTrace.EE.Counters.Write( " ================ EE COUNTER VSYNC START (frame: %d) ================", g_FrameCount );
|
||||||
|
|
||||||
// EE Profiling and Debug code.
|
// EE Profiling and Debug code.
|
||||||
// FIXME: should probably be moved to VsyncInThread, and handled
|
// FIXME: should probably be moved to VsyncInThread, and handled
|
||||||
|
@ -393,7 +394,8 @@ static __fi void VSyncStart(u32 sCycle)
|
||||||
|
|
||||||
static __fi void VSyncEnd(u32 sCycle)
|
static __fi void VSyncEnd(u32 sCycle)
|
||||||
{
|
{
|
||||||
EECNT_LOG( "///////// EE COUNTER VSYNC END (frame: %d) \\\\\\\\\\\\\\\\\\\\", g_FrameCount );
|
if(EmuConfig.Trace.Enabled && EmuConfig.Trace.EE.m_EnableAll)
|
||||||
|
SysTrace.EE.Counters.Write( " ================ EE COUNTER VSYNC END (frame: %d) ================", g_FrameCount );
|
||||||
|
|
||||||
g_FrameCount++;
|
g_FrameCount++;
|
||||||
|
|
||||||
|
|
|
@ -350,12 +350,12 @@ extern void __Log( const char* fmt, ... );
|
||||||
// passed into the function)
|
// passed into the function)
|
||||||
#ifdef PCSX2_DEVBUILD
|
#ifdef PCSX2_DEVBUILD
|
||||||
# define SysTraceActive(trace) SysTrace.trace.IsActive()
|
# define SysTraceActive(trace) SysTrace.trace.IsActive()
|
||||||
# define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write
|
|
||||||
#else
|
#else
|
||||||
# define SysTraceActive(trace) (false)
|
# define SysTraceActive(trace) (false)
|
||||||
# define macTrace(trace)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write
|
||||||
|
|
||||||
#define SIF_LOG macTrace(SIF)
|
#define SIF_LOG macTrace(SIF)
|
||||||
|
|
||||||
#define BIOS_LOG macTrace(EE.Bios)
|
#define BIOS_LOG macTrace(EE.Bios)
|
||||||
|
@ -373,6 +373,7 @@ extern void __Log( const char* fmt, ... );
|
||||||
#define GIF_LOG macTrace(EE.GIF)
|
#define GIF_LOG macTrace(EE.GIF)
|
||||||
#define EECNT_LOG macTrace(EE.Counters)
|
#define EECNT_LOG macTrace(EE.Counters)
|
||||||
#define VifCodeLog macTrace(EE.VIFcode)
|
#define VifCodeLog macTrace(EE.VIFcode)
|
||||||
|
#define GifTagLog macTrace(EE.GIFtag)
|
||||||
|
|
||||||
|
|
||||||
#define PSXBIOS_LOG macTrace(IOP.Bios)
|
#define PSXBIOS_LOG macTrace(IOP.Bios)
|
||||||
|
|
|
@ -92,6 +92,8 @@ union tDMA_TAG {
|
||||||
};
|
};
|
||||||
u32 _u32;
|
u32 _u32;
|
||||||
|
|
||||||
|
tDMA_TAG() {}
|
||||||
|
|
||||||
tDMA_TAG(u32 val) { _u32 = val; }
|
tDMA_TAG(u32 val) { _u32 = val; }
|
||||||
u16 upper() const { return (_u32 >> 16); }
|
u16 upper() const { return (_u32 >> 16); }
|
||||||
u16 lower() const { return (u16)_u32; }
|
u16 lower() const { return (u16)_u32; }
|
||||||
|
|
|
@ -108,8 +108,11 @@ __fi uint dmacInterrupt()
|
||||||
//DevCon.Warning("DMAC Suspended or Disabled on interrupt");
|
//DevCon.Warning("DMAC Suspended or Disabled on interrupt");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
HW_LOG("dmacInterrupt %x", (psHu16(DMAC_STAT + 2) & psHu16(DMAC_STAT) |
|
|
||||||
psHu16(DMAC_STAT) & 0x8000));
|
DMA_LOG("dmacInterrupt %x",
|
||||||
|
((psHu16(DMAC_STAT + 2) & psHu16(DMAC_STAT)) |
|
||||||
|
(psHu16(DMAC_STAT) & 0x8000))
|
||||||
|
);
|
||||||
|
|
||||||
//cpuException(0x800, cpuRegs.branch);
|
//cpuException(0x800, cpuRegs.branch);
|
||||||
return 0x800;
|
return 0x800;
|
||||||
|
|
|
@ -277,6 +277,7 @@ enum EERegisterAddresses
|
||||||
SIF2_CHCR = 0x1000C800,
|
SIF2_CHCR = 0x1000C800,
|
||||||
SIF2_MADR = 0x1000C810,
|
SIF2_MADR = 0x1000C810,
|
||||||
SIF2_QWC = 0x1000C820,
|
SIF2_QWC = 0x1000C820,
|
||||||
|
SIF2_TADR = 0x1000C830,
|
||||||
|
|
||||||
//fromSPR
|
//fromSPR
|
||||||
D8_CHCR = 0x1000D000,
|
D8_CHCR = 0x1000D000,
|
||||||
|
@ -286,6 +287,8 @@ enum EERegisterAddresses
|
||||||
fromSPR_CHCR = 0x1000D000,
|
fromSPR_CHCR = 0x1000D000,
|
||||||
fromSPR_MADR = 0x1000D010,
|
fromSPR_MADR = 0x1000D010,
|
||||||
fromSPR_QWC = 0x1000D020,
|
fromSPR_QWC = 0x1000D020,
|
||||||
|
fromSPR_TADR = 0x1000D030,
|
||||||
|
fromSPR_SADR = 0x1000D080,
|
||||||
|
|
||||||
//toSPR
|
//toSPR
|
||||||
D9_CHCR = 0x1000D400,
|
D9_CHCR = 0x1000D400,
|
||||||
|
@ -295,6 +298,8 @@ enum EERegisterAddresses
|
||||||
toSPR_CHCR = 0x1000D400,
|
toSPR_CHCR = 0x1000D400,
|
||||||
toSPR_MADR = 0x1000D410,
|
toSPR_MADR = 0x1000D410,
|
||||||
toSPR_QWC = 0x1000D420,
|
toSPR_QWC = 0x1000D420,
|
||||||
|
toSPR_TADR = 0x1000D430,
|
||||||
|
toSPR_SADR = 0x1000D480,
|
||||||
|
|
||||||
DMAC_CTRL = 0x1000E000,
|
DMAC_CTRL = 0x1000E000,
|
||||||
DMAC_STAT = 0x1000E010,
|
DMAC_STAT = 0x1000E010,
|
||||||
|
|
|
@ -26,17 +26,10 @@
|
||||||
#include "Vif_Dma.h"
|
#include "Vif_Dma.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
static __fi void IPU_INT0_FROM()
|
|
||||||
{
|
|
||||||
if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
tIPU_cmd ipu_cmd;
|
|
||||||
|
|
||||||
void ReorderBitstream();
|
|
||||||
|
|
||||||
// the BP doesn't advance and returns -1 if there is no data to be read
|
// the BP doesn't advance and returns -1 if there is no data to be read
|
||||||
|
__aligned16 tIPU_cmd ipu_cmd;
|
||||||
__aligned16 tIPU_BP g_BP;
|
__aligned16 tIPU_BP g_BP;
|
||||||
|
__aligned16 decoder_t decoder;
|
||||||
|
|
||||||
void IPUWorker();
|
void IPUWorker();
|
||||||
|
|
||||||
|
@ -53,11 +46,18 @@ int coded_block_pattern = 0;
|
||||||
|
|
||||||
|
|
||||||
u8 indx4[16*16/2];
|
u8 indx4[16*16/2];
|
||||||
__aligned16 decoder_t decoder;
|
|
||||||
|
|
||||||
|
void tIPU_cmd::clear()
|
||||||
|
{
|
||||||
|
memzero_sse_a(*this);
|
||||||
|
current = 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
__fi void IPUProcessInterrupt()
|
__fi void IPUProcessInterrupt()
|
||||||
{
|
{
|
||||||
if (ipuRegs.ctrl.BUSY && g_BP.IFC) IPUWorker();
|
if (ipuRegs.ctrl.BUSY) // && (g_BP.FP || g_BP.IFC || (ipu1dma.chcr.STR && ipu1dma.qwc > 0)))
|
||||||
|
IPUWorker();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
@ -194,7 +194,7 @@ __fi u32 ipuRead32(u32 mem)
|
||||||
pxAssert((mem & ~0xff) == 0x10002000);
|
pxAssert((mem & ~0xff) == 0x10002000);
|
||||||
mem &= 0xff; // ipu repeats every 0x100
|
mem &= 0xff; // ipu repeats every 0x100
|
||||||
|
|
||||||
//IPUProcessInterrupt();
|
IPUProcessInterrupt();
|
||||||
|
|
||||||
switch (mem)
|
switch (mem)
|
||||||
{
|
{
|
||||||
|
@ -236,7 +236,7 @@ __fi u64 ipuRead64(u32 mem)
|
||||||
pxAssert((mem & ~0xff) == 0x10002000);
|
pxAssert((mem & ~0xff) == 0x10002000);
|
||||||
mem &= 0xff; // ipu repeats every 0x100
|
mem &= 0xff; // ipu repeats every 0x100
|
||||||
|
|
||||||
//IPUProcessInterrupt();
|
IPUProcessInterrupt();
|
||||||
|
|
||||||
switch (mem)
|
switch (mem)
|
||||||
{
|
{
|
||||||
|
@ -286,13 +286,12 @@ __fi bool ipuWrite32(u32 mem, u32 value)
|
||||||
pxAssert((mem & ~0xfff) == 0x10002000);
|
pxAssert((mem & ~0xfff) == 0x10002000);
|
||||||
mem &= 0xfff;
|
mem &= 0xfff;
|
||||||
|
|
||||||
IPUProcessInterrupt();
|
|
||||||
|
|
||||||
switch (mem)
|
switch (mem)
|
||||||
{
|
{
|
||||||
ipucase(IPU_CMD): // IPU_CMD
|
ipucase(IPU_CMD): // IPU_CMD
|
||||||
IPU_LOG("write32: IPU_CMD=0x%08X", value);
|
IPU_LOG("write32: IPU_CMD=0x%08X", value);
|
||||||
IPUCMD_WRITE(value);
|
IPUCMD_WRITE(value);
|
||||||
|
IPUProcessInterrupt();
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ipucase(IPU_CTRL): // IPU_CTRL
|
ipucase(IPU_CTRL): // IPU_CTRL
|
||||||
|
@ -323,13 +322,12 @@ __fi bool ipuWrite64(u32 mem, u64 value)
|
||||||
pxAssert((mem & ~0xfff) == 0x10002000);
|
pxAssert((mem & ~0xfff) == 0x10002000);
|
||||||
mem &= 0xfff;
|
mem &= 0xfff;
|
||||||
|
|
||||||
IPUProcessInterrupt();
|
|
||||||
|
|
||||||
switch (mem)
|
switch (mem)
|
||||||
{
|
{
|
||||||
ipucase(IPU_CMD):
|
ipucase(IPU_CMD):
|
||||||
IPU_LOG("write64: IPU_CMD=0x%08X", value);
|
IPU_LOG("write64: IPU_CMD=0x%08X", value);
|
||||||
IPUCMD_WRITE((u32)value);
|
IPUCMD_WRITE((u32)value);
|
||||||
|
IPUProcessInterrupt();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,14 +350,9 @@ static void ipuBCLR(u32 val)
|
||||||
IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP);
|
IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ipuIDEC(u32 val, bool resume)
|
static __ri void ipuIDEC(tIPU_CMD_IDEC idec)
|
||||||
{
|
|
||||||
tIPU_CMD_IDEC idec(val);
|
|
||||||
|
|
||||||
if (!resume)
|
|
||||||
{
|
{
|
||||||
idec.log();
|
idec.log();
|
||||||
g_BP.Advance(idec.FB);
|
|
||||||
|
|
||||||
//from IPU_CTRL
|
//from IPU_CTRL
|
||||||
ipuRegs.ctrl.PCT = I_TYPE; //Intra DECoding;)
|
ipuRegs.ctrl.PCT = I_TYPE; //Intra DECoding;)
|
||||||
|
@ -382,21 +375,13 @@ static bool ipuIDEC(u32 val, bool resume)
|
||||||
decoder.dcr = 1; // resets DC prediction value
|
decoder.dcr = 1; // resets DC prediction value
|
||||||
}
|
}
|
||||||
|
|
||||||
return mpeg2sliceIDEC();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int s_bdec = 0;
|
static int s_bdec = 0;
|
||||||
|
|
||||||
static __fi bool ipuBDEC(u32 val, bool resume)
|
static __ri void ipuBDEC(tIPU_CMD_BDEC bdec)
|
||||||
{
|
|
||||||
tIPU_CMD_BDEC bdec(val);
|
|
||||||
|
|
||||||
if (!resume)
|
|
||||||
{
|
{
|
||||||
bdec.log(s_bdec);
|
bdec.log(s_bdec);
|
||||||
if (IsDebugBuild) s_bdec++;
|
if (IsDebugBuild) s_bdec++;
|
||||||
|
|
||||||
g_BP.Advance(bdec.FB);
|
|
||||||
decoder.coding_type = I_TYPE;
|
decoder.coding_type = I_TYPE;
|
||||||
decoder.mpeg1 = ipuRegs.ctrl.MP1;
|
decoder.mpeg1 = ipuRegs.ctrl.MP1;
|
||||||
decoder.q_scale_type = ipuRegs.ctrl.QST;
|
decoder.q_scale_type = ipuRegs.ctrl.QST;
|
||||||
|
@ -414,10 +399,7 @@ static __fi bool ipuBDEC(u32 val, bool resume)
|
||||||
memzero_sse_a(decoder.mb16);
|
memzero_sse_a(decoder.mb16);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mpeg2_slice();
|
static __fi bool ipuVDEC(u32 val)
|
||||||
}
|
|
||||||
|
|
||||||
static bool __fastcall ipuVDEC(u32 val)
|
|
||||||
{
|
{
|
||||||
switch (ipu_cmd.pos[0])
|
switch (ipu_cmd.pos[0])
|
||||||
{
|
{
|
||||||
|
@ -448,6 +430,14 @@ static bool __fastcall ipuVDEC(u32 val)
|
||||||
jNO_DEFAULT
|
jNO_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK ATTACK! This code OR's the MPEG decoder's bitstream position into the upper
|
||||||
|
// 16 bits of DATA; which really doesn't make sense since (a) we already rewound the bits
|
||||||
|
// back into the IPU internal buffer above, and (b) the IPU doesn't have an MPEG internal
|
||||||
|
// 32-bit decoder buffer of its own anyway. Furthermore, setting the upper 16 bits to
|
||||||
|
// any value other than zero appears to work fine. When set to zero, however, FMVs run
|
||||||
|
// very choppy (basically only decoding/updating every 30th frame or so). So yeah,
|
||||||
|
// someone with knowledge on the subject please feel free to explain this one. :) --air
|
||||||
|
|
||||||
ipuRegs.cmd.DATA &= 0xFFFF;
|
ipuRegs.cmd.DATA &= 0xFFFF;
|
||||||
ipuRegs.cmd.DATA |= 0x10000;
|
ipuRegs.cmd.DATA |= 0x10000;
|
||||||
|
|
||||||
|
@ -466,6 +456,7 @@ static bool __fastcall ipuVDEC(u32 val)
|
||||||
IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d",
|
IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d",
|
||||||
ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ?
|
ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ?
|
||||||
((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT);
|
((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
jNO_DEFAULT
|
jNO_DEFAULT
|
||||||
|
@ -474,7 +465,7 @@ static bool __fastcall ipuVDEC(u32 val)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __fi bool ipuFDEC(u32 val)
|
static __ri bool ipuFDEC(u32 val)
|
||||||
{
|
{
|
||||||
if (!getBits32((u8*)&ipuRegs.cmd.DATA, 0)) return false;
|
if (!getBits32((u8*)&ipuRegs.cmd.DATA, 0)) return false;
|
||||||
|
|
||||||
|
@ -488,8 +479,6 @@ static __fi bool ipuFDEC(u32 val)
|
||||||
|
|
||||||
static bool ipuSETIQ(u32 val)
|
static bool ipuSETIQ(u32 val)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((val >> 27) & 1)
|
if ((val >> 27) & 1)
|
||||||
{
|
{
|
||||||
u8 (&niq)[64] = decoder.niq;
|
u8 (&niq)[64] = decoder.niq;
|
||||||
|
@ -500,7 +489,7 @@ static bool ipuSETIQ(u32 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
IPU_LOG("Read non-intra quantization matrix from FIFO.");
|
IPU_LOG("Read non-intra quantization matrix from FIFO.");
|
||||||
for (i = 0; i < 8; i++)
|
for (uint i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
|
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
|
||||||
niq[i * 8 + 0], niq[i * 8 + 1], niq[i * 8 + 2], niq[i * 8 + 3],
|
niq[i * 8 + 0], niq[i * 8 + 1], niq[i * 8 + 2], niq[i * 8 + 3],
|
||||||
|
@ -517,7 +506,7 @@ static bool ipuSETIQ(u32 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
IPU_LOG("Read intra quantization matrix from FIFO.");
|
IPU_LOG("Read intra quantization matrix from FIFO.");
|
||||||
for (i = 0; i < 8; i++)
|
for (uint i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
|
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
|
||||||
iq[i * 8 + 0], iq[i * 8 + 1], iq[i * 8 + 2], iq[i *8 + 3],
|
iq[i * 8 + 0], iq[i * 8 + 1], iq[i * 8 + 2], iq[i *8 + 3],
|
||||||
|
@ -561,9 +550,8 @@ static bool ipuSETVQ(u32 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPU Transfers are split into 8Qwords so we need to send ALL the data
|
// IPU Transfers are split into 8Qwords so we need to send ALL the data
|
||||||
static bool __fastcall ipuCSC(u32 val)
|
static __ri bool ipuCSC(tIPU_CMD_CSC csc)
|
||||||
{
|
{
|
||||||
tIPU_CMD_CSC csc(val);
|
|
||||||
csc.log_from_YCbCr();
|
csc.log_from_YCbCr();
|
||||||
|
|
||||||
for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)
|
for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)
|
||||||
|
@ -577,22 +565,14 @@ static bool __fastcall ipuCSC(u32 val)
|
||||||
if (csc.OFM) ipu_dither(decoder.rgb32, decoder.rgb16, csc.DTE);
|
if (csc.OFM) ipu_dither(decoder.rgb32, decoder.rgb16, csc.DTE);
|
||||||
|
|
||||||
if (csc.OFM)
|
if (csc.OFM)
|
||||||
{
|
|
||||||
while (ipu_cmd.pos[1] < 32)
|
|
||||||
{
|
{
|
||||||
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
|
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
|
||||||
|
if (ipu_cmd.pos[1] < 32) return false;
|
||||||
if (ipu_cmd.pos[1] <= 0) return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
while (ipu_cmd.pos[1] < 64)
|
|
||||||
{
|
{
|
||||||
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb32) + 4 * ipu_cmd.pos[1], 64 - ipu_cmd.pos[1]);
|
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb32) + 4 * ipu_cmd.pos[1], 64 - ipu_cmd.pos[1]);
|
||||||
|
if (ipu_cmd.pos[1] < 64) return false;
|
||||||
if (ipu_cmd.pos[1] <= 0) return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ipu_cmd.pos[0] = 0;
|
ipu_cmd.pos[0] = 0;
|
||||||
|
@ -602,10 +582,8 @@ static bool __fastcall ipuCSC(u32 val)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo - Need to add the same stop and start code as CSC
|
static __ri bool ipuPACK(tIPU_CMD_CSC csc)
|
||||||
static bool ipuPACK(u32 val)
|
|
||||||
{
|
{
|
||||||
tIPU_CMD_CSC csc(val);
|
|
||||||
csc.log_from_RGB32();
|
csc.log_from_RGB32();
|
||||||
|
|
||||||
for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)
|
for (;ipu_cmd.index < (int)csc.MBC; ipu_cmd.index++)
|
||||||
|
@ -623,13 +601,11 @@ static bool ipuPACK(u32 val)
|
||||||
if (csc.OFM)
|
if (csc.OFM)
|
||||||
{
|
{
|
||||||
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
|
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
|
||||||
|
|
||||||
if (ipu_cmd.pos[1] < 32) return false;
|
if (ipu_cmd.pos[1] < 32) return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*)indx4) + 4 * ipu_cmd.pos[1], 8 - ipu_cmd.pos[1]);
|
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*)indx4) + 4 * ipu_cmd.pos[1], 8 - ipu_cmd.pos[1]);
|
||||||
|
|
||||||
if (ipu_cmd.pos[1] < 8) return false;
|
if (ipu_cmd.pos[1] < 8) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,206 +808,150 @@ u8 getBits8(u8 *address, bool advance)
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// IPU Worker / Dispatcher
|
// IPU Worker / Dispatcher
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
void IPUCMD_WRITE(u32 val)
|
|
||||||
|
// When a command is written, we set some various busy flags and clear some other junk.
|
||||||
|
// The actual decoding will be handled by IPUworker.
|
||||||
|
__fi void IPUCMD_WRITE(u32 val)
|
||||||
{
|
{
|
||||||
// don't process anything if currently busy
|
// don't process anything if currently busy
|
||||||
if (ipuRegs.ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread
|
//if (ipuRegs.ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread
|
||||||
|
|
||||||
ipuRegs.ctrl.ECD = 0;
|
ipuRegs.ctrl.ECD = 0;
|
||||||
ipuRegs.ctrl.SCD = 0; //clear ECD/SCD
|
ipuRegs.ctrl.SCD = 0;
|
||||||
ipu_cmd.clear();
|
ipu_cmd.clear();
|
||||||
ipu_cmd.current = val;
|
ipu_cmd.current = val;
|
||||||
|
|
||||||
switch (val >> 28)
|
switch (ipu_cmd.CMD)
|
||||||
{
|
{
|
||||||
|
// BCLR and SETTH require no data so they always execute inline:
|
||||||
|
|
||||||
case SCE_IPU_BCLR:
|
case SCE_IPU_BCLR:
|
||||||
ipuBCLR(val);
|
ipuBCLR(val);
|
||||||
hwIntcIrq(INTC_IPU); //DMAC_TO_IPU
|
hwIntcIrq(INTC_IPU); //DMAC_TO_IPU
|
||||||
|
ipuRegs.ctrl.BUSY = 0;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case SCE_IPU_VDEC:
|
|
||||||
|
|
||||||
g_BP.Advance(val & 0x3F);
|
|
||||||
|
|
||||||
// check if enough data in queue
|
|
||||||
if (ipuVDEC(val)) return;
|
|
||||||
|
|
||||||
ipuRegs.cmd.BUSY = 0x80000000;
|
|
||||||
ipuRegs.topbusy = 0x80000000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_FDEC:
|
|
||||||
IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, CHCR 0x%x",
|
|
||||||
val & 0x3f, g_BP.IFC, (int)g_BP.BP, ipu1dma.chcr._u32);
|
|
||||||
|
|
||||||
g_BP.Advance(val & 0x3F);
|
|
||||||
|
|
||||||
if (ipuFDEC(val)) return;
|
|
||||||
ipuRegs.cmd.BUSY = 0x80000000;
|
|
||||||
ipuRegs.topbusy = 0x80000000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_SETTH:
|
case SCE_IPU_SETTH:
|
||||||
ipuSETTH(val);
|
ipuSETTH(val);
|
||||||
hwIntcIrq(INTC_IPU);
|
hwIntcIrq(INTC_IPU);
|
||||||
|
ipuRegs.ctrl.BUSY = 0;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case SCE_IPU_SETIQ:
|
|
||||||
IPU_LOG("SETIQ command.");
|
|
||||||
if (val & 0x3f) IPU_LOG("Skip %d bits.", val & 0x3f);
|
|
||||||
g_BP.Advance(val & 0x3F);
|
|
||||||
if (ipuSETIQ(val)) return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_SETVQ:
|
|
||||||
if (ipuSETVQ(val)) return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_CSC:
|
|
||||||
ipu_cmd.pos[1] = 0;
|
|
||||||
ipu_cmd.index = 0;
|
|
||||||
|
|
||||||
if (ipuCSC(val))
|
|
||||||
{
|
|
||||||
IPU_INT0_FROM();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_PACK:
|
|
||||||
ipu_cmd.pos[1] = 0;
|
|
||||||
ipu_cmd.index = 0;
|
|
||||||
if (ipuPACK(val)) return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_IDEC:
|
case SCE_IPU_IDEC:
|
||||||
if (ipuIDEC(val, false))
|
g_BP.Advance(val & 0x3F);
|
||||||
{
|
ipuIDEC(val);
|
||||||
// idec done, ipu0 done too
|
ipuRegs.SetTopBusy();
|
||||||
IPU_INT0_FROM();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipuRegs.topbusy = 0x80000000;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCE_IPU_BDEC:
|
case SCE_IPU_BDEC:
|
||||||
if (ipuBDEC(val, false))
|
g_BP.Advance(val & 0x3F);
|
||||||
{
|
ipuBDEC(val);
|
||||||
IPU_INT0_FROM();
|
ipuRegs.SetTopBusy();
|
||||||
if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ipuRegs.topbusy = 0x80000000;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_VDEC:
|
||||||
|
g_BP.Advance(val & 0x3F);
|
||||||
|
ipuRegs.SetDataBusy();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_FDEC:
|
||||||
|
IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, CHCR 0x%x",
|
||||||
|
val & 0x3f, g_BP.IFC, g_BP.BP, ipu1dma.chcr._u32);
|
||||||
|
|
||||||
|
g_BP.Advance(val & 0x3F);
|
||||||
|
ipuRegs.SetDataBusy();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_SETIQ:
|
||||||
|
IPU_LOG("SETIQ command.");
|
||||||
|
g_BP.Advance(val & 0x3F);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_SETVQ:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_CSC:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_PACK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
jNO_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// have to resort to the thread
|
|
||||||
ipuRegs.ctrl.BUSY = 1;
|
ipuRegs.ctrl.BUSY = 1;
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
|
//if(!ipu1dma.chcr.STR) hwIntcIrq(INTC_IPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPUWorker()
|
__noinline void IPUWorker()
|
||||||
{
|
{
|
||||||
pxAssert(ipuRegs.ctrl.BUSY);
|
pxAssert(ipuRegs.ctrl.BUSY);
|
||||||
|
|
||||||
switch (ipu_cmd.CMD)
|
switch (ipu_cmd.CMD)
|
||||||
{
|
{
|
||||||
case SCE_IPU_VDEC:
|
// These are unreachable (BUSY will always be 0 for them)
|
||||||
if (!ipuVDEC(ipu_cmd.current))
|
//case SCE_IPU_BCLR:
|
||||||
{
|
//case SCE_IPU_SETTH:
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
//break;
|
||||||
return;
|
|
||||||
}
|
|
||||||
ipuRegs.cmd.BUSY = 0;
|
|
||||||
ipuRegs.topbusy = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_FDEC:
|
|
||||||
if (!ipuFDEC(ipu_cmd.current))
|
|
||||||
{
|
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ipuRegs.cmd.BUSY = 0;
|
|
||||||
ipuRegs.topbusy = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_SETIQ:
|
|
||||||
if (!ipuSETIQ(ipu_cmd.current))
|
|
||||||
{
|
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_SETVQ:
|
|
||||||
if (!ipuSETVQ(ipu_cmd.current))
|
|
||||||
{
|
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_CSC:
|
|
||||||
if (!ipuCSC(ipu_cmd.current))
|
|
||||||
{
|
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
IPU_INT0_FROM();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_PACK:
|
|
||||||
if (!ipuPACK(ipu_cmd.current))
|
|
||||||
{
|
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCE_IPU_IDEC:
|
case SCE_IPU_IDEC:
|
||||||
if (!ipuIDEC(ipu_cmd.current, true))
|
if (!mpeg2sliceIDEC()) return;
|
||||||
{
|
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipuRegs.ctrl.OFC = 0;
|
//ipuRegs.ctrl.OFC = 0;
|
||||||
ipuRegs.ctrl.BUSY = 0;
|
|
||||||
ipuRegs.topbusy = 0;
|
ipuRegs.topbusy = 0;
|
||||||
ipuRegs.cmd.BUSY = 0;
|
ipuRegs.cmd.BUSY = 0;
|
||||||
ipu_cmd.current = 0xffffffff;
|
|
||||||
|
|
||||||
// CHECK!: IPU0dma remains when IDEC is done, so we need to clear it
|
// CHECK!: IPU0dma remains when IDEC is done, so we need to clear it
|
||||||
IPU_INT0_FROM();
|
//IPU_INT0_FROM();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCE_IPU_BDEC:
|
case SCE_IPU_BDEC:
|
||||||
if (!ipuBDEC(ipu_cmd.current, true))
|
if (!mpeg2_slice()) return;
|
||||||
{
|
|
||||||
if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipuRegs.ctrl.BUSY = 0;
|
|
||||||
ipuRegs.topbusy = 0;
|
ipuRegs.topbusy = 0;
|
||||||
ipuRegs.cmd.BUSY = 0;
|
ipuRegs.cmd.BUSY = 0;
|
||||||
ipu_cmd.current = 0xffffffff;
|
|
||||||
|
|
||||||
IPU_INT0_FROM();
|
//if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU);
|
||||||
if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU);
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Console.WriteLn("Unknown IPU command: %08x", ipu_cmd.current);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_VDEC:
|
||||||
|
if (!ipuVDEC(ipu_cmd.current)) return;
|
||||||
|
|
||||||
|
ipuRegs.topbusy = 0;
|
||||||
|
ipuRegs.cmd.BUSY = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_FDEC:
|
||||||
|
if (!ipuFDEC(ipu_cmd.current)) return;
|
||||||
|
|
||||||
|
ipuRegs.topbusy = 0;
|
||||||
|
ipuRegs.cmd.BUSY = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_SETIQ:
|
||||||
|
if (!ipuSETIQ(ipu_cmd.current)) return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_SETVQ:
|
||||||
|
if (!ipuSETVQ(ipu_cmd.current)) return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_CSC:
|
||||||
|
if (!ipuCSC(ipu_cmd.current)) return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCE_IPU_PACK:
|
||||||
|
if (!ipuPACK(ipu_cmd.current)) return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
jNO_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
// success
|
// success
|
||||||
ipuRegs.ctrl.BUSY = 0;
|
ipuRegs.ctrl.BUSY = 0;
|
||||||
ipu_cmd.current = 0xffffffff;
|
ipu_cmd.current = 0xffffffff;
|
||||||
|
hwIntcIrq(INTC_IPU);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ struct tIPU_CMD
|
||||||
{
|
{
|
||||||
u32 DATA;
|
u32 DATA;
|
||||||
u32 BUSY;
|
u32 BUSY;
|
||||||
|
|
||||||
|
void SetBusy(bool busy=true)
|
||||||
|
{
|
||||||
|
BUSY = busy ? 0x80000000 : 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
union tIPU_CTRL {
|
union tIPU_CTRL {
|
||||||
|
@ -85,7 +90,7 @@ struct __aligned16 tIPU_BP {
|
||||||
BP += bits;
|
BP += bits;
|
||||||
pxAssume( BP <= 256 );
|
pxAssume( BP <= 256 );
|
||||||
|
|
||||||
if (BP > 127)
|
if (BP >= 128)
|
||||||
{
|
{
|
||||||
BP -= 128;
|
BP -= 128;
|
||||||
|
|
||||||
|
@ -100,8 +105,11 @@ struct __aligned16 tIPU_BP {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if FP == 1 then the buffer has been completely drained.
|
// if FP == 1 then the buffer has been completely drained.
|
||||||
// if FP == 0 then an already-drained buffer is being advanced.
|
// if FP == 0 then an already-drained buffer is being advanced, and we need to drop a
|
||||||
// In either case we just assign FP to 0.
|
// quadword from the IPU FIFO.
|
||||||
|
|
||||||
|
if (!FP)
|
||||||
|
ipu_fifo.in.read(&internal_qwc[0]);
|
||||||
|
|
||||||
FP = 0;
|
FP = 0;
|
||||||
}
|
}
|
||||||
|
@ -222,16 +230,33 @@ enum SCE_IPU
|
||||||
struct IPUregisters {
|
struct IPUregisters {
|
||||||
tIPU_CMD cmd;
|
tIPU_CMD cmd;
|
||||||
u32 dummy0[2];
|
u32 dummy0[2];
|
||||||
|
|
||||||
tIPU_CTRL ctrl;
|
tIPU_CTRL ctrl;
|
||||||
u32 dummy1[3];
|
u32 dummy1[3];
|
||||||
|
|
||||||
u32 ipubp;
|
u32 ipubp;
|
||||||
u32 dummy2[3];
|
u32 dummy2[3];
|
||||||
|
|
||||||
u32 top;
|
u32 top;
|
||||||
u32 topbusy;
|
u32 topbusy;
|
||||||
u32 dummy3[2];
|
u32 dummy3[2];
|
||||||
|
|
||||||
|
void SetTopBusy()
|
||||||
|
{
|
||||||
|
topbusy = 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDataBusy()
|
||||||
|
{
|
||||||
|
cmd.BUSY = 0x80000000;
|
||||||
|
topbusy = 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tIPU_cmd
|
union tIPU_cmd
|
||||||
|
{
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
int pos[6];
|
int pos[6];
|
||||||
|
@ -242,22 +267,21 @@ struct tIPU_cmd
|
||||||
};
|
};
|
||||||
u32 current;
|
u32 current;
|
||||||
};
|
};
|
||||||
void clear()
|
};
|
||||||
{
|
|
||||||
memzero(pos);
|
u128 _u128[2];
|
||||||
index = 0;
|
|
||||||
current = 0xffffffff;
|
void clear();
|
||||||
}
|
|
||||||
wxString desc() const
|
wxString desc() const
|
||||||
{
|
{
|
||||||
return wxsFormat(L"Ipu cmd: index = 0x%x, current = 0x%x, pos[0] = 0x%x, pos[1] = 0x%x",
|
return pxsFmt(L"Ipu cmd: index = 0x%x, current = 0x%x, pos[0] = 0x%x, pos[1] = 0x%x",
|
||||||
index, current, pos[0], pos[1]);
|
index, current, pos[0], pos[1]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static IPUregisters& ipuRegs = (IPUregisters&)eeHw[0x2000];
|
static IPUregisters& ipuRegs = (IPUregisters&)eeHw[0x2000];
|
||||||
|
|
||||||
extern tIPU_cmd ipu_cmd;
|
extern __aligned16 tIPU_cmd ipu_cmd;
|
||||||
extern int coded_block_pattern;
|
extern int coded_block_pattern;
|
||||||
|
|
||||||
extern int ipuInit();
|
extern int ipuInit();
|
||||||
|
|
|
@ -127,26 +127,6 @@ int IPU_Fifo_Output::write(const u32 *value, uint size)
|
||||||
} while(true);
|
} while(true);
|
||||||
|
|
||||||
return origsize - size;
|
return origsize - size;
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (ipuRegs.ctrl.OFC >= 8) IPU0dma();
|
|
||||||
|
|
||||||
uint transsize = min(size, 8 - (uint)ipuRegs.ctrl.OFC);
|
|
||||||
uint firsttrans = transsize;
|
|
||||||
|
|
||||||
while (transsize > 0)
|
|
||||||
{
|
|
||||||
CopyQWC(&data[writepos], value);
|
|
||||||
writepos = (writepos + 4) & 31;
|
|
||||||
value += 4;
|
|
||||||
--transsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipuRegs.ctrl.OFC += firsttrans;
|
|
||||||
IPU0dma();
|
|
||||||
|
|
||||||
return firsttrans;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPU_Fifo_Output::read(void *value, uint size)
|
void IPU_Fifo_Output::read(void *value, uint size)
|
||||||
|
|
|
@ -381,9 +381,7 @@ __fi void dmaIPU0() // fromIPU
|
||||||
hwDmacIrq(DMAC_FROM_IPU);
|
hwDmacIrq(DMAC_FROM_IPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
//IPUProcessInterrupt();
|
IPUProcessInterrupt();
|
||||||
extern void IPUWorker();
|
|
||||||
if (ipuRegs.ctrl.BUSY) IPUWorker();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void dmaIPU1() // toIPU
|
__fi void dmaIPU1() // toIPU
|
||||||
|
|
|
@ -688,7 +688,7 @@ void __fi finishmpeg2sliceIDEC()
|
||||||
coded_block_pattern = decoder.coded_block_pattern;
|
coded_block_pattern = decoder.coded_block_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mpeg2sliceIDEC()
|
__fi bool mpeg2sliceIDEC()
|
||||||
{
|
{
|
||||||
u16 code;
|
u16 code;
|
||||||
|
|
||||||
|
@ -699,7 +699,6 @@ bool mpeg2sliceIDEC()
|
||||||
decoder.dc_dct_pred[1] =
|
decoder.dc_dct_pred[1] =
|
||||||
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
||||||
|
|
||||||
decoder.mbc = 0;
|
|
||||||
ipuRegs.top = 0;
|
ipuRegs.top = 0;
|
||||||
ipuRegs.ctrl.ECD = 0;
|
ipuRegs.ctrl.ECD = 0;
|
||||||
|
|
||||||
|
@ -818,7 +817,6 @@ bool mpeg2sliceIDEC()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder.mbc++;
|
|
||||||
mbaCount = 0;
|
mbaCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,8 +865,6 @@ bool mpeg2sliceIDEC()
|
||||||
decoder.dc_dct_pred[0] =
|
decoder.dc_dct_pred[0] =
|
||||||
decoder.dc_dct_pred[1] =
|
decoder.dc_dct_pred[1] =
|
||||||
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision;
|
||||||
|
|
||||||
decoder.mbc += mbaCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -922,7 +918,7 @@ finish_idec:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mpeg2_slice()
|
__fi bool mpeg2_slice()
|
||||||
{
|
{
|
||||||
int DCT_offset, DCT_stride;
|
int DCT_offset, DCT_stride;
|
||||||
|
|
||||||
|
@ -1110,7 +1106,6 @@ bool mpeg2_slice()
|
||||||
ipuRegs.ctrl.SCD = 0;
|
ipuRegs.ctrl.SCD = 0;
|
||||||
coded_block_pattern = decoder.coded_block_pattern;
|
coded_block_pattern = decoder.coded_block_pattern;
|
||||||
|
|
||||||
decoder.mbc = 1;
|
|
||||||
decoder.SetOutputTo(mb16);
|
decoder.SetOutputTo(mb16);
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -1127,7 +1122,6 @@ bool mpeg2_slice()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder.mbc++;
|
|
||||||
mbaCount = 0;
|
mbaCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ __noinline void memzero_sse_a( T& dest )
|
||||||
|
|
||||||
float (*destxmm)[4] = (float(*)[4])&dest;
|
float (*destxmm)[4] = (float(*)[4])&dest;
|
||||||
|
|
||||||
#define StoreDestIdx(idx) case idx: _mm_store_ps(&destxmm[idx][0], zeroreg)
|
#define StoreDestIdx(idx) case idx: _mm_store_ps(&destxmm[idx-1][0], zeroreg)
|
||||||
|
|
||||||
switch( MZFqwc & 0x07 )
|
switch( MZFqwc & 0x07 )
|
||||||
{
|
{
|
||||||
|
@ -151,12 +151,7 @@ struct decoder_t {
|
||||||
uint ipu0_data; // amount of data in the output macroblock (in QWC)
|
uint ipu0_data; // amount of data in the output macroblock (in QWC)
|
||||||
uint ipu0_idx;
|
uint ipu0_idx;
|
||||||
|
|
||||||
/* bit parsing stuff */
|
int quantizer_scale;
|
||||||
//u32 bitstream_buf; /* current 32 bit working set */
|
|
||||||
//int bitstream_bits; /* used bits in working set */
|
|
||||||
|
|
||||||
int quantizer_scale; /* remove */
|
|
||||||
int dmv_offset; /* remove */
|
|
||||||
|
|
||||||
/* now non-slice-specific information */
|
/* now non-slice-specific information */
|
||||||
|
|
||||||
|
@ -191,8 +186,6 @@ struct decoder_t {
|
||||||
int dte;
|
int dte;
|
||||||
// Output Format
|
// Output Format
|
||||||
int ofm;
|
int ofm;
|
||||||
// Macroblock count
|
|
||||||
int mbc;
|
|
||||||
// Macroblock type
|
// Macroblock type
|
||||||
int macroblock_modes;
|
int macroblock_modes;
|
||||||
// DC Reset
|
// DC Reset
|
||||||
|
@ -205,8 +198,6 @@ struct decoder_t {
|
||||||
/* the zigzag scan we're supposed to be using, true for alt, false for normal */
|
/* the zigzag scan we're supposed to be using, true for alt, false for normal */
|
||||||
bool scantype;
|
bool scantype;
|
||||||
|
|
||||||
int second_field;
|
|
||||||
|
|
||||||
int mpeg1;
|
int mpeg1;
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
|
@ -225,12 +216,10 @@ struct decoder_t {
|
||||||
|
|
||||||
void AdvanceIpuDataBy(uint amt)
|
void AdvanceIpuDataBy(uint amt)
|
||||||
{
|
{
|
||||||
pxAssumeDev(ipu0_data>=amt, "IPU FIFO Overflow on advance!" );
|
pxAssumeMsg(ipu0_data>=amt, "IPU FIFO Overflow on advance!" );
|
||||||
ipu0_idx += amt;
|
ipu0_idx += amt;
|
||||||
ipu0_data -= amt;
|
ipu0_data -= amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi bool ReadIpuData(u128* out);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mpeg2_scan_pack
|
struct mpeg2_scan_pack
|
||||||
|
@ -248,9 +237,6 @@ extern s32 SBITS(uint bits);
|
||||||
extern void mpeg2_idct_copy(s16 * block, u8* dest, int stride);
|
extern void mpeg2_idct_copy(s16 * block, u8* dest, int stride);
|
||||||
extern void mpeg2_idct_add(int last, s16 * block, s16* dest, int stride);
|
extern void mpeg2_idct_add(int last, s16 * block, s16* dest, int stride);
|
||||||
|
|
||||||
#define IDEC 0
|
|
||||||
#define BDEC 1
|
|
||||||
|
|
||||||
extern bool mpeg2sliceIDEC();
|
extern bool mpeg2sliceIDEC();
|
||||||
extern bool mpeg2_slice();
|
extern bool mpeg2_slice();
|
||||||
extern int get_macroblock_address_increment();
|
extern int get_macroblock_address_increment();
|
||||||
|
|
|
@ -195,14 +195,8 @@ void psxDma9(u32 madr, u32 bcr, u32 chcr)
|
||||||
SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR);
|
SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR);
|
||||||
|
|
||||||
sif0.iop.busy = true;
|
sif0.iop.busy = true;
|
||||||
psHu32(SBUS_F240) |= 0x2000;
|
|
||||||
|
|
||||||
/*if (sif0.ee.busy)
|
|
||||||
{*/
|
|
||||||
SIF0Dma();
|
SIF0Dma();
|
||||||
psHu32(SBUS_F240) &= ~0x20;
|
|
||||||
psHu32(SBUS_F240) &= ~0x2000;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void psxDma10(u32 madr, u32 bcr, u32 chcr)
|
void psxDma10(u32 madr, u32 bcr, u32 chcr)
|
||||||
|
@ -210,15 +204,8 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr)
|
||||||
SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr);
|
SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr);
|
||||||
|
|
||||||
sif1.iop.busy = true;
|
sif1.iop.busy = true;
|
||||||
psHu32(SBUS_F240) |= 0x4000;
|
|
||||||
|
|
||||||
/*if (sif1.ee.busy)
|
|
||||||
{*/
|
|
||||||
SIF1Dma();
|
SIF1Dma();
|
||||||
psHu32(SBUS_F240) &= ~0x40;
|
|
||||||
psHu32(SBUS_F240) &= ~0x100;
|
|
||||||
psHu32(SBUS_F240) &= ~0x4000;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* psxDma11 & psxDma 12 are in IopSio2.cpp, along with the appropriate interrupt functions. */
|
/* psxDma11 & psxDma 12 are in IopSio2.cpp, along with the appropriate interrupt functions. */
|
||||||
|
|
|
@ -27,7 +27,7 @@ void psxHwReset() {
|
||||||
/* if (Config.Sio) psxHu32(0x1070) |= 0x80;
|
/* if (Config.Sio) psxHu32(0x1070) |= 0x80;
|
||||||
if (Config.SpuIrq) psxHu32(0x1070) |= 0x200;*/
|
if (Config.SpuIrq) psxHu32(0x1070) |= 0x200;*/
|
||||||
|
|
||||||
memzero_ptr<0x10000>(psxH);
|
memzero_ptr<0x10000>(iopHw);
|
||||||
|
|
||||||
// mdecInit(); //initialize mdec decoder
|
// mdecInit(); //initialize mdec decoder
|
||||||
cdrReset();
|
cdrReset();
|
||||||
|
|
|
@ -229,18 +229,19 @@ struct dma_mbct
|
||||||
wxString desc() const { return wxsFormat(L"madr: 0x%x bcr: 0x%x chcr: 0x%x tadr: 0x%x", madr, bcr, chcr, tadr); }
|
wxString desc() const { return wxsFormat(L"madr: 0x%x bcr: 0x%x chcr: 0x%x tadr: 0x%x", madr, bcr, chcr, tadr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define hw_dma0 (*(dma_mbc*) &psxH[0x1080])
|
static dma_mbc& hw_dma0 = (dma_mbc&) iopHw[0x1080];
|
||||||
#define hw_dma1 (*(dma_mbc*) &psxH[0x1090])
|
static dma_mbc& hw_dma1 = (dma_mbc&) iopHw[0x1090];
|
||||||
#define hw_dma2 (*(dma_mbct*)&psxH[0x10a0])
|
static dma_mbct& hw_dma2 = (dma_mbct&)iopHw[0x10a0];
|
||||||
#define hw_dma3 (*(dma_mbc*) &psxH[0x10b0])
|
static dma_mbc& hw_dma3 = (dma_mbc&) iopHw[0x10b0];
|
||||||
#define hw_dma4 (*(dma_mbct*)&psxH[0x10c0])
|
static dma_mbct& hw_dma4 = (dma_mbct&)iopHw[0x10c0];
|
||||||
#define hw_dma6 (*(dma_mbc*) &psxH[0x10e0])
|
static dma_mbc& hw_dma6 = (dma_mbc&) iopHw[0x10e0];
|
||||||
#define hw_dma7 (*(dma_mbc*) &psxH[0x1500])
|
static dma_mbc& hw_dma7 = (dma_mbc&) iopHw[0x1500];
|
||||||
#define hw_dma8 (*(dma_mbc*) &psxH[0x1510])
|
static dma_mbc& hw_dma8 = (dma_mbc&) iopHw[0x1510];
|
||||||
#define hw_dma9 (*(dma_mbct*)&psxH[0x1520])
|
static dma_mbct& hw_dma9 = (dma_mbct&)iopHw[0x1520];
|
||||||
#define hw_dma10 (*(dma_mbc*) &psxH[0x1530])
|
static dma_mbc& hw_dma10 = (dma_mbc&) iopHw[0x1530];
|
||||||
#define hw_dma11 (*(dma_mbc*) &psxH[0x1540])
|
static dma_mbc& hw_dma11 = (dma_mbc&) iopHw[0x1540];
|
||||||
#define hw_dma12 (*(dma_mbc*) &psxH[0x1550])
|
static dma_mbc& hw_dma12 = (dma_mbc&) iopHw[0x1550];
|
||||||
|
|
||||||
#define hw_dma(x) hw_dma##x
|
#define hw_dma(x) hw_dma##x
|
||||||
|
|
||||||
#define HW_DMA0_MADR (psxHu32(0x1080)) // MDEC in DMA
|
#define HW_DMA0_MADR (psxHu32(0x1080)) // MDEC in DMA
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue