5 * Copyright (C) 2002-2005 Monty and Xiph.Org
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.
26 #include <sys/types.h>
28 #include "reconstruct.h"
32 extern int input_rate
;
34 extern int input_size
;
36 /* accessed only in playback thread/setup */
38 static fftwf_plan fftwf_weight
;
43 static int blocksize
=0;
44 static int lopad
=0,hipad
=0;
45 static u_int32_t
*widthlookup
=0;
47 static float *leftwindow
=0;
48 static float *rightwindow
=0;
51 static float width
=.5;
54 static u_int32_t cache_active
;
55 static int cache_samples
;
56 static int fillstate
=0; /* 0: uninitialized
59 static time_linkage out
;
61 /* accessed across threads */
62 sig_atomic_t *declip_active
;
63 int *declip_prev_active
;
65 sig_atomic_t declip_visible
=0;
67 sig_atomic_t *declip_chtrigger
=0;
68 sig_atomic_t declip_pending_blocksize
=0;
69 sig_atomic_t declip_convergence
=0;
70 sig_atomic_t declip_iterations
=0;
73 typedef struct declip_feedback
{
74 feedback_generic parent_class
;
80 static feedback_generic_pool feedpool
;
82 static feedback_generic
*new_declip_feedback(void){
83 declip_feedback
*ret
=malloc(sizeof(*ret
));
84 ret
->clipcount
=malloc((input_ch
)*sizeof(*ret
->clipcount
));
85 ret
->peak
=malloc((input_ch
)*sizeof(*ret
->peak
));
86 ret
->total
=malloc((input_ch
)*sizeof(*ret
->total
));
87 return (feedback_generic
*)ret
;
90 static void push_declip_feedback(int *clip
,float *peak
,int *total
){
92 declip_feedback
*f
=(declip_feedback
*)
93 feedback_new(&feedpool
,new_declip_feedback
);
94 memcpy(f
->clipcount
,clip
,n
*sizeof(*clip
));
95 memcpy(f
->peak
,peak
,n
*sizeof(*peak
));
96 memcpy(f
->total
,total
,n
*sizeof(*total
));
97 feedback_push(&feedpool
,(feedback_generic
*)f
);
100 int pull_declip_feedback(int *clip
,float *peak
,int *total
){
101 declip_feedback
*f
=(declip_feedback
*)feedback_pull(&feedpool
);
105 if(clip
)memcpy(clip
,f
->clipcount
,sizeof(*clip
)*input_ch
);
106 if(peak
)memcpy(peak
,f
->peak
,sizeof(*peak
)*input_ch
);
107 if(total
)memcpy(total
,f
->total
,sizeof(*total
)*input_ch
);
109 feedback_old(&feedpool
,(feedback_generic
*)f
);
113 static void apply_window(float *out
,float *data
,int sq
){
115 int half
=max(left
,right
);
117 for(i
=0;i
<half
-left
;i
++)
121 for(j
=0;i
<half
;i
++,j
++)
122 out
[i
]=data
[i
]*leftwindow
[j
]*leftwindow
[j
];
123 for(j
=0;j
<right
;i
++,j
++)
124 out
[i
]=data
[i
]*rightwindow
[right
-j
]*rightwindow
[right
-j
];
126 for(j
=0;i
<half
;i
++,j
++)
127 out
[i
]=data
[i
]*leftwindow
[j
];
128 for(j
=0;j
<right
;i
++,j
++)
129 out
[i
]=data
[i
]*rightwindow
[right
-j
];
136 static void setup_window(int lleft
,int lright
){
140 leftwindow
=window_get(2,left
);
141 rightwindow
=window_get(2,right
);
144 static void setup_blocksize(int newblocksize
){
147 if(blocksize
)fftwf_destroy_plan(fftwf_weight
);
148 blocksize
=newblocksize
;
149 fftwf_weight
=fftwf_plan_dft_r2c_1d(blocksize
*2,work
,
150 (fftwf_complex
*)freq
,
153 lopad
=1-rint(fromBark(toBark(0.)-width
)*blocksize
*2/input_rate
);
154 hipad
=rint(fromBark(toBark(input_rate
*.5)+width
)*blocksize
*2/input_rate
)+lopad
;
155 for(i
=0;i
<blocksize
;i
++){
156 float bark
=toBark(input_rate
*i
/(blocksize
*2));
157 int hi
=rint(fromBark(bark
-width
)*(blocksize
*2)/input_rate
)-1+lopad
;
158 int lo
=rint(fromBark(bark
+width
)*(blocksize
*2)/input_rate
)+1+lopad
;
159 widthlookup
[i
]=(hi
<<16)+lo
;
162 reconstruct_reinit(blocksize
*2);
165 /* called only by initial setup */
166 int declip_load(void){
168 declip_active
=calloc(input_ch
,sizeof(*declip_active
));
169 declip_prev_active
=calloc(input_ch
,sizeof(*declip_prev_active
));
170 declip_chtrigger
=malloc(input_ch
*sizeof(*declip_chtrigger
));
171 for(i
=0;i
<input_ch
;i
++)
172 declip_chtrigger
[i
]=10000;
174 out
.channels
=input_ch
;
175 out
.data
=malloc(input_ch
*sizeof(*out
.data
));
176 for(i
=0;i
<input_ch
;i
++)
177 out
.data
[i
]=malloc(input_size
*sizeof(**out
.data
));
180 cache
=malloc(input_ch
*sizeof(*cache
));
181 for(i
=0;i
<input_ch
;i
++)
182 cache
[i
]=malloc(input_size
*sizeof(**cache
));
184 lap
=malloc(input_ch
*sizeof(*lap
));
185 for(i
=0;i
<input_ch
;i
++)
186 lap
[i
]=malloc(input_size
*sizeof(**lap
));
189 /* alloc for largest possible blocksize */
190 int blocksize
=input_size
*2;
191 int loestpad
=1-rint(fromBark(toBark(0.)-width
)*blocksize
*2/input_rate
);
192 int hiestpad
=rint(fromBark(toBark(input_rate
*.5)+width
)*blocksize
*2/input_rate
)+loestpad
;
193 widthlookup
=malloc((hiestpad
+1)*sizeof(*widthlookup
));
194 freq
=fftwf_malloc((blocksize
*2+2)*sizeof(*freq
));
195 work
=fftwf_malloc((blocksize
*2)*sizeof(*work
));
197 for(i
=0,j
=32;j
<=blocksize
*2;i
++,j
*=2){
198 fftwf_weight
=fftwf_plan_dft_r2c_1d(j
,work
,
199 (fftwf_complex
*)freq
,
201 fftwf_destroy_plan(fftwf_weight
);
204 reconstruct_init(32,input_size
*4);
206 declip_pending_blocksize
=input_size
*2;
210 /* called only in playback thread */
211 int declip_reset(void){
212 /* reset cached pipe state */
214 while(pull_declip_feedback(NULL
,NULL
,NULL
));
219 static void sliding_bark_average(float *f
,int n
,float width
){
221 double acc
=0.,del
=0.;
224 memset(sec
,0,sizeof(sec
));
228 int hi
=widthlookup
[i
]>>16;
229 int lo
=widthlookup
[i
]&(0xffff);
230 float del
=hypot(f
[(i
<<1)+1],f
[i
<<1])/(lo
-hi
);
232 float hidel
=del
/((i
-hi
+lopad
));
233 float lodel
=del
/((lo
-i
-lopad
));
242 for(i
=0;i
<lopad
;i
++){
248 f
[(i
<<1)+1]=f
[i
<<1]=1./(acc
*acc
);
255 /* work,freq are passed through the static buffer fftwf requires */
256 static void declip(int blocksize
,float trigger
,
257 float epsilon
, float iteration
,
258 int *runningtotal
, int *runningcount
){
259 float flag
[blocksize
*2];
260 int iterbound
,i
,count
=0;
262 /* too many apps screw up proper output scaling, so previously
263 clipped audio ends up getting rounded to just short of the rail
264 upon export. To avoid users accidentally shooting themselves in
265 the foot, trigger clipping at -.05dB rather than 0dB even if 0dB
266 is selected. This corresponds to mis-rounding 8 bit audio by 1.5
268 if(trigger
>.99426)trigger
=.99426;
270 for(i
=blocksize
/2;i
<blocksize
*3/2;i
++){
272 if(work
[i
]>=trigger
|| work
[i
]<=-trigger
){
279 *runningtotal
+=blocksize
;
280 *runningcount
+=count
;
283 for(i
=0;i
<blocksize
/2;i
++)flag
[i
]=0.;
284 for(i
=blocksize
*3/2;i
<blocksize
*2;i
++)flag
[i
]=0.;
285 apply_window(work
+blocksize
/2,work
+blocksize
/2,0);
287 fftwf_execute(fftwf_weight
);
288 sliding_bark_average(freq
,blocksize
*2,width
);
289 iterbound
=blocksize
*iteration
;
290 if(iterbound
<10)iterbound
=10;
292 reconstruct(work
,freq
,flag
,epsilon
,iterbound
);
294 apply_window(work
+blocksize
/2,work
+blocksize
/2,0);
296 apply_window(work
+blocksize
/2,work
+blocksize
/2,1);
300 /* called only by playback thread */
301 time_linkage
*declip_read(time_linkage
*in
){
303 float local_trigger
[input_ch
];
306 float peak
[input_ch
];
308 int next_blocksize
=declip_pending_blocksize
;
311 float local_convergence
;
312 float local_iterations
;
314 for(i
=0;i
<input_ch
;i
++)
315 local_trigger
[i
]=declip_chtrigger
[i
]*.0001;
316 local_iterations
=declip_iterations
*.0001;
317 local_convergence
=fromdB(declip_convergence
*.1);
319 memset(count
,0,sizeof(count
));
320 memset(peak
,0,sizeof(peak
));
321 memset(total
,0,sizeof(total
));
324 case 0: /* prime the lapping and cache */
326 /* set up for the blocksize we're actually using for now */
328 setup_blocksize(next_blocksize
);
329 setup_window(blocksize
/2,blocksize
/2);
332 for(i
=0;i
<input_ch
;i
++){
333 int channel_active
=declip_active
[i
];
334 declip_prev_active
[i
]=channel_active
;
337 if(declip_visible
&& !mute_channel_muted(in
->active
,i
)){
338 float *l
=in
->data
[i
];
339 for(j
=0;j
<in
->samples
;j
++)
340 if(fabs(l
[j
])>peak
[i
])peak
[i
]=fabs(l
[j
]);
345 /* fill work with the block spanning cache/in (first 1/4, last 1/4 are zeroed) */
346 memset(work
,0,sizeof(*work
)*blocksize
);
347 memcpy(work
+blocksize
,in
->data
[i
],sizeof(*work
)*blocksize
/2);
348 memset(work
+blocksize
+blocksize
/2,0,sizeof(*work
)*blocksize
/2);
349 declip(blocksize
,local_trigger
[i
],local_convergence
,local_iterations
,
352 /* second half of work goes to lap */
353 memcpy(lap
[i
],work
+blocksize
,sizeof(*work
)*blocksize
/2);
355 /* now iterate the pieces purely within in */
356 for(j
=0;j
+blocksize
<=input_size
;j
+=blocksize
/2){
357 memset(work
,0,sizeof(*work
)*blocksize
);
358 memcpy(work
+blocksize
/2,in
->data
[i
]+j
,sizeof(*work
)*blocksize
);
359 memset(work
+blocksize
+blocksize
/2,0,sizeof(*work
)*blocksize
/2);
361 declip(blocksize
,local_trigger
[i
],local_convergence
,local_iterations
,
364 /* second half of work goes to lap */
366 float *llap
=lap
[i
]+j
;
367 float *lwork
=work
+blocksize
/2;
368 for(k
=0;k
<blocksize
/2;k
++)
370 memcpy(llap
+k
,lwork
+k
,sizeof(*work
)*blocksize
/2);
374 }//else no declipping to do, so direct cache/lap buffer rotation */
377 float *temp
=cache
[i
];
378 cache
[i
]=in
->data
[i
];
380 memset(temp
,0,sizeof(*temp
)*input_size
);
383 cache_samples
=in
->samples
;
384 cache_active
=in
->active
;
387 if(in
->samples
==input_size
)break;
389 for(i
=0;i
<input_ch
;i
++)
390 memset(in
->data
[i
],0,sizeof(**in
->data
)*input_size
);
394 case 1: /* nominal processing */
395 orig_blocksize
=blocksize
;
397 /* the 'gap' transition and finishing off the output block is done
398 first as it may need to handle a blocksize transition (and a
399 temporary transition window */
401 if(next_blocksize
!= orig_blocksize
){
402 if(next_blocksize
> orig_blocksize
) setup_blocksize(next_blocksize
);
403 setup_window(orig_blocksize
/2,next_blocksize
/2);
406 /* the gap piece is also special in that it may need to deal with
407 a transition to/from bypass */
409 for(i
=0;i
<input_ch
;i
++){
410 int channel_active
=declip_active
[i
];
413 if(declip_visible
&& !mute_channel_muted(in
->active
,i
)){
414 float *l
=in
->data
[i
];
415 for(j
=0;j
<in
->samples
;j
++)
416 if(fabs(l
[j
])>peak
[i
])peak
[i
]=fabs(l
[j
]);
420 if(mute_channel_muted(cache_active
,i
)){
422 /* we may need cache for a later transition, so keep it up to date */
423 float *temp
=cache
[i
];
424 cache
[i
]=in
->data
[i
];
428 if(!mute_channel_muted(in
->active
,i
))
429 memset(lap
[i
],0,sizeof(*lap
[i
])*input_size
);
433 active
|=(1<<i
); /* audible output in out.data[i] */
435 if(mute_channel_muted(in
->active
,i
)){
436 if(declip_prev_active
[i
]){
437 /* Cache: Muted=False, Bypass=False
438 Input: Muted=True, Bypass=X */
440 /* transition to mute, so lap is finished output. Rotate all */
441 float *temp
=cache
[i
];
442 cache
[i
]=in
->data
[i
];
449 /* Cache: Muted=False, Bypass=True
450 Input: Muted=True, Bypass=X */
452 /* rotate in/cache/out, transition out */
453 float *temp
=out
.data
[i
];
454 out
.data
[i
]=cache
[i
];
455 cache
[i
]=in
->data
[i
];
460 if(!declip_prev_active
[i
]){
462 /* Cache: Muted=False, Bypass=True
463 Input: Muted=False, Bypass=True */
465 /* all bypass! rotate in/cache/out */
466 float *temp
=out
.data
[i
];
467 out
.data
[i
]=cache
[i
];
468 cache
[i
]=in
->data
[i
];
471 /* Cache: Muted=False, Bypass=True
472 Input: Muted=False, Bypass=False */
474 /* transition the lap; right window to left of in */
476 lap
[i
][j
]=in
->data
[i
][j
]*
477 rightwindow
[right
-j
]*rightwindow
[right
-j
];
479 /* all rotate in/cache/out */
480 float *temp
=out
.data
[i
];
481 out
.data
[i
]=cache
[i
];
482 cache
[i
]=in
->data
[i
];
487 /* Cache: Muted=False, Bypass=False
488 Input: Muted=False, Bypass=True */
490 /* finish off lap, then rotate all */
491 /* left window to end of cache */
492 for(j
=input_size
-left
,k
=0;j
<input_size
;j
++,k
++)
493 lap
[i
][j
]+=cache
[i
][j
]*leftwindow
[k
]*leftwindow
[k
];
494 float *temp
=cache
[i
];
495 cache
[i
]=in
->data
[i
];
502 /* Cache: Muted=False, Bypass=False
503 Input: Muted=False, Bypass=False */
505 /* nominal case; the only one involving declipping the gap */
506 memset(work
,0,sizeof(*work
)*blocksize
/2);
507 memcpy(work
+blocksize
/2,cache
[i
]+input_size
-blocksize
/2,sizeof(*work
)*blocksize
/2);
508 memcpy(work
+blocksize
,in
->data
[i
],sizeof(*work
)*blocksize
/2);
509 memset(work
+blocksize
+blocksize
/2,0,sizeof(*work
)*blocksize
/2);
511 declip(blocksize
,local_trigger
[i
],local_convergence
,local_iterations
,
514 /* finish lap from last frame */
516 float *llap
=lap
[i
]+input_size
-blocksize
/2;
517 float *lwork
=work
+blocksize
/2;
518 for(j
=0;j
<blocksize
/2;j
++)
522 float *temp
=out
.data
[i
];
527 in
->data
[i
]=cache
[i
];
530 /* begin lap for this frame */
531 memcpy(lap
[i
],work
+blocksize
,sizeof(*work
)*blocksize
/2);
537 declip_prev_active
[i
]=channel_active
;
540 /* also rotate metadata */
541 out
.samples
=cache_samples
;
542 cache_samples
=in
->samples
;
543 cache_active
=in
->active
;
545 /* finish transition to new blocksize (if a change is in progress) */
546 if(next_blocksize
!= orig_blocksize
){
547 if(next_blocksize
<= orig_blocksize
) setup_blocksize(next_blocksize
);
548 setup_window(blocksize
/2,blocksize
/2);
551 /* declip the rest of the current frame */
552 for(i
=0;i
<input_ch
;i
++){
553 if(!mute_channel_muted(cache_active
,i
)){
555 if(declip_prev_active
[i
]){
557 for(j
=0;j
+blocksize
<=input_size
;j
+=blocksize
/2){
558 memset(work
,0,sizeof(*work
)*blocksize
);
559 memcpy(work
+blocksize
/2,cache
[i
]+j
,sizeof(*work
)*blocksize
);
560 memset(work
+blocksize
+blocksize
/2,0,sizeof(*work
)*blocksize
/2);
561 declip(blocksize
,local_trigger
[i
],local_convergence
,local_iterations
,
565 float *llap
=lap
[i
]+j
;
566 float *lwork
=work
+blocksize
/2;
567 for(k
=0;k
<blocksize
/2;k
++)
569 memcpy(llap
+k
,lwork
+k
,sizeof(*work
)*blocksize
/2);
575 if(out
.samples
<input_size
)fillstate
=2;
577 case 2: /* we've pushed out EOF already */
581 push_declip_feedback(count
,peak
,total
); /* we can push one (and
582 exactly one) for every
583 block that comes in *or*
584 one for every block that
586 it's for every block that
590 int tozero
=input_size
-out
.samples
;
592 for(i
=0;i
<out
.channels
;i
++)
593 memset(out
.data
[i
]+out
.samples
,0,sizeof(**out
.data
)*tozero
);