#include <stdio.h>
#include <stdbool.h>
#include "usf.h"
#include "audio_hle.h"
#include "memory.h"


static void SPNOOP () {
	//char buff[0x100];
	//sprintf (buff, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24));
	//printf( "Audio HLE Error: %s\n", buff );
}

extern u16 ResampleLUT [0x200];

extern u32 loopval;

extern s16 Env_Dry;
extern s16 Env_Wet;
extern s16 Vol_Left;
extern s16 Vol_Right;
extern s16 VolTrg_Left;
extern s32 VolRamp_Left;
//extern u16 VolRate_Left;
extern s16 VolTrg_Right;
extern s32 VolRamp_Right;
//extern u16 VolRate_Right;


extern short hleMixerWorkArea[256];
extern u16 adpcmtable[0x88];

extern u8 BufferSpace[0x10000];

/*
static void SETVOL3 () { // Swapped Rate_Left and Vol
	u8 Flags = (u8)(inst1 >> 0x10);
	if (Flags & 0x4) { // 288
		if (Flags & 0x2) { // 290
			VolTrg_Left  = *(s16*)&inst1;
			VolRamp_Left = *(s32*)&inst2;
		} else {
			VolTrg_Right  = *(s16*)&inst1;
			VolRamp_Right = *(s32*)&inst2;
		}
	} else {
		Vol_Left	= *(s16*)&inst1;
		Env_Dry		= (s16)(*(s32*)&inst2 >> 0x10);
		Env_Wet		= *(s16*)&inst2;
	}
}
*/
static void SETVOL3 () {
	u8 Flags = (u8)(inst1 >> 0x10);
	if (Flags & 0x4) { // 288
		if (Flags & 0x2) { // 290
			Vol_Left  = *(s16*)&inst1; // 0x50
			Env_Dry		= (s16)(*(s32*)&inst2 >> 0x10); // 0x4E
			Env_Wet		= *(s16*)&inst2; // 0x4C
		} else {
			VolTrg_Right  = *(s16*)&inst1; // 0x46
			//VolRamp_Right = (u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
			VolRamp_Right = *(s32*)&inst2; // 0x48/0x4A
		}
	} else {
		VolTrg_Left  = *(s16*)&inst1; // 0x40
		VolRamp_Left = *(s32*)&inst2; // 0x42/0x44
	}
}

static void ENVMIXER3 () {
	u8 flags;
	u32 addy;

 	short *inp=(short *)(BufferSpace+0x4F0);
	short *out=(short *)(BufferSpace+0x9D0);
	short *aux1=(short *)(BufferSpace+0xB40);
	short *aux2=(short *)(BufferSpace+0xCB0);
	short *aux3=(short *)(BufferSpace+0xE20);
	s32 MainR;
	s32 MainL;
	s32 AuxR;
	s32 AuxL;

	int i1,o1,a1,a2,a3,y;
	//WORD AuxIncRate=1;
	short zero[8];
	memset(zero,0,16);

	flags = (u8)((inst1 >> 16) & 0xff);
	addy = (inst2 & 0xFFFFFF);

	s32 LAdder, LAcc, LVol;
	s32 RAdder, RAcc, RVol;
	s16 RSig, LSig; // Most significant part of the Ramp Value
	s16 Wet, Dry;
	s16 LTrg, RTrg;


	Vol_Right = (*(s16 *)&inst1);

	if (flags & A_INIT) {
		LAdder = VolRamp_Left / 8;
		LAcc  = 0;
		LVol  = Vol_Left;
		LSig = (s16)(VolRamp_Left >> 16);

		RAdder = VolRamp_Right / 8;
		RAcc  = 0;
		RVol  = Vol_Right;
		RSig = (s16)(VolRamp_Right >> 16);

		Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
		LTrg = VolTrg_Left; RTrg = VolTrg_Right; // Save Current Left/Right Targets
	} else {
		memcpy((u8 *)hleMixerWorkArea, N64MEM+addy, 80);
		Wet    = *(s16 *)(hleMixerWorkArea +  0); // 0-1
		Dry    = *(s16 *)(hleMixerWorkArea +  2); // 2-3
		LTrg   = *(s16 *)(hleMixerWorkArea +  4); // 4-5
		RTrg   = *(s16 *)(hleMixerWorkArea +  6); // 6-7
		LAdder = *(s32 *)(hleMixerWorkArea +  8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
		RAdder = *(s32 *)(hleMixerWorkArea + 10); // 10-11
		LAcc   = *(s32 *)(hleMixerWorkArea + 12); // 12-13
		RAcc   = *(s32 *)(hleMixerWorkArea + 14); // 14-15
		LVol   = *(s32 *)(hleMixerWorkArea + 16); // 16-17
		RVol   = *(s32 *)(hleMixerWorkArea + 18); // 18-19
		LSig   = *(s16 *)(hleMixerWorkArea + 20); // 20-21
		RSig   = *(s16 *)(hleMixerWorkArea + 22); // 22-23
		//u32 test  = *(s32 *)(hleMixerWorkArea + 24); // 22-23
		//if (test != 0x13371337)
		//	__asm int 3;
	}


	//if(!(flags&A_AUX)) {
	//	AuxIncRate=0;
	//	aux2=aux3=zero;
	//}

	for (y = 0; y < (0x170/2); y++) {

		// Left
		LAcc += LAdder;
		LVol += (LAcc >> 16);
		LAcc &= 0xFFFF;

		// Right
		RAcc += RAdder;
		RVol += (RAcc >> 16);
		RAcc &= 0xFFFF;
// ****************************************************************
		// Clamp Left
		if (LSig >= 0) { // VLT
			if (LVol > LTrg) {
				LVol = LTrg;
			}
		} else { // VGE
			if (LVol < LTrg) {
				LVol = LTrg;
			}
		}

		// Clamp Right
		if (RSig >= 0) { // VLT
			if (RVol > RTrg) {
				RVol = RTrg;
			}
		} else { // VGE
			if (RVol < RTrg) {
				RVol = RTrg;
			}
		}
// ****************************************************************
		MainL = ((Dry * LVol) + 0x4000) >> 15;
		MainR = ((Dry * RVol) + 0x4000) >> 15;

		o1 = out [y^1];
		a1 = aux1[y^1];
		i1 = inp [y^1];

		o1+=((i1*MainL)+0x4000)>>15;
		a1+=((i1*MainR)+0x4000)>>15;

// ****************************************************************

		if(o1>32767) o1=32767;
		else if(o1<-32768) o1=-32768;

		if(a1>32767) a1=32767;
		else if(a1<-32768) a1=-32768;

// ****************************************************************

		out[y^1]=o1;
		aux1[y^1]=a1;

// ****************************************************************
		//if (!(flags&A_AUX)) {
			a2 = aux2[y^1];
			a3 = aux3[y^1];

			AuxL  = ((Wet * LVol) + 0x4000) >> 15;
			AuxR  = ((Wet * RVol) + 0x4000) >> 15;

			a2+=((i1*AuxL)+0x4000)>>15;
			a3+=((i1*AuxR)+0x4000)>>15;

			if(a2>32767) a2=32767;
			else if(a2<-32768) a2=-32768;

			if(a3>32767) a3=32767;
			else if(a3<-32768) a3=-32768;

			aux2[y^1]=a2;
			aux3[y^1]=a3;
		}
	//}

	*(s16 *)(hleMixerWorkArea +  0) = Wet; // 0-1
	*(s16 *)(hleMixerWorkArea +  2) = Dry; // 2-3
	*(s16 *)(hleMixerWorkArea +  4) = LTrg; // 4-5
	*(s16 *)(hleMixerWorkArea +  6) = RTrg; // 6-7
	*(s32 *)(hleMixerWorkArea +  8) = LAdder; // 8-9 (hleMixerWorkArea is a 16bit pointer)
	*(s32 *)(hleMixerWorkArea + 10) = RAdder; // 10-11
	*(s32 *)(hleMixerWorkArea + 12) = LAcc; // 12-13
	*(s32 *)(hleMixerWorkArea + 14) = RAcc; // 14-15
	*(s32 *)(hleMixerWorkArea + 16) = LVol; // 16-17
	*(s32 *)(hleMixerWorkArea + 18) = RVol; // 18-19
	*(s16 *)(hleMixerWorkArea + 20) = LSig; // 20-21
	*(s16 *)(hleMixerWorkArea + 22) = RSig; // 22-23
	//*(u32 *)(hleMixerWorkArea + 24) = 0x13371337; // 22-23
	memcpy(N64MEM+addy, (u8 *)hleMixerWorkArea,80);
}

static void CLEARBUFF3 () {
	u16 addr = (u16)(inst1 & 0xffff);
	u16 count = (u16)(inst2 & 0xffff);
	memset(BufferSpace+addr+0x4f0, 0, count);
}

static void MIXER3 () { // Needs accuracy verification...
	u16 dmemin  = (u16)(inst2 >> 0x10)  + 0x4f0;
	u16 dmemout = (u16)(inst2 & 0xFFFF) + 0x4f0;
	s32 gain    = (s16)(inst1 & 0xFFFF)*2;
	s32 temp;
	int x;

	for (x = 0; x < 0x170; x+=2) { // I think I can do this a lot easier
		temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 16;
		temp += *(s16 *)(BufferSpace+dmemout+x);

		if ((s32)temp > 32767)
			temp = 32767;
		if ((s32)temp < -32768)
			temp = -32768;

		*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
	}
}

static void LOADBUFF3 () {
	u32 v0;
	u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
	v0 = (inst2 & 0xfffffc);
	u32 src = (inst1&0xffc)+0x4f0;
	memcpy (BufferSpace+src, (u8 *)N64MEM+v0, cnt);
}

static void SAVEBUFF3 () {
	u32 v0;
	u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
	v0 = (inst2 & 0xfffffc);
	u32 src = (inst1&0xffc)+0x4f0;
	memcpy (N64MEM+v0, (u8 *)BufferSpace+src, cnt);
}

static void LOADADPCM3 () { // Loads an ADPCM table - Works 100% Now 03-13-01
	u32 v0, x;
	v0 = (inst2 & 0xffffff);

	u16 *table = (u16 *)(RDRAM+v0);
	for (x = 0; x < ((inst1&0xffff)>>0x4); x++) {
		adpcmtable[0x1+(x<<3)] = table[0];
		adpcmtable[0x0+(x<<3)] = table[1];

		adpcmtable[0x3+(x<<3)] = table[2];
		adpcmtable[0x2+(x<<3)] = table[3];

		adpcmtable[0x5+(x<<3)] = table[4];
		adpcmtable[0x4+(x<<3)] = table[5];

		adpcmtable[0x7+(x<<3)] = table[6];
		adpcmtable[0x6+(x<<3)] = table[7];
		table += 8;
	}
}

static void DMEMMOVE3 () { // Needs accuracy verification...
	u32 v0, v1;
	u32 cnt;
	v0 = (inst1 & 0xFFFF) + 0x4f0;
	v1 = (inst2 >> 0x10) + 0x4f0;
	u32 count = ((inst2+3) & 0xfffc);

	for (cnt = 0; cnt < count; cnt++) {
		*(u8 *)(BufferSpace+((cnt+v1)^3)) = *(u8 *)(BufferSpace+((cnt+v0)^3));
	}
}

static void SETLOOP3 () {
	loopval = (inst2 & 0xffffff);
}

static void ADPCM3 () { // Verified to be 100% Accurate...
	short count = 0;
	unsigned char icode, code, Flags;
	int vscale, a[8];
	unsigned short index, j, inPtr;
	short *book1,*book2,*out;
	unsigned int Address;

	Flags=(u8)(inst2>>0x1c)&0xff;
	Address=(inst1 & 0xffffff);
	inPtr=(inst2>>12)&0xf;

	out=(short *)(BufferSpace+(inst2&0xfff)+0x4f0);
	count=(short)((inst2 >> 16)&0xfff);


	memset(out,0,32);

	if(!(Flags&0x1))
	{
		if(Flags&0x2)
		{
			memcpy(out,&RDRAM[loopval],32);
		}
		else
		{
			memcpy(out,&RDRAM[Address],32);
		}
	}

	int l1=out[15];
	int l2=out[14];
	int inp1[8];
	int inp2[8];
	out+=16;
	while(count>0)
	{
													// the first interation through, these values are
													// either 0 in the case of A_INIT, from a special
													// area of memory in the case of A_LOOP or just
													// the values we calculated the last time

		code=BufferSpace[(0x4f0+inPtr)^3];
		index=code&0xf;
		index<<=4;									// index into the adpcm code table
		book1=(short *)&adpcmtable[index];
		book2=book1+8;
		code>>=4;									// upper nibble is scale
		vscale=(0x8000>>((12-code)-1));			// very strange. 0x8000 would be .5 in 16:16 format
													// so this appears to be a fractional scale based
													// on the 12 based inverse of the scale value.  note
													// that this could be negative, in which case we do
													// not use the calculated vscale value... see the
													// if(code>12) check below

		inPtr++;									// coded adpcm data lies next
		j=0;
		while(j<8)									// loop of 8, for 8 coded nibbles from 4 bytes
													// which yields 8 short pcm values
		{
			icode=BufferSpace[(0x4f0+inPtr)^3];
			inPtr++;

			inp1[j]=(s16)((icode&0xf0)<<8);			// this will in effect be signed
			if(code<12)
				inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
			j++;

			inp1[j]=(s16)((icode&0xf)<<12);
			if(code<12)
				inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
			j++;
		}
		j=0;
		while(j<8)
		{
			icode=BufferSpace[(0x4f0+inPtr)^3];
			inPtr++;

			inp2[j]=(short)((icode&0xf0)<<8);			// this will in effect be signed
			if(code<12)
				inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
			j++;

			inp2[j]=(short)((icode&0xf)<<12);
			if(code<12)
				inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
			j++;
		}

		a[0]= (int)book1[0]*(int)l1;
		a[0]+=(int)book2[0]*(int)l2;
		a[0]+=(int)inp1[0]*(int)2048;

		a[1] =(int)book1[1]*(int)l1;
		a[1]+=(int)book2[1]*(int)l2;
		a[1]+=(int)book2[0]*inp1[0];
		a[1]+=(int)inp1[1]*(int)2048;

		a[2] =(int)book1[2]*(int)l1;
		a[2]+=(int)book2[2]*(int)l2;
		a[2]+=(int)book2[1]*inp1[0];
		a[2]+=(int)book2[0]*inp1[1];
		a[2]+=(int)inp1[2]*(int)2048;

		a[3] =(int)book1[3]*(int)l1;
		a[3]+=(int)book2[3]*(int)l2;
		a[3]+=(int)book2[2]*inp1[0];
		a[3]+=(int)book2[1]*inp1[1];
		a[3]+=(int)book2[0]*inp1[2];
		a[3]+=(int)inp1[3]*(int)2048;

		a[4] =(int)book1[4]*(int)l1;
		a[4]+=(int)book2[4]*(int)l2;
		a[4]+=(int)book2[3]*inp1[0];
		a[4]+=(int)book2[2]*inp1[1];
		a[4]+=(int)book2[1]*inp1[2];
		a[4]+=(int)book2[0]*inp1[3];
		a[4]+=(int)inp1[4]*(int)2048;

		a[5] =(int)book1[5]*(int)l1;
		a[5]+=(int)book2[5]*(int)l2;
		a[5]+=(int)book2[4]*inp1[0];
		a[5]+=(int)book2[3]*inp1[1];
		a[5]+=(int)book2[2]*inp1[2];
		a[5]+=(int)book2[1]*inp1[3];
		a[5]+=(int)book2[0]*inp1[4];
		a[5]+=(int)inp1[5]*(int)2048;

		a[6] =(int)book1[6]*(int)l1;
		a[6]+=(int)book2[6]*(int)l2;
		a[6]+=(int)book2[5]*inp1[0];
		a[6]+=(int)book2[4]*inp1[1];
		a[6]+=(int)book2[3]*inp1[2];
		a[6]+=(int)book2[2]*inp1[3];
		a[6]+=(int)book2[1]*inp1[4];
		a[6]+=(int)book2[0]*inp1[5];
		a[6]+=(int)inp1[6]*(int)2048;

		a[7] =(int)book1[7]*(int)l1;
		a[7]+=(int)book2[7]*(int)l2;
		a[7]+=(int)book2[6]*inp1[0];
		a[7]+=(int)book2[5]*inp1[1];
		a[7]+=(int)book2[4]*inp1[2];
		a[7]+=(int)book2[3]*inp1[3];
		a[7]+=(int)book2[2]*inp1[4];
		a[7]+=(int)book2[1]*inp1[5];
		a[7]+=(int)book2[0]*inp1[6];
		a[7]+=(int)inp1[7]*(int)2048;

		for(j=0;j<8;j++)
		{
			a[j^1]>>=11;
			if(a[j^1]>32767) a[j^1]=32767;
			else if(a[j^1]<-32768) a[j^1]=-32768;
			*(out++)=a[j^1];
		}

		l1=a[6];
		l2=a[7];

		a[0]= (int)book1[0]*(int)l1;
		a[0]+=(int)book2[0]*(int)l2;
		a[0]+=(int)inp2[0]*(int)2048;

		a[1] =(int)book1[1]*(int)l1;
		a[1]+=(int)book2[1]*(int)l2;
		a[1]+=(int)book2[0]*inp2[0];
		a[1]+=(int)inp2[1]*(int)2048;

		a[2] =(int)book1[2]*(int)l1;
		a[2]+=(int)book2[2]*(int)l2;
		a[2]+=(int)book2[1]*inp2[0];
		a[2]+=(int)book2[0]*inp2[1];
		a[2]+=(int)inp2[2]*(int)2048;

		a[3] =(int)book1[3]*(int)l1;
		a[3]+=(int)book2[3]*(int)l2;
		a[3]+=(int)book2[2]*inp2[0];
		a[3]+=(int)book2[1]*inp2[1];
		a[3]+=(int)book2[0]*inp2[2];
		a[3]+=(int)inp2[3]*(int)2048;

		a[4] =(int)book1[4]*(int)l1;
		a[4]+=(int)book2[4]*(int)l2;
		a[4]+=(int)book2[3]*inp2[0];
		a[4]+=(int)book2[2]*inp2[1];
		a[4]+=(int)book2[1]*inp2[2];
		a[4]+=(int)book2[0]*inp2[3];
		a[4]+=(int)inp2[4]*(int)2048;

		a[5] =(int)book1[5]*(int)l1;
		a[5]+=(int)book2[5]*(int)l2;
		a[5]+=(int)book2[4]*inp2[0];
		a[5]+=(int)book2[3]*inp2[1];
		a[5]+=(int)book2[2]*inp2[2];
		a[5]+=(int)book2[1]*inp2[3];
		a[5]+=(int)book2[0]*inp2[4];
		a[5]+=(int)inp2[5]*(int)2048;

		a[6] =(int)book1[6]*(int)l1;
		a[6]+=(int)book2[6]*(int)l2;
		a[6]+=(int)book2[5]*inp2[0];
		a[6]+=(int)book2[4]*inp2[1];
		a[6]+=(int)book2[3]*inp2[2];
		a[6]+=(int)book2[2]*inp2[3];
		a[6]+=(int)book2[1]*inp2[4];
		a[6]+=(int)book2[0]*inp2[5];
		a[6]+=(int)inp2[6]*(int)2048;

		a[7] =(int)book1[7]*(int)l1;
		a[7]+=(int)book2[7]*(int)l2;
		a[7]+=(int)book2[6]*inp2[0];
		a[7]+=(int)book2[5]*inp2[1];
		a[7]+=(int)book2[4]*inp2[2];
		a[7]+=(int)book2[3]*inp2[3];
		a[7]+=(int)book2[2]*inp2[4];
		a[7]+=(int)book2[1]*inp2[5];
		a[7]+=(int)book2[0]*inp2[6];
		a[7]+=(int)inp2[7]*(int)2048;

		for(j=0;j<8;j++)
		{
			a[j^1]>>=11;
			if(a[j^1]>32767) a[j^1]=32767;
			else if(a[j^1]<-32768) a[j^1]=-32768;
			*(out++)=a[j^1];
		}
		l1=a[6];
		l2=a[7];

		count-=32;
	}
	out-=16;
	memcpy(&RDRAM[Address],out,32);
}

static void RESAMPLE3 () {
	s32 temp;
	s32 accum;
	s16 *lut;
	short *dst;
	s16 *src;
	unsigned char Flags;
	u32 dstPtr, srcPtr, x, addy, Pitch, location, Accum, i;
	Flags=(u8)((inst2>>0x1e));
	Pitch=((inst2>>0xe)&0xffff)<<1;
	addy = (inst1 & 0xffffff);
	Accum=0;
	dst=(short *)(BufferSpace);
	src=(s16 *)(BufferSpace);
	srcPtr=((((inst2>>2)&0xfff)+0x4f0)/2);

	srcPtr -= 4;

	if (inst2 & 0x3) {
		dstPtr = 0x660/2;
	} else {
		dstPtr = 0x4f0/2;
	}

	if ((Flags & 0x1) == 0) {
		for (x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
			src[(srcPtr+x)^1] = ((u16 *)RDRAM)[((addy/2)+x)^1];
		Accum = *(u16 *)(RDRAM+addy+10);
	} else {
		for (x=0; x < 4; x++)
			src[(srcPtr+x)^1] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
	}

	//if ((Flags & 0x2))
	//	__asm int 3;

	for(i=0;i < 0x170/2;i++)	{
		location = (((Accum * 0x40) >> 0x10) * 8);
		//location = (Accum >> 0xa) << 0x3;
		lut = (s16 *)(((u8 *)ResampleLUT) + location);

		temp =  ((s32)*(s16*)(src+((srcPtr+0)^1))*((s32)((s16)lut[0])));
		accum = (s32)(temp >> 15);

		temp = ((s32)*(s16*)(src+((srcPtr+1)^1))*((s32)((s16)lut[1])));
		accum += (s32)(temp >> 15);

		temp = ((s32)*(s16*)(src+((srcPtr+2)^1))*((s32)((s16)lut[2])));
		accum += (s32)(temp >> 15);

		temp = ((s32)*(s16*)(src+((srcPtr+3)^1))*((s32)((s16)lut[3])));
		accum += (s32)(temp >> 15);

		if (accum > 32767) accum = 32767;
		if (accum < -32768) accum = -32768;

		dst[dstPtr^1] = (accum);
		dstPtr++;
		Accum += Pitch;
		srcPtr += (Accum>>16);
		Accum&=0xffff;
	}
	for (x=0; x < 4; x++)
		((u16 *)RDRAM)[((addy/2)+x)^1] = src[(srcPtr+x)^1];
	*(u16 *)(RDRAM+addy+10) = Accum;
}

static void INTERLEAVE3 () { // Needs accuracy verification...
	//u32 inL, inR;
	int x = 0;
	u16 *inSrcR;
	u16 *inSrcL;
	u16 Left, Right;

	u16 *outbuff = (u16 *)(BufferSpace + 0x4f0);//(u16 *)(AudioOutBuffer+dmem);

	inSrcR = (u16 *)(BufferSpace+0xb40);
	inSrcL = (u16 *)(BufferSpace+0x9d0);

	for (x = 0; x < (0x170/4); x++) {
		Left=*(inSrcL++);
		Right=*(inSrcR++);

		*(outbuff++)=*(inSrcR++);
		*(outbuff++)=*(inSrcL++);
		*(outbuff++)=(u16)Right;
		*(outbuff++)=(u16)Left;
	}
}

static void WHATISTHIS () {
}

u32 setaddr;
static void MP3ADDY () {
	setaddr = (inst2 & 0xffffff);
}

void rsp_run();
void mp3setup (unsigned int inst1, unsigned int inst2, unsigned int t8);

extern u32 base, dmembase;
extern char *pDMEM;

void MP3 ();

static void DISABLE () {
}


void (*ABI3[0x20])() = {
    DISABLE , ADPCM3 , CLEARBUFF3,	ENVMIXER3  , LOADBUFF3, RESAMPLE3  , SAVEBUFF3, MP3,
	MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3   , INTERLEAVE3, WHATISTHIS   , SETLOOP3,
    SPNOOP , SPNOOP, SPNOOP   , SPNOOP    , SPNOOP  , SPNOOP    , SPNOOP  , SPNOOP,
    SPNOOP , SPNOOP, SPNOOP   , SPNOOP    , SPNOOP  , SPNOOP    , SPNOOP  , SPNOOP
};
