Mercurial > mplayer.hg
annotate libaf/af_surround.c @ 32282:606e4157cd4c
Split alloc and init of context so that parameters can be set in the context
instead of requireing being passed through function parameters. This also
makes sws work with AVOptions.
author | michael |
---|---|
date | Sun, 26 Sep 2010 19:33:57 +0000 |
parents | 0f1b5b68af32 |
children | 8fa2f43cb760 |
rev | line source |
---|---|
28227
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
1 /* |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
2 * Filter to do simple decoding of matrixed surround sound. |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
3 * This will provide a (basic) surround-sound effect from |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
4 * audio encoded for Dolby Surround, Pro Logic etc. |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
5 * |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
6 * original author: Steve Davies <steve@daviesfam.org> |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
7 * |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
8 * This file is part of MPlayer. |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
9 * |
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
10 * MPlayer is free software; you can redistribute it and/or modify |
8678 | 11 * it under the terms of the GNU General Public License as published by |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
28227
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
15 * MPlayer is distributed in the hope that it will be useful, |
8678 | 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
21977
cea0eb833758
Fix FSF address and otherwise broken license headers.
diego
parents:
14275
diff
changeset
|
20 * You should have received a copy of the GNU General Public License along |
28227
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
21 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
21977
cea0eb833758
Fix FSF address and otherwise broken license headers.
diego
parents:
14275
diff
changeset
|
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
28227
089d5341f9bc
Fix two more instances of nonstandard license headers.
diego
parents:
24888
diff
changeset
|
23 */ |
8678 | 24 |
25 /* The principle: Make rear channels by extracting anti-phase data | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
26 from the front channels, delay by 20ms and feed to rear in anti-phase |
8678 | 27 */ |
28 | |
29 | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
30 /* SPLITREAR: Define to decode two distinct rear channels - this |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
31 doesn't work so well in practice because separation in a passive |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
32 matrix is not high. C (dialogue) to Ls and Rs 14dB or so - so |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
33 dialogue leaks to the rear. Still - give it a try and send |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
34 feedback. Comment this define for old behavior of a single |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
35 surround sent to rear in anti-phase */ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
36 #define SPLITREAR 1 |
8678 | 37 |
38 #include <stdio.h> | |
39 #include <stdlib.h> | |
40 #include <string.h> | |
41 | |
42 #include "af.h" | |
43 #include "dsp.h" | |
44 | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
45 #define L 32 // Length of fir filter |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
46 #define LD 65536 // Length of delay buffer |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
47 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
48 // 32 Tap fir filter loop unrolled |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
49 #define FIR(x,w,y) \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
50 y = ( w[0] *x[0] +w[1] *x[1] +w[2] *x[2] +w[3] *x[3] \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
51 + w[4] *x[4] +w[5] *x[5] +w[6] *x[6] +w[7] *x[7] \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
52 + w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
53 + w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
54 + w[16]*x[16]+w[17]*x[17]+w[18]*x[18]+w[19]*x[19] \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
55 + w[20]*x[20]+w[21]*x[21]+w[22]*x[22]+w[23]*x[23] \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
56 + w[24]*x[24]+w[25]*x[25]+w[26]*x[26]+w[27]*x[27] \ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
57 + w[28]*x[28]+w[29]*x[29]+w[30]*x[30]+w[31]*x[31]) |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
58 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
59 // Add to circular queue macro + update index |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
60 #ifdef SPLITREAR |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
61 #define ADDQUE(qi,rq,lq,r,l)\ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
62 lq[qi]=lq[qi+L]=(l);\ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
63 rq[qi]=rq[qi+L]=(r);\ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
64 qi=(qi-1)&(L-1); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
65 #else |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
66 #define ADDQUE(qi,lq,l)\ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
67 lq[qi]=lq[qi+L]=(l);\ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
68 qi=(qi-1)&(L-1); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
69 #endif |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
70 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
71 // Macro for updating queue index in delay queues |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
72 #define UPDATEQI(qi) qi=(qi+1)&(LD-1) |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
73 |
8678 | 74 // instance data |
75 typedef struct af_surround_s | |
76 { | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
77 float lq[2*L]; // Circular queue for filtering left rear channel |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
78 float rq[2*L]; // Circular queue for filtering right rear channel |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
79 float w[L]; // FIR filter coefficients for surround sound 7kHz low-pass |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
80 float* dr; // Delay queue right rear channel |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
81 float* dl; // Delay queue left rear channel |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
82 float d; // Delay time |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
83 int i; // Position in circular buffer |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
84 int wi; // Write index for delay queue |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
85 int ri; // Read index for delay queue |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
86 }af_surround_t; |
8678 | 87 |
88 // Initialization and runtime control | |
89 static int control(struct af_instance_s* af, int cmd, void* arg) | |
90 { | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
91 af_surround_t *s = af->setup; |
8678 | 92 switch(cmd){ |
93 case AF_CONTROL_REINIT:{ | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
94 float fc; |
8678 | 95 af->data->rate = ((af_data_t*)arg)->rate; |
96 af->data->nch = ((af_data_t*)arg)->nch*2; | |
14245 | 97 af->data->format = AF_FORMAT_FLOAT_NE; |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
98 af->data->bps = 4; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
99 |
8678 | 100 if (af->data->nch != 4){ |
29049 | 101 mp_msg(MSGT_AFILTER, MSGL_ERR, "[surround] Only stereo input is supported.\n"); |
8678 | 102 return AF_DETACH; |
103 } | |
104 // Surround filer coefficients | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
105 fc = 2.0 * 7000.0/(float)af->data->rate; |
14275
de13fd557440
less namespace pollution #2 (prefixed globals in filter.c with af_filter_)
alex
parents:
14245
diff
changeset
|
106 if (-1 == af_filter_design_fir(L, s->w, &fc, LP|HAMMING, 0)){ |
29049 | 107 mp_msg(MSGT_AFILTER, MSGL_ERR, "[surround] Unable to design low-pass filter.\n"); |
8678 | 108 return AF_ERROR; |
109 } | |
110 | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
111 // Free previous delay queues |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
112 if(s->dl) |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
113 free(s->dl); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
114 if(s->dr) |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
115 free(s->dr); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
116 // Allocate new delay queues |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
117 s->dl = calloc(LD,af->data->bps); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
118 s->dr = calloc(LD,af->data->bps); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
119 if((NULL == s->dl) || (NULL == s->dr)) |
29049 | 120 mp_msg(MSGT_AFILTER, MSGL_FATAL, "[delay] Out of memory\n"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
121 |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
122 // Initialize delay queue index |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
123 if(AF_OK != af_from_ms(1, &s->d, &s->wi, af->data->rate, 0.0, 1000.0)) |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
124 return AF_ERROR; |
12569 | 125 // printf("%i\n",s->wi); |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
126 s->ri = 0; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
127 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
128 if((af->data->format != ((af_data_t*)arg)->format) || |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
129 (af->data->bps != ((af_data_t*)arg)->bps)){ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
130 ((af_data_t*)arg)->format = af->data->format; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
131 ((af_data_t*)arg)->bps = af->data->bps; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
132 return AF_FALSE; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
133 } |
8678 | 134 return AF_OK; |
135 } | |
136 case AF_CONTROL_COMMAND_LINE:{ | |
137 float d = 0; | |
138 sscanf((char*)arg,"%f",&d); | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
139 if ((d < 0) || (d > 1000)){ |
29049 | 140 mp_msg(MSGT_AFILTER, MSGL_ERR, "[surround] Invalid delay time, valid time values" |
10719
caec33353477
1000l and I imho this would win 'The Bug/Typo of the Year' award
alex
parents:
8763
diff
changeset
|
141 " are 0ms to 1000ms current value is %0.3f ms\n",d); |
8678 | 142 return AF_ERROR; |
143 } | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
144 s->d = d; |
8678 | 145 return AF_OK; |
146 } | |
147 } | |
148 return AF_UNKNOWN; | |
149 } | |
150 | |
151 // Deallocate memory | |
152 static void uninit(struct af_instance_s* af) | |
153 { | |
22176 | 154 if(af->data) |
8678 | 155 free(af->data->audio); |
22176 | 156 free(af->data); |
157 free(af->setup); | |
8678 | 158 } |
159 | |
160 // The beginnings of an active matrix... | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
161 static float steering_matrix[][12] = { |
8678 | 162 // LL RL LR RR LS RS |
163 // LLs RLs LRs RRs LC RC | |
164 {.707, .0, .0, .707, .5, -.5, | |
165 .5878, -.3928, .3928, -.5878, .5, .5}, | |
166 }; | |
167 | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
168 // Experimental moving average dominance |
8678 | 169 //static int amp_L = 0, amp_R = 0, amp_C = 0, amp_S = 0; |
170 | |
171 // Filter data through filter | |
172 static af_data_t* play(struct af_instance_s* af, af_data_t* data){ | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
173 af_surround_t* s = (af_surround_t*)af->setup; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
174 float* m = steering_matrix[0]; |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
175 float* in = data->audio; // Input audio data |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
176 float* out = NULL; // Output audio data |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
177 float* end = in + data->len / sizeof(float); // Loop end |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
178 int i = s->i; // Filter queue index |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
179 int ri = s->ri; // Read index for delay queue |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
180 int wi = s->wi; // Write index for delay queue |
8678 | 181 |
182 if (AF_OK != RESIZE_LOCAL_BUFFER(af, data)) | |
183 return NULL; | |
184 | |
185 out = af->data->audio; | |
186 | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
187 while(in < end){ |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
188 /* Dominance: |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
189 abs(in[0]) abs(in[1]); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
190 abs(in[0]+in[1]) abs(in[0]-in[1]); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
191 10 * log( abs(in[0]) / (abs(in[1])|1) ); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
192 10 * log( abs(in[0]+in[1]) / (abs(in[0]-in[1])|1) ); */ |
8678 | 193 |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
194 /* About volume balancing... |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
195 Surround encoding does the following: |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
196 Lt=L+.707*C+.707*S, Rt=R+.707*C-.707*S |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
197 So S should be extracted as: |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
198 (Lt-Rt) |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
199 But we are splitting the S to two output channels, so we |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
200 must take 3dB off as we split it: |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
201 Ls=Rs=.707*(Lt-Rt) |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
202 Trouble is, Lt could be +1, Rt -1, so possibility that S will |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
203 overflow. So to avoid that, we cut L/R by 3dB (*.707), and S by |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
204 6dB (/2). This keeps the overall balance, but guarantees no |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
205 overflow. */ |
8678 | 206 |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
207 // Output front left and right |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
208 out[0] = m[0]*in[0] + m[1]*in[1]; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
209 out[1] = m[2]*in[0] + m[3]*in[1]; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
210 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
211 // Low-pass output @ 7kHz |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
212 FIR((&s->lq[i]), s->w, s->dl[wi]); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
213 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
214 // Delay output by d ms |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
215 out[2] = s->dl[ri]; |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
216 |
8678 | 217 #ifdef SPLITREAR |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
218 // Low-pass output @ 7kHz |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
219 FIR((&s->rq[i]), s->w, s->dr[wi]); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
220 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
221 // Delay output by d ms |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
222 out[3] = s->dr[ri]; |
8678 | 223 #else |
224 out[3] = -out[2]; | |
225 #endif | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
226 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
227 // Update delay queues indexes |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
228 UPDATEQI(ri); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
229 UPDATEQI(wi); |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
230 |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
231 // Calculate and save surround in circular queue |
8678 | 232 #ifdef SPLITREAR |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
233 ADDQUE(i, s->rq, s->lq, m[6]*in[0]+m[7]*in[1], m[8]*in[0]+m[9]*in[1]); |
8678 | 234 #else |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
235 ADDQUE(i, s->lq, m[4]*in[0]+m[5]*in[1]); |
8678 | 236 #endif |
237 | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
238 // Next sample... |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
239 in = &in[data->nch]; |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
240 out = &out[af->data->nch]; |
8678 | 241 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
242 |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
243 // Save indexes |
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
244 s->i = i; s->ri = ri; s->wi = wi; |
8678 | 245 |
246 // Set output data | |
247 data->audio = af->data->audio; | |
24888 | 248 data->len *= 2; |
8678 | 249 data->nch = af->data->nch; |
250 | |
251 return data; | |
252 } | |
253 | |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22176
diff
changeset
|
254 static int af_open(af_instance_t* af){ |
8678 | 255 af->control=control; |
256 af->uninit=uninit; | |
257 af->play=play; | |
24888 | 258 af->mul=2; |
8678 | 259 af->data=calloc(1,sizeof(af_data_t)); |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
260 af->setup=calloc(1,sizeof(af_surround_t)); |
8678 | 261 if(af->data == NULL || af->setup == NULL) |
262 return AF_ERROR; | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
263 ((af_surround_t*)af->setup)->d = 20; |
8678 | 264 return AF_OK; |
265 } | |
266 | |
267 af_info_t af_info_surround = | |
268 { | |
269 "Surround decoder filter", | |
270 "surround", | |
271 "Steve Davies <steve@daviesfam.org>", | |
272 "", | |
8763
19e96e60a3d0
Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
anders
parents:
8678
diff
changeset
|
273 AF_FLAGS_NOT_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22176
diff
changeset
|
274 af_open |
8678 | 275 }; |