Mercurial > mplayer.hg
annotate libaf/af_delay.c @ 25886:feb0f4e3c81f
Fix r25817 to not always destroy codec_tag, this broke playback of e.g. ape files.
author | reimar |
---|---|
date | Tue, 29 Jan 2008 19:05:36 +0000 |
parents | b2402b4f0afa |
children | 72d0b1444141 |
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 | |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
8698
diff
changeset
|
166 static int af_open(af_instance_t* af){ |
7568 | 167 af->control=control; |
168 af->uninit=uninit; | |
169 af->play=play; | |
24888 | 170 af->mul=1; |
7568 | 171 af->data=calloc(1,sizeof(af_data_t)); |
172 af->setup=calloc(1,sizeof(af_delay_t)); | |
173 if(af->data == NULL || af->setup == NULL) | |
174 return AF_ERROR; | |
175 return AF_OK; | |
176 } | |
177 | |
178 // Description of this filter | |
179 af_info_t af_info_delay = { | |
180 "Delay audio filter", | |
181 "delay", | |
182 "Anders", | |
183 "", | |
7615 | 184 AF_FLAGS_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
8698
diff
changeset
|
185 af_open |
7568 | 186 }; |
187 | |
188 |