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,
26 #include "dspechofuncs.h"
28 #define min(a,b) (((a)<(b))?(a):(b))
29 #define max(a,b) (((a)>(b))?(a):(b))
32 * Inputs: ahiede_Delay, ahiede_Feedback, ahiede_Mix, ahiede_Cross
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)
43 * left in ->---+----------+---------------------| >---->(+)----> left out
45 * FeedbackNO \¯/ \¯/ FeedbackNS |
49 * | +--->(+)-->| T |----+-------| >------+
50 * | | ^ |___| | MixD |/
58 * (+)<--(-----------< |-----+
64 * | (+)<---------< |-----+
72 * +----(--->(+)-->| T |----+-------| >------+
76 * FeedbackNO /_\ /_\ FeedbackNS |
78 * right in ->-------+-----+---------------------| >---->(+)----> right out
84 * The delay buffer: (BuffSamples = 5, Delay = 8 Total size = 13
91 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
94 * 2) BuffSamples times
99 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
102 * Or optimized using a circular buffer:
105 * Offset<BuffSamples => BuffSamples-Offset times:
110 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
113 * BuffSamples<=Offset<=Delay => BuffSamples times:
118 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
121 * Offset>Delay => BuffSamples+Delay-Offset times:
126 * |_|_|_|_|_|_|_|_|_|_|_|_|_|
129 * The delay buffer: (BuffSamples = 5, Delay = 3 Total size = 8
131 * Offset<BuffSamples => BuffSamples-Offset times:
139 * Offset>=BuffSamples => BuffSamples+Delay-Offset times:
151 * LoopsLeft=BuffSamples
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
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
178 do_DSPEcho ( struct Echo
*es
,
180 struct AHIPrivAudioCtrl
*audioctrl
,
181 void (*echofunc
)(LONG
, struct Echo
*, void **, void **, void **) )
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
;
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
;
223 loops
= audioctrl
->ac
.ahiac_MaxBuffSamples
+ es
->ahiecho_Delay
- offset
;
226 loops
= min(loops
, samples
);
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 **************************************************************/
248 do_DSPEchoMono16( struct Echo
*es
,
250 struct AHIPrivAudioCtrl
*audioctrl
)
252 do_DSPEcho( es
, buf
, audioctrl
, EchoMono16
);
257 do_DSPEchoStereo16( struct Echo
*es
,
259 struct AHIPrivAudioCtrl
*audioctrl
)
261 do_DSPEcho( es
, buf
, audioctrl
, EchoStereo16
);
266 do_DSPEchoMono32 ( struct Echo
*es
,
268 struct AHIPrivAudioCtrl
*audioctrl
)
270 do_DSPEcho( es
, buf
, audioctrl
, EchoMono32
);
275 do_DSPEchoStereo32( struct Echo
*es
,
277 struct AHIPrivAudioCtrl
*audioctrl
)
279 do_DSPEcho( es
, buf
, audioctrl
, EchoStereo32
);
284 do_DSPEchoMulti32( struct Echo
*es
,
286 struct AHIPrivAudioCtrl
*audioctrl
)
288 do_DSPEcho( es
, buf
, audioctrl
, EchoMulti32
);