annotate libaf/af_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 d6f40a06867b
children 906f7a2dc085
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
1 /*=============================================================================
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
2 //
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
3 // This software has been released under the terms of the GNU Public
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
5 //
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
6 // Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
7 //
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
8 //=============================================================================
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
9 */
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
10
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
11 /* This audio filter changes the sample rate. */
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
12 #include <stdio.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
13 #include <stdlib.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
14 #include <unistd.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
15 #include <inttypes.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
16
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
17 #include "af.h"
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
18 #include "dsp.h"
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
19
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
20 /* Below definition selects the length of each poly phase component.
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
21 Valid definitions are L8 and L16, where the number denotes the
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
22 length of the filter. This definition affects the computational
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
23 complexity (see play()), the performance (see filter.h) and the
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
24 memory usage. The filterlenght is choosen to 8 if the machine is
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
25 slow and to 16 if the machine is fast and has MMX.
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
26 */
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
27
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
28 #if !defined(HAVE_MMX) // This machine is slow
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
29 #define L8
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
30 #else
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
31 #define L16
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
32 #endif
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
33
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
34 #include "af_resample.h"
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
35
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
36 // Filtering types
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
37 #define TYPE_LIN 0 // Linear interpolation
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
38 #define TYPE_INT 1 // 16 bit integer
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
39 #define TYPE_FLOAT 2 // 32 bit floating point
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
40
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
41 // Accuracy for linear interpolation
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
42 #define STEPACCURACY 32
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
43
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
44 // local data
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
45 typedef struct af_resample_s
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
46 {
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
47 void* w; // Current filter weights
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
48 void** xq; // Circular buffers
7580
255039c14525 Changing to 32 bit aritmetics for counters
anders
parents: 7571
diff changeset
49 uint32_t xi; // Index for circular buffers
255039c14525 Changing to 32 bit aritmetics for counters
anders
parents: 7571
diff changeset
50 uint32_t wi; // Index for w
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
51 uint32_t i; // Number of new samples to put in x queue
7580
255039c14525 Changing to 32 bit aritmetics for counters
anders
parents: 7571
diff changeset
52 uint32_t dn; // Down sampling factor
255039c14525 Changing to 32 bit aritmetics for counters
anders
parents: 7571
diff changeset
53 uint32_t up; // Up sampling factor
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
54 uint64_t step; // Step size for linear interpolation
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
55 uint64_t pt; // Pointer remainder for linear interpolation
7998
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
56 int sloppy; // Enable sloppy resampling to reduce memory usage
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
57 int type; // Filter type
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
58 } af_resample_t;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
59
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
60 // Euclids algorithm for calculating Greatest Common Divisor GCD(a,b)
7894
3aba91eb5c1f made gcd() static
arpi
parents: 7719
diff changeset
61 static inline int gcd(register int a, register int b)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
62 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
63 register int r = min(a,b);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
64 a=max(a,b);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
65 b=r;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
66
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
67 r=a%b;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
68 while(r!=0){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
69 a=b;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
70 b=r;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
71 r=a%b;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
72 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
73 return b;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
74 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
75
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
76 // Fast linear interpolation resample with modest audio quality
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
77 static int linint(af_data_t* c,af_data_t* l, af_resample_t* s)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
78 {
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
79 uint32_t len = 0; // Number of input samples
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
80 uint32_t nch = l->nch; // Words pre transfer
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
81 uint64_t step = s->step;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
82 int16_t* in16 = ((int16_t*)c->audio);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
83 int16_t* out16 = ((int16_t*)l->audio);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
84 int32_t* in32 = ((int32_t*)c->audio);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
85 int32_t* out32 = ((int32_t*)l->audio);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
86 uint64_t end = ((((uint64_t)c->len)/2LL)<<STEPACCURACY);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
87 uint64_t pt = s->pt;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
88 uint16_t tmp;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
89
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
90 switch (nch){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
91 case 1:
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
92 while(pt < end){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
93 out16[len++]=in16[pt>>STEPACCURACY];
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
94 pt+=step;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
95 }
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
96 s->pt=pt & ((1LL<<STEPACCURACY)-1);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
97 break;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
98 case 2:
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
99 end/=2;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
100 while(pt < end){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
101 out32[len++]=in32[pt>>STEPACCURACY];
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
102 pt+=step;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
103 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
104 len=(len<<1);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
105 s->pt=pt & ((1LL<<STEPACCURACY)-1);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
106 break;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
107 default:
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
108 end /=nch;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
109 while(pt < end){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
110 tmp=nch;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
111 do {
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
112 tmp--;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
113 out16[len+tmp]=in16[tmp+(pt>>STEPACCURACY)*nch];
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
114 } while (tmp);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
115 len+=nch;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
116 pt+=step;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
117 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
118 s->pt=pt & ((1LL<<STEPACCURACY)-1);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
119 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
120 return len;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
121 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
122
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
123 // Initialization and runtime control
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
124 static int control(struct af_instance_s* af, int cmd, void* arg)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
125 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
126 switch(cmd){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
127 case AF_CONTROL_REINIT:{
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
128 af_resample_t* s = (af_resample_t*)af->setup;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
129 af_data_t* n = (af_data_t*)arg; // New configureation
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
130 int i,d = 0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
131 int rv = AF_OK;
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
132 size_t tsz = (s->type==TYPE_INT) ? sizeof(int16_t) : sizeof(float);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
133
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
134 // Make sure this filter isn't redundant
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
135 if(af->data->rate == n->rate)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
136 return AF_DETACH;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
137
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
138 // If linear interpolation
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
139 if(s->type == TYPE_LIN){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
140 s->pt=0LL;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
141 s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
142 af_msg(AF_MSG_VERBOSE,"[resample] Linear interpolation step: 0x%016X.\n",
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
143 s->step);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
144 af->mul.n = af->data->rate;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
145 af->mul.d = n->rate;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
146 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
147
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
148 // Create space for circular bufers (if nesessary)
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
149 if((af->data->nch != n->nch) && (s->type != TYPE_LIN)){
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
150 // First free the old ones
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
151 if(s->xq){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
152 for(i=1;i<af->data->nch;i++)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
153 if(s->xq[i])
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
154 free(s->xq[i]);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
155 free(s->xq);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
156 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
157 // ... then create new
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
158 s->xq = malloc(n->nch*sizeof(void*));
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
159 for(i=0;i<n->nch;i++)
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
160 s->xq[i] = malloc(2*L*tsz);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
161 s->xi = 0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
162 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
163
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
164 // Set parameters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
165 af->data->nch = n->nch;
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
166 if(s->type == TYPE_INT || s->type == TYPE_LIN){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
167 af->data->format = AF_FORMAT_NE | AF_FORMAT_SI;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
168 af->data->bps = 2;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
169 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
170 else{
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
171 af->data->format = AF_FORMAT_NE | AF_FORMAT_F;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
172 af->data->bps = 4;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
173 }
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
174 if(af->data->format != n->format || af->data->bps != n->bps)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
175 rv = AF_FALSE;
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
176 n->format = af->data->format;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
177 n->bps = af->data->bps;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
178
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
179 // If linear interpolation is used the setup is done.
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
180 if(s->type == TYPE_LIN)
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
181 return rv;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
182
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
183 // Calculate up and down sampling factors
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
184 d=gcd(af->data->rate,n->rate);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
185
7998
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
186 // If sloppy resampling is enabled limit the upsampling factor
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
187 if(s->sloppy && (af->data->rate/d > 5000)){
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
188 int up=af->data->rate/2;
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
189 int dn=n->rate/2;
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
190 int m=2;
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
191 while(af->data->rate/(d*m) > 5000){
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
192 d=gcd(up,dn);
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
193 up/=2; dn/=2; m*=2;
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
194 }
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
195 d*=m;
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
196 }
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
197
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
198 // Check if the the design needs to be redone
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
199 if(s->up != af->data->rate/d || s->dn != n->rate/d){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
200 float* w;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
201 float* wt;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
202 float fc;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
203 int j;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
204 s->up = af->data->rate/d;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
205 s->dn = n->rate/d;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
206
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
207 // Calculate cuttof frequency for filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
208 fc = 1/(float)(max(s->up,s->dn));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
209 // Allocate space for polyphase filter bank and protptype filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
210 w = malloc(sizeof(float) * s->up *L);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
211 if(NULL != s->w)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
212 free(s->w);
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
213 s->w = malloc(L*s->up*tsz);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
214
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
215 // Design prototype filter type using Kaiser window with beta = 10
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
216 if(NULL == w || NULL == s->w ||
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
217 -1 == design_fir(s->up*L, w, &fc, LP|KAISER , 10.0)){
8167
e8832e66babd New features:
anders
parents: 8071
diff changeset
218 af_msg(AF_MSG_ERROR,"[resample] Unable to design prototype filter.\n");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
219 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
220 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
221 // Copy data from prototype to polyphase filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
222 wt=w;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
223 for(j=0;j<L;j++){//Columns
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
224 for(i=0;i<s->up;i++){//Rows
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
225 if(s->type == TYPE_INT){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
226 float t=(float)s->up*32767.0*(*wt);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
227 ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5));
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
228 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
229 else
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
230 ((float*)s->w)[i*L+j] = (float)s->up*(*wt);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
231 wt++;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
232 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
233 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
234 free(w);
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
235 af_msg(AF_MSG_VERBOSE,"[resample] New filter designed up: %i "
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
236 "down: %i\n", s->up, s->dn);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
237 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
238
7665
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7616
diff changeset
239 // Set multiplier and delay
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7616
diff changeset
240 af->delay = (double)(1000*L/2)/((double)n->rate);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
241 af->mul.n = s->up;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
242 af->mul.d = s->dn;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
243 return rv;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
244 }
7998
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
245 case AF_CONTROL_COMMAND_LINE:{
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
246 af_resample_t* s = (af_resample_t*)af->setup;
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
247 int rate=0;
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
248 int lin=0;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
249 sscanf((char*)arg,"%i:%i:%i", &rate, &(s->sloppy), &lin);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
250 if(lin)
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
251 s->type = TYPE_LIN;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
252 return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate);
7998
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7894
diff changeset
253 }
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
254 case AF_CONTROL_POST_CREATE:
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
255 ((af_resample_t*)af->setup)->type =
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
256 ((af_cfg_t*)arg)->force == AF_INIT_SLOW ? TYPE_INT : TYPE_FLOAT;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
257 return AF_OK;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
258 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
259 // Reinit must be called after this function has been called
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
260
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
261 // Sanity check
7616
d09c125a88fa Changing frequency limit for resampling
anders
parents: 7615
diff changeset
262 if(((int*)arg)[0] < 8000 || ((int*)arg)[0] > 192000){
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
263 af_msg(AF_MSG_ERROR,"[resample] The output sample frequency "
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
264 "must be between 8kHz and 192kHz. Current value is %i \n",
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
265 ((int*)arg)[0]);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
266 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
267 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
268
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
269 af->data->rate=((int*)arg)[0];
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
270 af_msg(AF_MSG_VERBOSE,"[resample] Changing sample rate "
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
271 "to %iHz\n",af->data->rate);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
272 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
273 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
274 return AF_UNKNOWN;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
275 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
276
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
277 // Deallocate memory
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
278 static void uninit(struct af_instance_s* af)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
279 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
280 if(af->data)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
281 free(af->data);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
282 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
283
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
284 // Filter data through filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
285 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
286 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
287 int len = 0; // Length of output data
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
288 af_data_t* c = data; // Current working data
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
289 af_data_t* l = af->data; // Local data
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
290 af_resample_t* s = (af_resample_t*)af->setup;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
291
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
292 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
293 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
294
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
295 // Run resampling
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
296 switch(s->type){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
297 case(TYPE_INT):
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
298 # define FORMAT_I 1
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
299 if(s->up>s->dn){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
300 # define UP
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
301 # include "af_resample.h"
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
302 # undef UP
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
303 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
304 else{
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
305 # define DN
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
306 # include "af_resample.h"
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
307 # undef DN
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
308 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
309 break;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
310 case(TYPE_FLOAT):
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
311 # undef FORMAT_I
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
312 # define FORMAT_F 1
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
313 if(s->up>s->dn){
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
314 # define UP
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
315 # include "af_resample.h"
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
316 # undef UP
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
317 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
318 else{
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
319 # define DN
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
320 # include "af_resample.h"
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
321 # undef DN
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
322 }
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
323 break;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
324 case(TYPE_LIN):
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
325 len = linint(c, l, s);
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
326 break;
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
327 }
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
328
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
329 // Set output data
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
330 c->audio = l->audio;
8607
d6f40a06867b Changes includes:
anders
parents: 8451
diff changeset
331 c->len = len*l->bps;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
332 c->rate = l->rate;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
333
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
334 return c;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
335 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
336
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
337 // Allocate memory and set function pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
338 static int open(af_instance_t* af){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
339 af->control=control;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
340 af->uninit=uninit;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
341 af->play=play;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
342 af->mul.n=1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
343 af->mul.d=1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
344 af->data=calloc(1,sizeof(af_data_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
345 af->setup=calloc(1,sizeof(af_resample_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
346 if(af->data == NULL || af->setup == NULL)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
347 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
348 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
349 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
350
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
351 // Description of this plugin
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
352 af_info_t af_info_resample = {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
353 "Sample frequency conversion",
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
354 "resample",
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
355 "Anders",
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
356 "",
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7602
diff changeset
357 AF_FLAGS_REENTRANT,
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
358 open
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
359 };
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
360