revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / AHI / Device / dspecho.c
blobeea914c0feff1f04fed7bf937b14b189c9baad53
1 /*
2 AHI - Hardware independent audio subsystem
3 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
18 MA 02139, USA.
21 #include <config.h>
23 #include "ahi_def.h"
24 #include "dsp.h"
25 #include "dspecho.h"
26 #include "dspechofuncs.h"
28 #define min(a,b) (((a)<(b))?(a):(b))
29 #define max(a,b) (((a)>(b))?(a):(b))
31 /**************
32 * Inputs: ahiede_Delay, ahiede_Feedback, ahiede_Mix, ahiede_Cross
34 * Delay = ahide_Delay
35 * MixN = 1-ahide_Mix
36 * MixD = ahide_Mix
37 * FeedbackDO = ahide_Feedback*ahide_Cross
38 * FeedbackDS = ahide_Feedback*(1-ahide_Cross)
39 * FeedbackNO = (1-ahide_Feedback)*ahide_Cross
40 * FeedbackNS = (1-ahide_Feedback)*(1-ahide_Cross)
42 * |\
43 * left in ->---+----------+---------------------| >---->(+)----> left out
44 * | | MixN |/ ^
45 * FeedbackNO \¯/ \¯/ FeedbackNS |
46 * v v |
47 * | | |
48 * | v |¯¯¯| |\ |
49 * | +--->(+)-->| T |----+-------| >------+
50 * | | ^ |___| | MixD |/
51 * | | | Delay |
52 * | | | |
53 * | | | /| |
54 * | | +-----< |-----+
55 * | | FeedbackDS \| |
56 * | | |
57 * | | /| |
58 * (+)<--(-----------< |-----+
59 * | | \| FeedbackDO
60 * | |
61 * | |
62 * | |
63 * | | /| FeedbackDO
64 * | (+)<---------< |-----+
65 * | | \| |
66 * | | |
67 * | | FeedbackDS /| |
68 * | | +-----< |-----+
69 * | | | \| |
70 * | | | |
71 * | | v |¯¯¯| | |\
72 * +----(--->(+)-->| T |----+-------| >------+
73 * | ^ |___| MixD |/ |
74 * | | Delay |
75 * ^ ^ |
76 * FeedbackNO /_\ /_\ FeedbackNS |
77 * | | |\ v
78 * right in ->-------+-----+---------------------| >---->(+)----> right out
79 * MixN |/
82 **************
84 * The delay buffer: (BuffSamples = 5, Delay = 8 Total size = 13
86 * 1) Delay times
88 * +---------+
89 * | |
90 * v ^
91 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
92 * *---------*
94 * 2) BuffSamples times
96 * +-Mix-----------+
97 * | |
98 * ^ v
99 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
100 * *---------*
102 * Or optimized using a circular buffer:
105 * Offset<BuffSamples => BuffSamples-Offset times:
107 * +-Mix-----------+
108 * | |
109 * ^ v
110 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
111 * *---------*
113 * BuffSamples<=Offset<=Delay => BuffSamples times:
115 * +-Mix-----+
116 * | |
117 * v ^
118 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
119 * *---------*
121 * Offset>Delay => BuffSamples+Delay-Offset times:
123 * +-Mix-----+
124 * | |
125 * v ^
126 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
127 * --* *--------
129 * The delay buffer: (BuffSamples = 5, Delay = 3 Total size = 8
131 * Offset<BuffSamples => BuffSamples-Offset times:
133 * +-Mix-+
134 * | |
135 * ^ v
136 * |_|_|_|_|_|_|_|_|
137 * *---------*
139 * Offset>=BuffSamples => BuffSamples+Delay-Offset times:
141 * +-----Mix-+
142 * | |
143 * v ^
144 * |_|_|_|_|_|_|_|_|
145 * ----* *------
149 * Algoritm:
151 * LoopsLeft=BuffSamples
152 * Offset=0
153 * Src=E
154 * Dst=E+Delay
155 * Loop:
156 * If LoopsLeft <= 0 GOTO Exit
157 * IF Src >= (E + MaxBuffSamples + Delay) THEN Src = Src - (MaxBuffSamples + Delay)
158 * IF Dst >= (E + MaxBuffSamples + Delay) THEN Dst = Dst - (MaxBuffSamples + Delay)
159 * IF Offset >= (MaxBuffSamples + Delay) THEN Offset = Offset - (MaxBuffSamples + Delay)
161 * IF Offset < MaxBuffSamples THEN LoopTimes = MaxBuffSamples-Offset : GOTO Echo
162 * IF Offset <= Delay THEN LoopTimes = MaxBuffSamples : GOTO Echo
163 * LoopTimes = MaxBuffSamples+Delay-Offset
164 * Echo:
165 * LoopTimes = min(LoopTimes,LoopsLeft)
166 * Echo LoopTimes samples
168 * Src = Src + LoopTimes
169 * Dst = Dst + LoopTimes
170 * Offset = Offset + LoopTimes
171 * LoopsLeft = LoopsLeft - LoopTimes
172 * GOTO Loop
173 * Exit:
177 static void
178 do_DSPEcho ( struct Echo *es,
179 void *buf,
180 struct AHIPrivAudioCtrl *audioctrl,
181 void (*echofunc)(LONG, struct Echo *, void **, void **, void **) )
183 LONG samples, loops;
184 ULONG offset;
185 void *srcptr, *dstptr;
187 samples = audioctrl->ac.ahiac_BuffSamples;
188 offset = es->ahiecho_Offset;
189 srcptr = es->ahiecho_SrcPtr;
190 dstptr = es->ahiecho_DstPtr;
192 while(samples > 0)
194 /* Circular buffer stuff */
196 if(srcptr >= es->ahiecho_EndPtr)
198 srcptr = (char *) srcptr - es->ahiecho_BufferSize;
201 if(dstptr >= es->ahiecho_EndPtr)
203 dstptr = (char *) dstptr - es->ahiecho_BufferSize;
206 if(offset >= es->ahiecho_BufferLength)
208 offset -= es->ahiecho_BufferLength;
213 if(offset < audioctrl->ac.ahiac_MaxBuffSamples)
215 loops = audioctrl->ac.ahiac_MaxBuffSamples - offset;
217 else if(offset <= es->ahiecho_Delay)
219 loops = audioctrl->ac.ahiac_MaxBuffSamples;
221 else
223 loops = audioctrl->ac.ahiac_MaxBuffSamples + es->ahiecho_Delay - offset;
226 loops = min(loops, samples);
228 samples -= loops;
229 offset += loops;
231 /* Call echo function */
233 echofunc(loops, es, &buf, &srcptr, &dstptr);
235 } // while(samples > 0)
237 es->ahiecho_Offset = offset;
238 es->ahiecho_SrcPtr = srcptr;
239 es->ahiecho_DstPtr = dstptr;
245 /* Entry points **************************************************************/
247 void
248 do_DSPEchoMono16( struct Echo *es,
249 void *buf,
250 struct AHIPrivAudioCtrl *audioctrl )
252 do_DSPEcho( es, buf, audioctrl, EchoMono16 );
256 void
257 do_DSPEchoStereo16( struct Echo *es,
258 void *buf,
259 struct AHIPrivAudioCtrl *audioctrl )
261 do_DSPEcho( es, buf, audioctrl, EchoStereo16 );
265 void
266 do_DSPEchoMono32 ( struct Echo *es,
267 void *buf,
268 struct AHIPrivAudioCtrl *audioctrl )
270 do_DSPEcho( es, buf, audioctrl, EchoMono32 );
274 void
275 do_DSPEchoStereo32( struct Echo *es,
276 void *buf,
277 struct AHIPrivAudioCtrl *audioctrl )
279 do_DSPEcho( es, buf, audioctrl, EchoStereo32 );
283 void
284 do_DSPEchoMulti32( struct Echo *es,
285 void *buf,
286 struct AHIPrivAudioCtrl *audioctrl )
288 do_DSPEcho( es, buf, audioctrl, EchoMulti32 );