Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
RishiRecon
GitHub Repository: RishiRecon/exploits
Path: blob/main/misc/emulator/xnes/snem/dsp.c
28515 views
1
#include <stdio.h>
2
#include "snes.h"
3
struct
4
{
5
union
6
{
7
unsigned short ya;
8
struct
9
{
10
unsigned char a,y;
11
} b;
12
} ya;
13
unsigned char x;
14
unsigned char s;
15
unsigned short pc;
16
struct
17
{
18
int c,z,h,p,v,n;
19
} p;
20
unsigned short opc[8];
21
} spc;
22
23
unsigned char spuram[0x10080];
24
25
int decode[64];
26
27
int samppos[8],sampf[8]; // the type of samppos and sampf were the fixed type of allegro
28
int sampfreq[8];
29
int sampvol[8][3];
30
int sampsamp[8];
31
int keyed[8];
32
int sloop[8];
33
34
#define ATTACK 1
35
#define DECAY 2
36
#define SUSTAIN 3
37
#define RELEASE 4
38
typedef struct ADSR
39
{
40
int sr,sl,ar,dr;
41
int ena;
42
} ADSR;
43
ADSR adsr[8];
44
int adsrstate[8];
45
float voicelev[8];
46
float voicediff[8];
47
float voicetarg[8];
48
int realvol[8];
49
50
float ardiffs[16]=
51
{
52
0.00406146,0.00543660,0.01110239,0.01665625,
53
0.02602639,0.04383392,0.06406127,0.10463323,
54
0.17350216,0.26025324,0.41640625,0.69400864,
55
1.00195313,1.00312500,1.00520833,1.00000000
56
};
57
float drdiffs[8]=
58
{
59
0.01100112,0.02250859,0.03785366,0.05743075,
60
0.09253413,0.15141997,0.22508057,0.45016647
61
};
62
float srdiffs[32]=
63
{
64
0.00000000,0.00043760,0.00059696,0.00069290,
65
0.00087412,0.00118859,0.00138580,0.00176956,
66
0.00234520,0.00282490,0.00354445,0.00475969,
67
0.00574574,0.00693966,0.00925288,0.01110239,
68
0.01387932,0.01892683,0.02250859,0.02823301,
69
0.03785366,0.04501185,0.05743608,0.07571265,
70
0.09253413,0.11103989,0.15141997,0.18104411,
71
0.22508057,0.30283994,0.45016647,0.59486531
72
};
73
74
unsigned short diraddr;
75
76
void writedsp(int a, unsigned char v)
77
{
78
int c;
79
if (a&1)
80
{
81
dspregs[dspaddr&127]=v;
82
switch (dspaddr&127)
83
{
84
case 0x00: case 0x10: case 0x20: case 0x30:
85
case 0x40: case 0x50: case 0x60: case 0x70:
86
sampvol[dspaddr>>4][0]=v&127;
87
sampvol[dspaddr>>4][2]=sampvol[dspaddr>>4][0]+sampvol[dspaddr>>4][1];
88
break;
89
case 0x01: case 0x11: case 0x21: case 0x31:
90
case 0x41: case 0x51: case 0x61: case 0x71:
91
sampvol[dspaddr>>4][1]=v&127;
92
sampvol[dspaddr>>4][2]=sampvol[dspaddr>>4][0]+sampvol[dspaddr>>4][1];
93
break;
94
case 0x02: case 0x12: case 0x22: case 0x32:
95
case 0x42: case 0x52: case 0x62: case 0x72:
96
sampfreq[dspaddr>>4]&=0xFF00;
97
sampfreq[dspaddr>>4]|=v;
98
break;
99
case 0x03: case 0x13: case 0x23: case 0x33:
100
case 0x43: case 0x53: case 0x63: case 0x73:
101
sampfreq[dspaddr>>4]&=0xFF;
102
sampfreq[dspaddr>>4]|=((v&0x3F)<<8);
103
break;
104
case 0x04: case 0x14: case 0x24: case 0x34:
105
case 0x44: case 0x54: case 0x64: case 0x74:
106
sampsamp[dspaddr>>4]=v&63;
107
samppos[dspaddr>>4]=0;
108
break;
109
case 0x05: case 0x15: case 0x25: case 0x35:
110
case 0x45: case 0x55: case 0x65: case 0x75:
111
dspaddr>>=4;
112
adsr[dspaddr].ena=v>>7;
113
adsr[dspaddr].dr=(v>>4)&7;
114
adsr[dspaddr].ar=v&15;
115
if (adsrstate[dspaddr]==ATTACK) voicediff[dspaddr]=ardiffs[adsr[dspaddr].ar];
116
break;
117
case 0x06: case 0x16: case 0x26: case 0x36:
118
case 0x46: case 0x56: case 0x66: case 0x76:
119
dspaddr>>=4;
120
adsr[dspaddr].sr=v&31;
121
adsr[dspaddr].sl=v>>5;
122
break;
123
124
case 0x4c:
125
// printf("Key on %02X %04X\n",v,spc.pc);
126
for (c=0;c<8;c++)
127
{
128
if (v&(1<<c))
129
{
130
keyed[c]=1;
131
adsrstate[c]=ATTACK;
132
voicelev[c]=0;
133
voicediff[c]=ardiffs[adsr[c].ar&15];
134
samppos[c]=0;
135
sloop[c]=0;
136
}
137
}
138
break;
139
case 0x5c:
140
// printf("Key off %02X %04X\n",v,spc.pc);
141
for (c=0;c<8;c++)
142
{
143
if (v&(1<<c))
144
{
145
keyed[c]=0;
146
samppos[c]=0;
147
sloop[c]=0;
148
adsrstate[c]=0;
149
}
150
}
151
break;
152
case 0x5D:
153
diraddr=v<<8;
154
memset(decode,1,sizeof(decode));
155
updatespuaccess(v);
156
break;
157
}
158
}
159
else
160
dspaddr=v;
161
}
162
163
unsigned char readdsp(int a)
164
{
165
if (a&1) return dspregs[dspaddr&127];
166
return dspaddr;
167
}
168
169
unsigned short samples[64][32768],sampler[64][32768];
170
int samp[64][2];
171
int samplen[64][2],samplenr[64];
172
int samploop[64],samploopp[64];
173
174
175
int decodedelay=60;
176
177
signed short lastsamp[2];
178
int range,filter;
179
inline signed short decodebrr(int v)
180
{
181
signed short temp=v&0xF;
182
float tempf;
183
if (temp&8) temp|=0xFFF0;
184
temp<<=range;
185
switch (filter)
186
{
187
case 0: break;
188
case 1: tempf=(float)lastsamp[0]*((float)15/(float)16); temp+=tempf; break;
189
case 2: tempf=((float)lastsamp[0]*((float)61/(float)32))-((float)lastsamp[1]*((float)15/(float)16)); temp+=tempf; break;
190
case 3: tempf=((float)lastsamp[0]*((float)115/(float)64))-((float)lastsamp[1]*((float)13/(float)16)); temp+=tempf; break;
191
default:
192
printf("Unimplemented filter type %i\n",filter);
193
exit(-1);
194
}
195
lastsamp[1]=lastsamp[0];
196
lastsamp[0]=temp;
197
return temp;
198
}
199
#ifdef SOUND
200
int decodecalls=0;
201
void decodesamples()
202
{
203
unsigned char *block;
204
int c;
205
unsigned short addr,addr2=diraddr,laddr,faddr;
206
signed short temp;
207
int bnum;
208
unsigned short saddr;
209
decodecalls++;
210
decodecalls&=15;
211
for (c=0;c<64;c++)
212
{
213
if (decodecalls==15) decode[c]=5;
214
if (decode[c]==5)
215
{
216
samp[c][0]=samp[c][1]=samploop[c]=0;
217
faddr=addr=spuram[addr2]|(spuram[addr2+1]<<8);
218
laddr=spuram[addr2+2]|(spuram[addr2+3]<<8);
219
addr2+=4;
220
if (addr)
221
{
222
samp[c][0]=1;
223
block=&spuram[addr];
224
saddr=0;
225
bnum=0;
226
lastsamp[0]=lastsamp[1]=0;
227
while (saddr<0x7000)
228
{
229
if (block[0]&2) samploop[c]=1;
230
// if (c==0) printf("Block 0 : %02X saddr %04X\n",block[0],saddr);
231
range=block[0]>>4;
232
filter=(block[0]>>2)&3;
233
temp=decodebrr(block[1]>>4); samples[c][saddr++]=(signed short)temp;
234
temp=decodebrr(block[1]&0xF); samples[c][saddr++]=(signed short)temp;
235
temp=decodebrr(block[2]>>4); samples[c][saddr++]=(signed short)temp;
236
temp=decodebrr(block[2]&0xF); samples[c][saddr++]=(signed short)temp;
237
temp=decodebrr(block[3]>>4); samples[c][saddr++]=(signed short)temp;
238
temp=decodebrr(block[3]&0xF); samples[c][saddr++]=(signed short)temp;
239
temp=decodebrr(block[4]>>4); samples[c][saddr++]=(signed short)temp;
240
temp=decodebrr(block[4]&0xF); samples[c][saddr++]=(signed short)temp;
241
temp=decodebrr(block[5]>>4); samples[c][saddr++]=(signed short)temp;
242
temp=decodebrr(block[5]&0xF); samples[c][saddr++]=(signed short)temp;
243
temp=decodebrr(block[6]>>4); samples[c][saddr++]=(signed short)temp;
244
temp=decodebrr(block[6]&0xF); samples[c][saddr++]=(signed short)temp;
245
temp=decodebrr(block[7]>>4); samples[c][saddr++]=(signed short)temp;
246
temp=decodebrr(block[7]&0xF); samples[c][saddr++]=(signed short)temp;
247
temp=decodebrr(block[8]>>4); samples[c][saddr++]=(signed short)temp;
248
temp=decodebrr(block[8]&0xF); samples[c][saddr++]=(signed short)temp;
249
bnum+=16;
250
if (block[0]&1) goto donesmp1;
251
addr+=9;
252
block=&spuram[addr];
253
}
254
donesmp1:
255
samplen[c][0]=bnum;
256
if (laddr)
257
{
258
samp[c][1]=1;
259
addr=laddr;
260
block=&spuram[addr];
261
bnum=0;
262
saddr=0;
263
while ((block[0]&2) && saddr<0x7000)
264
{
265
range=block[0]>>4;
266
filter=(block[0]>>2)&3;
267
temp=decodebrr(block[1]>>4); sampler[c][saddr++]=(signed short)temp;
268
temp=decodebrr(block[1]&0xF); sampler[c][saddr++]=(signed short)temp;
269
temp=decodebrr(block[2]>>4); sampler[c][saddr++]=(signed short)temp;
270
temp=decodebrr(block[2]&0xF); sampler[c][saddr++]=(signed short)temp;
271
temp=decodebrr(block[3]>>4); sampler[c][saddr++]=(signed short)temp;
272
temp=decodebrr(block[3]&0xF); sampler[c][saddr++]=(signed short)temp;
273
temp=decodebrr(block[4]>>4); sampler[c][saddr++]=(signed short)temp;
274
temp=decodebrr(block[4]&0xF); sampler[c][saddr++]=(signed short)temp;
275
temp=decodebrr(block[5]>>4); sampler[c][saddr++]=(signed short)temp;
276
temp=decodebrr(block[5]&0xF); sampler[c][saddr++]=(signed short)temp;
277
temp=decodebrr(block[6]>>4); sampler[c][saddr++]=(signed short)temp;
278
temp=decodebrr(block[6]&0xF); sampler[c][saddr++]=(signed short)temp;
279
temp=decodebrr(block[7]>>4); sampler[c][saddr++]=(signed short)temp;
280
temp=decodebrr(block[7]&0xF); sampler[c][saddr++]=(signed short)temp;
281
temp=decodebrr(block[8]>>4); sampler[c][saddr++]=(signed short)temp;
282
temp=decodebrr(block[8]&0xF); sampler[c][saddr++]=(signed short)temp;
283
bnum+=16;
284
if (block[0]&1) goto donesmp2;
285
addr+=9;
286
block=&spuram[addr];
287
}
288
donesmp2:
289
samplen[c][1]=bnum;
290
}
291
// printf("Sample %i decoded len %i looplen %i\n",c,samplen[c][0],samplen[c][1]);
292
}
293
decode[c]=0;
294
}
295
else
296
{
297
if (decode[c]) decode[c]++;
298
addr2+=4;
299
}
300
}
301
}
302
303
AUDIOSTREAM *as;
304
FILE *sf;
305
306
void initsound()
307
{
308
install_sound(DIGI_AUTODETECT,MIDI_NONE,0);
309
as=play_audio_stream(533,16,0,30000,255,128);
310
/// sf=fopen("sound.pcm","wb");
311
}
312
int decodedelay2=5;
313
void updatesound()
314
{
315
unsigned short *buf;
316
int c,d;
317
uint32 templ;
318
319
buf=0;
320
buf=(unsigned short *)get_audio_stream_buffer(as);
321
if (buf)
322
{
323
decodesamples();
324
for (c=0;c<8;c++)
325
sampf[c]=sampfreq[c]<<4;
326
for (c=0;c<8;c++)
327
{
328
if (adsr[c].ena)
329
{
330
switch (adsrstate[c])
331
{
332
case ATTACK:
333
voicelev[c]+=voicediff[c];
334
realvol[c]=(int)(voicelev[c]*(float)sampvol[c][2]);
335
if (voicelev[c]>=1)
336
{
337
voicelev[c]=1;
338
adsrstate[c]=DECAY;
339
voicediff[c]=drdiffs[adsr[c].dr&7];
340
voicetarg[c]=((float)((adsr[c].sl&7)+1))/8;
341
}
342
break;
343
case DECAY:
344
voicelev[c]-=(voicediff[c]*(1-voicetarg[c]));
345
if (voicelev[c]<=voicetarg[c])
346
{
347
voicelev[c]=1;
348
adsrstate[c]=SUSTAIN;
349
voicediff[c]=srdiffs[adsr[c].sr&31];
350
}
351
realvol[c]=(int)(voicelev[c]*(float)sampvol[c][2]);
352
break;
353
case SUSTAIN:
354
voicelev[c]-=voicediff[c];
355
if (voicelev[c]==0)
356
{
357
adsrstate[c]=0;
358
}
359
realvol[c]=(int)((voicelev[c]*voicetarg[c])*(float)sampvol[c][2]);
360
break;
361
}
362
}
363
else
364
realvol[c]=sampvol[c][2];
365
}
366
for (c=0;c<533;c++)
367
{
368
buf[c]=0;
369
for (d=0;d<8;d++)
370
{
371
if (keyed[d] && samp[sampsamp[d]][sloop[d]])
372
{
373
if (sloop[d]) templ=sampler[sampsamp[d]][(samppos[d]>>16)&32767];
374
else templ=samples[sampsamp[d]][(samppos[d]>>16)&32767];
375
if (templ&0x8000) templ|=0xFFFF0000;
376
templ*=(realvol[d]);//sampvol[d][2];
377
templ>>=8;
378
buf[c]+=(templ&0xFFFF);
379
samppos[d]+=sampf[d];
380
if ((samppos[d]>>16)>=samplen[sampsamp[d]][sloop[d]])
381
{
382
if (samp[sampsamp[d]][1] && samploop[sampsamp[d]])
383
{
384
sloop[d]=1;
385
samppos[d]=0;
386
}
387
else
388
keyed[d]=0;
389
}
390
}
391
}
392
393
}
394
395
for (c=0;c<533;c++) buf[c]^=0x8000;
396
free_audio_stream_buffer(as);
397
for (c=0;c<8;c++) dspregs[(c<<4)|8]=voicelev[c]*256;
398
399
}
400
}
401
#else
402
void updatesound(){}
403
404
#endif
405