Mercurial > mplayer.hg
annotate libaf/af_delay.c @ 19382:7c6c205b88b6
trying to fix the reverting paragraph
if you dissagree, dont hesitate to revert this commit or flame, but at least we should not claim that svn cannot revert commits except by recommiting the old version
author | michael |
---|---|
date | Sun, 13 Aug 2006 22:14:32 +0000 |
parents | 739ecaea201b |
children | fd6f824ef894 |
rev | line source |
---|---|
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
1 /* This audio filter delays the output signal for the different |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
2 channels and can be used for simple position panning. Extension for |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
3 this filter would be a reverb. |
7568 | 4 */ |
5 #include <stdio.h> | |
6 #include <stdlib.h> | |
7 #include <string.h> | |
8698 | 8 #include <inttypes.h> |
7568 | 9 |
10 #include "af.h" | |
11 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
12 #define L 65536 |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
13 |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
14 #define UPDATEQI(qi) qi=(qi+1)&(L-1) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
15 |
7568 | 16 // Data for specific instances of this filter |
17 typedef struct af_delay_s | |
18 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
19 void* q[AF_NCH]; // Circular queues used for delaying audio signal |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
20 int wi[AF_NCH]; // Write index |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
21 int ri; // Read index |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
22 float d[AF_NCH]; // Delay [ms] |
7568 | 23 }af_delay_t; |
24 | |
25 // Initialization and runtime control | |
26 static int control(struct af_instance_s* af, int cmd, void* arg) | |
27 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
28 af_delay_t* s = af->setup; |
7568 | 29 switch(cmd){ |
30 case AF_CONTROL_REINIT:{ | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
31 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
32 |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
33 // Free prevous delay queues |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
34 for(i=0;i<af->data->nch;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
35 if(s->q[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
36 free(s->q[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
37 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
38 |
7568 | 39 af->data->rate = ((af_data_t*)arg)->rate; |
40 af->data->nch = ((af_data_t*)arg)->nch; | |
41 af->data->format = ((af_data_t*)arg)->format; | |
42 af->data->bps = ((af_data_t*)arg)->bps; | |
43 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
44 // Allocate new delay queues |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
45 for(i=0;i<af->data->nch;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
46 s->q[i] = calloc(L,af->data->bps); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
47 if(NULL == s->q[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
48 af_msg(AF_MSG_FATAL,"[delay] Out of memory\n"); |
7568 | 49 } |
50 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
51 return control(af,AF_CONTROL_DELAY_LEN | AF_CONTROL_SET,s->d); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
52 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
53 case AF_CONTROL_COMMAND_LINE:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
54 int n = 1; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
55 int i = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
56 char* cl = arg; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
57 while(n && i < AF_NCH ){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
58 sscanf(cl,"%f:%n",&s->d[i],&n); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
59 if(n==0 || cl[n-1] == '\0') |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
60 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
61 cl=&cl[n]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
62 i++; |
7568 | 63 } |
64 return AF_OK; | |
65 } | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
66 case AF_CONTROL_DELAY_LEN | AF_CONTROL_SET:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
67 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
68 if(AF_OK != af_from_ms(AF_NCH, arg, s->wi, af->data->rate, 0.0, 1000.0)) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
69 return AF_ERROR; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
70 s->ri = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
71 for(i=0;i<AF_NCH;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
72 af_msg(AF_MSG_DEBUG0,"[delay] Channel %i delayed by %0.3fms\n", |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
73 i,clamp(s->d[i],0.0,1000.0)); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
74 af_msg(AF_MSG_DEBUG1,"[delay] Channel %i delayed by %i samples\n", |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
75 i,s->wi[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
76 } |
8607 | 77 return AF_OK; |
7568 | 78 } |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
79 case AF_CONTROL_DELAY_LEN | AF_CONTROL_GET:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
80 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
81 for(i=0;i<AF_NCH;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
82 if(s->ri > s->wi[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
83 s->wi[i] = L - (s->ri - s->wi[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
84 else |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
85 s->wi[i] = s->wi[i] - s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
86 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
87 return af_to_ms(AF_NCH, s->wi, arg, af->data->rate); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
88 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
89 } |
7568 | 90 return AF_UNKNOWN; |
91 } | |
92 | |
93 // Deallocate memory | |
94 static void uninit(struct af_instance_s* af) | |
95 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
96 int i; |
7568 | 97 if(af->data) |
98 free(af->data); | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
99 for(i=0;i<AF_NCH;i++) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
100 if(((af_delay_t*)(af->setup))->q[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
101 free(((af_delay_t*)(af->setup))->q[i]); |
7568 | 102 if(af->setup) |
103 free(af->setup); | |
104 } | |
105 | |
106 // Filter data through filter | |
107 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
108 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
109 af_data_t* c = data; // Current working data |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
110 af_delay_t* s = af->setup; // Setup for this instance |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
111 int nch = c->nch; // Number of channels |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
112 int len = c->len/c->bps; // Number of sample in data chunk |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
113 int ri = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
114 int ch,i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
115 for(ch=0;ch<nch;ch++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
116 switch(c->bps){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
117 case 1:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
118 int8_t* a = c->audio; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
119 int8_t* q = s->q[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
120 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
121 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
122 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
123 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
124 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
125 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
126 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
127 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
128 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
129 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
130 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
131 case 2:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
132 int16_t* a = c->audio; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
133 int16_t* q = s->q[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
134 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
135 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
136 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
137 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
138 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
139 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
140 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
141 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
142 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
143 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
144 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
145 case 4:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
146 int32_t* a = c->audio; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
147 int32_t* q = s->q[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
148 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
149 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
150 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
151 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
152 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
153 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
154 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
155 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
156 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
157 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
158 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
159 } |
7568 | 160 } |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
161 s->ri = ri; |
7568 | 162 return c; |
163 } | |
164 | |
165 // Allocate memory and set function pointers | |
166 static int open(af_instance_t* af){ | |
167 af->control=control; | |
168 af->uninit=uninit; | |
169 af->play=play; | |
170 af->mul.n=1; | |
171 af->mul.d=1; | |
172 af->data=calloc(1,sizeof(af_data_t)); | |
173 af->setup=calloc(1,sizeof(af_delay_t)); | |
174 if(af->data == NULL || af->setup == NULL) | |
175 return AF_ERROR; | |
176 return AF_OK; | |
177 } | |
178 | |
179 // Description of this filter | |
180 af_info_t af_info_delay = { | |
181 "Delay audio filter", | |
182 "delay", | |
183 "Anders", | |
184 "", | |
7615 | 185 AF_FLAGS_REENTRANT, |
7568 | 186 open |
187 }; | |
188 | |
189 |