Mercurial > mplayer.hg
annotate libaf/af_delay.c @ 35467:364387ae95f4
Fix bug with stop button and playlist.
Although the current file was stopped and its information still
displayed, play would skip to next file in list. Now, the file
stopped can be resumed.
author | ib |
---|---|
date | Sun, 02 Dec 2012 15:56:19 +0000 |
parents | a93891202051 |
children | 2b9bc3c2933d |
rev | line source |
---|---|
28229
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
1 /* |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
2 * This audio filter delays the output signal for the different |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
3 * channels and can be used for simple position panning. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
4 * An extension for this filter would be a reverb. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
5 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
6 * This file is part of MPlayer. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
7 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
11 * (at your option) any later version. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
12 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
16 * GNU General Public License for more details. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
17 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
21 */ |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
22 |
7568 | 23 #include <stdio.h> |
24 #include <stdlib.h> | |
25 #include <string.h> | |
8698 | 26 #include <inttypes.h> |
7568 | 27 |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
32537
diff
changeset
|
28 #include "mp_msg.h" |
7568 | 29 #include "af.h" |
30 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
31 #define L 65536 |
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 #define UPDATEQI(qi) qi=(qi+1)&(L-1) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
34 |
7568 | 35 // Data for specific instances of this filter |
36 typedef struct af_delay_s | |
37 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
38 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
|
39 int wi[AF_NCH]; // Write index |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
40 int ri; // Read index |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
41 float d[AF_NCH]; // Delay [ms] |
7568 | 42 }af_delay_t; |
43 | |
44 // Initialization and runtime control | |
45 static int control(struct af_instance_s* af, int cmd, void* arg) | |
46 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
47 af_delay_t* s = af->setup; |
7568 | 48 switch(cmd){ |
49 case AF_CONTROL_REINIT:{ | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
50 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
51 |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
52 // Free prevous delay queues |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30633
diff
changeset
|
53 for(i=0;i<af->data->nch;i++) |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30633
diff
changeset
|
54 free(s->q[i]); |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
55 |
7568 | 56 af->data->rate = ((af_data_t*)arg)->rate; |
57 af->data->nch = ((af_data_t*)arg)->nch; | |
58 af->data->format = ((af_data_t*)arg)->format; | |
59 af->data->bps = ((af_data_t*)arg)->bps; | |
60 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
61 // Allocate new delay queues |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
62 for(i=0;i<af->data->nch;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
63 s->q[i] = calloc(L,af->data->bps); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
64 if(NULL == s->q[i]) |
29049 | 65 mp_msg(MSGT_AFILTER, MSGL_FATAL, "[delay] Out of memory\n"); |
7568 | 66 } |
67 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
68 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
|
69 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
70 case AF_CONTROL_COMMAND_LINE:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
71 int n = 1; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
72 int i = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
73 char* cl = arg; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
74 while(n && i < AF_NCH ){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
75 sscanf(cl,"%f:%n",&s->d[i],&n); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
76 if(n==0 || cl[n-1] == '\0') |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
77 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
78 cl=&cl[n]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
79 i++; |
7568 | 80 } |
81 return AF_OK; | |
82 } | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
83 case AF_CONTROL_DELAY_LEN | AF_CONTROL_SET:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
84 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
85 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
|
86 return AF_ERROR; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
87 s->ri = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
88 for(i=0;i<AF_NCH;i++){ |
29049 | 89 mp_msg(MSGT_AFILTER, MSGL_DBG2, "[delay] Channel %i delayed by %0.3fms\n", |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
90 i,clamp(s->d[i],0.0,1000.0)); |
29049 | 91 mp_msg(MSGT_AFILTER, MSGL_DBG3, "[delay] Channel %i delayed by %i samples\n", |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
92 i,s->wi[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
93 } |
8607 | 94 return AF_OK; |
7568 | 95 } |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
96 case AF_CONTROL_DELAY_LEN | AF_CONTROL_GET:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
97 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
98 for(i=0;i<AF_NCH;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
99 if(s->ri > s->wi[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
100 s->wi[i] = L - (s->ri - s->wi[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
101 else |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
102 s->wi[i] = s->wi[i] - s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
103 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
104 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
|
105 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
106 } |
7568 | 107 return AF_UNKNOWN; |
108 } | |
109 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
110 // Deallocate memory |
7568 | 111 static void uninit(struct af_instance_s* af) |
112 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
113 int i; |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30633
diff
changeset
|
114 |
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30633
diff
changeset
|
115 free(af->data); |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
116 for(i=0;i<AF_NCH;i++) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
117 free(((af_delay_t*)(af->setup))->q[i]); |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
30633
diff
changeset
|
118 free(af->setup); |
7568 | 119 } |
120 | |
121 // Filter data through filter | |
122 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
123 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
124 af_data_t* c = data; // Current working data |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
125 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
|
126 int nch = c->nch; // Number of channels |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
127 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
|
128 int ri = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
129 int ch,i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
130 for(ch=0;ch<nch;ch++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
131 switch(c->bps){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
132 case 1:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
133 int8_t* a = c->audio; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
134 int8_t* q = s->q[ch]; |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
135 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
136 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
137 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
138 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
139 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
140 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
141 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
142 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
143 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
144 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
145 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
146 case 2:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
147 int16_t* a = c->audio; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
148 int16_t* q = s->q[ch]; |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
149 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
150 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
151 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
152 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
153 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
154 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
155 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
156 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
157 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
158 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
159 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
160 case 4:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
161 int32_t* a = c->audio; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
162 int32_t* q = s->q[ch]; |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
163 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
164 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
165 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
166 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
167 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
168 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
169 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
170 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
171 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
172 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
173 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
174 } |
7568 | 175 } |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
176 s->ri = ri; |
7568 | 177 return c; |
178 } | |
179 | |
180 // 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
|
181 static int af_open(af_instance_t* af){ |
7568 | 182 af->control=control; |
183 af->uninit=uninit; | |
184 af->play=play; | |
24888 | 185 af->mul=1; |
7568 | 186 af->data=calloc(1,sizeof(af_data_t)); |
187 af->setup=calloc(1,sizeof(af_delay_t)); | |
188 if(af->data == NULL || af->setup == NULL) | |
189 return AF_ERROR; | |
190 return AF_OK; | |
191 } | |
192 | |
193 // Description of this filter | |
194 af_info_t af_info_delay = { | |
195 "Delay audio filter", | |
196 "delay", | |
197 "Anders", | |
198 "", | |
7615 | 199 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
|
200 af_open |
7568 | 201 }; |