-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDPCM.js
More file actions
82 lines (74 loc) · 2.29 KB
/
Copy pathDPCM.js
File metadata and controls
82 lines (74 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
desc: NES APU DPCM Filter (12khz)
//Please use 44khz internal samplerate for this!
//This uses an internal samplerate reduction to match the 12000HZ that the NES uses!
slider1:24<1,32,1>DC Removal rate
slider2:0.01<0.01,1,0.01>Scrollspeed
slider3:0<0,1,1{False,True}>Freeze
@slider
S1=slider1;
S2=slider2;
Freeze=slider3;
@init
function downsample()(
BUF[50000+mb_index]=spl0;
mb_index+=1;
mb_index>3?(mb_index=0;Tick=1-Tick;doSampleProcessing=1):doSampleProcessing=0;
BUF[50000]
);
gfx_clear=0;
INPUT=0;
OUTPUT=0;
DCOFFSET=0;
function DPCMsign(target,current)(
target<current?0:1;
);
function doDPCM(get,value)(
//get last sample if possible
(lasts==value)?dither=1:dither=0;
//recursive,will output set, should use it as next get at all times.
//clamps at minmax of 0000000-FFFFFFF
min=0;
max=127;
dither&&isSilent?ADD=Tick-(Tick==0);
get?(value>max?max:value+max(ADD,1);):(value>min?min:value-max(ADD,1););
);
function APU_HandleAudio(Input)(
// Input = 0-127 (0000000-FFFFFFF)
// => -1=>1 Signed output
((Input/64)-1);
);
function APU_DCRemove(Recursive,rate)(
//recursive DC Removal
//decaying "rate" per second;
R=(rate/srate)*3;
// has to feed back into itself.
DCOFFSET=(DCOFFSET*(1-R))+R*Recursive;
Recursive;
);
gfx_clear=-1;
@sample
isSilent=(abs(spl0)<1/4294967291);
// ensure that we have no 32bit noise that can trigger this
spl0=max(-1,min(1,spl0));
INPUT=downsample();
doSampleProcessing?(
SGN=DPCMsign(-64+(INPUT)*64,OUTPUT); //get sample
OUTPUT=APU_DCRemove(doDPCM(SGN,OUTPUT),S1); // recursive step approaching
lasts=OUTPUT;// used for dithering when required
spl0=APU_HandleAudio(OUTPUT-(DCOFFSET*2))*(isSilent==0); // output current step
spl1=spl0; //make mono
):(spl0=APU_HandleAudio(OUTPUT-(DCOFFSET*2))*(isSilent==0);spl1=spl0);
((INDEX<gfx_W)+(1-Freeze))?(
INDEX=(INDEX+S2)*(INDEX<gfx_w);
BUF[INDEX%gfx_w]=spl0; // for gfx display
);
@gfx
gfx_clear=1;
loop(gfx_w,
gfx_mode=0;
gfx_r=1;gfx_g=1;gfx_b=1;
gfx_x>=gfx_w?(gfx_clear=0;gfx_x=0):(gfx_x=gfx_x+1;gfx_clear=-1);
gfx_y=256-256*BUF[gfx_x];
BUF[gfx_x]-BUF[gfx_x-2]<0?(gfx_r=0;gfx_g=128/255;gfx_b=255/255;):(gfx_r=255/255;gfx_g=0/255;gfx_b=128/255;);
gfx_line(gfx_x,256,gfx_x+1,256-256*BUF[gfx_x]);
gfx_clear=0;)