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.
30 extern int input_size
;
31 extern int input_rate
;
33 /* called only by initial setup */
34 int subband_load(subband_state
*f
,int bands
,int qblocksize
,int ch
){
36 memset(f
,0,sizeof(*f
));
38 f
->qblocksize
=qblocksize
;
42 f
->lap
=malloc(bands
*sizeof(*f
->lap
));
43 f
->cache0
=malloc(ch
*sizeof(*f
->cache0
));
44 f
->cache1
=malloc(ch
*sizeof(*f
->cache1
));
46 f
->lap_activeP
=malloc(ch
*sizeof(*f
->lap_activeP
));
47 f
->lap_active1
=malloc(ch
*sizeof(*f
->lap_active1
));
48 f
->lap_active0
=malloc(ch
*sizeof(*f
->lap_active0
));
49 f
->lap_activeC
=malloc(ch
*sizeof(*f
->lap_activeC
));
51 f
->visible1
=malloc(ch
*sizeof(*f
->visible1
));
52 f
->visible0
=malloc(ch
*sizeof(*f
->visible0
));
53 f
->visibleC
=malloc(ch
*sizeof(*f
->visibleC
));
55 f
->effect_activeP
=malloc(ch
*sizeof(*f
->effect_activeP
));
56 f
->effect_active1
=malloc(ch
*sizeof(*f
->effect_active1
));
57 f
->effect_active0
=malloc(ch
*sizeof(*f
->effect_active0
));
58 f
->effect_activeC
=malloc(ch
*sizeof(*f
->effect_activeC
));
60 f
->wP
=calloc(ch
,sizeof(*f
->wP
));
61 f
->w1
=calloc(ch
,sizeof(*f
->w1
));
62 f
->w0
=calloc(ch
,sizeof(*f
->w0
));
63 f
->wC
=calloc(ch
,sizeof(*f
->wC
));
66 f
->cache0
[i
]=malloc(input_size
*sizeof(**f
->cache0
));
68 f
->cache1
[i
]=malloc(input_size
*sizeof(**f
->cache1
));
71 f
->lap
[i
]=malloc(ch
*sizeof(**f
->lap
));
73 f
->lap
[i
][j
]=malloc(input_size
*3*sizeof(***f
->lap
));
77 f
->out
.data
=malloc(ch
*sizeof(*f
->out
.data
));
79 f
->out
.data
[i
]=malloc(input_size
*sizeof(**f
->out
.data
));
81 f
->window
=window_get(1,f
->qblocksize
);
83 f
->fftwf_forward_out
= fftwf_malloc(sizeof(*f
->fftwf_forward_out
) *
85 f
->fftwf_backward_in
= fftwf_malloc(sizeof(*f
->fftwf_backward_in
) *
87 f
->fftwf_forward_in
= fftwf_malloc(sizeof(*f
->fftwf_forward_in
) *
89 f
->fftwf_backward_out
= fftwf_malloc(sizeof(*f
->fftwf_backward_out
) *
92 f
->fftwf_forward
=fftwf_plan_dft_r2c_1d(f
->qblocksize
*4,
94 (fftwf_complex
*)f
->fftwf_forward_out
,
96 f
->fftwf_backward
=fftwf_plan_dft_c2r_1d(f
->qblocksize
*4,
97 (fftwf_complex
*)f
->fftwf_backward_in
,
98 f
->fftwf_backward_out
,
104 /* called only by initial setup */
105 int subband_load_freqs(subband_state
*f
,subband_window
*w
,
106 const float *freq_list
,int bands
){
109 memset(w
,0,sizeof(*w
));
113 /* unlike old postfish, we offer all frequencies via smoothly
114 supersampling the spectrum */
115 /* I'm too lazy to figure out the integral symbolically, use this
116 fancy CPU thingy for something */
118 w
->ho_window
=malloc(bands
*sizeof(*w
->ho_window
));
120 w
->ho_window
[i
]=calloc((f
->qblocksize
*2+1),sizeof(**w
->ho_window
));
122 /* first, build the first-pass desired, supersampled response */
123 for(j
=0;j
<(((f
->qblocksize
*2+1)/10)<<5);j
++){
124 float localf
= .5*j
*input_rate
/(f
->qblocksize
<<6);
127 for(i
=0;i
<bands
;i
++){
128 float lastf
=(i
>0?freq_list
[i
-1]:0);
129 float thisf
=freq_list
[i
];
130 float nextf
=freq_list
[i
+1];
132 if(localf
>=lastf
&& localf
<nextf
){
135 if(i
!=0)localwin
= sin((localf
-lastf
)/(thisf
-lastf
)*M_PIl
*.5);
137 if(i
+1!=bands
)localwin
= sin((nextf
-localf
)/(nextf
-thisf
)*M_PIl
*.5);
141 w
->ho_window
[i
][localbin
]+=localwin
*(1./32);
146 for(;j
<f
->qblocksize
*2+1;j
++){
147 float localf
= .5*j
*input_rate
/(f
->qblocksize
<<1);
149 for(i
=0;i
<bands
;i
++){
150 float lastf
=(i
>0?freq_list
[i
-1]:0);
151 float thisf
=freq_list
[i
];
152 float nextf
=freq_list
[i
+1];
154 if(localf
>=lastf
&& localf
<nextf
){
157 if(i
!=0)localwin
= sin((localf
-lastf
)/(thisf
-lastf
)*M_PIl
*.5);
159 if(i
+1!=bands
)localwin
= sin((nextf
-localf
)/(nextf
-thisf
)*M_PIl
*.5);
162 w
->ho_window
[i
][j
]+=localwin
*localwin
;
167 for(i
=0;i
<bands
;i
++){
168 /* window each desired response in the time domain so that our
169 convolution is properly padded against being circular */
170 memset(f
->fftwf_backward_in
,0,sizeof(*f
->fftwf_backward_in
)*
171 (f
->qblocksize
*4+2));
172 for(j
=0;j
<f
->qblocksize
*2+1;j
++)
173 f
->fftwf_backward_in
[j
*2]=w
->ho_window
[i
][j
];
175 fftwf_execute(f
->fftwf_backward
);
177 /* window response in time */
178 memcpy(f
->fftwf_forward_in
,f
->fftwf_backward_out
,
179 f
->qblocksize
*4*sizeof(*f
->fftwf_forward_in
));
180 for(j
=0;j
<f
->qblocksize
;j
++){
181 float val
=cos(j
*M_PI
/(f
->qblocksize
*2));
182 val
=sin(val
*val
*M_PIl
*.5);
183 f
->fftwf_forward_in
[j
]*= sin(val
*val
*M_PIl
*.5);
186 for(;j
<f
->qblocksize
*3;j
++)
187 f
->fftwf_forward_in
[j
]=0.;
189 for(;j
<f
->qblocksize
*4;j
++){
190 float val
=sin((j
-f
->qblocksize
*3)*M_PI
/(f
->qblocksize
*2));
191 val
=sin(val
*val
*M_PIl
*.5);
192 f
->fftwf_forward_in
[j
]*=sin(val
*val
*M_PIl
*.5);
195 /* back to frequency; this is all-real data still */
196 fftwf_execute(f
->fftwf_forward
);
197 for(j
=0;j
<f
->qblocksize
*4+2;j
++)
198 f
->fftwf_forward_out
[j
]/=f
->qblocksize
*4;
200 /* now take what we learned and distill it a bit */
201 for(j
=0;j
<f
->qblocksize
*2+1;j
++)
202 w
->ho_window
[i
][j
]=f
->fftwf_forward_out
[j
*2];
209 /* called only in playback thread */
210 int subband_reset(subband_state
*f
){
211 /* reset cached pipe state */
216 /* Brute force: subband the time data input by doing the equivalent of
217 linear time-convolution using the response filters created earlier
218 and padded FFTs with 75% overlap. */
220 static void subband_work(subband_state
*f
,
227 int i
,j
,k
,l
,off
,ch
=f
->out
.channels
;
228 float *workoff
=f
->fftwf_forward_in
+f
->qblocksize
;
229 u_int32_t mutemask
=in
->active
;
231 f
->mutemaskC
=mutemask
;
237 (visible
[i
]||active
[i
]) && !mute_channel_muted(mutemask
,i
);
238 int content_p0
= f
->lap_active0
[i
];
239 int content_p1
= f
->lap_active1
[i
];
241 int maxbands
=w
[i
]->freq_bands
;
242 if(maxbands
<f
->w0
[i
]->freq_bands
)maxbands
=f
->w0
[i
]->freq_bands
;
243 if(maxbands
<f
->w1
[i
]->freq_bands
)maxbands
=f
->w1
[i
]->freq_bands
;
246 f
->effect_activeC
[i
] = active
[i
] && !mute_channel_muted(mutemask
,i
);
247 f
->visibleC
[i
] = visible
[i
];
249 if(!content_p1
&& !content_p0
&& !content_p
){
250 /* all disabled, lap is already zeroed. Nothing to do */
253 }else if(!content_p0
&& content_p
){
254 /* from inactive to active; first block to be processed must be
255 entirely within new data so prepare the lap */
257 for(k
=0;k
<maxbands
;k
++)
258 memset(f
->lap
[k
][i
]+input_size
*2,0,f
->qblocksize
*3*sizeof(***f
->lap
));
260 }else if (content_p0
&& !content_p
){
261 /* from active to inactive; the previous lap is done, just zero out this frame */
262 for(k
=0;k
<maxbands
;k
++)
263 memset(f
->lap
[k
][i
]+input_size
*2,0,input_size
*sizeof(*f
->lap
[k
][i
]));
266 if(content_p
){ /* there is something to do */
268 if(content_p0
){ /* was lap active last block? */
269 j
=0; /* yes; span the gap */
272 j
=3; /* no; start entirely within new data */
276 for(;j
<(input_size
/f
->qblocksize
);j
++){
280 memcpy(workoff
,f
->cache0
[i
]+input_size
-f
->qblocksize
*2,
281 sizeof(*workoff
)*f
->qblocksize
*2);
284 memcpy(workoff
,f
->cache0
[i
]+input_size
-f
->qblocksize
,
285 sizeof(*workoff
)*f
->qblocksize
);
286 memcpy(workoff
+f
->qblocksize
,in
->data
[i
],
287 sizeof(*workoff
)*f
->qblocksize
);
290 memcpy(workoff
,in
->data
[i
]+off
,
291 sizeof(*workoff
)*f
->qblocksize
*2);
296 /* window; assume the edges are already zeroed */
297 window_apply(workoff
,f
->window
,.25/f
->qblocksize
,f
->qblocksize
);
299 fftwf_execute(f
->fftwf_forward
);
301 /* repeatedly filter and transform back */
302 for(k
=0;k
<w
[i
]->freq_bands
;k
++){
303 float *lapcb
=f
->lap
[k
][i
]+input_size
*2+(j
-3)*f
->qblocksize
;
304 float *hw
=w
[i
]->ho_window
[k
];
306 for(l
=0;l
<f
->qblocksize
*2+1;l
++){
307 f
->fftwf_backward_in
[2*l
]=
308 f
->fftwf_forward_out
[2*l
]*hw
[l
];
309 f
->fftwf_backward_in
[2*l
+1]=
310 f
->fftwf_forward_out
[2*l
+1]*hw
[l
];
313 fftwf_execute(f
->fftwf_backward
);
315 /* lap back into the subband; the convolution is already
316 balanced so no further windowing needed */
317 for(l
=0;l
<f
->qblocksize
*3;l
++)
318 lapcb
[l
]+=f
->fftwf_backward_out
[l
];
319 for(;l
<f
->qblocksize
*4;l
++)
320 lapcb
[l
]=f
->fftwf_backward_out
[l
];
324 /* if we're suddenly processing fewer bands than we were, we
325 have to trail out zeroes until the band lap is emptied */
326 for(k
=w
[i
]->freq_bands
;k
<maxbands
;k
++)
327 memset(f
->lap
[k
][i
]+input_size
*2,0,sizeof(*f
->lap
[k
][i
])*input_size
);
333 static void unsubband_work(subband_state
*f
,time_linkage
*in
,
336 int i
,j
,k
,ch
=f
->out
.channels
;
338 f
->lap_samples
+=in
->samples
;
341 int content_pP
= f
->lap_activeP
[i
];
342 int content_p1
= f
->lap_active1
[i
];
343 int content_p0
= f
->lap_active0
[i
];
344 int content_pC
= f
->lap_activeC
[i
];
346 int active_pP
= f
->effect_activeP
[i
];
347 int active_p1
= f
->effect_active1
[i
];
348 int active_p0
= f
->effect_active0
[i
];
350 int muted_pP
= mute_channel_muted(f
->mutemaskP
,i
);
351 int muted_p1
= mute_channel_muted(f
->mutemask1
,i
);
352 int muted_p0
= mute_channel_muted(f
->mutemask0
,i
);
354 int maxbands
=f
->wC
[i
]->freq_bands
;
355 if(maxbands
<f
->w0
[i
]->freq_bands
)maxbands
=f
->w0
[i
]->freq_bands
;
356 if(maxbands
<f
->w1
[i
]->freq_bands
)maxbands
=f
->w1
[i
]->freq_bands
;
358 /* even if the lapping for a channel is active, we will draw
359 output from the cache if the effect is inactive; it saves
360 performing the summation across bands */
364 if muted, lap is inactive
365 if visible or active (and not muted) lap is active
366 if inactive and invisible, lap is inactive
369 1. (I) (I) A : muted; do nothing, the mask will take care of it
370 2. X I I : full bypass, audible data; rotate the cache into output
371 3. I A I : not possible
374 we transition from effect active/inactive/active:
376 a) transitions always happen in the shared active portion
377 b) sum frame from active lap
378 c) window beginning/end of resulting summation if necessary
379 d) window/add beginning/end of final frame from cache data if necessary
384 if(muted_p1
|| !active_p1
){
385 /* case 1,2; they're similar enough */
387 float *temp
=f
->cache1
[i
];
388 f
->cache1
[i
]=out
->data
[i
];
390 /* mutemask will be propogated later */
396 float *o
=out
->data
[i
];
397 memcpy(o
,f
->lap
[0][i
],input_size
*sizeof(*out
->data
[i
]));
398 for(j
=1;j
<maxbands
;j
++){
399 float *x
=f
->lap
[j
][i
];
400 for(k
=0;k
<input_size
;k
++)
404 /* c) window beginning/end of summation if needed */
405 if(!active_pP
&& content_pP
){
407 /* transitioning to active effect, but the lap was already
408 previously active; window the transition */
409 float *lo
=o
+f
->qblocksize
;
410 memset(o
,0,sizeof(*o
)*f
->qblocksize
);
411 for(j
=0;j
<f
->qblocksize
;j
++)
414 }else if (!active_p0
&& content_p0
){
416 /* transitioning from active effect, but the lap will continue
417 to be active; window the transition */
418 float *lo
=o
+input_size
-f
->qblocksize
*2;
419 memset(o
+input_size
-f
->qblocksize
,0,sizeof(*o
)*f
->qblocksize
);
420 for(j
=0;j
<f
->qblocksize
;j
++)
421 lo
[j
]*=f
->window
[f
->qblocksize
-j
];
423 } /* else any transitions we need are already windowed as
424 above by the lap handling code in subband_work */
426 /* d) window/add cache bits if needed */
427 if(!active_pP
&& !muted_pP
){
428 /* beginning transition */
429 float *lo
=o
+f
->qblocksize
;
430 float *lc
=f
->cache1
[i
]+f
->qblocksize
;
432 memcpy(o
,f
->cache1
[i
],sizeof(*o
)*f
->qblocksize
);
433 for(j
=0;j
<f
->qblocksize
;j
++)
434 lo
[j
]+=lc
[j
]*f
->window
[f
->qblocksize
-j
];
436 }else if (!active_p0
&& !muted_p0
){
438 float *lo
=o
+input_size
-f
->qblocksize
*2;
439 float *lc
=f
->cache1
[i
]+input_size
-f
->qblocksize
*2;
441 memcpy(o
+input_size
-f
->qblocksize
,
442 f
->cache1
[i
]+input_size
-f
->qblocksize
,
443 sizeof(*o
)*f
->qblocksize
);
444 for(j
=0;j
<f
->qblocksize
;j
++)
445 lo
[j
]+=lc
[j
]*f
->window
[j
];
451 /* out is done for this channel */
453 if(content_p1
|| content_p0
|| content_pC
){
454 for(j
=0;j
<maxbands
;j
++)
455 memmove(f
->lap
[j
][i
],f
->lap
[j
][i
]+input_size
,
456 sizeof(***f
->lap
)*input_size
*2);
458 f
->lap_activeP
[i
]=f
->lap_active1
[i
];
459 f
->lap_active1
[i
]=f
->lap_active0
[i
];
460 f
->lap_active0
[i
]=f
->lap_activeC
[i
];
462 /* rotate cache data vectors */
464 float *temp
=f
->cache1
[i
];
465 f
->cache1
[i
]=f
->cache0
[i
];
466 f
->cache0
[i
]=in
->data
[i
];
471 out
->active
=f
->mutemask1
;
472 f
->out
.samples
=(f
->lap_samples
>input_size
?input_size
:f
->lap_samples
);
475 /* rotate full-frame data for next frame */
477 memcpy(f
->effect_activeP
,f
->effect_active1
,ch
*sizeof(*f
->effect_active1
));
478 memcpy(f
->effect_active1
,f
->effect_active0
,ch
*sizeof(*f
->effect_active0
));
479 memcpy(f
->effect_active0
,f
->effect_activeC
,ch
*sizeof(*f
->effect_activeC
));
481 memcpy(f
->visible1
,f
->visible0
,ch
*sizeof(*f
->visible0
));
482 memcpy(f
->visible0
,f
->visibleC
,ch
*sizeof(*f
->visibleC
));
484 f
->mutemaskP
=f
->mutemask1
;
485 f
->mutemask1
=f
->mutemask0
;
486 f
->mutemask0
=f
->mutemaskC
;
488 memcpy(f
->wP
,f
->w1
,ch
*sizeof(*f
->w1
));
489 memcpy(f
->w1
,f
->w0
,ch
*sizeof(*f
->w0
));
490 memcpy(f
->w0
,f
->wC
,ch
*sizeof(*f
->wC
));
492 f
->lap_samples
-=(out
?f
->out
.samples
:0);
496 /* called only by playback thread */
497 time_linkage
*subband_read(time_linkage
*in
, subband_state
*f
,
498 subband_window
**w
,int *visible
, int *active
,
499 void (*workfunc
)(void *),void *arg
){
500 int i
,j
,ch
=f
->out
.channels
;
502 switch(f
->fillstate
){
503 case 0: /* begin priming the lapping and cache */
509 /* initially zero the lapping and cache */
511 for(j
=0;j
<f
->bands
;j
++)
512 memset(f
->lap
[j
][i
],0,sizeof(***f
->lap
)*input_size
*2);
513 memset(f
->cache1
[i
],0,sizeof(**f
->cache1
)*input_size
);
514 memset(f
->cache0
[i
],0,sizeof(**f
->cache0
)*input_size
);
518 /* and set up state variables */
519 /* set the vars to 'active' so that if the first frame is an
520 active frame, we don't transition window into it (the window
521 would have been in the previous frame */
523 int set
=(visible
[i
]||active
[i
]) && !mute_channel_muted(in
->active
,i
);
524 f
->lap_activeP
[i
]=set
;
525 f
->lap_active1
[i
]=set
;
526 f
->lap_active0
[i
]=set
;
534 memcpy(f
->effect_activeP
,active
,sizeof(*f
->effect_activeP
)*ch
);
535 memcpy(f
->effect_active1
,active
,sizeof(*f
->effect_active1
)*ch
);
536 memcpy(f
->effect_active0
,active
,sizeof(*f
->effect_active0
)*ch
);
537 //memset(f->effect_activeC,1,sizeof(*f->effect_activeC)*ch);
539 memset(f
->visible1
,0,sizeof(*f
->visible1
)*ch
);
540 memset(f
->visible0
,0,sizeof(*f
->visible0
)*ch
);
542 f
->mutemaskP
=in
->active
;
543 f
->mutemask1
=in
->active
;
544 f
->mutemask0
=in
->active
;
546 /* initially zero the padding of the input working array */
547 memset(f
->fftwf_forward_in
,0,f
->qblocksize
*4*sizeof(*f
->fftwf_forward_in
));
549 /* extrapolation mechanism; avoid harsh transients at edges */
552 if(f
->lap_active0
[i
]){
553 preextrapolate_helper(in
->data
[i
],input_size
,
554 f
->cache0
[i
],input_size
);
556 if(in
->samples
<input_size
)
557 postextrapolate_helper(f
->cache0
[i
],input_size
,
558 in
->data
[i
],in
->samples
,
559 in
->data
[i
]+in
->samples
,
560 input_size
-in
->samples
);
564 subband_work(f
,in
,w
,visible
,active
);
566 unsubband_work(f
,in
,NULL
);
570 if(in
->samples
==input_size
)goto tidy_up
;
573 memset(in
->data
[i
],0,sizeof(**in
->data
)*input_size
);
577 case 1: /* finish priming the lapping and cache */
579 /* extrapolation mechanism; avoid harsh transients at edges */
581 if(in
->samples
<input_size
)
583 if((active
[i
] || visible
[i
]) && !mute_channel_muted(in
->active
,i
))
584 postextrapolate_helper(f
->cache0
[i
],input_size
,
585 in
->data
[i
],in
->samples
,
586 in
->data
[i
]+in
->samples
,
587 input_size
-in
->samples
);
590 subband_work(f
,in
,w
,visible
,active
);
592 unsubband_work(f
,in
,NULL
);
596 if(in
->samples
==input_size
)goto tidy_up
;
599 memset(in
->data
[i
],0,sizeof(**in
->data
)*input_size
);
603 case 2: /* nominal processing */
605 if(in
->samples
<input_size
)
607 if((active
[i
] || visible
[i
]) && !mute_channel_muted(in
->active
,i
))
608 postextrapolate_helper(f
->cache0
[i
],input_size
,
609 in
->data
[i
],in
->samples
,
610 in
->data
[i
]+in
->samples
,
611 input_size
-in
->samples
);
614 subband_work(f
,in
,w
,visible
,active
);
616 unsubband_work(f
,in
,&f
->out
);
618 if(f
->out
.samples
<input_size
)f
->fillstate
=3;
621 case 3: /* we've pushed out EOF already */
628 int tozero
=input_size
-f
->out
.samples
;
630 for(i
=0;i
<f
->out
.channels
;i
++)
631 memset(f
->out
.data
[i
]+f
->out
.samples
,0,sizeof(**f
->out
.data
)*tozero
);