diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
| commit | 379a8879f7dae1a9074317c0270e12dd203b32c0 (patch) | |
| tree | 348efb7ecd4f7cbc030f4b5db6683a857f2ae6cf /libpcsxcore/decode_xa.c | |
| parent | d34b4220bde29d7937d927e9d17a50470a36c500 (diff) | |
| download | pcsxr-379a8879f7dae1a9074317c0270e12dd203b32c0.tar.gz | |
Temporarily reverted r64524 until I (or someone else) find the time to sort out the stuff.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64536 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore/decode_xa.c')
| -rw-r--r-- | libpcsxcore/decode_xa.c | 734 |
1 files changed, 367 insertions, 367 deletions
diff --git a/libpcsxcore/decode_xa.c b/libpcsxcore/decode_xa.c index abca4cc7..9198659e 100644 --- a/libpcsxcore/decode_xa.c +++ b/libpcsxcore/decode_xa.c @@ -1,367 +1,367 @@ -/*************************************************************************** - * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team * - * * - * 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 program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * - ***************************************************************************/ - -/* -* XA audio decoding functions (Kazzuya). -*/ - -#include "decode_xa.h" - -#define FIXED - -#define NOT(_X_) (!(_X_)) -#define XACLAMP(_X_,_MI_,_MA_) {if(_X_<_MI_)_X_=_MI_;if(_X_>_MA_)_X_=_MA_;} - -#define SH 4 -#define SHC 10 - -//============================================ -//=== ADPCM DECODING ROUTINES -//============================================ - -#ifndef FIXED -static double K0[4] = { - 0.0, - 0.9375, - 1.796875, - 1.53125 -}; - -static double K1[4] = { - 0.0, - 0.0, - -0.8125, - -0.859375 -}; -#else -static int K0[4] = { - 0.0 * (1<<SHC), - 0.9375 * (1<<SHC), - 1.796875 * (1<<SHC), - 1.53125 * (1<<SHC) -}; - -static int K1[4] = { - 0.0 * (1<<SHC), - 0.0 * (1<<SHC), - -0.8125 * (1<<SHC), - -0.859375 * (1<<SHC) -}; -#endif - -#define BLKSIZ 28 /* block size (32 - 4 nibbles) */ - -//=========================================== -static void ADPCM_InitDecode(ADPCM_Decode_t *decp) { - decp->y0 = 0; - decp->y1 = 0; -} - -//=========================================== -#ifndef FIXED -#define IK0(fid) ((int)((-K0[fid]) * (1<<SHC))) -#define IK1(fid) ((int)((-K1[fid]) * (1<<SHC))) -#else -#define IK0(fid) (-K0[fid]) -#define IK1(fid) (-K1[fid]) -#endif - -static __inline void ADPCM_DecodeBlock16( ADPCM_Decode_t *decp, u8 filter_range, const void *vblockp, short *destp, int inc ) { - int i; - int range, filterid; - s32 fy0, fy1; - const u16 *blockp; - - blockp = (const unsigned short *)vblockp; - filterid = (filter_range >> 4) & 0x0f; - range = (filter_range >> 0) & 0x0f; - - fy0 = decp->y0; - fy1 = decp->y1; - - for (i = BLKSIZ/4; i; --i) { - s32 y; - s32 x0, x1, x2, x3; - - y = *blockp++; - x3 = (short)( y & 0xf000) >> range; x3 <<= SH; - x2 = (short)((y << 4) & 0xf000) >> range; x2 <<= SH; - x1 = (short)((y << 8) & 0xf000) >> range; x1 <<= SH; - x0 = (short)((y << 12) & 0xf000) >> range; x0 <<= SH; - - x0 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x0; - x1 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x1; - x2 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x2; - x3 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x3; - - XACLAMP( x0, -32768<<SH, 32767<<SH ); *destp = x0 >> SH; destp += inc; - XACLAMP( x1, -32768<<SH, 32767<<SH ); *destp = x1 >> SH; destp += inc; - XACLAMP( x2, -32768<<SH, 32767<<SH ); *destp = x2 >> SH; destp += inc; - XACLAMP( x3, -32768<<SH, 32767<<SH ); *destp = x3 >> SH; destp += inc; - } - decp->y0 = fy0; - decp->y1 = fy1; -} - -static int headtable[4] = {0,2,8,10}; - -//=========================================== -static void xa_decode_data( xa_decode_t *xdp, unsigned char *srcp ) { - const u8 *sound_groupsp; - const u8 *sound_datap, *sound_datap2; - int i, j, k, nbits; - u16 data[4096], *datap; - short *destp; - - destp = xdp->pcm; - nbits = xdp->nbits == 4 ? 4 : 2; - - if (xdp->stereo) { // stereo - if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A - for (j=0; j < 18; j++) { - sound_groupsp = srcp + j * 128; // sound groups header - sound_datap = sound_groupsp + 16; // sound data just after the header - - for (i=0; i < nbits; i++) { - datap = data; - sound_datap2 = sound_datap + i; - - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (u16)sound_datap2[0] | - (u16)(sound_datap2[4] << 8); - } - - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, - destp+0, 2 ); - - datap = data; - sound_datap2 = sound_datap + i; - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (u16)sound_datap2[0] | - (u16)(sound_datap2[4] << 8); - } - ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data, - destp+1, 2 ); - - destp += 28*2; - } - } - } else { // level B/C - for (j=0; j < 18; j++) { - sound_groupsp = srcp + j * 128; // sound groups header - sound_datap = sound_groupsp + 16; // sound data just after the header - - for (i=0; i < nbits; i++) { - datap = data; - sound_datap2 = sound_datap + i; - - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (u16)(sound_datap2[ 0] & 0x0f) | - ((u16)(sound_datap2[ 4] & 0x0f) << 4) | - ((u16)(sound_datap2[ 8] & 0x0f) << 8) | - ((u16)(sound_datap2[12] & 0x0f) << 12); - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, - destp+0, 2 ); - - datap = data; - sound_datap2 = sound_datap + i; - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (u16)(sound_datap2[ 0] >> 4) | - ((u16)(sound_datap2[ 4] >> 4) << 4) | - ((u16)(sound_datap2[ 8] >> 4) << 8) | - ((u16)(sound_datap2[12] >> 4) << 12); - } - ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data, - destp+1, 2 ); - - destp += 28*2; - } - } - } - } else { // mono - if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A - for (j=0; j < 18; j++) { - sound_groupsp = srcp + j * 128; // sound groups header - sound_datap = sound_groupsp + 16; // sound data just after the header - - for (i=0; i < nbits; i++) { - datap = data; - sound_datap2 = sound_datap + i; - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (u16)sound_datap2[0] | - (u16)(sound_datap2[4] << 8); - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, - destp, 1 ); - - destp += 28; - - datap = data; - sound_datap2 = sound_datap + i; - for (k=0; k < 14; k++, sound_datap2 += 8) { - *(datap++) = (u16)sound_datap2[0] | - (u16)(sound_datap2[4] << 8); - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data, - destp, 1 ); - - destp += 28; - } - } - } else { // level B/C - for (j=0; j < 18; j++) { - sound_groupsp = srcp + j * 128; // sound groups header - sound_datap = sound_groupsp + 16; // sound data just after the header - - for (i=0; i < nbits; i++) { - datap = data; - sound_datap2 = sound_datap + i; - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (u16)(sound_datap2[ 0] & 0x0f) | - ((u16)(sound_datap2[ 4] & 0x0f) << 4) | - ((u16)(sound_datap2[ 8] & 0x0f) << 8) | - ((u16)(sound_datap2[12] & 0x0f) << 12); - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, - destp, 1 ); - - destp += 28; - - datap = data; - sound_datap2 = sound_datap + i; - for (k=0; k < 7; k++, sound_datap2 += 16) { - *(datap++) = (u16)(sound_datap2[ 0] >> 4) | - ((u16)(sound_datap2[ 4] >> 4) << 4) | - ((u16)(sound_datap2[ 8] >> 4) << 8) | - ((u16)(sound_datap2[12] >> 4) << 12); - } - ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data, - destp, 1 ); - - destp += 28; - } - } - } - } -} - -//============================================ -//=== XA SPECIFIC ROUTINES -//============================================ -typedef struct { -u8 filenum; -u8 channum; -u8 submode; -u8 coding; - -u8 filenum2; -u8 channum2; -u8 submode2; -u8 coding2; -} xa_subheader_t; - -#define SUB_SUB_EOF (1<<7) // end of file -#define SUB_SUB_RT (1<<6) // real-time sector -#define SUB_SUB_FORM (1<<5) // 0 form1 1 form2 -#define SUB_SUB_TRIGGER (1<<4) // used for interrupt -#define SUB_SUB_DATA (1<<3) // contains data -#define SUB_SUB_AUDIO (1<<2) // contains audio -#define SUB_SUB_VIDEO (1<<1) // contains video -#define SUB_SUB_EOR (1<<0) // end of record - -#define AUDIO_CODING_GET_STEREO(_X_) ( (_X_) & 3) -#define AUDIO_CODING_GET_FREQ(_X_) (((_X_) >> 2) & 3) -#define AUDIO_CODING_GET_BPS(_X_) (((_X_) >> 4) & 3) -#define AUDIO_CODING_GET_EMPHASIS(_X_) (((_X_) >> 6) & 1) - -#define SUB_UNKNOWN 0 -#define SUB_VIDEO 1 -#define SUB_AUDIO 2 - -//============================================ -static int parse_xa_audio_sector( xa_decode_t *xdp, - xa_subheader_t *subheadp, - unsigned char *sectorp, - int is_first_sector ) { - if ( is_first_sector ) { - switch ( AUDIO_CODING_GET_FREQ(subheadp->coding) ) { - case 0: xdp->freq = 37800; break; - case 1: xdp->freq = 18900; break; - default: xdp->freq = 0; break; - } - switch ( AUDIO_CODING_GET_BPS(subheadp->coding) ) { - case 0: xdp->nbits = 4; break; - case 1: xdp->nbits = 8; break; - default: xdp->nbits = 0; break; - } - switch ( AUDIO_CODING_GET_STEREO(subheadp->coding) ) { - case 0: xdp->stereo = 0; break; - case 1: xdp->stereo = 1; break; - default: xdp->stereo = 0; break; - } - - if ( xdp->freq == 0 ) - return -1; - - ADPCM_InitDecode( &xdp->left ); - ADPCM_InitDecode( &xdp->right ); - - xdp->nsamples = 18 * 28 * 8; - if (xdp->stereo == 1) xdp->nsamples /= 2; - } - xa_decode_data( xdp, sectorp ); - - return 0; -} - -//================================================================ -//=== THIS IS WHAT YOU HAVE TO CALL -//=== xdp - structure were all important data are returned -//=== sectorp - data in input -//=== pcmp - data in output -//=== is_first_sector - 1 if it's the 1st sector of the stream -//=== - 0 for any other successive sector -//=== return -1 if error -//================================================================ -s32 xa_decode_sector( xa_decode_t *xdp, - unsigned char *sectorp, int is_first_sector ) { - if (parse_xa_audio_sector(xdp, (xa_subheader_t *)sectorp, sectorp + sizeof(xa_subheader_t), is_first_sector)) - return -1; - - return 0; -} - -/* EXAMPLE: -"nsamples" is the number of 16 bit samples -every sample is 2 bytes in mono and 4 bytes in stereo - -xa_decode_t xa; - - sectorp = read_first_sector(); - xa_decode_sector( &xa, sectorp, 1 ); - play_wave( xa.pcm, xa.freq, xa.nsamples ); - - while ( --n_sectors ) - { - sectorp = read_next_sector(); - xa_decode_sector( &xa, sectorp, 0 ); - play_wave( xa.pcm, xa.freq, xa.nsamples ); - } -*/ +/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * *
+ * 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 program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* XA audio decoding functions (Kazzuya).
+*/
+
+#include "decode_xa.h"
+
+#define FIXED
+
+#define NOT(_X_) (!(_X_))
+#define XACLAMP(_X_,_MI_,_MA_) {if(_X_<_MI_)_X_=_MI_;if(_X_>_MA_)_X_=_MA_;}
+
+#define SH 4
+#define SHC 10
+
+//============================================
+//=== ADPCM DECODING ROUTINES
+//============================================
+
+#ifndef FIXED
+static double K0[4] = {
+ 0.0,
+ 0.9375,
+ 1.796875,
+ 1.53125
+};
+
+static double K1[4] = {
+ 0.0,
+ 0.0,
+ -0.8125,
+ -0.859375
+};
+#else
+static int K0[4] = {
+ 0.0 * (1<<SHC),
+ 0.9375 * (1<<SHC),
+ 1.796875 * (1<<SHC),
+ 1.53125 * (1<<SHC)
+};
+
+static int K1[4] = {
+ 0.0 * (1<<SHC),
+ 0.0 * (1<<SHC),
+ -0.8125 * (1<<SHC),
+ -0.859375 * (1<<SHC)
+};
+#endif
+
+#define BLKSIZ 28 /* block size (32 - 4 nibbles) */
+
+//===========================================
+void ADPCM_InitDecode(ADPCM_Decode_t *decp) {
+ decp->y0 = 0;
+ decp->y1 = 0;
+}
+
+//===========================================
+#ifndef FIXED
+#define IK0(fid) ((int)((-K0[fid]) * (1<<SHC)))
+#define IK1(fid) ((int)((-K1[fid]) * (1<<SHC)))
+#else
+#define IK0(fid) (-K0[fid])
+#define IK1(fid) (-K1[fid])
+#endif
+
+static __inline void ADPCM_DecodeBlock16( ADPCM_Decode_t *decp, u8 filter_range, const void *vblockp, short *destp, int inc ) {
+ int i;
+ int range, filterid;
+ s32 fy0, fy1;
+ const u16 *blockp;
+
+ blockp = (const unsigned short *)vblockp;
+ filterid = (filter_range >> 4) & 0x0f;
+ range = (filter_range >> 0) & 0x0f;
+
+ fy0 = decp->y0;
+ fy1 = decp->y1;
+
+ for (i = BLKSIZ/4; i; --i) {
+ s32 y;
+ s32 x0, x1, x2, x3;
+
+ y = *blockp++;
+ x3 = (short)( y & 0xf000) >> range; x3 <<= SH;
+ x2 = (short)((y << 4) & 0xf000) >> range; x2 <<= SH;
+ x1 = (short)((y << 8) & 0xf000) >> range; x1 <<= SH;
+ x0 = (short)((y << 12) & 0xf000) >> range; x0 <<= SH;
+
+ x0 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x0;
+ x1 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x1;
+ x2 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x2;
+ x3 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x3;
+
+ XACLAMP( x0, -32768<<SH, 32767<<SH ); *destp = x0 >> SH; destp += inc;
+ XACLAMP( x1, -32768<<SH, 32767<<SH ); *destp = x1 >> SH; destp += inc;
+ XACLAMP( x2, -32768<<SH, 32767<<SH ); *destp = x2 >> SH; destp += inc;
+ XACLAMP( x3, -32768<<SH, 32767<<SH ); *destp = x3 >> SH; destp += inc;
+ }
+ decp->y0 = fy0;
+ decp->y1 = fy1;
+}
+
+static int headtable[4] = {0,2,8,10};
+
+//===========================================
+static void xa_decode_data( xa_decode_t *xdp, unsigned char *srcp ) {
+ const u8 *sound_groupsp;
+ const u8 *sound_datap, *sound_datap2;
+ int i, j, k, nbits;
+ u16 data[4096], *datap;
+ short *destp;
+
+ destp = xdp->pcm;
+ nbits = xdp->nbits == 4 ? 4 : 2;
+
+ if (xdp->stereo) { // stereo
+ if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp+0, 2 );
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+ ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data,
+ destp+1, 2 );
+
+ destp += 28*2;
+ }
+ }
+ } else { // level B/C
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] & 0x0f) |
+ ((u16)(sound_datap2[ 4] & 0x0f) << 4) |
+ ((u16)(sound_datap2[ 8] & 0x0f) << 8) |
+ ((u16)(sound_datap2[12] & 0x0f) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp+0, 2 );
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] >> 4) |
+ ((u16)(sound_datap2[ 4] >> 4) << 4) |
+ ((u16)(sound_datap2[ 8] >> 4) << 8) |
+ ((u16)(sound_datap2[12] >> 4) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data,
+ destp+1, 2 );
+
+ destp += 28*2;
+ }
+ }
+ }
+ } else { // mono
+ if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp, 1 );
+
+ destp += 28;
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 14; k++, sound_datap2 += 8) {
+ *(datap++) = (u16)sound_datap2[0] |
+ (u16)(sound_datap2[4] << 8);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data,
+ destp, 1 );
+
+ destp += 28;
+ }
+ }
+ } else { // level B/C
+ for (j=0; j < 18; j++) {
+ sound_groupsp = srcp + j * 128; // sound groups header
+ sound_datap = sound_groupsp + 16; // sound data just after the header
+
+ for (i=0; i < nbits; i++) {
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] & 0x0f) |
+ ((u16)(sound_datap2[ 4] & 0x0f) << 4) |
+ ((u16)(sound_datap2[ 8] & 0x0f) << 8) |
+ ((u16)(sound_datap2[12] & 0x0f) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
+ destp, 1 );
+
+ destp += 28;
+
+ datap = data;
+ sound_datap2 = sound_datap + i;
+ for (k=0; k < 7; k++, sound_datap2 += 16) {
+ *(datap++) = (u16)(sound_datap2[ 0] >> 4) |
+ ((u16)(sound_datap2[ 4] >> 4) << 4) |
+ ((u16)(sound_datap2[ 8] >> 4) << 8) |
+ ((u16)(sound_datap2[12] >> 4) << 12);
+ }
+ ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data,
+ destp, 1 );
+
+ destp += 28;
+ }
+ }
+ }
+ }
+}
+
+//============================================
+//=== XA SPECIFIC ROUTINES
+//============================================
+typedef struct {
+u8 filenum;
+u8 channum;
+u8 submode;
+u8 coding;
+
+u8 filenum2;
+u8 channum2;
+u8 submode2;
+u8 coding2;
+} xa_subheader_t;
+
+#define SUB_SUB_EOF (1<<7) // end of file
+#define SUB_SUB_RT (1<<6) // real-time sector
+#define SUB_SUB_FORM (1<<5) // 0 form1 1 form2
+#define SUB_SUB_TRIGGER (1<<4) // used for interrupt
+#define SUB_SUB_DATA (1<<3) // contains data
+#define SUB_SUB_AUDIO (1<<2) // contains audio
+#define SUB_SUB_VIDEO (1<<1) // contains video
+#define SUB_SUB_EOR (1<<0) // end of record
+
+#define AUDIO_CODING_GET_STEREO(_X_) ( (_X_) & 3)
+#define AUDIO_CODING_GET_FREQ(_X_) (((_X_) >> 2) & 3)
+#define AUDIO_CODING_GET_BPS(_X_) (((_X_) >> 4) & 3)
+#define AUDIO_CODING_GET_EMPHASIS(_X_) (((_X_) >> 6) & 1)
+
+#define SUB_UNKNOWN 0
+#define SUB_VIDEO 1
+#define SUB_AUDIO 2
+
+//============================================
+static int parse_xa_audio_sector( xa_decode_t *xdp,
+ xa_subheader_t *subheadp,
+ unsigned char *sectorp,
+ int is_first_sector ) {
+ if ( is_first_sector ) {
+ switch ( AUDIO_CODING_GET_FREQ(subheadp->coding) ) {
+ case 0: xdp->freq = 37800; break;
+ case 1: xdp->freq = 18900; break;
+ default: xdp->freq = 0; break;
+ }
+ switch ( AUDIO_CODING_GET_BPS(subheadp->coding) ) {
+ case 0: xdp->nbits = 4; break;
+ case 1: xdp->nbits = 8; break;
+ default: xdp->nbits = 0; break;
+ }
+ switch ( AUDIO_CODING_GET_STEREO(subheadp->coding) ) {
+ case 0: xdp->stereo = 0; break;
+ case 1: xdp->stereo = 1; break;
+ default: xdp->stereo = 0; break;
+ }
+
+ if ( xdp->freq == 0 )
+ return -1;
+
+ ADPCM_InitDecode( &xdp->left );
+ ADPCM_InitDecode( &xdp->right );
+
+ xdp->nsamples = 18 * 28 * 8;
+ if (xdp->stereo == 1) xdp->nsamples /= 2;
+ }
+ xa_decode_data( xdp, sectorp );
+
+ return 0;
+}
+
+//================================================================
+//=== THIS IS WHAT YOU HAVE TO CALL
+//=== xdp - structure were all important data are returned
+//=== sectorp - data in input
+//=== pcmp - data in output
+//=== is_first_sector - 1 if it's the 1st sector of the stream
+//=== - 0 for any other successive sector
+//=== return -1 if error
+//================================================================
+s32 xa_decode_sector( xa_decode_t *xdp,
+ unsigned char *sectorp, int is_first_sector ) {
+ if (parse_xa_audio_sector(xdp, (xa_subheader_t *)sectorp, sectorp + sizeof(xa_subheader_t), is_first_sector))
+ return -1;
+
+ return 0;
+}
+
+/* EXAMPLE:
+"nsamples" is the number of 16 bit samples
+every sample is 2 bytes in mono and 4 bytes in stereo
+
+xa_decode_t xa;
+
+ sectorp = read_first_sector();
+ xa_decode_sector( &xa, sectorp, 1 );
+ play_wave( xa.pcm, xa.freq, xa.nsamples );
+
+ while ( --n_sectors )
+ {
+ sectorp = read_next_sector();
+ xa_decode_sector( &xa, sectorp, 0 );
+ play_wave( xa.pcm, xa.freq, xa.nsamples );
+ }
+*/
|
