home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 106 / EnigmaAmiga106CD.iso / software / sviluppo / ahisrc / device / dspecho_68k.s < prev    next >
Encoding:
Text File  |  1999-04-22  |  17.6 KB  |  768 lines

  1. ; $Id: dspecho_68k.s,v 4.11 1999/04/22 19:42:10 lcs Exp $
  2.  
  3. ;    AHI - Hardware independent audio subsystem
  4. ;    Copyright (C) 1996-1999 Martin Blom <martin@blom.org>
  5. ;     
  6. ;    This library is free software; you can redistribute it and/or
  7. ;    modify it under the terms of the GNU Library General Public
  8. ;    License as published by the Free Software Foundation; either
  9. ;    version 2 of the License, or (at your option) any later version.
  10. ;     
  11. ;    This library is distributed in the hope that it will be useful,
  12. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. ;    Library General Public License for more details.
  15. ;     
  16. ;    You should have received a copy of the GNU Library General Public
  17. ;    License along with this library; if not, write to the
  18. ;    Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
  19. ;    MA 02139, USA.
  20.  
  21.     include    exec/types.i
  22.     include    exec/macros.i
  23.  
  24.     include    ahi_def.i
  25.     include dsp.i
  26.  
  27.     XDEF    _do_DSPEchoMono16
  28.     XDEF    _do_DSPEchoMono16Fast
  29.     XDEF    _do_DSPEchoStereo16
  30.     XDEF    _do_DSPEchoStereo16Fast
  31.     XDEF    _do_DSPEchoMono32
  32.     XDEF    _do_DSPEchoStereo32
  33.     XDEF    _do_DSPEchoMono16NCFM
  34.     XDEF    _do_DSPEchoStereo16NCFM
  35.     XDEF    _do_DSPEchoMono16NCFMFast
  36.     XDEF    _do_DSPEchoStereo16NCFMFast
  37.  
  38.     section    .text,code
  39.  
  40. ***
  41. *** DSPECHO
  42. ***
  43.  
  44. **************
  45. * Inputs: ahiede_Delay, ahiede_Feedback, ahiede_Mix, ahiede_Cross
  46. *
  47. * Delay      = ahide_Delay
  48. * MixN       = 1-ahide_Mix
  49. * MixD       = ahide_Mix
  50. * FeedbackDO = ahide_Feedback*ahide_Cross
  51. * FeedbackDS = ahide_Feedback*(1-ahide_Cross)
  52. * FeedbackNO = (1-ahide_Feedback)*ahide_Cross
  53. * FeedbackNS = (1-ahide_Feedback)*(1-ahide_Cross)
  54. *
  55. *                                               |\
  56. * left in ->---+----------+---------------------| >---->(+)----> left out
  57. *              |          |                MixN |/       ^
  58. *  FeedbackNO \¯/        \¯/ FeedbackNS                  |
  59. *              v          v                              |
  60. *              |          |                              |
  61. *              |          v    |¯¯¯|            |\       |
  62. *              |    +--->(+)-->| T |----+-------| >------+
  63. *              |    |     ^    |___|    |  MixD |/
  64. *              |    |     |    Delay    |
  65. *              |    |     |             |
  66. *              |    |     |      /|     |
  67. *              |    |     +-----< |-----+
  68. *              |    | FeedbackDS \|     |
  69. *              |    |                   |
  70. *              |    |            /|     |
  71. *             (+)<--(-----------< |-----+
  72. *              |    |            \| FeedbackDO
  73. *              |    |
  74. *              |    |
  75. *              |    |
  76. *              |    |            /| FeedbackDO
  77. *              |   (+)<---------< |-----+
  78. *              |    |            \|     |
  79. *              |    |                   |
  80. *              |    | FeedbackDS /|     |
  81. *              |    |     +-----< |-----+
  82. *              |    |     |      \|     |
  83. *              |    |     |             |
  84. *              |    |     v    |¯¯¯|    |       |\
  85. *              +----(--->(+)-->| T |----+-------| >------+
  86. *                   |     ^    |___|       MixD |/       |
  87. *                   |     |    Delay                     |
  88. *                   ^     ^                              |
  89. *       FeedbackNO /_\   /_\ FeedbackNS                  |
  90. *                   |     |                     |\       v
  91. * right in ->-------+-----+---------------------| >---->(+)----> right out
  92. *                                          MixN |/
  93. *
  94. *
  95. **************
  96. *
  97. * The delay buffer: (BuffSamples = 5, Delay = 8 Total size = 13
  98. *
  99. *  1) Delay times
  100. *
  101. *  +---------+
  102. *  |         |
  103. *  v         ^
  104. * |_|_|_|_|_|_|_|_|_|_|_|_|_|
  105. * *---------*
  106. *
  107. *  2) BuffSamples times
  108. *
  109. *  +-Mix-----------+
  110. *  |               |
  111. *  ^               v
  112. * |_|_|_|_|_|_|_|_|_|_|_|_|_|
  113. * *---------*
  114. *
  115. * Or optimized using a circular buffer:
  116. *
  117. *
  118. * Offset<BuffSamples => BuffSamples-Offset times:
  119. *
  120. *  +-Mix-----------+
  121. *  |               |
  122. *  ^               v
  123. * |_|_|_|_|_|_|_|_|_|_|_|_|_|
  124. * *---------*
  125. *
  126. * BuffSamples<=Offset<=Delay => BuffSamples times:
  127. *
  128. *  +-Mix-----+
  129. *  |         |
  130. *  v         ^
  131. * |_|_|_|_|_|_|_|_|_|_|_|_|_|
  132. *           *---------*
  133. *
  134. * Offset>Delay => BuffSamples+Delay-Offset times:
  135. *
  136. *          +-Mix-----+
  137. *          |         |
  138. *          v         ^
  139. * |_|_|_|_|_|_|_|_|_|_|_|_|_|
  140. * --*               *--------
  141. *
  142. * The delay buffer: (BuffSamples = 5, Delay = 3 Total size = 8
  143. *
  144. * Offset<BuffSamples => BuffSamples-Offset times:
  145. *
  146. *  +-Mix-+
  147. *  |     |
  148. *  ^     v
  149. * |_|_|_|_|_|_|_|_|
  150. * *---------*
  151. *
  152. * Offset>=BuffSamples => BuffSamples+Delay-Offset times:
  153. *
  154. *  +-----Mix-+
  155. *  |         |
  156. *  v         ^
  157. * |_|_|_|_|_|_|_|_|
  158. * ----*     *------
  159. *
  160. *
  161. *
  162. * Algoritm:
  163. *
  164. *   LoopsLeft=BuffSamples
  165. *   Offset=0
  166. *   Src=E
  167. *   Dst=E+Delay
  168. * Loop:
  169. *   If LoopsLeft <= 0 GOTO Exit
  170. *   IF Src >= (E + MaxBuffSamples + Delay) THEN Src = Src - (MaxBuffSamples + Delay)
  171. *   IF Dst >= (E + MaxBuffSamples + Delay) THEN Dst = Dst - (MaxBuffSamples + Delay)
  172. *   IF Offset >= (MaxBuffSamples + Delay) THEN Offset = Offset - (MaxBuffSamples + Delay)
  173. *
  174. *   IF Offset < MaxBuffSamples THEN LoopTimes = MaxBuffSamples-Offset : GOTO Echo
  175. *   IF Offset <= Delay THEN LoopTimes = MaxBuffSamples : GOTO Echo 
  176. *   LoopTimes = MaxBuffSamples+Delay-Offset
  177. * Echo:
  178. *   LoopTimes = min(LoopTimes,LoopsLeft)
  179. *   Echo LoopTimes samples
  180. *
  181. *   Src = Src + LoopTimes
  182. *   Dst = Dst + LoopTimes
  183. *   Offset = Offset + LoopTimes
  184. *   LoopsLeft = LoopsLeft - LoopTimes
  185. *   GOTO Loop
  186. * Exit:
  187. *
  188.  
  189. ;in:
  190. * a0    struct Echo *
  191. * a1    Buffer pointer
  192. * a2    audioctrl
  193.  
  194. * All registers scratch
  195.  
  196. *******************************************************************************
  197.  
  198. DSPECHO_PRE    MACRO
  199. LOCALSIZE    SET    4
  200.     subq.l    #LOCALSIZE,sp            ;Local variable
  201.  
  202.     move.l    ahiac_BuffSamples(a2),(sp)    ;Looped
  203.     move.l    ahiecho_Offset(a0),d6
  204.     move.l    ahiecho_SrcPtr(a0),a3
  205.     move.l    ahiecho_DstPtr(a0),a6
  206. .loop
  207.     tst.l    (sp)
  208.     ble    .exit
  209.  
  210. * Circular buffer stuff
  211.     cmp.l    ahiecho_EndPtr(a0),a3
  212.     blo    .src_ok
  213.     sub.l    ahiecho_BufferSize(a0),a3
  214. .src_ok
  215.     cmp.l    ahiecho_EndPtr(a0),a6
  216.     blo    .dst_ok
  217.     sub.l    ahiecho_BufferSize(a0),a6
  218. .dst_ok
  219.     cmp.l    ahiecho_BufferLength(a0),d6
  220.     blo    .offs_ok
  221.     sub.l    ahiecho_BufferLength(a0),d6
  222. .offs_ok
  223.  
  224.     cmp.l    ahiac_MaxBuffSamples(a2),d6
  225.     bhs    .hi_buffsamples
  226.     move.l    ahiac_MaxBuffSamples(a2),d7
  227.     sub.l    d6,d7
  228.     bra    .echo
  229. .hi_buffsamples
  230.     cmp.l    ahiecho_Delay(a0),d6
  231.     bhi    .hi_delay
  232.     move.l    ahiac_MaxBuffSamples(a2),d7
  233.     bra    .echo
  234. .hi_delay
  235.     move.l    ahiac_MaxBuffSamples(a2),d7
  236.     add.l    ahiecho_Delay(a0),d7
  237.     sub.l    d6,d7
  238.  
  239. .echo
  240.     sub.l    d7,(sp)
  241.     bpl    .loopsleft_ok
  242.     add.l    (sp),d7                ;Gives min((sp),d7)
  243.     clr.l    (sp)
  244. .loopsleft_ok
  245.     add.l    d7,d6
  246.     subq.l    #1,d7
  247.     bmi    .exit                ;This is an error (should not happen)
  248.  
  249.  
  250. ;    movem.l    d0-d7/a0-a6,$100000
  251.     ENDM
  252.  
  253.  
  254. DSPECHO_POST    MACRO
  255.  
  256.  
  257. ;    cmp.l    ahiecho_EndPtr(a0),a3
  258. ;    bhi    .error
  259. ;    cmp.l    ahiecho_EndPtr(a0),a6
  260. ;    bhi    .error
  261. ;    cmp.l    ahiecho_BufferLength(a0),d6
  262. ;    bhi    .error
  263. ;    bra    .loop
  264. ;.error
  265. ;    pushm    a0/a1
  266. ;    move.w    #$fff,$dff180
  267. ;    lea    $100000,a0
  268. ;    lea    $110000,a1
  269. ;    move.l    (a0)+,(a1)+
  270. ;    move.l    (a0)+,(a1)+
  271. ;    move.l    (a0)+,(a1)+
  272. ;    move.l    (a0)+,(a1)+
  273. ;    move.l    (a0)+,(a1)+
  274. ;    move.l    (a0)+,(a1)+
  275. ;    move.l    (a0)+,(a1)+
  276. ;    move.l    (a0)+,(a1)+
  277. ;    move.l    (a0)+,(a1)+
  278. ;    move.l    (a0)+,(a1)+
  279. ;    move.l    (a0)+,(a1)+
  280. ;    move.l    (a0)+,(a1)+
  281. ;    move.l    (a0)+,(a1)+
  282. ;    move.l    (a0)+,(a1)+
  283. ;    move.l    (a0)+,(a1)+
  284. ;    popm    a0/a1
  285.  
  286.     bra    .loop
  287.  
  288. .exit
  289.     move.l    d6,ahiecho_Offset(a0)
  290.     move.l    a3,ahiecho_SrcPtr(a0)
  291.     move.l    a6,ahiecho_DstPtr(a0)
  292.  
  293.     addq.l    #LOCALSIZE,sp
  294.     rts
  295.     ENDM
  296.  
  297.  
  298.  
  299. _do_DSPEchoMono16:
  300.  IFGE    __CPU-68020
  301.     DSPECHO_PRE
  302. ;in:
  303. * d0-d5    Scratch
  304. * a1    & x[n]           (Advance)
  305. * a3    & d[n-N]         (Advance)
  306. * a6    & d[n]           (Advance)
  307.  
  308. .echoloop
  309.     move.w    (a1),d0                ;Get sample x[n]
  310.     ext.l    d0
  311.     move.l    d0,d1
  312.     muls.l    ahiecho_MixN(a0),d0
  313.     move.w    (a3)+,d3            ;Get delayed sample d[n-N]
  314.     ext.l    d3
  315.     move.l    d3,d2
  316.     muls.l    ahiecho_MixD(a0),d3
  317.     add.l    d0,d3
  318.     swap.w    d3
  319.     move.w    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  320.  
  321.     addq.l    #1,d2                ;Fix for -1
  322.     muls.l    ahiecho_FeedbackDS(a0),d2    ;d2=FeedbackDS*d[n-N]
  323.  
  324.     muls.l    ahiecho_FeedbackNS(a0),d1
  325.     add.l    d1,d2                ;d2=...+FeedbackNS*x[n]
  326.     swap.w    d2
  327.  
  328.     move.w    d2,(a6)+            ;store d2
  329.     dbf    d7,.echoloop
  330.     DSPECHO_POST
  331.  ENDC
  332.  
  333.  
  334. _do_DSPEchoMono16Fast:
  335.  IFGE    __CPU-68020
  336.     DSPECHO_PRE
  337. ;in:
  338. * d0-d5    Scratch
  339. * a1    & x[n]           (Advance)
  340. * a3    & d[n-N]         (Advance)
  341. * a6    & d[n]           (Advance)
  342.  
  343.     push    d6
  344.     move.l    ahiecho_MixN(a0),d4
  345.     move.l    ahiecho_MixD(a0),d5
  346.     move.l    ahiecho_FeedbackDS(a0),d6
  347. .echoloop
  348.     move.w    (a1),d0                ;Get sample x[n]
  349.     move.w    d0,d1
  350.     asr.w    d4,d0    
  351.     move.w    (a3)+,d3            ;Get delayed sample d[n-N]
  352.     move.w    d3,d2
  353.     asr.w    d5,d3
  354.     add.w    d0,d3
  355.     move.w    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  356.  
  357.     asr.w    d6,d2                ;d2=FeedbackDS*d[n-N]
  358.  
  359.     move.l    ahiecho_FeedbackNS(a0),d0
  360.     asr.w    d0,d1
  361.     add.w    d1,d2                ;d2=...+FeedbackNS*x[n]
  362.  
  363.     move.w    d2,(a6)+            ;store d2
  364.     dbf    d7,.echoloop
  365.     pop    d6
  366.     DSPECHO_POST
  367.  ENDC
  368.  
  369.  
  370. _do_DSPEchoStereo16:
  371.  IFGE    __CPU-68020
  372.     DSPECHO_PRE
  373. ;in:
  374. * d0-d5    Scratch
  375. * a1    & x[n]           (Advance)
  376. * a3    & d[n-N]         (Advance)
  377. * a6    & d[n]           (Advance)
  378.  
  379. .echoloop
  380.     move.w    (a1),d0                ;Get left sample x[n]
  381.     ext.l    d0
  382.     move.l    d0,d1
  383.     muls.l    ahiecho_MixN(a0),d0
  384.     move.w    (a3)+,d3            ;Get left delayed sample d[n-N]
  385.     ext.l    d3
  386.     move.l    d3,d2
  387.     muls.l    ahiecho_MixD(a0),d3
  388.     add.l    d0,d3
  389.     swap.w    d3
  390.     move.w    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  391.  
  392.     move.w    (a1),d0                ;Get right sample x[n]
  393.     ext.l    d0
  394.     move.l    d0,d4
  395.     muls.l    ahiecho_MixN(a0),d0
  396.     move.w    (a3)+,d3            ;Get right delayed sample d[n-N]
  397.     ext.l    d3
  398.     move.l    d3,d5
  399.     muls.l    ahiecho_MixD(a0),d3
  400.     add.l    d0,d3
  401.     swap.w    d3
  402.     move.w    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  403.  
  404.     addq.l    #1,d2                ;Fix for -1
  405.     move.l    d2,d0
  406.     muls.l    ahiecho_FeedbackDS(a0),d2    ;d2=FeedbackDS*d[n-N] (left)
  407.     muls.l    ahiecho_FeedbackDO(a0),d0
  408.  
  409.     addq.l    #1,d5                ;Fix for -1
  410.     move.l    d5,d3
  411.     muls.l    ahiecho_FeedbackDS(a0),d5    ;d5=FeedbackDS*d[n-N] (right)
  412.     muls.l    ahiecho_FeedbackDO(a0),d3
  413.  
  414.     add.l    d3,d2                ;d2=...+FeedbackDO*d[n-N]
  415.     add.l    d0,d5                ;d5=...+FeedbackDO*d[n-N]
  416.  
  417.     move.l    d1,d0
  418.     muls.l    ahiecho_FeedbackNS(a0),d0
  419.     add.l    d0,d2                ;d2=...+FeedbackNS*x[n]
  420.     muls.l    ahiecho_FeedbackNO(a0),d1
  421.     add.l    d1,d5                ;d5=...+FeedbackNO*x[n]
  422.  
  423.     move.l    d4,d0
  424.     muls.l    ahiecho_FeedbackNO(a0),d0
  425.     add.l    d0,d2                ;d2=...+FeedbackNO*x[n]
  426.     muls.l    ahiecho_FeedbackNS(a0),d4
  427.     add.l    d4,d5                ;d5=...+FeedbackNS*x[n]
  428.  
  429.     swap.w    d5
  430.     move.w    d5,d2
  431.     move.l    d2,(a6)+            ;store d2 and d5
  432.     dbf    d7,.echoloop
  433.     DSPECHO_POST
  434.  ENDC
  435.  
  436.  
  437. _do_DSPEchoStereo16Fast:
  438.  IFGE    __CPU-68020
  439.     DSPECHO_PRE
  440. ;in:
  441. * d0-d5    Scratch
  442. * a1    & x[n]           (Advance)
  443. * a3    & d[n-N]         (Advance)
  444. * a6    & d[n]           (Advance)
  445.  
  446.     push    d6
  447. .echoloop
  448.     move.w    (a1),d0                ;Get left sample x[n]
  449.     move.w    d0,d1
  450.     move.l    ahiecho_MixN(a0),d6
  451.     asr.w    d6,d0
  452.     move.w    (a3)+,d3            ;Get left delayed sample d[n-N]
  453.     move.w    d3,d2
  454.     move.l    ahiecho_MixD(a0),d6
  455.     asr.w    d6,d3
  456.     add.w    d0,d3
  457.     move.w    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  458.  
  459.     move.w    (a1),d0                ;Get right sample x[n]
  460.     move.w    d0,d4
  461.     move.l    ahiecho_MixN(a0),d6
  462.     asr.w    d6,d0
  463.     move.w    (a3)+,d3            ;Get right delayed sample d[n-N]
  464.     move.w    d3,d5
  465.     move.l    ahiecho_MixD(a0),d6
  466.     asr.w    d6,d3
  467.     add.w    d0,d3
  468.     move.w    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  469.  
  470.     move.w    d2,d0
  471.     move.l    ahiecho_FeedbackDS(a0),d6
  472.     asr.w    d6,d2                ;d2=FeedbackDS*d[n-N] (left)
  473.     move.l    ahiecho_FeedbackDO(a0),d6
  474.     asr.w    d6,d0
  475.  
  476.     move.w    d5,d3
  477.     move.l    ahiecho_FeedbackDS(a0),d6
  478.     asr.w    d6,d5                ;d5=FeedbackDS*d[n-N] (right)
  479.     move.l    ahiecho_FeedbackDO(a0),d6
  480.     asr.w    d6,d3
  481.  
  482.     add.w    d3,d2                ;d2=...+FeedbackDO*d[n-N]
  483.     add.w    d0,d5                ;d5=...+FeedbackDO*d[n-N]
  484.  
  485.     move.w    d1,d0
  486.     move.l    ahiecho_FeedbackNS(a0),d6
  487.     asr.w    d6,d0
  488.     add.w    d0,d2                ;d2=...+FeedbackNS*x[n]
  489.     move.l    ahiecho_FeedbackNO(a0),d6
  490.     asr.w    d6,d1
  491.     add.w    d1,d5                ;d5=...+FeedbackNO*x[n]
  492.  
  493.     move.w    d4,d0
  494.     move.l    ahiecho_FeedbackNO(a0),d6
  495.     asr.w    d6,d0
  496.     add.w    d0,d2                ;d2=...+FeedbackNO*x[n]
  497.     move.l    ahiecho_FeedbackNS(a0),d6
  498.     asr.w    d6,d4
  499.     add.w    d4,d5                ;d5=...+FeedbackNS*x[n]
  500.  
  501.     swap.w    d2
  502.     move.w    d5,d2
  503.     move.l    d2,(a6)+            ;store d2 and d5
  504.     dbf    d7,.echoloop
  505.     pop    d6
  506.     DSPECHO_POST
  507.  ENDC
  508.  
  509.  
  510. _do_DSPEchoMono32:
  511.  IFGE    __CPU-68020
  512.     DSPECHO_PRE
  513. ;in:
  514. * d0-d5    Scratch
  515. * a1    & x[n]           (Advance)
  516. * a3    & d[n-N]         (Advance)
  517. * a6    & d[n]           (Advance)
  518.  
  519. *** The delay buffer is only 16 bit, and only the upper word of the 32 bit
  520. *** input data is used!
  521.  
  522. .echoloop
  523.     move.w    (a1),d0                ;Get sample x[n] (high word)
  524.     ext.l    d0
  525.     move.l    d0,d1
  526.     muls.l    ahiecho_MixN(a0),d0
  527.     move.w    (a3)+,d3            ;Get delayed sample d[n-N]
  528.     ext.l    d3
  529.     move.l    d3,d2
  530.     muls.l    ahiecho_MixD(a0),d3
  531.     add.l    d0,d3
  532.     move.l    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  533.  
  534.     addq.l    #1,d2                ;Fix for -1
  535.     muls.l    ahiecho_FeedbackDS(a0),d2    ;d2=FeedbackDS*d[n-N]
  536.  
  537.     muls.l    ahiecho_FeedbackNS(a0),d1
  538.     add.l    d1,d2                ;d2=...+FeedbackNS*x[n]
  539.  
  540.     swap.w    d2
  541.     move.w    d2,(a6)+            ;store d2
  542.     dbf    d7,.echoloop
  543.     DSPECHO_POST
  544.  ENDC
  545.  
  546. _do_DSPEchoStereo32:
  547.  IFGE    __CPU-68020
  548.     DSPECHO_PRE
  549. ;in:
  550. * d0-d5    Scratch
  551. * a1    & x[n]           (Advance)
  552. * a3    & d[n-N]         (Advance)
  553. * a6    & d[n]           (Advance)
  554.  
  555. *** The delay buffer is only 16 bit, and only the upper word of the 32 bit
  556. *** input data is used!
  557.  
  558. .echoloop
  559.     move.w    (a1),d0                ;Get left sample x[n] (high word)
  560.     ext.l    d0
  561.     move.l    d0,d1
  562.     muls.l    ahiecho_MixN(a0),d0
  563.     move.w    (a3)+,d3            ;Get left delayed sample d[n-N]
  564.     ext.l    d3
  565.     move.l    d3,d2
  566.     muls.l    ahiecho_MixD(a0),d3
  567.     add.l    d0,d3
  568.     move.l    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  569.  
  570.     move.w    (a1),d0                ;Get right sample x[n] (high word)
  571.     ext.l    d0
  572.     move.l    d0,d4
  573.     muls.l    ahiecho_MixN(a0),d0
  574.     move.w    (a3)+,d3            ;Get right delayed sample d[n-N]
  575.     ext.l    d3
  576.     move.l    d3,d5
  577.     muls.l    ahiecho_MixD(a0),d3
  578.     add.l    d0,d3
  579.     move.l    d3,(a1)+            ;x[n]=MixN*x[n]+MixD*d[n-N]
  580.  
  581.     addq.l    #1,d2                ;Fix for -1
  582.     move.l    d2,d0
  583.     muls.l    ahiecho_FeedbackDS(a0),d2    ;d2=FeedbackDS*d[n-N] (left)
  584.     muls.l    ahiecho_FeedbackDO(a0),d0
  585.  
  586.     addq.l    #1,d5                ;Fix for -1
  587.     move.l    d5,d3
  588.     muls.l    ahiecho_FeedbackDS(a0),d5    ;d5=FeedbackDS*d[n-N] (right)
  589.     muls.l    ahiecho_FeedbackDO(a0),d3
  590.  
  591.     add.l    d3,d2                ;d2=...+FeedbackDO*d[n-N]
  592.     add.l    d0,d5                ;d5=...+FeedbackDO*d[n-N]
  593.  
  594.     move.l    d1,d0
  595.     muls.l    ahiecho_FeedbackNS(a0),d0
  596.     add.l    d0,d2                ;d2=...+FeedbackNS*x[n]
  597.     muls.l    ahiecho_FeedbackNO(a0),d1
  598.     add.l    d1,d5                ;d5=...+FeedbackNO*x[n]
  599.  
  600.     move.l    d4,d0
  601.     muls.l    ahiecho_FeedbackNO(a0),d0
  602.     add.l    d0,d2                ;d2=...+FeedbackNO*x[n]
  603.     muls.l    ahiecho_FeedbackNS(a0),d4
  604.     add.l    d4,d5                ;d5=...+FeedbackNS*x[n]
  605.  
  606.     swap.w    d5
  607.     move.w    d5,d2
  608.     move.l    d2,(a6)+            ;store d1 and d4
  609.     dbf    d7,.echoloop
  610.     DSPECHO_POST
  611.  ENDC
  612.  
  613.  
  614.  
  615.  
  616.  
  617. * Delay      = ahide_Delay
  618. * FeedbackDS = ahide_Feedback
  619. * FeedbackNS = (1-ahide_Feedback)
  620. *
  621. *
  622. * left in ->--------------+                              +-----> left out
  623. *                         |                              |
  624. *                        \¯/ (FeedbackNS)                |
  625. *                         v                              |
  626. *                         |                              |
  627. *                         v    |¯¯¯|                     |
  628. *                        (+)-->| T |----+----------------+
  629. *                         ^    |___|    |
  630. *                         |    Delay    |
  631. *                         |             |
  632. *                         |      /|     |
  633. *                         +-----< |-----+
  634. *                     FeedbackDS \|
  635. *
  636. *
  637. *
  638. *
  639. *
  640. * NOTE!! We tweak the MasterVolume, so we can ignore FeedbackNS! Clever, eh? ;-)
  641. *
  642. *
  643. *
  644. *
  645. *
  646. *                     FeedbackDS /|
  647. *                         +-----< |-----+
  648. *                         |      \|     |
  649. *                         |             |
  650. *                         v    |¯¯¯|    |
  651. *                        (+)-->| T |----+----------------+
  652. *                         ^    |___|                     |
  653. *                         |    Delay                     |
  654. *                         ^                              |
  655. *                        /_\ (FeedbackNS)                |
  656. *                         |                              |
  657. * right in ->-------------+                              +-----> right out
  658. *
  659.  
  660.  
  661. _do_DSPEchoMono16NCFM:
  662.  IFGE    __CPU-68020
  663.     DSPECHO_PRE
  664. ;in:
  665. * d0-d5    Scratch
  666. * a1    & x[n]           (Advance)
  667. * a3    & d[n-N]         (Advance)
  668. * a6    & d[n]           (Advance)
  669.  
  670. .echoloop
  671.     move.w    (a1),d0                ;Get sample x[n]
  672.     ext.l    d0
  673.     move.w    (a3)+,d1            ;Get delayed sample d[n-N]
  674.     move.w    d1,(a1)+
  675.     ext.l    d1
  676.     muls.l    ahiecho_FeedbackDS(a0),d1    ;FeedbackDS*d[n-N]
  677.     swap.w    d1
  678.     add.w    d0,d1
  679.     move.w    d1,(a6)+
  680.     dbf    d7,.echoloop
  681.     DSPECHO_POST
  682.  ENDC
  683.  
  684. _do_DSPEchoMono16NCFMFast:
  685.  IFGE    __CPU-68020
  686.     DSPECHO_PRE
  687. ;in:
  688. * d0-d5    Scratch
  689. * a1    & x[n]           (Advance)
  690. * a3    & d[n-N]         (Advance)
  691. * a6    & d[n]           (Advance)
  692.  
  693.     move.l    ahiecho_FeedbackDS(a0),d2
  694. .echoloop
  695.     move.w    (a1),d0                ;Get sample x[n]
  696.     move.w    (a3)+,d1            ;Get delayed sample d[n-N]
  697.     move.w    d1,(a1)+
  698.     asr.w    d2,d1                ;FeedbackDS*d[n-N]
  699.     add.w    d0,d1
  700.     move.w    d1,(a6)+
  701.     dbf    d7,.echoloop
  702.     DSPECHO_POST
  703.  ENDC
  704.  
  705.  
  706. _do_DSPEchoStereo16NCFM:
  707.  IFGE    __CPU-68020
  708.     DSPECHO_PRE
  709. ;in:
  710. * d0-d5    Scratch
  711. * a1    & x[n]           (Advance)
  712. * a3    & d[n-N]         (Advance)
  713. * a6    & d[n]           (Advance)
  714.  
  715. .echoloop
  716.     move.w    (a1),d0                ;Get sample x[n] (left)
  717.     ext.l    d0
  718.     move.w    (a3)+,d1            ;Get delayed sample d[n-N]
  719.     move.w    d1,(a1)+
  720.     ext.l    d1
  721.     muls.l    ahiecho_FeedbackDS(a0),d1    ;FeedbackDS*d[n-N]
  722.     swap.w    d1
  723.     add.w    d0,d1
  724.     move.w    d1,(a6)+
  725.  
  726.     move.w    (a1),d0                ;Get sample x[n] (right)
  727.     ext.l    d0
  728.     move.w    (a3)+,d1            ;Get delayed sample d[n-N]
  729.     move.w    d1,(a1)+
  730.     ext.l    d1
  731.     muls.l    ahiecho_FeedbackDS(a0),d1    ;FeedbackDS*d[n-N]
  732.     swap.w    d1
  733.     add.w    d0,d1
  734.     move.w    d1,(a6)+
  735.     dbf    d7,.echoloop
  736.     DSPECHO_POST
  737.  ENDC
  738.  
  739.  
  740. _do_DSPEchoStereo16NCFMFast:
  741.  IFGE    __CPU-68020
  742.     DSPECHO_PRE
  743. ;in:
  744. * d0-d5    Scratch
  745. * a1    & x[n]           (Advance)
  746. * a3    & d[n-N]         (Advance)
  747. * a6    & d[n]           (Advance)
  748.  
  749.     move.l    ahiecho_FeedbackDS(a0),d2
  750.     move.l    ahiecho_FeedbackDS(a0),d3
  751. .echoloop
  752.     move.w    (a1),d0                ;Get sample x[n]
  753.     move.w    (a3)+,d1            ;Get delayed sample d[n-N]
  754.     move.w    d1,(a1)+
  755.     asr.w    d2,d1                ;FeedbackDS*d[n-N]
  756.     add.w    d0,d1
  757.     move.w    d1,(a6)+
  758.  
  759.     move.w    (a1),d0                ;Get sample x[n]
  760.     move.w    (a3)+,d1            ;Get delayed sample d[n-N]
  761.     move.w    d1,(a1)+
  762.     asr.w    d3,d1                ;FeedbackDS*d[n-N]
  763.     add.w    d0,d1
  764.     move.w    d1,(a6)+
  765.     dbf    d7,.echoloop
  766.     DSPECHO_POST
  767.  ENDC
  768.