mirror of https://github.com/AxioDL/metaforce.git
parent
9cfe73d278
commit
6e160560fa
@ -0,0 +1,92 @@ |
||||
#include "dsp.h" |
||||
|
||||
static const int NibbleToInt[16] = {0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1}; |
||||
|
||||
static inline short SampClamp(int val) |
||||
{ |
||||
if (val < -32768) val = -32768; |
||||
if (val > 32767) val = 32767; |
||||
return val; |
||||
} |
||||
|
||||
void DSPDecompressFrame(int16_t* out, const uint8_t* in, |
||||
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, |
||||
unsigned lastSample) |
||||
{ |
||||
uint8_t cIdx = (in[0]>>4) & 0xf; |
||||
int16_t factor1 = coefs[cIdx][0]; |
||||
int16_t factor2 = coefs[cIdx][1]; |
||||
uint8_t exp = in[0] & 0xf; |
||||
for (int s=0 ; s<14 && s<lastSample ; ++s) |
||||
{ |
||||
int sampleData = (s&1)? |
||||
NibbleToInt[(in[s/2+1])&0xf]: |
||||
NibbleToInt[(in[s/2+1]>>4)&0xf]; |
||||
sampleData <<= exp; |
||||
sampleData <<= 11; |
||||
sampleData += 1024; |
||||
sampleData += |
||||
factor1 * *prev1 + |
||||
factor2 * *prev2; |
||||
sampleData >>= 11; |
||||
sampleData = SampClamp(sampleData); |
||||
out[s] = sampleData; |
||||
*prev2 = *prev1; |
||||
*prev1 = sampleData; |
||||
} |
||||
} |
||||
|
||||
void DSPDecompressFrameStereoStride(int16_t* out, const uint8_t* in, |
||||
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, |
||||
unsigned lastSample) |
||||
{ |
||||
uint8_t cIdx = (in[0]>>4) & 0xf; |
||||
int16_t factor1 = coefs[cIdx][0]; |
||||
int16_t factor2 = coefs[cIdx][1]; |
||||
uint8_t exp = in[0] & 0xf; |
||||
for (int s=0 ; s<14 && s<lastSample ; ++s) |
||||
{ |
||||
int sampleData = (s&1)? |
||||
NibbleToInt[(in[s/2+1])&0xf]: |
||||
NibbleToInt[(in[s/2+1]>>4)&0xf]; |
||||
sampleData <<= exp; |
||||
sampleData <<= 11; |
||||
sampleData += 1024; |
||||
sampleData += |
||||
factor1 * *prev1 + |
||||
factor2 * *prev2; |
||||
sampleData >>= 11; |
||||
sampleData = SampClamp(sampleData); |
||||
out[s*2] = sampleData; |
||||
*prev2 = *prev1; |
||||
*prev1 = sampleData; |
||||
} |
||||
} |
||||
|
||||
void DSPDecompressFrameStereoDupe(int16_t* out, const uint8_t* in, |
||||
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, |
||||
unsigned lastSample) |
||||
{ |
||||
uint8_t cIdx = (in[0]>>4) & 0xf; |
||||
int16_t factor1 = coefs[cIdx][0]; |
||||
int16_t factor2 = coefs[cIdx][1]; |
||||
uint8_t exp = in[0] & 0xf; |
||||
for (int s=0 ; s<14 && s<lastSample ; ++s) |
||||
{ |
||||
int sampleData = (s&1)? |
||||
NibbleToInt[(in[s/2+1])&0xf]: |
||||
NibbleToInt[(in[s/2+1]>>4)&0xf]; |
||||
sampleData <<= exp; |
||||
sampleData <<= 11; |
||||
sampleData += 1024; |
||||
sampleData += |
||||
factor1 * *prev1 + |
||||
factor2 * *prev2; |
||||
sampleData >>= 11; |
||||
sampleData = SampClamp(sampleData); |
||||
out[s*2] = sampleData; |
||||
out[s*2+1] = sampleData; |
||||
*prev2 = *prev1; |
||||
*prev1 = sampleData; |
||||
} |
||||
} |
@ -0,0 +1,24 @@ |
||||
#ifndef _DSP_h |
||||
#define _DSP_h |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#include <stdint.h> |
||||
|
||||
void DSPDecompressFrame(int16_t* out, const uint8_t* in, |
||||
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, |
||||
unsigned lastSample); |
||||
void DSPDecompressFrameStereoStride(int16_t* out, const uint8_t* in, |
||||
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, |
||||
unsigned lastSample); |
||||
void DSPDecompressFrameStereoDupe(int16_t* out, const uint8_t* in, |
||||
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2, |
||||
unsigned lastSample); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif // _DSP_h
|
@ -0,0 +1,457 @@ |
||||
/* G.721 decoder, from Sun's public domain CCITT-ADPCM sources,
|
||||
* retrieved from ftp://ftp.cwi.nl/pub/audio/ccitt-adpcm.tar.gz
|
||||
* |
||||
* For reference, here's the original license: |
||||
* |
||||
* This source code is a product of Sun Microsystems, Inc. and is provided |
||||
* for unrestricted use. Users may copy or modify this source code without |
||||
* charge. |
||||
* |
||||
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING |
||||
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. |
||||
* |
||||
* Sun source code is provided with no support and without any obligation on |
||||
* the part of Sun Microsystems, Inc. to assist in its use, correction, |
||||
* modification or enhancement. |
||||
* |
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE |
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE |
||||
* OR ANY PART THEREOF. |
||||
* |
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue |
||||
* or profits or other special, indirect and consequential damages, even if |
||||
* Sun has been advised of the possibility of such damages. |
||||
* |
||||
* Sun Microsystems, Inc. |
||||
* 2550 Garcia Avenue |
||||
* Mountain View, California 94043 |
||||
* |
||||
*/ |
||||
|
||||
#include <stdlib.h> |
||||
#include "g721.h" |
||||
|
||||
static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, |
||||
0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000}; |
||||
|
||||
/*
|
||||
* quan() |
||||
* |
||||
* quantizes the input val against the table of size short integers. |
||||
* It returns i if table[i - 1] <= val < table[i]. |
||||
* |
||||
* Using linear search for simple coding. |
||||
*/ |
||||
static int |
||||
quan( |
||||
int val, |
||||
short *table, |
||||
int size) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < size; i++) |
||||
if (val < *table++) |
||||
break; |
||||
return (i); |
||||
} |
||||
|
||||
/*
|
||||
* fmult() |
||||
* |
||||
* returns the integer product of the 14-bit integer "an" and |
||||
* "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". |
||||
*/ |
||||
static int |
||||
fmult( |
||||
int an, |
||||
int srn) |
||||
{ |
||||
short anmag, anexp, anmant; |
||||
short wanexp, wanmant; |
||||
short retval; |
||||
|
||||
anmag = (an > 0) ? an : ((-an) & 0x1FFF); |
||||
anexp = quan(anmag, power2, 15) - 6; |
||||
anmant = (anmag == 0) ? 32 : |
||||
(anexp >= 0) ? anmag >> anexp : anmag << -anexp; |
||||
wanexp = anexp + ((srn >> 6) & 0xF) - 13; |
||||
|
||||
wanmant = (anmant * (srn & 077) + 0x30) >> 4; |
||||
retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : |
||||
(wanmant >> -wanexp); |
||||
|
||||
return (((an ^ srn) < 0) ? -retval : retval); |
||||
} |
||||
|
||||
/*
|
||||
* g72x_init_state() |
||||
* |
||||
* This routine initializes and/or resets the g72x_state structure |
||||
* pointed to by 'state_ptr'. |
||||
* All the initial state values are specified in the CCITT G.721 document. |
||||
*/ |
||||
void |
||||
g72x_init_state(struct g72x_state *state_ptr) |
||||
{ |
||||
int cnta; |
||||
|
||||
state_ptr->yl = 34816; |
||||
state_ptr->yu = 544; |
||||
state_ptr->dms = 0; |
||||
state_ptr->dml = 0; |
||||
state_ptr->ap = 0; |
||||
for (cnta = 0; cnta < 2; cnta++) { |
||||
state_ptr->a[cnta] = 0; |
||||
state_ptr->pk[cnta] = 0; |
||||
state_ptr->sr[cnta] = 32; |
||||
} |
||||
for (cnta = 0; cnta < 6; cnta++) { |
||||
state_ptr->b[cnta] = 0; |
||||
state_ptr->dq[cnta] = 32; |
||||
} |
||||
state_ptr->td = 0; |
||||
} |
||||
|
||||
/*
|
||||
* predictor_zero() |
||||
* |
||||
* computes the estimated signal from 6-zero predictor. |
||||
* |
||||
*/ |
||||
static int |
||||
predictor_zero( |
||||
struct g72x_state *state_ptr) |
||||
{ |
||||
int i; |
||||
int sezi; |
||||
|
||||
sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]); |
||||
for (i = 1; i < 6; i++) /* ACCUM */ |
||||
sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]); |
||||
return (sezi); |
||||
} |
||||
/*
|
||||
* predictor_pole() |
||||
* |
||||
* computes the estimated signal from 2-pole predictor. |
||||
* |
||||
*/ |
||||
static int |
||||
predictor_pole( |
||||
struct g72x_state *state_ptr) |
||||
{ |
||||
return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) + |
||||
fmult(state_ptr->a[0] >> 2, state_ptr->sr[0])); |
||||
} |
||||
/*
|
||||
* step_size() |
||||
* |
||||
* computes the quantization step size of the adaptive quantizer. |
||||
* |
||||
*/ |
||||
static long |
||||
step_size( |
||||
struct g72x_state *state_ptr) |
||||
{ |
||||
long y; |
||||
long dif; |
||||
long al; |
||||
|
||||
if (state_ptr->ap >= 256) |
||||
return (state_ptr->yu); |
||||
else { |
||||
y = state_ptr->yl >> 6; |
||||
dif = state_ptr->yu - y; |
||||
al = state_ptr->ap >> 2; |
||||
if (dif > 0) |
||||
y += (dif * al) >> 6; |
||||
else if (dif < 0) |
||||
y += (dif * al + 0x3F) >> 6; |
||||
return (y); |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* reconstruct() |
||||
* |
||||
* Returns reconstructed difference signal 'dq' obtained from |
||||
* codeword 'i' and quantization step size scale factor 'y'. |
||||
* Multiplication is performed in log base 2 domain as addition. |
||||
*/ |
||||
static int |
||||
reconstruct( |
||||
int sign, /* 0 for non-negative value */ |
||||
int dqln, /* G.72x codeword */ |
||||
int y) /* Step size multiplier */ |
||||
{ |
||||
short dql; /* Log of 'dq' magnitude */ |
||||
short dex; /* Integer part of log */ |
||||
short dqt; |
||||
short dq; /* Reconstructed difference signal sample */ |
||||
|
||||
dql = dqln + (y >> 2); /* ADDA */ |
||||
|
||||
if (dql < 0) { |
||||
return ((sign) ? -0x8000 : 0); |
||||
} else { /* ANTILOG */ |
||||
dex = (dql >> 7) & 15; |
||||
dqt = 128 + (dql & 127); |
||||
dq = (dqt << 7) >> (14 - dex); |
||||
return ((sign) ? (dq - 0x8000) : dq); |
||||
} |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* update() |
||||
* |
||||
* updates the state variables for each output code |
||||
*/ |
||||
static void |
||||
update( |
||||
/*int code_size,*/ /* distinguish 723_40 with others */ |
||||
int y, /* quantizer step size */ |
||||
int wi, /* scale factor multiplier */ |
||||
int fi, /* for long/short term energies */ |
||||
int dq, /* quantized prediction difference */ |
||||
int sr, /* reconstructed signal */ |
||||
int dqsez, /* difference from 2-pole predictor */ |
||||
struct g72x_state *state_ptr) /* coder state pointer */ |
||||
{ |
||||
int cnt; |
||||
short mag, exp; /* Adaptive predictor, FLOAT A */ |
||||
short a2p; /* LIMC */ |
||||
short a1ul; /* UPA1 */ |
||||
short pks1; /* UPA2 */ |
||||
short fa1; |
||||
char tr; /* tone/transition detector */ |
||||
short ylint, thr2, dqthr; |
||||
short ylfrac, thr1; |
||||
short pk0; |
||||
|
||||
pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */ |
||||
|
||||
mag = dq & 0x7FFF; /* prediction difference magnitude */ |
||||
/* TRANS */ |
||||
ylint = state_ptr->yl >> 15; /* exponent part of yl */ |
||||
ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */ |
||||
thr1 = (32 + ylfrac) << ylint; /* threshold */ |
||||
thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ |
||||
dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */ |
||||
if (state_ptr->td == 0) /* signal supposed voice */ |
||||
tr = 0; |
||||
else if (mag <= dqthr) /* supposed data, but small mag */ |
||||
tr = 0; /* treated as voice */ |
||||
else /* signal is data (modem) */ |
||||
tr = 1; |
||||
|
||||
/*
|
||||
* Quantizer scale factor adaptation. |
||||
*/ |
||||
|
||||
/* FUNCTW & FILTD & DELAY */ |
||||
/* update non-steady state step size multiplier */ |
||||
state_ptr->yu = y + ((wi - y) >> 5); |
||||
|
||||
/* LIMB */ |
||||
if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */ |
||||
state_ptr->yu = 544; |
||||
else if (state_ptr->yu > 5120) |
||||
state_ptr->yu = 5120; |
||||
|
||||
/* FILTE & DELAY */ |
||||
/* update steady state step size multiplier */ |
||||
state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6); |
||||
|
||||
/*
|
||||
* Adaptive predictor coefficients. |
||||
*/ |
||||
if (tr == 1) { /* reset a's and b's for modem signal */ |
||||
state_ptr->a[0] = 0; |
||||
state_ptr->a[1] = 0; |
||||
state_ptr->b[0] = 0; |
||||
state_ptr->b[1] = 0; |
||||
state_ptr->b[2] = 0; |
||||
state_ptr->b[3] = 0; |
||||
state_ptr->b[4] = 0; |
||||
state_ptr->b[5] = 0; |
||||
a2p=0; /* won't be used, clear warning */ |
||||
} else { /* update a's and b's */ |
||||
pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ |
||||
|
||||
/* update predictor pole a[1] */ |
||||
a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7); |
||||
if (dqsez != 0) { |
||||
fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0]; |
||||
if (fa1 < -8191) /* a2p = function of fa1 */ |
||||
a2p -= 0x100; |
||||
else if (fa1 > 8191) |
||||
a2p += 0xFF; |
||||
else |
||||
a2p += fa1 >> 5; |
||||
|
||||
if (pk0 ^ state_ptr->pk[1]) |
||||
/* LIMC */ |
||||
if (a2p <= -12160) |
||||
a2p = -12288; |
||||
else if (a2p >= 12416) |
||||
a2p = 12288; |
||||
else |
||||
a2p -= 0x80; |
||||
else if (a2p <= -12416) |
||||
a2p = -12288; |
||||
else if (a2p >= 12160) |
||||
a2p = 12288; |
||||
else |
||||
a2p += 0x80; |
||||
} |
||||
|
||||
/* TRIGB & DELAY */ |
||||
state_ptr->a[1] = a2p; |
||||
|
||||
/* UPA1 */ |
||||
/* update predictor pole a[0] */ |
||||
state_ptr->a[0] -= state_ptr->a[0] >> 8; |
||||
if (dqsez != 0) { |
||||
if (pks1 == 0) |
||||
state_ptr->a[0] += 192; |
||||
else |
||||
state_ptr->a[0] -= 192; |
||||
} |
||||
|
||||
/* LIMD */ |
||||
a1ul = 15360 - a2p; |
||||
if (state_ptr->a[0] < -a1ul) |
||||
state_ptr->a[0] = -a1ul; |
||||
else if (state_ptr->a[0] > a1ul) |
||||
state_ptr->a[0] = a1ul; |
||||
|
||||
/* UPB : update predictor zeros b[6] */ |
||||
for (cnt = 0; cnt < 6; cnt++) { |
||||
/*if (code_size == 5)*/ /* for 40Kbps G.723 */ |
||||
/* state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;*/ |
||||
/*else*/ /* for G.721 and 24Kbps G.723 */ |
||||
state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; |
||||
if (dq & 0x7FFF) { /* XOR */ |
||||
if ((dq ^ state_ptr->dq[cnt]) >= 0) |
||||
state_ptr->b[cnt] += 128; |
||||
else |
||||
state_ptr->b[cnt] -= 128; |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (cnt = 5; cnt > 0; cnt--) |
||||
state_ptr->dq[cnt] = state_ptr->dq[cnt-1]; |
||||
/* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ |
||||
if (mag == 0) { |
||||
state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; |
||||
} else { |
||||
exp = quan(mag, power2, 15); |
||||
state_ptr->dq[0] = (dq >= 0) ? |
||||
(exp << 6) + ((mag << 6) >> exp) : |
||||
(exp << 6) + ((mag << 6) >> exp) - 0x400; |
||||
} |
||||
|
||||
state_ptr->sr[1] = state_ptr->sr[0]; |
||||
/* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ |
||||
if (sr == 0) { |
||||
state_ptr->sr[0] = 0x20; |
||||
} else if (sr > 0) { |
||||
exp = quan(sr, power2, 15); |
||||
state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp); |
||||
} else if (sr > -32768) { |
||||
mag = -sr; |
||||
exp = quan(mag, power2, 15); |
||||
state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; |
||||
} else |
||||
state_ptr->sr[0] = 0xFC20; |
||||
|
||||
/* DELAY A */ |
||||
state_ptr->pk[1] = state_ptr->pk[0]; |
||||
state_ptr->pk[0] = pk0; |
||||
|
||||
/* TONE */ |
||||
if (tr == 1) /* this sample has been treated as data */ |
||||
state_ptr->td = 0; /* next one will be treated as voice */ |
||||
else if (a2p < -11776) /* small sample-to-sample correlation */ |
||||
state_ptr->td = 1; /* signal may be data */ |
||||
else /* signal is voice */ |
||||
state_ptr->td = 0; |
||||
|
||||
/*
|
||||
* Adaptation speed control. |
||||
*/ |
||||
state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */ |
||||
state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */ |
||||
|
||||
if (tr == 1) |
||||
state_ptr->ap = 256; |
||||
else if (y < 1536) /* SUBTC */ |
||||
state_ptr->ap += (0x200 - state_ptr->ap) >> 4; |
||||
else if (state_ptr->td == 1) |
||||
state_ptr->ap += (0x200 - state_ptr->ap) >> 4; |
||||
else if (abs((state_ptr->dms << 2) - state_ptr->dml) >= |
||||
(state_ptr->dml >> 3)) |
||||
state_ptr->ap += (0x200 - state_ptr->ap) >> 4; |
||||
else |
||||
state_ptr->ap += (-state_ptr->ap) >> 4; |
||||
} |
||||
|
||||
/*
|
||||
* Maps G.721 code word to reconstructed scale factor normalized log |
||||
* magnitude values. |
||||
*/ |
||||
static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, |
||||
425, 373, 323, 273, 213, 135, 4, -2048}; |
||||
|
||||
/* Maps G.721 code word to log of scale factor multiplier. */ |
||||
static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, |
||||
1122, 355, 198, 112, 64, 41, 18, -12}; |
||||
/*
|
||||
* Maps G.721 code words to a set of values whose long and short |
||||
* term averages are computed and then compared to give an indication |
||||
* how stationary (steady state) the signal is. |
||||
*/ |
||||
static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, |
||||
0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; |
||||
/*
|
||||
* g721_decoder() |
||||
* |
||||
* Description: |
||||
* |
||||
* Decodes a 4-bit code of G.721 encoded data of i and |
||||
* returns the resulting linear PCM, A-law or u-law value. |
||||
* return -1 for unknown out_coding value. |
||||
*/ |
||||
int |
||||
g721_decoder(int i, |
||||
struct g72x_state *state_ptr) |
||||
{ |
||||
short sezi, sei, sez, se; /* ACCUM */ |
||||
short y; /* MIX */ |
||||
short sr; /* ADDB */ |
||||
short dq; |
||||
short dqsez; |
||||
|
||||
i &= 0x0f; /* mask to get proper bits */ |
||||
sezi = predictor_zero(state_ptr); |
||||
sez = sezi >> 1; |
||||
sei = sezi + predictor_pole(state_ptr); |
||||
se = sei >> 1; /* se = estimated signal */ |
||||
|
||||
y = step_size(state_ptr); /* dynamic quantizer step size */ |
||||
|
||||
dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */ |
||||
|
||||
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */ |
||||
|
||||
dqsez = sr - se + sez; /* pole prediction diff. */ |
||||
|
||||
update(y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); |
||||
|
||||
return (sr << 2); /* sr was 14-bit dynamic range */ |
||||
} |
||||
|
@ -0,0 +1,45 @@ |
||||
#ifndef _g721_h |
||||
#define _g721_h |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct g72x_state { |
||||
long yl; /* Locked or steady state step size multiplier. */ |
||||
short yu; /* Unlocked or non-steady state step size multiplier. */ |
||||
short dms; /* Short term energy estimate. */ |
||||
short dml; /* Long term energy estimate. */ |
||||
short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ |
||||
|
||||
short a[2]; /* Coefficients of pole portion of prediction filter. */ |
||||
short b[6]; /* Coefficients of zero portion of prediction filter. */ |
||||
short pk[2]; /*
|
||||
* Signs of previous two samples of a partially |
||||
* reconstructed signal. |
||||
*/ |
||||
short dq[6]; /*
|
||||
* Previous 6 samples of the quantized difference |
||||
* signal represented in an internal floating point |
||||
* format. |
||||
*/ |
||||
short sr[2]; /*
|
||||
* Previous 2 samples of the quantized difference |
||||
* signal represented in an internal floating point |
||||
* format. |
||||
*/ |
||||
char td; /* delayed tone detect, new in 1988 version */ |
||||
}; |
||||
|
||||
void |
||||
g72x_init_state(struct g72x_state *state_ptr); |
||||
|
||||
int |
||||
g721_decoder(int i, |
||||
struct g72x_state *state_ptr); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif |
@ -0,0 +1,118 @@ |
||||
#include "CDvdFile.hpp" |
||||
#include "CDvdRequest.hpp" |
||||
|
||||
namespace urde |
||||
{ |
||||
|
||||
hecl::ProjectPath CDvdFile::m_DvdRoot; |
||||
|
||||
class CFileDvdRequest : public IDvdRequest |
||||
{ |
||||
CDvdFile& m_dvdFile; |
||||
void* m_buf; |
||||
u32 m_len; |
||||
ESeekOrigin m_whence; |
||||
int m_offset; |
||||
bool m_cancel = false; |
||||
bool m_complete = false; |
||||
public: |
||||
~CFileDvdRequest() |
||||
{ |
||||
PostCancelRequest(); |
||||
} |
||||
|
||||
void WaitUntilComplete() |
||||
{ |
||||
while (!m_complete && !m_cancel) |
||||
{ |
||||
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); |
||||
} |
||||
} |
||||
bool IsComplete() {return m_complete;} |
||||
void PostCancelRequest() |
||||
{ |
||||
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); |
||||
m_cancel = true; |
||||
} |
||||
|
||||
EMediaType GetMediaType() const |
||||
{ |
||||
return EMediaType::File; |
||||
} |
||||
|
||||
CFileDvdRequest(CDvdFile& file, void* buf, u32 len, ESeekOrigin whence, int off) |
||||
: m_dvdFile(file), m_buf(buf), m_len(len), m_whence(whence), m_offset(off) {} |
||||
|
||||
void DoRequest() |
||||
{ |
||||
if (m_cancel) |
||||
return; |
||||
if (m_whence == ESeekOrigin::Cur && m_offset == 0) |
||||
m_dvdFile.m_reader.readBytesToBuf(m_buf, m_len); |
||||
else |
||||
{ |
||||
m_dvdFile.m_reader.seek(m_offset, athena::SeekOrigin(m_whence)); |
||||
m_dvdFile.m_reader.readBytesToBuf(m_buf, m_len); |
||||
} |
||||
m_complete = true; |
||||
} |
||||
}; |
||||
|
||||
std::thread CDvdFile::m_WorkerThread; |
||||
std::mutex CDvdFile::m_WorkerMutex; |
||||
std::condition_variable CDvdFile::m_WorkerCV; |
||||
bool CDvdFile::m_WorkerRun = false; |
||||
std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue; |
||||
void CDvdFile::WorkerProc() |
||||
{ |
||||
while (m_WorkerRun) |
||||
{ |
||||
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); |
||||
if (CDvdFile::m_RequestQueue.size()) |
||||
{ |
||||
std::vector<std::shared_ptr<IDvdRequest>> swapQueue; |
||||
swapQueue.swap(CDvdFile::m_RequestQueue); |
||||
lk.unlock(); |
||||
for (std::shared_ptr<IDvdRequest>& req : swapQueue) |
||||
{ |
||||
CFileDvdRequest& concreteReq = static_cast<CFileDvdRequest&>(*req); |
||||
concreteReq.DoRequest(); |
||||
} |
||||
lk.lock(); |
||||
} |
||||
m_WorkerCV.wait(lk); |
||||
} |
||||
} |
||||
|
||||
std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off) |
||||
{ |
||||
CFileDvdRequest* req = new CFileDvdRequest(*this, buf, len, whence, off); |
||||
std::shared_ptr<IDvdRequest> ret(req); |
||||
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); |
||||
m_RequestQueue.emplace_back(ret); |
||||
lk.unlock(); |
||||
m_WorkerCV.notify_one(); |
||||
return ret; |
||||
} |
||||
|
||||
void CDvdFile::Initialize(const hecl::ProjectPath& path) |
||||
{ |
||||
m_DvdRoot = path; |
||||
if (m_WorkerRun) |
||||
return; |
||||
m_WorkerRun = true; |
||||
m_WorkerThread = std::thread(WorkerProc); |
||||
} |
||||
|
||||
void CDvdFile::Shutdown() |
||||
{ |
||||
if (!m_WorkerRun) |
||||
return; |
||||
m_WorkerRun = false; |
||||
m_WorkerCV.notify_one(); |
||||
if (m_WorkerThread.joinable()) |
||||
m_WorkerThread.join(); |
||||
m_RequestQueue.clear(); |
||||
} |
||||
|
||||
} |
@ -1,17 +0,0 @@ |
||||
#include "CDvdRequest.hpp" |
||||
|
||||
namespace urde |
||||
{ |
||||
|
||||
void CDvdRequest::WaitUntilComplete() |
||||
{ |
||||
} |
||||
bool CDvdRequest::IsComplete() |
||||
{ |
||||
return false; |
||||
} |
||||
void CDvdRequest::PostCancelRequest() |
||||
{ |
||||
} |
||||
|
||||
} |
@ -1,75 +0,0 @@ |
||||
#include "CMoviePlayer.hpp" |
||||
|
||||
namespace urde |
||||
{ |
||||
|
||||
CMoviePlayer::CMoviePlayer(const char* path, float startTime, bool flag) |
||||
: CDvdFile(path) |
||||
{ |
||||
} |
||||
|
||||
void CMoviePlayer::VerifyCallbackStatus() |
||||
{ |
||||
} |
||||
void CMoviePlayer::DisableStaticAudio() |
||||
{ |
||||
} |
||||
void CMoviePlayer::SetStaticAudioVolume(int vol) |
||||
{ |
||||
} |
||||
void CMoviePlayer::SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd) |
||||
{ |
||||
} |
||||
void CMoviePlayer::MixAudio(short* out, const short* in, u32 length) |
||||
{ |
||||
} |
||||
void CMoviePlayer::MixStaticAudio(short* out, const short* in, u32 length) |
||||
{ |
||||
} |
||||
void CMoviePlayer::StaticMyAudioCallback() |
||||
{ |
||||
} |
||||
void CMoviePlayer::Rewind() |
||||
{ |
||||
} |
||||
|
||||
bool CMoviePlayer::GetIsMovieFinishedPlaying() const |
||||
{ |
||||
return false; |
||||
} |
||||
bool CMoviePlayer::GetIsFullyCached() const |
||||
{ |
||||
return false; |
||||
} |
||||
float CMoviePlayer::GetPlayedSeconds() const |
||||
{ |
||||
return 0.0; |
||||
} |
||||
float CMoviePlayer::GetTotalSeconds() const |
||||
{ |
||||
return 0.0; |
||||
} |
||||
void CMoviePlayer::SetPlayMode(EPlayMode mode) |
||||
{ |
||||
} |
||||
void CMoviePlayer::DrawFrame(const CVector3f& a, const CVector3f& b, |
||||
const CVector3f& c, const CVector3f& d) |
||||
{ |
||||
} |
||||
void CMoviePlayer::Update(float dt) |
||||
{ |
||||
} |
||||
void CMoviePlayer::DecodeFromRead(const void* data) |
||||
{ |
||||
} |
||||
void CMoviePlayer::ReadCompleted() |
||||
{ |
||||
} |
||||
void CMoviePlayer::PostDVDReadRequestIfNeeded() |
||||
{ |
||||
} |
||||
void CMoviePlayer::InitializeTextures() |
||||
{ |
||||
} |
||||
|
||||
} |
@ -1,44 +0,0 @@ |
||||
#ifndef __PSHAG_CMOVIEPLAYER_HPP__ |
||||
#define __PSHAG_CMOVIEPLAYER_HPP__ |
||||
|
||||
#include "RetroTypes.hpp" |
||||
#include "CDvdFile.hpp" |
||||
|
||||
namespace urde |
||||
{ |
||||
class CVector3f; |
||||
|
||||
class CMoviePlayer : public CDvdFile |
||||
{ |
||||
public: |
||||
enum class EPlayMode |
||||
{ |
||||
}; |
||||
|
||||
CMoviePlayer(const char* path, float startTime, bool flag); |
||||
|
||||
static void VerifyCallbackStatus(); |
||||
static void DisableStaticAudio(); |
||||
static void SetStaticAudioVolume(int vol); |
||||
static void SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd); |
||||
void MixAudio(short* out, const short* in, u32 length); |
||||
static void MixStaticAudio(short* out, const short* in, u32 length); |
||||
static void StaticMyAudioCallback(); |
||||
void Rewind(); |
||||
|
||||
bool GetIsMovieFinishedPlaying() const; |
||||
bool GetIsFullyCached() const; |
||||
float GetPlayedSeconds() const; |
||||
float GetTotalSeconds() const; |
||||
void SetPlayMode(EPlayMode); |
||||
void DrawFrame(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d); |
||||
void Update(float dt); |
||||
void DecodeFromRead(const void* data); |
||||
void ReadCompleted(); |
||||
void PostDVDReadRequestIfNeeded(); |
||||
void InitializeTextures(); |
||||
}; |
||||
|
||||
} |
||||
|
||||
#endif // __PSHAG_CMOVIEPLAYER_HPP__
|
@ -1,17 +0,0 @@ |
||||
#include "CDvdRequest.hpp" |
||||
|
||||
namespace urde |
||||
{ |
||||
|
||||
void CNODDvdRequest::WaitUntilComplete() |
||||
{ |
||||
} |
||||
bool CNODDvdRequest::IsComplete() |
||||
{ |
||||
return false; |
||||
} |
||||
void CNODDvdRequest::PostCancelRequest() |
||||
{ |
||||
} |
||||
|
||||
} |