1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - ucode3.cpp *
3
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4
* Copyright (C) 2002 Hacktarux *
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 2 of the License, or *
9
* (at your option) any later version. *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program; if not, write to the *
18
* Free Software Foundation, Inc., *
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26
# include "wintypes.h"
33
static void SPNOOP () {
35
sprintf (buff, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24));
37
MessageBox (NULL, buff, "Audio HLE Error", MB_OK);
39
printf( "Audio HLE Error: %s\n", buff );
43
extern u16 ResampleLUT [0x200];
51
extern s16 VolTrg_Left;
52
extern s32 VolRamp_Left;
53
//extern u16 VolRate_Left;
54
extern s16 VolTrg_Right;
55
extern s32 VolRamp_Right;
56
//extern u16 VolRate_Right;
59
extern short hleMixerWorkArea[256];
60
extern u16 adpcmtable[0x88];
62
extern u8 BufferSpace[0x10000];
65
static void SETVOL3 () { // Swapped Rate_Left and Vol
66
u8 Flags = (u8)(inst1 >> 0x10);
67
if (Flags & 0x4) { // 288
68
if (Flags & 0x2) { // 290
69
VolTrg_Left = *(s16*)&inst1;
70
VolRamp_Left = *(s32*)&inst2;
72
VolTrg_Right = *(s16*)&inst1;
73
VolRamp_Right = *(s32*)&inst2;
76
Vol_Left = *(s16*)&inst1;
77
Env_Dry = (s16)(*(s32*)&inst2 >> 0x10);
78
Env_Wet = *(s16*)&inst2;
82
static void SETVOL3 () {
83
u8 Flags = (u8)(inst1 >> 0x10);
84
if (Flags & 0x4) { // 288
85
if (Flags & 0x2) { // 290
86
Vol_Left = *(s16*)&inst1; // 0x50
87
Env_Dry = (s16)(*(s32*)&inst2 >> 0x10); // 0x4E
88
Env_Wet = *(s16*)&inst2; // 0x4C
90
VolTrg_Right = *(s16*)&inst1; // 0x46
91
//VolRamp_Right = (u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
92
VolRamp_Right = *(s32*)&inst2; // 0x48/0x4A
95
VolTrg_Left = *(s16*)&inst1; // 0x40
96
VolRamp_Left = *(s32*)&inst2; // 0x42/0x44
100
static void ENVMIXER3 () {
101
u8 flags = (u8)((inst1 >> 16) & 0xff);
102
u32 addy = (inst2 & 0xFFFFFF);
104
short *inp=(short *)(BufferSpace+0x4F0);
105
short *out=(short *)(BufferSpace+0x9D0);
106
short *aux1=(short *)(BufferSpace+0xB40);
107
short *aux2=(short *)(BufferSpace+0xCB0);
108
short *aux3=(short *)(BufferSpace+0xE20);
118
s32 LAdder, LAcc, LVol;
119
s32 RAdder, RAcc, RVol;
120
s16 RSig, LSig; // Most significant part of the Ramp Value
124
Vol_Right = (*(s16 *)&inst1);
126
if (flags & A_INIT) {
127
LAdder = VolRamp_Left / 8;
130
LSig = (s16)(VolRamp_Left >> 16);
132
RAdder = VolRamp_Right / 8;
135
RSig = (s16)(VolRamp_Right >> 16);
137
Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
138
LTrg = VolTrg_Left; RTrg = VolTrg_Right; // Save Current Left/Right Targets
140
memcpy((u8 *)hleMixerWorkArea, rsp.RDRAM+addy, 80);
141
Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1
142
Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3
143
LTrg = *(s16 *)(hleMixerWorkArea + 4); // 4-5
144
RTrg = *(s16 *)(hleMixerWorkArea + 6); // 6-7
145
LAdder = *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
146
RAdder = *(s32 *)(hleMixerWorkArea + 10); // 10-11
147
LAcc = *(s32 *)(hleMixerWorkArea + 12); // 12-13
148
RAcc = *(s32 *)(hleMixerWorkArea + 14); // 14-15
149
LVol = *(s32 *)(hleMixerWorkArea + 16); // 16-17
150
RVol = *(s32 *)(hleMixerWorkArea + 18); // 18-19
151
LSig = *(s16 *)(hleMixerWorkArea + 20); // 20-21
152
RSig = *(s16 *)(hleMixerWorkArea + 22); // 22-23
153
//u32 test = *(s32 *)(hleMixerWorkArea + 24); // 22-23
154
//if (test != 0x13371337)
158
//if(!(flags&A_AUX)) {
163
for (int y = 0; y < (0x170/2); y++) {
167
LVol += (LAcc >> 16);
172
RVol += (RAcc >> 16);
174
// ****************************************************************
176
if (LSig >= 0) { // VLT
187
if (RSig >= 0) { // VLT
196
// ****************************************************************
197
MainL = ((Dry * LVol) + 0x4000) >> 15;
198
MainR = ((Dry * RVol) + 0x4000) >> 15;
204
o1+=((i1*MainL)+0x4000)>>15;
205
a1+=((i1*MainR)+0x4000)>>15;
207
// ****************************************************************
209
if(o1>32767) o1=32767;
210
else if(o1<-32768) o1=-32768;
212
if(a1>32767) a1=32767;
213
else if(a1<-32768) a1=-32768;
215
// ****************************************************************
220
// ****************************************************************
221
//if (!(flags&A_AUX)) {
225
AuxL = ((Wet * LVol) + 0x4000) >> 15;
226
AuxR = ((Wet * RVol) + 0x4000) >> 15;
228
a2+=((i1*AuxL)+0x4000)>>15;
229
a3+=((i1*AuxR)+0x4000)>>15;
231
if(a2>32767) a2=32767;
232
else if(a2<-32768) a2=-32768;
234
if(a3>32767) a3=32767;
235
else if(a3<-32768) a3=-32768;
242
*(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1
243
*(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3
244
*(s16 *)(hleMixerWorkArea + 4) = LTrg; // 4-5
245
*(s16 *)(hleMixerWorkArea + 6) = RTrg; // 6-7
246
*(s32 *)(hleMixerWorkArea + 8) = LAdder; // 8-9 (hleMixerWorkArea is a 16bit pointer)
247
*(s32 *)(hleMixerWorkArea + 10) = RAdder; // 10-11
248
*(s32 *)(hleMixerWorkArea + 12) = LAcc; // 12-13
249
*(s32 *)(hleMixerWorkArea + 14) = RAcc; // 14-15
250
*(s32 *)(hleMixerWorkArea + 16) = LVol; // 16-17
251
*(s32 *)(hleMixerWorkArea + 18) = RVol; // 18-19
252
*(s16 *)(hleMixerWorkArea + 20) = LSig; // 20-21
253
*(s16 *)(hleMixerWorkArea + 22) = RSig; // 22-23
254
//*(u32 *)(hleMixerWorkArea + 24) = 0x13371337; // 22-23
255
memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
258
static void ENVMIXER3o () {
259
u8 flags = (u8)((inst1 >> 16) & 0xff);
260
u32 addy = (inst2 & 0xFFFFFF);// + SEGMENTS[(inst2>>24)&0xf];
261
//static FILE *dfile = fopen ("d:\\envmix.txt", "wt");
262
// ********* Make sure these conditions are met... ***********
263
if ((AudioInBuffer | AudioOutBuffer | AudioAuxA | AudioAuxC | AudioAuxE | AudioCount) & 0x3) {
265
MessageBox (NULL, "Unaligned EnvMixer... please report this to Azimer with the following information: RomTitle, Place in the rom it occurred, and any save state just before the error", "AudioHLE Error", MB_OK);
267
printf( "Unaligned EnvMixer... please report this to Azimer with the following information: RomTitle, Place in the rom it occurred, and any save state just before the error" );
270
// ------------------------------------------------------------
271
short *inp=(short *)(BufferSpace+0x4F0);
272
short *out=(short *)(BufferSpace+0x9D0);
273
short *aux1=(short *)(BufferSpace+0xB40);
274
short *aux2=(short *)(BufferSpace+0xCB0);
275
short *aux3=(short *)(BufferSpace+0xE20);
290
//fprintf (dfile, "\n----------------------------------------------------\n");
291
Vol_Right = (*(s16 *)&inst1);
292
if (flags & A_INIT) {
293
LVol = (((s32)(s16)Vol_Left * VolRamp_Left) - ((s32)(s16)Vol_Left << 16)) >> 3;
294
RVol = (((s32)(s16)Vol_Right * VolRamp_Right) - ((s32)(s16)Vol_Right << 16)) >> 3;
295
LAcc = ((s32)(s16)Vol_Left << 16);
296
RAcc = ((s32)(s16)Vol_Right << 16);
297
Wet = Env_Wet; Dry = Env_Dry; // Save Wet/Dry values
298
//LTrg = (VolTrg_Left << 16); RTrg = (VolTrg_Right << 16); // Save Current Left/Right Targets
299
LTrg = VolTrg_Left*0x10000; RTrg = VolTrg_Right*0x10000;
300
//fprintf (dfile, "Vol_Left = %08X LVol = %08X\n", Vol_Left, LVol);
302
// Load LVol, RVol, LAcc, and RAcc (all 32bit)
303
// Load Wet, Dry, LTrg, RTrg
304
memcpy((u8 *)hleMixerWorkArea, (rsp.RDRAM+addy), 80);
305
Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1
306
Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3
307
LTrg = *(s32 *)(hleMixerWorkArea + 4); // 4-5
308
RTrg = *(s32 *)(hleMixerWorkArea + 6); // 6-7
309
LVol = *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
310
RVol = *(s32 *)(hleMixerWorkArea + 10); // 10-11
311
LAcc = *(s32 *)(hleMixerWorkArea + 12); // 12-13
312
RAcc = *(s32 *)(hleMixerWorkArea + 14); // 14-15
320
//fprintf (dfile, "LTrg = %08X, LVol = %08X\n", LTrg, LVol);
322
for (int x=0; x<(0x170/2); x++) {
331
//LAcc = (LTrg << 16);
332
//RAcc = (RTrg << 16);
337
if (LVol < 0) { // Decrementing
349
if (RVol < 0) { // Decrementing
361
//fprintf (dfile, "%04X ", (LAcc>>16));
363
MainL = ((Dry * (LAcc>>16)) + 0x4000) >> 15;
364
MainR = ((Dry * (RAcc>>16)) + 0x4000) >> 15;
365
AuxL = ((Wet * (LAcc>>16)) + 0x4000) >> 15;
366
AuxR = ((Wet * (RAcc>>16)) + 0x4000) >> 15;
367
/*if (MainL>32767) MainL = 32767;
368
else if (MainL<-32768) MainL = -32768;
369
if (MainR>32767) MainR = 32767;
370
else if (MainR<-32768) MainR = -32768;
371
if (AuxL>32767) AuxL = 32767;
372
else if (AuxL<-32768) AuxR = -32768;
373
if (AuxR>32767) AuxR = 32767;
374
else if (AuxR<-32768) AuxR = -32768;*/
376
MainR = (Dry * RTrg + 0x10000) >> 15;
377
MainL = (Dry * LTrg + 0x10000) >> 15;
378
AuxR = (Wet * RTrg + 0x8000) >> 16;
379
AuxL = (Wet * LTrg + 0x8000) >> 16;*/
381
o1+=(/*(o1*0x7fff)+*/(i1*MainR)+0x4000)>>15;
383
a1+=(/*(a1*0x7fff)+*/(i1*MainL)+0x4000)>>15;
385
if(o1>32767) o1=32767;
386
else if(o1<-32768) o1=-32768;
388
if(a1>32767) a1=32767;
389
else if(a1<-32768) a1=-32768;
394
a2+=(/*(a2*0x7fff)+*/(i1*AuxR)+0x4000)>>15;
395
a3+=(/*(a3*0x7fff)+*/(i1*AuxL)+0x4000)>>15;
397
if(a2>32767) a2=32767;
398
else if(a2<-32768) a2=-32768;
400
if(a3>32767) a3=32767;
401
else if(a3<-32768) a3=-32768;
408
*(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1
409
*(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3
410
*(s32 *)(hleMixerWorkArea + 4) = LTrg; // 4-5
411
*(s32 *)(hleMixerWorkArea + 6) = RTrg; // 6-7
412
*(s32 *)(hleMixerWorkArea + 8) = LVol; // 8-9 (hleMixerWorkArea is a 16bit pointer)
413
*(s32 *)(hleMixerWorkArea + 10) = RVol; // 10-11
414
*(s32 *)(hleMixerWorkArea + 12) = LAcc; // 12-13
415
*(s32 *)(hleMixerWorkArea + 14) = RAcc; // 14-15
416
memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
419
static void ENVMIXER3 () { // Borrowed from RCP...
420
u8 flags = (u8)((inst1 >> 16) & 0xff);
421
u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
423
short *inp=(short *)(BufferSpace+0x4F0);
424
short *out=(short *)(BufferSpace+0x9D0);
425
short *aux1=(short *)(BufferSpace+0xB40);
426
short *aux2=(short *)(BufferSpace+0xCB0);
427
short *aux3=(short *)(BufferSpace+0xE20);
429
Vol_Right = (inst1 & 0xffff); // Needed for future references
441
MainR = (Env_Dry * VolTrg_Right + 0x10000) >> 15;
442
MainL = (Env_Dry * VolTrg_Left + 0x10000) >> 15;
443
AuxR = (Env_Wet * VolTrg_Right + 0x8000) >> 16;
444
AuxL = (Env_Wet * VolTrg_Left + 0x8000) >> 16;
446
memcpy((u8 *)hleMixerWorkArea, (rsp.RDRAM+addy), 80);
447
MainR=hleMixerWorkArea[0];
448
MainL=hleMixerWorkArea[2];
449
AuxR=hleMixerWorkArea[4];
450
AuxL=hleMixerWorkArea[6];
457
for(int i=0;i<(0x170/2);i++)
465
o1=((o1*0x7fff)+(i1*MainR)+0x10000)>>15;
466
a2=((a2*0x7fff)+(i1*AuxR)+0x8000)>>16;
468
a1=((a1*0x7fff)+(i1*MainL)+0x10000)>>15;
469
a3=((a3*0x7fff)+(i1*AuxL)+0x8000)>>16;
471
if(o1>32767) o1=32767;
472
else if(o1<-32768) o1=-32768;
474
if(a1>32767) a1=32767;
475
else if(a1<-32768) a1=-32768;
477
if(a2>32767) a2=32767;
478
else if(a2<-32768) a2=-32768;
480
if(a3>32767) a3=32767;
481
else if(a3<-32768) a3=-32768;
490
hleMixerWorkArea[0]=MainR;
491
hleMixerWorkArea[2]=MainL;
492
hleMixerWorkArea[4]=AuxR;
493
hleMixerWorkArea[6]=AuxL;
494
memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
498
static void CLEARBUFF3 () {
499
u16 addr = (u16)(inst1 & 0xffff);
500
u16 count = (u16)(inst2 & 0xffff);
501
memset(BufferSpace+addr+0x4f0, 0, count);
504
static void MIXER3 () { // Needs accuracy verification...
505
u16 dmemin = (u16)(inst2 >> 0x10) + 0x4f0;
506
u16 dmemout = (u16)(inst2 & 0xFFFF) + 0x4f0;
507
//u8 flags = (u8)((inst1 >> 16) & 0xff);
508
s32 gain = (s16)(inst1 & 0xFFFF)*2;
511
for (int x=0; x < 0x170; x+=2) { // I think I can do this a lot easier
512
temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 16;
513
temp += *(s16 *)(BufferSpace+dmemout+x);
515
if ((s32)temp > 32767)
517
if ((s32)temp < -32768)
520
*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
524
static void LOADBUFF3 () {
526
u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
527
v0 = (inst2 & 0xfffffc);
528
u32 src = (inst1&0xffc)+0x4f0;
529
memcpy (BufferSpace+src, rsp.RDRAM+v0, cnt);
532
static void SAVEBUFF3 () {
534
u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
535
v0 = (inst2 & 0xfffffc);
536
u32 src = (inst1&0xffc)+0x4f0;
537
memcpy (rsp.RDRAM+v0, BufferSpace+src, cnt);
540
static void LOADADPCM3 () { // Loads an ADPCM table - Works 100% Now 03-13-01
542
v0 = (inst2 & 0xffffff);
543
//memcpy (dmem+0x3f0, rsp.RDRAM+v0, inst1&0xffff);
544
//assert ((inst1&0xffff) <= 0x80);
545
u16 *table = (u16 *)(rsp.RDRAM+v0);
546
for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
547
adpcmtable[0x1+(x<<3)] = table[0];
548
adpcmtable[0x0+(x<<3)] = table[1];
550
adpcmtable[0x3+(x<<3)] = table[2];
551
adpcmtable[0x2+(x<<3)] = table[3];
553
adpcmtable[0x5+(x<<3)] = table[4];
554
adpcmtable[0x4+(x<<3)] = table[5];
556
adpcmtable[0x7+(x<<3)] = table[6];
557
adpcmtable[0x6+(x<<3)] = table[7];
562
static void DMEMMOVE3 () { // Needs accuracy verification...
565
v0 = (inst1 & 0xFFFF) + 0x4f0;
566
v1 = (inst2 >> 0x10) + 0x4f0;
567
u32 count = ((inst2+3) & 0xfffc);
569
//memcpy (dmem+v1, dmem+v0, count-1);
570
for (cnt = 0; cnt < count; cnt++) {
571
*(u8 *)(BufferSpace+((cnt+v1)^3)) = *(u8 *)(BufferSpace+((cnt+v0)^3));
575
static void SETLOOP3 () {
576
loopval = (inst2 & 0xffffff);
579
static void ADPCM3 () { // Verified to be 100% Accurate...
580
BYTE Flags=(u8)(inst2>>0x1c)&0xff;
581
//WORD Gain=(u16)(inst1&0xffff);
582
DWORD Address=(inst1 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
583
WORD inPtr=(inst2>>12)&0xf;
584
//short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
585
short *out=(short *)(BufferSpace+(inst2&0xfff)+0x4f0);
586
//BYTE *in=(BYTE *)(BufferSpace+((inst2>>12)&0xf)+0x4f0);
587
short count=(short)((inst2 >> 16)&0xfff);
602
for(int i=0;i<16;i++)
604
out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];
606
memcpy(out,&rsp.RDRAM[loopval],32);
610
for(int i=0;i<16;i++)
612
out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];
614
memcpy(out,&rsp.RDRAM[Address],32);
625
// the first interation through, these values are
626
// either 0 in the case of A_INIT, from a special
627
// area of memory in the case of A_LOOP or just
628
// the values we calculated the last time
630
code=BufferSpace[(0x4f0+inPtr)^3];
632
index<<=4; // index into the adpcm code table
633
book1=(short *)&adpcmtable[index];
635
code>>=4; // upper nibble is scale
636
vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format
637
// so this appears to be a fractional scale based
638
// on the 12 based inverse of the scale value. note
639
// that this could be negative, in which case we do
640
// not use the calculated vscale value... see the
641
// if(code>12) check below
643
inPtr++; // coded adpcm data lies next
645
while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes
646
// which yields 8 short pcm values
648
icode=BufferSpace[(0x4f0+inPtr)^3];
651
inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed
653
inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
658
inp1[j]=(s16)((icode&0xf)<<12);
660
inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
668
icode=BufferSpace[(0x4f0+inPtr)^3];
671
inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed
673
inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
678
inp2[j]=(short)((icode&0xf)<<12);
680
inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
686
a[0]= (int)book1[0]*(int)l1;
687
a[0]+=(int)book2[0]*(int)l2;
688
a[0]+=(int)inp1[0]*(int)2048;
690
a[1] =(int)book1[1]*(int)l1;
691
a[1]+=(int)book2[1]*(int)l2;
692
a[1]+=(int)book2[0]*inp1[0];
693
a[1]+=(int)inp1[1]*(int)2048;
695
a[2] =(int)book1[2]*(int)l1;
696
a[2]+=(int)book2[2]*(int)l2;
697
a[2]+=(int)book2[1]*inp1[0];
698
a[2]+=(int)book2[0]*inp1[1];
699
a[2]+=(int)inp1[2]*(int)2048;
701
a[3] =(int)book1[3]*(int)l1;
702
a[3]+=(int)book2[3]*(int)l2;
703
a[3]+=(int)book2[2]*inp1[0];
704
a[3]+=(int)book2[1]*inp1[1];
705
a[3]+=(int)book2[0]*inp1[2];
706
a[3]+=(int)inp1[3]*(int)2048;
708
a[4] =(int)book1[4]*(int)l1;
709
a[4]+=(int)book2[4]*(int)l2;
710
a[4]+=(int)book2[3]*inp1[0];
711
a[4]+=(int)book2[2]*inp1[1];
712
a[4]+=(int)book2[1]*inp1[2];
713
a[4]+=(int)book2[0]*inp1[3];
714
a[4]+=(int)inp1[4]*(int)2048;
716
a[5] =(int)book1[5]*(int)l1;
717
a[5]+=(int)book2[5]*(int)l2;
718
a[5]+=(int)book2[4]*inp1[0];
719
a[5]+=(int)book2[3]*inp1[1];
720
a[5]+=(int)book2[2]*inp1[2];
721
a[5]+=(int)book2[1]*inp1[3];
722
a[5]+=(int)book2[0]*inp1[4];
723
a[5]+=(int)inp1[5]*(int)2048;
725
a[6] =(int)book1[6]*(int)l1;
726
a[6]+=(int)book2[6]*(int)l2;
727
a[6]+=(int)book2[5]*inp1[0];
728
a[6]+=(int)book2[4]*inp1[1];
729
a[6]+=(int)book2[3]*inp1[2];
730
a[6]+=(int)book2[2]*inp1[3];
731
a[6]+=(int)book2[1]*inp1[4];
732
a[6]+=(int)book2[0]*inp1[5];
733
a[6]+=(int)inp1[6]*(int)2048;
735
a[7] =(int)book1[7]*(int)l1;
736
a[7]+=(int)book2[7]*(int)l2;
737
a[7]+=(int)book2[6]*inp1[0];
738
a[7]+=(int)book2[5]*inp1[1];
739
a[7]+=(int)book2[4]*inp1[2];
740
a[7]+=(int)book2[3]*inp1[3];
741
a[7]+=(int)book2[2]*inp1[4];
742
a[7]+=(int)book2[1]*inp1[5];
743
a[7]+=(int)book2[0]*inp1[6];
744
a[7]+=(int)inp1[7]*(int)2048;
749
if(a[j^1]>32767) a[j^1]=32767;
750
else if(a[j^1]<-32768) a[j^1]=-32768;
758
a[0]= (int)book1[0]*(int)l1;
759
a[0]+=(int)book2[0]*(int)l2;
760
a[0]+=(int)inp2[0]*(int)2048;
762
a[1] =(int)book1[1]*(int)l1;
763
a[1]+=(int)book2[1]*(int)l2;
764
a[1]+=(int)book2[0]*inp2[0];
765
a[1]+=(int)inp2[1]*(int)2048;
767
a[2] =(int)book1[2]*(int)l1;
768
a[2]+=(int)book2[2]*(int)l2;
769
a[2]+=(int)book2[1]*inp2[0];
770
a[2]+=(int)book2[0]*inp2[1];
771
a[2]+=(int)inp2[2]*(int)2048;
773
a[3] =(int)book1[3]*(int)l1;
774
a[3]+=(int)book2[3]*(int)l2;
775
a[3]+=(int)book2[2]*inp2[0];
776
a[3]+=(int)book2[1]*inp2[1];
777
a[3]+=(int)book2[0]*inp2[2];
778
a[3]+=(int)inp2[3]*(int)2048;
780
a[4] =(int)book1[4]*(int)l1;
781
a[4]+=(int)book2[4]*(int)l2;
782
a[4]+=(int)book2[3]*inp2[0];
783
a[4]+=(int)book2[2]*inp2[1];
784
a[4]+=(int)book2[1]*inp2[2];
785
a[4]+=(int)book2[0]*inp2[3];
786
a[4]+=(int)inp2[4]*(int)2048;
788
a[5] =(int)book1[5]*(int)l1;
789
a[5]+=(int)book2[5]*(int)l2;
790
a[5]+=(int)book2[4]*inp2[0];
791
a[5]+=(int)book2[3]*inp2[1];
792
a[5]+=(int)book2[2]*inp2[2];
793
a[5]+=(int)book2[1]*inp2[3];
794
a[5]+=(int)book2[0]*inp2[4];
795
a[5]+=(int)inp2[5]*(int)2048;
797
a[6] =(int)book1[6]*(int)l1;
798
a[6]+=(int)book2[6]*(int)l2;
799
a[6]+=(int)book2[5]*inp2[0];
800
a[6]+=(int)book2[4]*inp2[1];
801
a[6]+=(int)book2[3]*inp2[2];
802
a[6]+=(int)book2[2]*inp2[3];
803
a[6]+=(int)book2[1]*inp2[4];
804
a[6]+=(int)book2[0]*inp2[5];
805
a[6]+=(int)inp2[6]*(int)2048;
807
a[7] =(int)book1[7]*(int)l1;
808
a[7]+=(int)book2[7]*(int)l2;
809
a[7]+=(int)book2[6]*inp2[0];
810
a[7]+=(int)book2[5]*inp2[1];
811
a[7]+=(int)book2[4]*inp2[2];
812
a[7]+=(int)book2[3]*inp2[3];
813
a[7]+=(int)book2[2]*inp2[4];
814
a[7]+=(int)book2[1]*inp2[5];
815
a[7]+=(int)book2[0]*inp2[6];
816
a[7]+=(int)inp2[7]*(int)2048;
821
if(a[j^1]>32767) a[j^1]=32767;
822
else if(a[j^1]<-32768) a[j^1]=-32768;
824
//*(out+j+0x1f8)=a[j^1];
832
memcpy(&rsp.RDRAM[Address],out,32);
835
static void RESAMPLE3 () {
836
BYTE Flags=(u8)((inst2>>0x1e));
837
DWORD Pitch=((inst2>>0xe)&0xffff)<<1;
838
u32 addy = (inst1 & 0xffffff);
844
dst=(short *)(BufferSpace);
845
src=(s16 *)(BufferSpace);
846
u32 srcPtr=((((inst2>>2)&0xfff)+0x4f0)/2);
847
u32 dstPtr;//=(AudioOutBuffer/2);
851
//if (addy > (1024*1024*8))
852
// addy = (inst2 & 0xffffff);
862
if ((Flags & 0x1) == 0) {
863
for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
864
src[(srcPtr+x)^1] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^1];
865
Accum = *(u16 *)(rsp.RDRAM+addy+10);
867
for (int x=0; x < 4; x++)
868
src[(srcPtr+x)^1] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
871
for(int i=0;i < 0x170/2;i++) {
872
location = (((Accum * 0x40) >> 0x10) * 8);
873
//location = (Accum >> 0xa) << 0x3;
874
lut = (s16 *)(((u8 *)ResampleLUT) + location);
876
temp = ((s32)*(s16*)(src+((srcPtr+0)^1))*((s32)((s16)lut[0])));
877
accum = (s32)(temp >> 15);
879
temp = ((s32)*(s16*)(src+((srcPtr+1)^1))*((s32)((s16)lut[1])));
880
accum += (s32)(temp >> 15);
882
temp = ((s32)*(s16*)(src+((srcPtr+2)^1))*((s32)((s16)lut[2])));
883
accum += (s32)(temp >> 15);
885
temp = ((s32)*(s16*)(src+((srcPtr+3)^1))*((s32)((s16)lut[3])));
886
accum += (s32)(temp >> 15);
887
/* temp = ((s64)*(s16*)(src+((srcPtr+0)^1))*((s64)((s16)lut[0]<<1)));
888
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
889
else temp = (temp^0x8000);
890
temp = (s32)(temp >> 16);
891
if ((s32)temp > 32767) temp = 32767;
892
if ((s32)temp < -32768) temp = -32768;
893
accum = (s32)(s16)temp;
895
temp = ((s64)*(s16*)(src+((srcPtr+1)^1))*((s64)((s16)lut[1]<<1)));
896
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
897
else temp = (temp^0x8000);
898
temp = (s32)(temp >> 16);
899
if ((s32)temp > 32767) temp = 32767;
900
if ((s32)temp < -32768) temp = -32768;
901
accum += (s32)(s16)temp;
903
temp = ((s64)*(s16*)(src+((srcPtr+2)^1))*((s64)((s16)lut[2]<<1)));
904
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
905
else temp = (temp^0x8000);
906
temp = (s32)(temp >> 16);
907
if ((s32)temp > 32767) temp = 32767;
908
if ((s32)temp < -32768) temp = -32768;
909
accum += (s32)(s16)temp;
911
temp = ((s64)*(s16*)(src+((srcPtr+3)^1))*((s64)((s16)lut[3]<<1)));
912
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
913
else temp = (temp^0x8000);
914
temp = (s32)(temp >> 16);
915
if ((s32)temp > 32767) temp = 32767;
916
if ((s32)temp < -32768) temp = -32768;
917
accum += (s32)(s16)temp;*/
919
if (accum > 32767) accum = 32767;
920
if (accum < -32768) accum = -32768;
922
dst[dstPtr^1] = (accum);
925
srcPtr += (Accum>>16);
928
for (int x=0; x < 4; x++)
929
((u16 *)rsp.RDRAM)[((addy/2)+x)^1] = src[(srcPtr+x)^1];
930
*(u16 *)(rsp.RDRAM+addy+10) = Accum;
933
static void INTERLEAVE3 () { // Needs accuracy verification...
935
u16 *outbuff = (u16 *)(BufferSpace + 0x4f0);//(u16 *)(AudioOutBuffer+dmem);
940
//inR = inst2 & 0xFFFF;
941
//inL = (inst2 >> 16) & 0xFFFF;
943
inSrcR = (u16 *)(BufferSpace+0xb40);
944
inSrcL = (u16 *)(BufferSpace+0x9d0);
946
for (int x = 0; x < (0x170/4); x++) {
950
*(outbuff++)=*(inSrcR++);
951
*(outbuff++)=*(inSrcL++);
952
*(outbuff++)=(u16)Right;
953
*(outbuff++)=(u16)Left;
957
*(outbuff++)=(u16)Left;
959
*(outbuff++)=(u16)Right;
961
*(outbuff++)=(u16)Left;
962
*(outbuff++)=(u16)Right;*/
966
//static void UNKNOWN ();
971
BYTE error_protection : 1; // 0=yes, 1=no
972
BYTE lay : 2; // 4-lay = layerI, II or III
973
BYTE version : 1; // 3=mpeg 1.0, 2=mpeg 2.5 0=mpeg 2.0
976
BYTE extension : 1; // Unknown
977
BYTE padding : 1; // padding
978
BYTE sampling_freq : 2; // see table below
979
BYTE bitrate_index : 4; // see table below
981
BYTE emphasis : 2; //see table below
982
BYTE original : 1; // 0=no 1=yes
983
BYTE copyright : 1; // 0=no 1=yes
984
BYTE mode_ext : 2; // used with "joint stereo" mode
985
BYTE mode : 2; // Channel Mode
992
static void WHATISTHIS () {
995
//static FILE *fp = fopen ("d:\\mp3info.txt", "wt");
997
static void MP3ADDY () {
998
setaddr = (inst2 & 0xffffff);
1003
void mp3setup (DWORD inst1, DWORD inst2, DWORD t8);
1006
extern u32 base, dmembase;
1014
// Setup Registers...
1015
mp3setup (inst1, inst2, 0xFA0);
1017
// Setup Memory Locations...
1018
//u32 base = ((u32*)dmem)[0xFD0/4]; // Should be 000291A0
1019
memcpy (BufferSpace, dmembase+rsp.RDRAM, 0x10);
1020
((u32*)BufferSpace)[0x0] = base;
1021
((u32*)BufferSpace)[0x008/4] += base;
1022
((u32*)BufferSpace)[0xFFC/4] = loopval;
1023
((u32*)BufferSpace)[0xFF8/4] = dmembase;
1025
memcpy (imem+0x238, rsp.RDRAM+((u32*)BufferSpace)[0x008/4], 0x9C0);
1026
((u32*)BufferSpace)[0xFF4/4] = setaddr;
1027
pDMEM = (char *)BufferSpace;
1029
dmembase = ((u32*)BufferSpace)[0xFF8/4];
1030
loopval = ((u32*)BufferSpace)[0xFFC/4];
1031
//0x1A98 SW S1, 0x0FF4 (R0)
1032
//0x1A9C SW S0, 0x0FF8 (R0)
1033
//0x1AA0 SW T7, 0x0FFC (R0)
1034
//0x1AA4 SW T3, 0x0FF0 (R0)
1035
//fprintf (fp, "mp3: inst1: %08X, inst2: %08X\n", inst1, inst2);
1038
FFT = Fast Fourier Transform
1039
DCT = Discrete Cosine Transform
1040
MPEG-1 Layer 3 retains Layer 2�s 1152-sample window, as well as the FFT polyphase filter for
1041
backward compatibility, but adds a modified DCT filter. DCT�s advantages over DFTs (discrete
1042
Fourier transforms) include half as many multiply-accumulate operations and half the
1043
generated coefficients because the sinusoidal portion of the calculation is absent, and DCT
1044
generally involves simpler math. The finite lengths of a conventional DCTs� bandpass impulse
1045
responses, however, may result in block-boundary effects. MDCTs overlap the analysis blocks
1046
and lowpass-filter the decoded audio to remove aliases, eliminating these effects. MDCTs also
1047
have a higher transform coding gain than the standard DCT, and their basic functions
1048
correspond to better bandpass response.
1050
MPEG-1 Layer 3�s DCT sub-bands are unequally sized, and correspond to the human auditory
1051
system�s critical bands. In Layer 3 decoders must support both constant- and variable-bit-rate
1052
bit streams. (However, many Layer 1 and 2 decoders also handle variable bit rates). Finally,
1053
Layer 3 encoders Huffman-code the quantized coefficients before archiving or transmission for
1054
additional lossless compression. Bit streams range from 32 to 320 kbps, and 128-kbps rates
1055
achieve near-CD quality, an important specification to enable dual-channel ISDN
1056
(integrated-services-digital-network) to be the future high-bandwidth pipe to the home.
1059
static void DISABLE () {
1060
//MessageBox (NULL, "Help", "ABI 3 Command 0", MB_OK);
1065
void (*ABI3[0x20])() = {
1066
DISABLE , ADPCM3 , CLEARBUFF3, ENVMIXER3 , LOADBUFF3, RESAMPLE3 , SAVEBUFF3, MP3,
1067
MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3,
1068
SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP,
1069
SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP
1072
void (*ABI3[32])(void) =
1074
SPNOOP , ADPCM3 , CLEARBUFF3, SPNOOP ,
1075
MIXER3 , RESAMPLE3 , SPNOOP , MP3 ,
1076
MP3ADDY , SETVOL3 , DMEMMOVE3 , LOADADPCM3,
1077
MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3 ,
1078
SPNOOP , /*MEMHALVE , ENVSET1*/ SPNOOP, SPNOOP , ENVMIXER3 ,
1079
LOADBUFF3, SAVEBUFF3 , /*ENVSET2*/SPNOOP , SPNOOP ,
1080
SPNOOP , SPNOOP , SPNOOP , SPNOOP ,
1081
SPNOOP , SPNOOP , SPNOOP , SPNOOP