Recognizes if input is ogg or not.
[xiph.git] / postfish / mix.c
blob6933d0c0c10dfdf839e22c0edcf12619d5c549c1
1 /*
3 * postfish
4 *
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)
10 * any later version.
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.
24 #include "postfish.h"
25 #include "feedback.h"
26 #include "mix.h"
27 #include "window.h"
29 extern int input_ch;
30 extern int input_size;
31 extern int input_rate;
33 mix_settings *mix_set;
35 sig_atomic_t atten_visible;
36 sig_atomic_t *mixpanel_active;
37 sig_atomic_t *mixpanel_visible;
40 typedef struct{
41 time_linkage out;
42 feedback_generic_pool feedpool;
44 mix_settings *prev;
45 mix_settings *curr;
47 float **cacheP;
48 float **cachePP;
50 float **cachePA;
51 float **cachePPA;
53 float **cachePB;
54 float **cachePPB;
56 int fillstate;
57 } mix_state;
59 mix_state ms;
61 /* this should be moved somewhere obvious/generic */
62 static float *window;
64 /* feedback! */
65 typedef struct limit_feedback{
66 feedback_generic parent_class;
67 float **peak;
68 float **rms;
69 int bypass;
70 } mix_feedback;
72 static feedback_generic *new_mix_feedback(void){
73 mix_feedback *ret=calloc(1,sizeof(*ret));
74 return (feedback_generic *)ret;
77 /* peak, rms are pulled in array[mixblock][input_ch] order */
78 int pull_mix_feedback(float **peak,float **rms){
79 mix_feedback *f=(mix_feedback *)feedback_pull(&ms.feedpool);
80 int i;
82 if(!f)return 0;
84 if(f->bypass){
85 feedback_old(&ms.feedpool,(feedback_generic *)f);
86 return 2;
87 }else{
88 if(peak)
89 for(i=0;i<MIX_BLOCKS+5;i++)
90 memcpy(peak[i],f->peak[i],sizeof(**peak)*input_ch);
91 if(rms)
92 for(i=0;i<MIX_BLOCKS+5;i++)
93 memcpy(rms[i],f->rms[i],sizeof(**rms)*input_ch);
94 feedback_old(&ms.feedpool,(feedback_generic *)f);
95 return 1;
99 /* called only by initial setup */
100 int mix_load(int outch){
101 int i;
103 mix_set=calloc(input_ch,sizeof(*mix_set));
104 mixpanel_active=calloc(input_ch,sizeof(*mixpanel_active));
105 mixpanel_visible=calloc(input_ch,sizeof(*mixpanel_visible));
107 memset(&ms,0,sizeof(ms));
108 ms.prev=calloc(input_ch,sizeof(*ms.prev));
109 ms.curr=calloc(input_ch,sizeof(*ms.curr));
111 ms.cacheP=malloc(input_ch*sizeof(*ms.cacheP));
112 ms.cachePP=malloc(input_ch*sizeof(*ms.cachePP));
113 ms.cachePA=malloc(input_ch*sizeof(*ms.cachePA));
114 ms.cachePPA=malloc(input_ch*sizeof(*ms.cachePPA));
115 ms.cachePB=malloc(input_ch*sizeof(*ms.cachePB));
116 ms.cachePPB=malloc(input_ch*sizeof(*ms.cachePPB));
117 for(i=0;i<input_ch;i++)
118 ms.cacheP[i]=malloc(input_size*sizeof(**ms.cacheP));
119 for(i=0;i<input_ch;i++)
120 ms.cachePP[i]=malloc(input_size*sizeof(**ms.cachePP));
121 for(i=0;i<input_ch;i++)
122 ms.cachePA[i]=malloc(input_size*sizeof(**ms.cachePA));
123 for(i=0;i<input_ch;i++)
124 ms.cachePPA[i]=malloc(input_size*sizeof(**ms.cachePPA));
125 for(i=0;i<input_ch;i++)
126 ms.cachePB[i]=malloc(input_size*sizeof(**ms.cachePB));
127 for(i=0;i<input_ch;i++)
128 ms.cachePPB[i]=malloc(input_size*sizeof(**ms.cachePPB));
130 ms.out.channels=outch;
131 ms.out.data=malloc(outch*sizeof(*ms.out.data));
132 for(i=0;i<outch;i++)
133 ms.out.data[i]=malloc(input_size*sizeof(**ms.out.data));
135 window=window_get(1,input_size);
137 return 0;
140 /* called only in playback thread */
141 int mix_reset(){
142 while(pull_mix_feedback(NULL,NULL));
143 ms.fillstate=0;
144 return 0;
147 static void mixwork(float *data,float *cacheP,float *cachePP,
148 float *out,
149 float att,int del,int inv,
150 float attP,float delP,int invP){
151 int offset=0;
152 int i;
154 if(-del>input_size*2)del= -input_size*2;
155 if(-delP>input_size*2)delP= -input_size*2;
157 if(inv)att*=-1.;
158 if(invP)attP*=-1.;
160 if(att==attP && del==delP){
162 /* straight copy from cache with attenuation */
163 i=input_size*2+del;
164 while(i<input_size && offset<input_size)
165 out[offset++]+=cachePP[i++]*att;
167 i=input_size+del;
168 if(i<0)i=0;
169 while(i<input_size && offset<input_size)
170 out[offset++]+=cacheP[i++]*att;
172 i=0;
173 while(offset<input_size)
174 out[offset++]+=data[i++]*att;
176 }else{
177 /* lapped dual copy from cache */
179 /* current settings */
180 i=input_size*2+del;
181 while(i<input_size && offset<input_size){
182 out[offset]+=cachePP[i++]*att*window[offset];
183 offset++;
186 i=input_size+del;
187 if(i<0)i=0;
188 while(i<input_size && offset<input_size){
189 out[offset]+=cacheP[i++]*att*window[offset];
190 offset++;
193 i=0;
194 while(offset<input_size){
195 out[offset]+=data[i++]*att*window[offset];
196 offset++;
199 /* ...lapped transition from old settings */
200 offset=0;
201 i=input_size*2+delP;
202 while(i<input_size && offset<input_size){
203 out[offset]+=cachePP[i++]*attP*window[input_size-offset-1];
204 offset++;
207 i=input_size+delP;
208 if(i<0)i=0;
209 while(i<input_size && offset<input_size){
210 out[offset]+=cacheP[i++]*attP*window[input_size-offset-1];
211 offset++;
214 i=0;
215 while(offset<input_size){
216 out[offset]+=data[i++]*attP*window[input_size-offset-1];
217 offset++;
222 /* smooth active/inactive transitions while adding */
223 static void mixadd(float *in,float *out,int active,int activeP){
224 int i;
225 if(!active && !activeP)return;
226 if(active && activeP){
227 for(i=0;i<input_size;i++)
228 out[i]+=in[i];
229 return;
231 /* mutes no longer need be transitioned */
234 /* called only by playback thread */
235 time_linkage *mix_read(time_linkage *in,
236 time_linkage *inA, // reverb channel
237 time_linkage *inB){ // reverb channel
239 int i,j,k,outch=ms.out.channels;
240 int outactive[outch];
242 float peak[MIX_BLOCKS+5][input_ch];
243 float rms[MIX_BLOCKS+5][input_ch];
244 int bypass=1;
246 if(in->samples==0){
247 ms.out.samples=0;
248 return &ms.out;
250 memset(outactive,0,sizeof(outactive));
251 memset(peak,0,sizeof(peak));
252 memset(rms,0,sizeof(rms));
254 /* eliminate asynch change possibility */
255 memcpy(ms.curr,mix_set,sizeof(*mix_set)*input_ch);
257 /* fillstate here is only used for lazy initialization/reset */
258 if(ms.fillstate==0){
259 /* zero the cache */
260 for(i=0;i<input_ch;i++){
261 memset(ms.cacheP[i],0,sizeof(**ms.cacheP)*input_size);
262 memset(ms.cachePP[i],0,sizeof(**ms.cachePP)*input_size);
263 memset(ms.cachePA[i],0,sizeof(**ms.cachePA)*input_size);
264 memset(ms.cachePPA[i],0,sizeof(**ms.cachePPA)*input_size);
265 memset(ms.cachePB[i],0,sizeof(**ms.cachePB)*input_size);
266 memset(ms.cachePPB[i],0,sizeof(**ms.cachePPB)*input_size);
268 memcpy(ms.prev,ms.curr,sizeof(*mix_set)*input_ch);
269 ms.fillstate=1;
272 /* zero the output block; we'll me mixing into it input-by-input */
273 for(i=0;i<outch;i++)
274 memset(ms.out.data[i],0,sizeof(**ms.out.data)*input_size);
276 /* a bit of laziness that may actually save CPU time by avoiding
277 special-cases later */
278 for(i=0;i<input_ch;i++){
279 if(mute_channel_muted(in->active,i))
280 memset(in->data[i],0,sizeof(**in->data)*input_size);
281 if(mute_channel_muted(inA->active,i))
282 memset(inA->data[i],0,sizeof(**inA->data)*input_size);
283 if(mute_channel_muted(inB->active,i))
284 memset(inB->data[i],0,sizeof(**inB->data)*input_size);
287 /* input-by-input */
288 for(i=0;i<input_ch;i++){
289 int feedit=mixpanel_visible[i];
290 int feeditM=atten_visible;
292 /* master feedback is a bit of a pain; the metrics we need aren't
293 produced by any of the mixdowns below. Do it by hand */
294 if(feeditM){
295 float mix[input_size];
296 float att=fromdB(ms.curr[i].master_att * .1);
297 int del=rint(ms.curr[i].master_delay*.00001*input_rate);
298 float acc=0.;
300 if(!mute_channel_muted(in->active,i)){
301 memset(mix,0,sizeof(mix));
302 mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
303 mix,att,del,0,att,del,0);
305 bypass=0;
306 for(j=0;j<input_size;j++){
307 float val=mix[j]*mix[j];
308 if(val>peak[0][i])peak[0][i]=val;
309 acc+=val;
312 rms[0][i]=acc/input_size;
315 acc=0.;
316 if(inA && !mute_channel_muted(inA->active,i)){
317 memset(mix,0,sizeof(mix));
318 mixwork(inA->data[i],ms.cachePA[i],ms.cachePPA[i],
319 mix,att,del,0,att,del,0);
321 bypass=0;
322 for(j=0;j<input_size;j++){
323 float val=mix[j]*mix[j];
324 if(val>peak[1][i])peak[1][i]=val;
325 acc+=val;
328 rms[1][i]=acc/input_size;
331 acc=0.;
332 if(inB && !mute_channel_muted(inB->active,i)){
333 memset(mix,0,sizeof(mix));
334 mixwork(inB->data[i],ms.cachePB[i],ms.cachePPB[i],
335 mix,att,del,0,att,del,0);
337 bypass=0;
338 for(j=0;j<input_size;j++){
339 float val=mix[j]*mix[j];
340 if(val>peak[2][i])peak[2][i]=val;
341 acc+=val;
344 rms[2][i]=acc/input_size;
348 /* placer settings; translate to final numbers */
349 int placer=ms.curr[i].placer_place;
350 int placerP=ms.prev[i].placer_place;
352 /* place mix */
354 int mixedA=0,mixedB=0;
355 float mixA[input_size],mixB[input_size];
357 for(j=0;j<OUTPUT_CHANNELS;j++){
358 int destA=ms.curr[i].placer_destA[j];
359 int destAP=ms.prev[i].placer_destA[j];
360 int destB=ms.curr[i].placer_destB[j];
361 int destBP=ms.prev[i].placer_destB[j];
363 if(destA || destAP){
364 outactive[j]=1;
366 if(!mixedA){
367 float relA=(placer>100 ? placer*.01-1. : 0.);
368 float relAP=(placerP>100 ? placerP*.01-1. : 0.);
370 float attA=fromdB((ms.curr[i].master_att + ms.curr[i].placer_att * relA)*.1);
371 float attAP=fromdB((ms.prev[i].master_att + ms.prev[i].placer_att * relAP)*.1);
372 int delA=rint((ms.curr[i].master_delay + ms.curr[i].placer_delay * relA)*.00001*input_rate);
373 int delAP=rint((ms.prev[i].master_delay + ms.prev[i].placer_delay * relAP)*.00001*input_rate);
375 float attA_r=fromdB(ms.curr[i].master_att*.1);
376 float attAP_r=fromdB(ms.prev[i].master_att*.1);
377 int delA_r=rint(ms.curr[i].master_delay*.00001*input_rate);
378 int delAP_r=rint(ms.prev[i].master_delay*.00001*input_rate);
380 memset(mixA,0,sizeof(mixA));
381 mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
382 mixA,attA,delA,0,attAP,delAP,0);
383 mixwork(inA->data[i],ms.cachePA[i],ms.cachePPA[i],
384 mixA,attA_r,delA_r,0,attAP_r,delAP_r,0);
385 mixedA=1;
388 mixadd(mixA,ms.out.data[j],destA,destAP);
390 if(destB || destBP){
391 outactive[j]=1;
393 if(!mixedB){
394 float relB=(placer<100 ? 1.-placer*.01 : 0.);
395 float relBP=(placerP<100 ? 1.-placerP*.01 : 0.);
397 float attB=fromdB((ms.curr[i].master_att + ms.curr[i].placer_att * relB)*.1);
398 float attBP=fromdB((ms.prev[i].master_att + ms.prev[i].placer_att * relBP)*.1);
399 int delB=rint((ms.curr[i].master_delay + ms.curr[i].placer_delay * relB)*.00001*input_rate);
400 int delBP= rint((ms.prev[i].master_delay + ms.prev[i].placer_delay * relBP)*.00001*input_rate);
402 float attB_r=fromdB(ms.curr[i].master_att*.1);
403 float attBP_r=fromdB(ms.prev[i].master_att*.1);
404 int delB_r=rint(ms.curr[i].master_delay*.00001*input_rate);
405 int delBP_r= rint(ms.prev[i].master_delay*.00001*input_rate);
407 memset(mixB,0,sizeof(mixB));
408 mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
409 mixB,attB,delB,0,attBP,delBP,0);
410 mixwork(inB->data[i],ms.cachePB[i],ms.cachePPB[i],
411 mixB,attB_r,delB_r,0,attBP_r,delBP_r,0);
412 mixedB=1;
414 mixadd(mixB,ms.out.data[j],destB,destBP);
418 /* feedback for A */
419 if(feedit){
420 float acc=0.;
421 bypass=0;
422 if(mixedA){
423 for(j=0;j<input_size;j++){
424 float val=mixA[j]*mixA[j];
425 if(val>peak[3][i])peak[3][i]=val;
426 acc+=val;
429 peak[3][i]=peak[3][i];
430 rms[3][i]=acc/input_size;
434 /* feedback for B */
435 if(feedit){
436 float acc=0.;
437 bypass=0;
438 if(mixedB){
439 for(j=0;j<input_size;j++){
440 float val=mixB[j]*mixB[j];
441 if(val>peak[4][i])peak[4][i]=val;
442 acc+=val;
445 peak[4][i]=peak[4][i];
446 rms[4][i]=acc/input_size;
451 /* direct block mix */
452 for(k=0;k<MIX_BLOCKS;k++){
453 float mix[input_size];
455 int sourceM=ms.curr[i].insert_source[k][0];
456 int sourceMP=ms.prev[i].insert_source[k][0];
457 int sourceA=ms.curr[i].insert_source[k][1];
458 int sourceAP=ms.prev[i].insert_source[k][1];
459 int sourceB=ms.curr[i].insert_source[k][2];
460 int sourceBP=ms.prev[i].insert_source[k][2];
462 float att=
463 fromdB((ms.curr[i].master_att +
464 ms.curr[i].insert_att[k])*.1);
466 int del=
467 rint((ms.curr[i].master_delay +
468 ms.curr[i].insert_delay[k])*.00001*input_rate);
470 float attP=
471 fromdB((ms.prev[i].master_att +
472 ms.prev[i].insert_att[k])*.1);
474 int delP=
475 rint((ms.prev[i].master_delay +
476 ms.prev[i].insert_delay[k])*.00001*input_rate);
478 if(sourceM || sourceMP ||
479 sourceA || sourceAP ||
480 sourceB || sourceBP){
481 memset(mix,0,sizeof(mix));
483 /* master */
484 if(sourceM || sourceMP)
485 mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
486 mix,
487 (sourceM ? att : 0),
488 del,ms.curr[i].insert_invert[k],
489 (sourceMP ? attP : 0),
490 delP,ms.prev[i].insert_invert[k]);
492 /* reverbA */
493 if(sourceA || sourceAP)
494 if(inA)
495 mixwork(inA->data[i],ms.cachePA[i],ms.cachePPA[i],
496 mix,
497 (sourceA ? att : 0),
498 del,ms.curr[i].insert_invert[k],
499 (sourceAP ? attP : 0),
500 delP,ms.prev[i].insert_invert[k]);
502 /* reverbB */
503 if(sourceB || sourceBP)
504 if(inB)
505 mixwork(inB->data[i],ms.cachePB[i],ms.cachePPB[i],
506 mix,
507 (sourceB ? att : 0),
508 del,ms.curr[i].insert_invert[k],
509 (sourceBP ? attP : 0),
510 delP,ms.prev[i].insert_invert[k]);
512 /* mix into output */
513 for(j=0;j<OUTPUT_CHANNELS;j++){
514 int dest=ms.curr[i].insert_dest[k][j];
515 int destP=ms.prev[i].insert_dest[k][j];
517 if(dest || destP){
518 outactive[j]=1;
519 mixadd(mix,ms.out.data[j],dest,destP);
523 /* feedback */
524 if(feedit){
525 float acc=0.;
526 bypass=0;
527 for(j=0;j<input_size;j++){
528 float val=mix[j]*mix[j];
529 if(val>peak[5+k][i])peak[5+k][i]=val;
530 acc+=val;
533 peak[5+k][i]=peak[5+k][i];
534 rms[5+k][i]=acc/input_size;
539 /* rotate data cache */
541 float *temp=ms.cachePP[i];
542 ms.cachePP[i]=ms.cacheP[i];
543 ms.cacheP[i]=in->data[i];
544 in->data[i]=temp;
546 if(inA){
547 temp=ms.cachePPA[i];
548 ms.cachePPA[i]=ms.cachePA[i];
549 ms.cachePA[i]=inA->data[i];
550 inA->data[i]=temp;
553 if(inB){
554 temp=ms.cachePPB[i];
555 ms.cachePPB[i]=ms.cachePB[i];
556 ms.cachePB[i]=inB->data[i];
557 inB->data[i]=temp;
562 /* finish output data */
563 ms.out.samples=in->samples;
564 ms.out.active=0;
565 for(i=0;i<OUTPUT_CHANNELS;i++)
566 if(outactive[i])
567 ms.out.active|=(1<<i);
569 /* rotate settings cache */
571 mix_settings *temp=ms.curr;
572 ms.curr=ms.prev;
573 ms.prev=temp;
576 /* push feedback */
577 if(bypass){
578 mix_feedback *mf=
579 (mix_feedback *)feedback_new(&ms.feedpool,new_mix_feedback);
580 mf->bypass=1;
581 feedback_push(&ms.feedpool,(feedback_generic *)mf);
582 }else{
583 mix_feedback *mf=
584 (mix_feedback *)feedback_new(&ms.feedpool,new_mix_feedback);
586 if(!mf->peak){
587 mf->peak=malloc((MIX_BLOCKS+5)*sizeof(*mf->peak));
588 mf->rms=malloc((MIX_BLOCKS+5)*sizeof(*mf->rms));
590 for(i=0;i<MIX_BLOCKS+5;i++)
591 mf->rms[i]=malloc(input_ch*sizeof(**mf->rms));
592 for(i=0;i<MIX_BLOCKS+5;i++)
593 mf->peak[i]=malloc(input_ch*sizeof(**mf->peak));
596 for(i=0;i<MIX_BLOCKS+5;i++){
597 memcpy(mf->peak[i],peak[i],input_ch*sizeof(**peak));
598 memcpy(mf->rms[i],rms[i],input_ch*sizeof(**rms));
600 mf->bypass=0;
601 feedback_push(&ms.feedpool,(feedback_generic *)mf);
604 return &ms.out;