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:
gregory.hainaut@gmail.com 2010-10-15 09:32:41 +00:00
parent 0d4e02995d
commit d84d8e8a2a
278 changed files with 42076 additions and 44620 deletions

View File

@ -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 "")

62
3rdparty/liba52/a52.h vendored
View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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>

View 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 */

View File

@ -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);
}

View File

@ -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
};

View File

@ -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 */

View File

@ -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

View File

@ -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

109
3rdparty/portaudio/build/msvc/readme.txt vendored Normal file
View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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;
*/
} }
} }

View File

@ -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 );

View File

@ -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, &currentTime); stream->recipricalOfActualOutputSampleRate_ioProcCopy = stream->recipricalOfActualOutputSampleRate;
timeInfo.currentTime = TimeStampToSecs(stream, &currentTime); 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, &currentTime); timeInfo.currentTime = HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() );
timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);
/*
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

View File

@ -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;

View File

@ -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 );

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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)

View 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

View File

@ -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)

View File

@ -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})

View File

@ -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)
#--------------------------------------- #---------------------------------------
#--------------------------------------- #---------------------------------------

View File

@ -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);
} }
}; };

View File

@ -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(); }

View File

@ -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;

View File

@ -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 );

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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"

View 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

View File

@ -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.

View File

@ -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

View File

@ -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

1
debian-upstream/compat Normal file
View File

@ -0,0 +1 @@
7

117
debian-upstream/control Normal file
View File

@ -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.

108
debian-upstream/control_ppa Normal file
View File

@ -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.

168
debian-upstream/copyright Normal file
View File

@ -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.

View File

@ -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
debian-upstream/docs Normal file
View File

View File

@ -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)

View File

@ -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) {

View File

@ -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;

View File

@ -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
}

View File

@ -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

View File

@ -0,0 +1,2 @@
usr/share/games/pcsx2/shaders
var/games/pcsx2/

View File

@ -0,0 +1,2 @@
bin/plugins/ps2hw.dat usr/share/games/pcsx2/shaders/
bin/GameIndex.dbf var/games/pcsx2/

View File

@ -0,0 +1 @@
usr/lib/games/pcsx2/plugins

View File

@ -0,0 +1 @@
bin/plugins/lib* usr/lib/games/pcsx2/plugins

View File

@ -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

View File

@ -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;

View File

@ -0,0 +1,3 @@
usr/games
usr/share/pixmaps
usr/share/applications

View File

@ -0,0 +1,3 @@
bin/pcsx2 usr/games
debian/pcsx2.desktop usr/share/applications
debian/pcsx2.xpm usr/share/pixmaps

View File

@ -0,0 +1 @@
bin/docs/pcsx2.man

View File

@ -0,0 +1,6 @@
?package(pcsx2): \
needs="X11" \
section="Applications/Emulators" \
title="pcsx2" \
longtitle="A playstation 2 emulators" \
command="/usr/games/pcsx2"

1971
debian-upstream/pcsx2.xpm Normal file

File diff suppressed because it is too large Load Diff

87
debian-upstream/rules Executable file
View File

@ -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

87
debian-upstream/rules_fglrx Executable file
View File

@ -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

View File

@ -0,0 +1 @@
3.0 (quilt)

11
debian-upstream/watch Normal file
View File

@ -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

View File

@ -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\*

View File

@ -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

View File

@ -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

View File

@ -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" />

View File

@ -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)

View File

@ -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);

View File

@ -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
{ {

View File

@ -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++;

View File

@ -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)

View File

@ -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; }

View File

@ -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;

View File

@ -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,

View File

@ -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);
} }

View File

@ -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();

View File

@ -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)

View File

@ -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

View File

@ -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;
} }

View File

@ -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();

View File

@ -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. */

View File

@ -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();

View File

@ -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