Mercurial > mplayer.hg
annotate libao2/pl_resample.c @ 8660:39476cbd1673
I have looked at the fullscreen code and realized that there are
generally two types of layer support for window managers:
- NetWM states (FULLSCREEN, STAYS_ON_TOP, ABOVE)
sawfish, metacity, kwin
- _WIN_LAYER
IceWM, WindowMaker
So we don't need any other window manager detection functions, we need
only to check for these two.
Code tested on lots of windowmanagers.
patch by Filip Kalinski <filon@pld.org.pl>
author | arpi |
---|---|
date | Mon, 30 Dec 2002 18:50:15 +0000 |
parents | fb88ccbc5ccc |
children | cd67631ae382 |
rev | line source |
---|---|
3631 | 1 /*============================================================================= |
2 // | |
4049 | 3 // This software has been released under the terms of the GNU Public |
4 // license. See http://www.gnu.org/copyleft/gpl.html for details. | |
3631 | 5 // |
6 // Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au | |
7 // | |
8 //============================================================================= | |
9 */ | |
10 | |
11 /* This audio output plugin changes the sample rate. The output | |
12 samplerate from this plugin is specified by using the switch | |
13 `fout=F' where F is the desired output sample frequency | |
14 */ | |
15 | |
16 #define PLUGIN | |
17 | |
18 #include <stdio.h> | |
19 #include <stdlib.h> | |
20 #include <unistd.h> | |
21 #include <inttypes.h> | |
22 | |
23 #include "audio_out.h" | |
24 #include "audio_plugin.h" | |
25 #include "audio_plugin_internal.h" | |
26 #include "afmt.h" | |
4535 | 27 #include "../config.h" |
3631 | 28 |
29 static ao_info_t info = | |
30 { | |
31 "Sample frequency conversion audio plugin", | |
32 "resample", | |
33 "Anders", | |
34 "" | |
35 }; | |
36 | |
37 LIBAO_PLUGIN_EXTERN(resample) | |
38 | |
39 #define min(a,b) (((a) < (b)) ? (a) : (b)) | |
40 #define max(a,b) (((a) > (b)) ? (a) : (b)) | |
41 | |
42 /* Below definition selects the length of each poly phase component. | |
4725
534ef9323eca
MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents:
4535
diff
changeset
|
43 Valid definitions are L8 and L16, where the number denotes the |
3631 | 44 length of the filter. This definition affects the computational |
45 complexity (see play()), the performance (see filter.h) and the | |
4725
534ef9323eca
MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents:
4535
diff
changeset
|
46 memory usage. The filterlenght is choosen to 8 if the machine is |
534ef9323eca
MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents:
4535
diff
changeset
|
47 slow and to 16 if the machine is fast and has MMX. |
3631 | 48 */ |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
49 |
4725
534ef9323eca
MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents:
4535
diff
changeset
|
50 #if !defined(HAVE_SSE) && !defined(HAVE_3DNOW) //This machine is slow |
4789 | 51 |
3631 | 52 #define W W8 // Filter bank parameters |
53 #define L 8 // Filter length | |
4789 | 54 #ifdef HAVE_MMX |
55 #define FIR(x,w,y) *y=(int16_t)firn(x,w,8); | |
56 #else /* HAVE_MMX */ | |
57 // Unrolled loop to speed up execution | |
58 #define FIR(x,w,y){ \ | |
59 int16_t a = (w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]) >> 16; \ | |
60 int16_t b = (w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7]) >> 16; \ | |
61 y[0] = a+b; \ | |
62 } | |
63 #endif /* HAVE_MMX */ | |
64 | |
65 #else /* Fast machine */ | |
66 | |
4725
534ef9323eca
MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents:
4535
diff
changeset
|
67 #define W W16 |
534ef9323eca
MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents:
4535
diff
changeset
|
68 #define L 16 |
4789 | 69 #define FIR(x,w,y) *y=(int16_t)firn(x,w,16); |
70 | |
4725
534ef9323eca
MMX part rewritten and 16 tap filter added for better sound qualty
anders
parents:
4535
diff
changeset
|
71 #endif |
3631 | 72 |
73 #define CH 6 // Max number of channels | |
74 #define UP 128 /* Up sampling factor. Increasing this value will | |
75 improve frequency accuracy. Think about the L1 | |
76 cashing of filter parameters - how big can it be? */ | |
77 | |
78 #include "fir.h" | |
79 #include "filter.h" | |
80 | |
81 // local data | |
82 typedef struct pl_resample_s | |
83 { | |
84 int16_t* data; // Data buffer | |
85 int16_t* w; // Current filter weights | |
86 uint16_t dn; // Down sampling factor | |
87 uint16_t up; // Up sampling factor | |
88 int channels; // Number of channels | |
89 int len; // Lenght of buffer | |
90 int16_t ws[UP*L]; // List of all available filters | |
91 int16_t xs[CH][L*2]; // Circular buffers | |
92 } pl_resample_t; | |
93 | |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
94 static pl_resample_t pl_resample = {NULL,NULL,1,1,1,0,W}; |
3631 | 95 |
96 // to set/get/query special features/parameters | |
97 static int control(int cmd,int arg){ | |
98 switch(cmd){ | |
99 case AOCONTROL_PLUGIN_SET_LEN: | |
100 if(pl_resample.data) | |
101 free(pl_resample.data); | |
102 pl_resample.len = ao_plugin_data.len; | |
103 pl_resample.data=(int16_t*)malloc(pl_resample.len); | |
104 if(!pl_resample.data) | |
105 return CONTROL_ERROR; | |
106 ao_plugin_data.len = (int)((double)ao_plugin_data.len * | |
4374
0a95c5074c50
Fixed sig 11 caused by resampling plugin, some cosmetic changes and speed improvements
anders
parents:
4171
diff
changeset
|
107 ((double)pl_resample.dn)/ |
0a95c5074c50
Fixed sig 11 caused by resampling plugin, some cosmetic changes and speed improvements
anders
parents:
4171
diff
changeset
|
108 ((double)pl_resample.up)); |
3631 | 109 return CONTROL_OK; |
110 } | |
111 return -1; | |
112 } | |
113 | |
114 // open & setup audio device | |
115 // return: 1=success 0=fail | |
116 static int init(){ | |
117 int fin=ao_plugin_data.rate; | |
118 int fout=ao_plugin_cfg.pl_resample_fout; | |
119 pl_resample.w=pl_resample.ws; | |
120 pl_resample.up=UP; | |
121 | |
122 // Sheck input format | |
123 if(ao_plugin_data.format != AFMT_S16_LE){ | |
124 fprintf(stderr,"[pl_resample] Input audio format not yet suported. \n"); | |
125 return 0; | |
126 } | |
127 // Sanity check and calculate down sampling factor | |
128 if((float)max(fin,fout)/(float)min(fin,fout) > 10){ | |
129 fprintf(stderr,"[pl_resample] The difference between fin and fout is too large.\n"); | |
130 return 0; | |
131 } | |
132 pl_resample.dn=(int)(0.5+((float)(fin*pl_resample.up))/((float)fout)); | |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
133 |
3631 | 134 pl_resample.channels=ao_plugin_data.channels; |
135 if(ao_plugin_data.channels>CH){ | |
136 fprintf(stderr,"[pl_resample] Too many channels, max is 6.\n"); | |
137 return 0; | |
138 } | |
139 | |
140 // Tell the world what we are up to | |
141 printf("[pl_resample] Up=%i, Down=%i, True fout=%f\n", | |
142 pl_resample.up,pl_resample.dn, | |
143 ((float)fin*pl_resample.up)/((float)pl_resample.dn)); | |
144 | |
145 // This plugin changes buffersize and adds some delay | |
146 ao_plugin_data.sz_mult/=((float)pl_resample.up)/((float)pl_resample.dn); | |
147 ao_plugin_data.delay_fix-= ((float)L/2) * (1/fout); | |
148 ao_plugin_data.rate=fout; | |
149 return 1; | |
150 } | |
151 | |
152 // close plugin | |
153 static void uninit(){ | |
154 if(pl_resample.data) | |
155 free(pl_resample.data); | |
156 pl_resample.data=NULL; | |
157 } | |
158 | |
159 // empty buffers | |
160 static void reset(){ | |
161 } | |
162 | |
8123
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7472
diff
changeset
|
163 /* forward declarations */ |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7472
diff
changeset
|
164 int upsample(); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7472
diff
changeset
|
165 int downsample(); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7472
diff
changeset
|
166 |
3631 | 167 // processes 'ao_plugin_data.len' bytes of 'data' |
168 // called for every block of data | |
169 // FIXME: this routine needs to be optimized (it is probably possible to do a lot here) | |
170 static int play(){ | |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
171 if(pl_resample.up==pl_resample.dn){ |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
172 register int16_t* in = ((int16_t*)ao_plugin_data.data); |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
173 register int16_t* end = in+ao_plugin_data.len/2; |
8451 | 174 while(in < end) *(in++)>>=1; |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
175 return 1; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
176 } |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
177 if(pl_resample.up>pl_resample.dn) |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
178 return upsample(); |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
4789
diff
changeset
|
179 // if(pl_resample.up<pl_resample.dn) |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
180 return downsample(); |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
181 } |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
182 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
183 int upsample(){ |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
184 static uint16_t pwi = 0; // Index for w |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
185 static uint16_t pxi = 0; // Index for circular queue |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
186 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
187 uint16_t ci = pl_resample.channels; // Index for channels |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
188 uint16_t nch = pl_resample.channels; // Number of channels |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
189 uint16_t len = 0; // Number of input samples |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
190 uint16_t inc = pl_resample.up/pl_resample.dn; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
191 uint16_t level = pl_resample.up%pl_resample.dn; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
192 uint16_t up = pl_resample.up; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
193 uint16_t dn = pl_resample.dn; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
194 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
195 register int16_t* w = pl_resample.w; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
196 register uint16_t wi,xi; // Temporary indexes |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
197 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
198 // Index current channel |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
199 while(ci--){ |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
200 // Temporary pointers |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
201 register int16_t* x = pl_resample.xs[ci]; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
202 register int16_t* in = ((int16_t*)ao_plugin_data.data)+ci; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
203 register int16_t* out = pl_resample.data+ci; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
204 int16_t* end = in+ao_plugin_data.len/2; // Block loop end |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
205 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
206 wi = pwi; xi = pxi; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
207 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
208 while(in < end){ |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
209 register uint16_t i = inc; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
210 if(wi<level) i++; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
211 |
4789 | 212 xi=updateq(x,in,xi,L); |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
213 in+=nch; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
214 while(i--){ |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
215 // Run the FIR filter |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
216 FIR((&x[xi]),(&w[wi*L]),out); |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
217 len++; out+=nch; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
218 // Update wi to point at the correct polyphase component |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
219 wi=(wi+dn)%up; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
220 } |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
221 } |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
222 } |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
223 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
224 // Save values that needs to be kept for next time |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
225 pwi = wi; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
226 pxi = xi; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
227 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
228 // Set new data |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
229 ao_plugin_data.len=len*2; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
230 ao_plugin_data.data=pl_resample.data; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
231 return 1; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
232 } |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
233 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
234 int downsample(){ |
3631 | 235 static uint16_t pwi = 0; // Index for w |
236 static uint16_t pxi = 0; // Index for circular queue | |
237 static uint16_t pi = 1; // Number of new samples to put in x queue | |
238 | |
239 uint16_t ci = pl_resample.channels; // Index for channels | |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
240 uint16_t len = 0; // Number of input samples |
3631 | 241 uint16_t nch = pl_resample.channels; // Number of channels |
242 uint16_t inc = pl_resample.dn/pl_resample.up; | |
243 uint16_t level = pl_resample.dn%pl_resample.up; | |
244 uint16_t up = pl_resample.up; | |
245 uint16_t dn = pl_resample.dn; | |
246 | |
247 register uint16_t i,wi,xi; // Temporary indexes | |
248 | |
249 | |
250 // Index current channel | |
251 while(ci--){ | |
252 // Temporary pointers | |
253 register int16_t* x = pl_resample.xs[ci]; | |
254 register int16_t* in = ((int16_t*)ao_plugin_data.data)+ci; | |
255 register int16_t* out = pl_resample.data+ci; | |
256 // Block loop end | |
257 register int16_t* end = in+ao_plugin_data.len/2; | |
258 i = pi; wi = pwi; xi = pxi; | |
259 | |
260 while(in < end){ | |
261 | |
4789 | 262 xi=updateq(x,in,xi,L); |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
263 in+=nch; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
264 if(!--i){ |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
265 // Run the FIR filter |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
266 FIR((&x[xi]),(&pl_resample.w[wi*L]),out); |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
267 len++; out+=nch; |
3631 | 268 |
4171
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
269 // Update wi to point at the correct polyphase component |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
270 wi=(wi+dn)%up; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
271 |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
272 // Insert i number of new samples in queue |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
273 i = inc; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
274 if(wi<level) i++; |
585f0c77d8f5
Sync problem when using fractional resampling fixed + speed increased.
anders
parents:
4049
diff
changeset
|
275 } |
3631 | 276 } |
277 } | |
278 // Save values that needs to be kept for next time | |
279 pwi = wi; | |
280 pxi = xi; | |
281 pi = i; | |
282 // Set new data | |
283 ao_plugin_data.len=len*2; | |
284 ao_plugin_data.data=pl_resample.data; | |
285 return 1; | |
286 } |