5 * Copyright (C) 2002-2005 Monty
7 * Postfish is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * Postfish is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Postfish; see the file COPYING. If not, write to the
19 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
27 static void _analysis(char *base
,int seq
, float *data
, int n
,int dB
,
32 sprintf(buf
,"%s_%d.m",base
,seq
);
39 fprintf(f
,"%d %f\n",(int)(i
+offset
),todB(data
[i
]));
41 fprintf(f
,"%d %f\n",(int)(i
+offset
),(data
[i
]));
50 /* Common follower code */
52 static void prepare_peak(float *peak
, float *x
, int n
, int ahead
,
53 int hold
, peak_state
*ps
){
58 /* Although we have two input_size blocks of zeroes after a
59 reset, we may still need to look ahead explicitly after a
60 reset if the lookahead is exceptionally long */
63 for(ii
=0;ii
<ahead
;ii
++)
64 if((x
[ii
]*x
[ii
])>val
){
70 if(val
>peak
[0])peak
[0]=val
;
73 if((x
[ii
+ahead
]*x
[ii
+ahead
])>val
){
74 val
=(x
[ii
+ahead
]*x
[ii
+ahead
]);
80 for(jj
=ii
+ahead
-1;jj
>=ii
;jj
--){
81 if((x
[jj
]*x
[jj
])>val
)val
=(x
[jj
]*x
[jj
]);
82 if(jj
<n
&& val
>peak
[jj
])peak
[jj
]=val
;
84 val
=(x
[ii
+ahead
]*x
[ii
+ahead
]);
87 if(val
>peak
[ii
])peak
[ii
]=val
;
90 ps
->loc
=loc
-input_size
;
94 static void fill_work(float **A
, float **B
, int ch
, float *work
,
95 int ahead
, int hold
, int mode
, peak_state
*ps
){
101 memset(work
,0,sizeof(*work
)*input_size
);
104 float bigcache
[input_size
*2];
105 memcpy(bigcache
,A
[0],sizeof(*bigcache
)*input_size
);
106 memcpy(bigcache
+input_size
,B
[0],sizeof(*bigcache
)*input_size
);
110 float *bb
= bigcache
+input_size
;
111 for(i
=0;i
<input_size
;i
++)
112 if(bigcache
[i
]*bigcache
[i
]<AA
[i
]*AA
[i
])
114 for(i
=0;i
<input_size
;i
++)
115 if(bb
[i
]*bb
[i
]<BB
[i
]*BB
[i
])
118 prepare_peak(work
, bigcache
, input_size
, ahead
, hold
, ps
);
121 float bigcache
[input_size
];
122 memcpy(bigcache
,A
[0],sizeof(*bigcache
)*input_size
);
125 for(i
=0;i
<input_size
;i
++)
126 if(bigcache
[i
]*bigcache
[i
]<AA
[i
]*AA
[i
])
129 prepare_peak(work
, bigcache
, input_size
, ahead
, hold
, ps
);
131 prepare_peak(work
, A
[0], input_size
, ahead
, hold
, ps
);
136 float *cachea
=A
[0]+ahead
;
140 float *worka
=work
+input_size
-ahead
;
142 for(k
=0;k
<input_size
-ahead
;k
++)
143 work
[k
]=cachea
[k
]*cachea
[k
];
145 worka
[k
]=cacheb
[k
]*cacheb
[k
];
150 for(k
=0;k
<input_size
-ahead
;k
++)
151 work
[k
]+=cachea
[k
]*cachea
[k
];
153 worka
[k
]+=cacheb
[k
]*cacheb
[k
];
157 for(k
=0;k
<input_size
;k
++)
163 for(k
=0;k
<input_size
;k
++)
164 work
[k
]=cachea
[k
]*cachea
[k
];
167 for(k
=0;k
<input_size
;k
++)
168 work
[k
]+=cachea
[k
]*cachea
[k
];
172 for(k
=0;k
<input_size
;k
++)
181 void bi_compand(float **A
,float **B
,
186 float currmultiplier
,
188 int mode
,int softknee
,
189 iir_filter
*attack
, iir_filter
*decay
,
190 iir_state
*iir
, peak_state
*ps
,
194 float work
[input_size
];
195 float kneelevel
=fromdB(corner
*2);
196 int hold
,ahead
=(mode
?step_ahead(attack
->alpha
):impulse_ahead2(attack
->alpha
));
198 if(ahead
>input_size
)ahead
=input_size
;
199 hold
=ahead
*(1.-lookahead
);
202 fill_work(A
,B
,ch
,work
,ahead
,hold
,mode
,ps
);
207 if(!active
|| !adj
)adj
=work
;
210 if(multiplier
!=currmultiplier
){
212 compute_iir_over_soft_del(work
, input_size
, iir
, attack
, decay
,
213 kneelevel
, multiplier
, currmultiplier
, adj
);
215 compute_iir_over_hard_del(work
, input_size
, iir
, attack
, decay
,
216 kneelevel
, multiplier
, currmultiplier
, adj
);
220 compute_iir_over_soft(work
, input_size
, iir
, attack
, decay
,
221 kneelevel
, multiplier
, adj
);
223 compute_iir_over_hard(work
, input_size
, iir
, attack
, decay
,
224 kneelevel
, multiplier
, adj
);
228 if(multiplier
!=currmultiplier
){
230 compute_iir_under_soft_del(work
, input_size
, iir
, attack
, decay
,
231 kneelevel
, multiplier
, currmultiplier
, adj
);
233 compute_iir_under_hard_del(work
, input_size
, iir
, attack
, decay
,
234 kneelevel
, multiplier
, currmultiplier
, adj
);
238 compute_iir_under_soft(work
, input_size
, iir
, attack
, decay
,
239 kneelevel
, multiplier
, adj
);
241 compute_iir_under_hard(work
, input_size
, iir
, attack
, decay
,
242 kneelevel
, multiplier
, adj
);
249 void full_compand(float **A
,float **B
,int ch
,float *adj
,
250 float multiplier
,float currmultiplier
,
252 iir_filter
*attack
, iir_filter
*decay
,
253 iir_state
*iir
, peak_state
*ps
,
257 float work
[input_size
];
258 int ahead
=(mode
?step_ahead(attack
->alpha
):impulse_ahead2(attack
->alpha
));
260 fill_work(A
,B
,ch
,work
,ahead
,0,mode
,ps
);
265 compute_iir_symmetric_limited(work
, input_size
, iir
, attack
, decay
);
268 if(multiplier
!=currmultiplier
){
269 float multiplier_add
=(currmultiplier
-multiplier
)/input_size
;
271 for(k
=0;k
<input_size
;k
++){
272 adj
[k
]-=(todB_a2(work
[k
])+adj
[k
])*multiplier
;
273 multiplier
+=multiplier_add
;
276 for(k
=0;k
<input_size
;k
++)
277 adj
[k
]-=(todB_a2(work
[k
])+adj
[k
])*multiplier
;