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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
4 */
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
5 #include <stdio.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
6 #include <stdlib.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
7 #include <string.h>
8698
739ecaea201b fix compilation on solaris
attila
parents: 8675
diff changeset
8 #include <inttypes.h>
7568
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 #include "af.h"
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
16 // Data for specific instances of this filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
17 typedef struct af_delay_s
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
23 }af_delay_t;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
24
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
25 // Initialization and runtime control
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
26 static int control(struct af_instance_s* af, int cmd, void* arg)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
29 switch(cmd){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
39 af->data->rate = ((af_data_t*)arg)->rate;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
40 af->data->nch = ((af_data_t*)arg)->nch;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
41 af->data->format = ((af_data_t*)arg)->format;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
42 af->data->bps = ((af_data_t*)arg)->bps;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
49 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
63 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
64 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d6f40a06867b Changes includes:
anders
parents: 8348
diff changeset
77 return AF_OK;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
90 return AF_UNKNOWN;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
91 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
92
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
93 // Deallocate memory
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
94 static void uninit(struct af_instance_s* af)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
95 {
8675
54c386615a70 Extending delay to have different delays for different channels
anders
parents: 8607
diff changeset
96 int i;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
97 if(af->data)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
102 if(af->setup)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
103 free(af->setup);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
104 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
105
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
106 // Filter data through filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
107 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
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
160 }
8675
54c386615a70 Extending delay to have different delays for different channels
anders
parents: 8607
diff changeset
161 s->ri = ri;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
162 return c;
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
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
165 // Allocate memory and set function pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
166 static int open(af_instance_t* af){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
167 af->control=control;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
168 af->uninit=uninit;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
169 af->play=play;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
170 af->mul.n=1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
171 af->mul.d=1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
172 af->data=calloc(1,sizeof(af_data_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
173 af->setup=calloc(1,sizeof(af_delay_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
174 if(af->data == NULL || af->setup == NULL)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
175 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
176 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
177 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
178
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
179 // Description of this filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
180 af_info_t af_info_delay = {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
181 "Delay audio filter",
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
182 "delay",
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
183 "Anders",
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
184 "",
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7568
diff changeset
185 AF_FLAGS_REENTRANT,
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
186 open
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
187 };
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
188
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
189