home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 106 / EnigmaAmiga106CD.iso / software / sviluppo / ahisrc / device / addroutines_hifi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  20.1 KB  |  931 lines

  1. /* $Id: addroutines_hifi.c,v 4.1 1999/09/11 20:35:29 lcs Exp $ */
  2.  
  3. /*
  4.      AHI - Hardware independent audio subsystem
  5.      Copyright (C) 1996-1999 Martin Blom <martin@blom.org>
  6.      
  7.      This library is free software; you can redistribute it and/or
  8.      modify it under the terms of the GNU Library General Public
  9.      License as published by the Free Software Foundation; either
  10.      version 2 of the License, or (at your option) any later version.
  11.      
  12.      This library is distributed in the hope that it will be useful,
  13.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.      Library General Public License for more details.
  16.      
  17.      You should have received a copy of the GNU Library General Public
  18.      License along with this library; if not, write to the
  19.      Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
  20.      MA 02139, USA.
  21. */
  22.  
  23. #include <config.h>
  24. #include <CompilerSpecific.h>
  25. #include "addroutines.h"
  26.  
  27. /******************************************************************************
  28. ** Add-Routines ***************************************************************
  29. ******************************************************************************/
  30.  
  31. /*
  32. ** LONG      Samples
  33. ** LONG      ScaleLeft
  34. ** LONG      ScaleRight
  35. ** LONG        *StartPointLeft
  36. ** LONG        *StartPointRight
  37. ** void     *Src
  38. ** void    **Dst
  39. ** LONG         FirstOffsetI
  40. ** Fixed64  *Offset
  41. ** Fixed64   Add
  42. ** BOOL      StopAtZero
  43. */
  44.  
  45. /*
  46.  
  47. Notes:
  48.  
  49. The fraction offset is divided by two in order to make sure that the
  50. calculation of linearsample fits a LONG (0 =< offsetf <= 32767).
  51.  
  52. The routines could be faster, of course.  One idea is to split the for loop
  53. into two loops in order to eliminate the FirstOffsetI test in the second loop.
  54.  
  55. */ 
  56.  
  57. /*****************************************************************************/
  58.  
  59. /* Forward mixing code */
  60.  
  61. #define offseti ( (long) ( offset >> 32 ) )
  62.  
  63. #define offsetf ( (long) ( (unsigned long) ( offset & 0xffffffffULL ) >> 17) )
  64.  
  65. LONG
  66. AddByteMono( ADDARGS )
  67. {
  68.   BYTE    *src    = Src;
  69.   LONG    *dst    = *Dst;
  70.   Fixed64  offset = *Offset;
  71.   int      i;
  72.   LONG     startpoint, endpoint = 0; // Make compiler happy
  73.   LONG     lastpoint;
  74.  
  75.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  76.  
  77.   for( i = 0; i < Samples; i++)
  78.   {
  79.     if( offseti == FirstOffsetI ) {
  80.       startpoint = *StartPointLeft;
  81.     }
  82.     else
  83.     {
  84.       startpoint = src[ offseti - 1 ] << 8;
  85.     }
  86.  
  87.     endpoint = src[ offseti ] << 8;
  88.  
  89.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  90.  
  91.     if( StopAtZero &&
  92.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  93.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  94.     {
  95.       break;
  96.     }
  97.  
  98.     lastpoint = startpoint;
  99.  
  100.     *dst++ += ScaleLeft * startpoint;
  101.  
  102.     offset += Add;
  103.   }
  104.  
  105.   *StartPointLeft = endpoint;
  106.  
  107.   *Dst    = dst;
  108.   *Offset = offset;
  109.  
  110.   return i;
  111. }
  112.  
  113.  
  114. LONG
  115. AddByteStereo( ADDARGS )
  116. {
  117.   BYTE    *src    = Src;
  118.   LONG    *dst    = *Dst;
  119.   Fixed64  offset = *Offset;
  120.   int      i;
  121.   LONG     startpoint, endpoint = 0; // Make compiler happy
  122.   LONG     lastpoint;
  123.  
  124.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  125.   
  126.   for( i = 0; i < Samples; i++)
  127.   {
  128.     if( offseti == FirstOffsetI ) {
  129.       startpoint = *StartPointLeft;
  130.     }
  131.     else
  132.     {
  133.       startpoint = src[ offseti - 1 ] << 8;
  134.     }
  135.  
  136.     endpoint = src[ offseti ] << 8;
  137.  
  138.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  139.  
  140.     if( StopAtZero &&
  141.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  142.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  143.     {
  144.       break;
  145.     }
  146.  
  147.     lastpoint = startpoint;
  148.  
  149.     *dst++ += ScaleLeft * startpoint;
  150.     *dst++ += ScaleRight * startpoint;
  151.  
  152.     offset += Add;
  153.   }
  154.  
  155.   *StartPointLeft = endpoint;
  156.  
  157.   *Dst    = dst;
  158.   *Offset = offset;
  159.  
  160.   return i;
  161. }
  162.  
  163.  
  164. LONG
  165. AddBytesMono( ADDARGS )
  166. {
  167.   BYTE    *src    = Src;
  168.   LONG    *dst    = *Dst;
  169.   Fixed64  offset = *Offset;
  170.   int      i;
  171.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  172.   LONG     lastpointL, lastpointR;
  173.  
  174.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  175.  
  176.   for( i = 0; i < Samples; i++)
  177.   {
  178.     if( offseti == FirstOffsetI ) {
  179.       startpointL = *StartPointLeft;
  180.       startpointR = *StartPointRight;
  181.     }
  182.     else
  183.     {
  184.       startpointL = src[ offseti * 2 + 0 - 2 ] << 8;
  185.       startpointR = src[ offseti * 2 + 1 - 2 ] << 8;
  186.     }
  187.  
  188.     endpointL = src[ offseti * 2 + 0 ] << 8;
  189.     endpointR = src[ offseti * 2 + 1 ] << 8;
  190.  
  191.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  192.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  193.  
  194.     if( StopAtZero &&
  195.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  196.           ( lastpointR < 0 && startpointR >= 0 ) ||
  197.           ( lastpointL > 0 && startpointL <= 0 ) ||
  198.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  199.     {
  200.       break;
  201.     }
  202.  
  203.     lastpointL = startpointL;
  204.     lastpointR = startpointR;
  205.  
  206.     *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
  207.  
  208.     offset += Add;
  209.   }
  210.  
  211.   *StartPointLeft = endpointL;
  212.   *StartPointRight = endpointR;
  213.  
  214.   *Dst    = dst;
  215.   *Offset = offset;
  216.  
  217.   return i;
  218. }
  219.  
  220.  
  221. LONG
  222. AddBytesStereo( ADDARGS )
  223. {
  224.   BYTE    *src    = Src;
  225.   LONG    *dst    = *Dst;
  226.   Fixed64  offset = *Offset;
  227.   int      i;
  228.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  229.   LONG     lastpointL, lastpointR;
  230.  
  231.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  232.  
  233.   for( i = 0; i < Samples; i++)
  234.   {
  235.     if( offseti == FirstOffsetI ) {
  236.       startpointL = *StartPointLeft;
  237.       startpointR = *StartPointRight;
  238.     }
  239.     else
  240.     {
  241.       startpointL = src[ offseti * 2 + 0 - 2 ] << 8;
  242.       startpointR = src[ offseti * 2 + 1 - 2 ] << 8;
  243.     }
  244.  
  245.     endpointL = src[ offseti * 2 + 0 ] << 8;
  246.     endpointR = src[ offseti * 2 + 1 ] << 8;
  247.  
  248.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  249.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  250.  
  251.     if( StopAtZero &&
  252.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  253.           ( lastpointR < 0 && startpointR >= 0 ) ||
  254.           ( lastpointL > 0 && startpointL <= 0 ) ||
  255.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  256.     {
  257.       break;
  258.     }
  259.  
  260.     lastpointL = startpointL;
  261.     lastpointR = startpointR;
  262.  
  263.     *dst++ += ScaleLeft * startpointL;
  264.     *dst++ += ScaleRight * startpointR;
  265.  
  266.     offset += Add;
  267.   }
  268.  
  269.   *StartPointLeft = endpointL;
  270.   *StartPointRight = endpointR;
  271.  
  272.   *Dst    = dst;
  273.   *Offset = offset;
  274.  
  275.   return i;
  276. }
  277.  
  278.  
  279. LONG
  280. AddWordMono( ADDARGS )
  281. {
  282.   WORD    *src    = Src;
  283.   LONG    *dst    = *Dst;
  284.   Fixed64  offset = *Offset;
  285.   int      i;
  286.   LONG     startpoint, endpoint = 0; // Make compiler happy
  287.   LONG     lastpoint;
  288.  
  289.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  290.  
  291.   for( i = 0; i < Samples; i++)
  292.   {
  293.     if( offseti == FirstOffsetI ) {
  294.       startpoint = *StartPointLeft;
  295.     }
  296.     else
  297.     {
  298.       startpoint = src[ offseti - 1 ];
  299.     }
  300.  
  301.     endpoint = src[ offseti ];
  302.  
  303.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  304.  
  305.     if( StopAtZero &&
  306.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  307.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  308.     {
  309.       break;
  310.     }
  311.  
  312.     lastpoint = startpoint;
  313.  
  314.     *dst++ += ScaleLeft * startpoint;
  315.  
  316.     offset += Add;
  317.   }
  318.  
  319.   *StartPointLeft = endpoint;
  320.  
  321.   *Dst    = dst;
  322.   *Offset = offset;
  323.  
  324.   return i;
  325. }
  326.  
  327.  
  328. LONG
  329. AddWordStereo( ADDARGS )
  330. {
  331.   WORD    *src    = Src;
  332.   LONG    *dst    = *Dst;
  333.   Fixed64  offset = *Offset;
  334.   int      i;
  335.   LONG     startpoint, endpoint = 0; // Make compiler happy
  336.   LONG     lastpoint;
  337.  
  338.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  339.   
  340.   for( i = 0; i < Samples; i++)
  341.   {
  342.     if( offseti == FirstOffsetI ) {
  343.       startpoint = *StartPointLeft;
  344.     }
  345.     else
  346.     {
  347.       startpoint = src[ offseti - 1 ];
  348.     }
  349.  
  350.     endpoint = src[ offseti ];
  351.  
  352.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  353.  
  354.     if( StopAtZero &&
  355.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  356.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  357.     {
  358.       break;
  359.     }
  360.  
  361.     lastpoint = startpoint;
  362.  
  363.     *dst++ += ScaleLeft * startpoint;
  364.     *dst++ += ScaleRight * startpoint;
  365.  
  366.     offset += Add;
  367.   }
  368.  
  369.   *StartPointLeft = endpoint;
  370.  
  371.   *Dst    = dst;
  372.   *Offset = offset;
  373.  
  374.   return i;
  375. }
  376.  
  377. LONG
  378. AddWordsMono( ADDARGS )
  379. {
  380.   WORD    *src    = Src;
  381.   LONG    *dst    = *Dst;
  382.   Fixed64  offset = *Offset;
  383.   int      i;
  384.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  385.   LONG     lastpointL, lastpointR;
  386.  
  387.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  388.  
  389.   for( i = 0; i < Samples; i++)
  390.   {
  391.     if( offseti == FirstOffsetI ) {
  392.       startpointL = *StartPointLeft;
  393.       startpointR = *StartPointRight;
  394.     }
  395.     else
  396.     {
  397.       startpointL = src[ offseti * 2 + 0 - 2 ];
  398.       startpointR = src[ offseti * 2 + 1 - 2 ];
  399.     }
  400.  
  401.     endpointL = src[ offseti * 2 + 0 ];
  402.     endpointR = src[ offseti * 2 + 1 ];
  403.  
  404.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  405.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  406.  
  407.     if( StopAtZero &&
  408.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  409.           ( lastpointR < 0 && startpointR >= 0 ) ||
  410.           ( lastpointL > 0 && startpointL <= 0 ) ||
  411.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  412.     {
  413.       break;
  414.     }
  415.  
  416.     lastpointL = startpointL;
  417.     lastpointR = startpointR;
  418.  
  419.     *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
  420.  
  421.     offset += Add;
  422.   }
  423.  
  424.   *StartPointLeft = endpointL;
  425.   *StartPointRight = endpointR;
  426.  
  427.   *Dst    = dst;
  428.   *Offset = offset;
  429.  
  430.   return i;
  431. }
  432.  
  433.  
  434. LONG
  435. AddWordsStereo( ADDARGS )
  436. {
  437.   WORD    *src    = Src;
  438.   LONG    *dst    = *Dst;
  439.   Fixed64  offset = *Offset;
  440.   int      i;
  441.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  442.   LONG     lastpointL, lastpointR;
  443.  
  444.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  445.  
  446.   for( i = 0; i < Samples; i++)
  447.   {
  448.     if( offseti == FirstOffsetI ) {
  449.       startpointL = *StartPointLeft;
  450.       startpointR = *StartPointRight;
  451.     }
  452.     else
  453.     {
  454.       startpointL = src[ offseti * 2 + 0 - 2 ];
  455.       startpointR = src[ offseti * 2 + 1 - 2 ];
  456.     }
  457.  
  458.     endpointL = src[ offseti * 2 + 0 ];
  459.     endpointR = src[ offseti * 2 + 1 ];
  460.  
  461.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  462.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  463.  
  464.     if( StopAtZero &&
  465.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  466.           ( lastpointR < 0 && startpointR >= 0 ) ||
  467.           ( lastpointL > 0 && startpointL <= 0 ) ||
  468.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  469.     {
  470.       break;
  471.     }
  472.  
  473.     lastpointL = startpointL;
  474.     lastpointR = startpointR;
  475.  
  476.     *dst++ += ScaleLeft * startpointL;
  477.     *dst++ += ScaleRight * startpointR;
  478.  
  479.     offset += Add;
  480.   }
  481.  
  482.   *StartPointLeft = endpointL;
  483.   *StartPointRight = endpointR;
  484.  
  485.   *Dst    = dst;
  486.   *Offset = offset;
  487.  
  488.   return i;
  489. }
  490.  
  491. #undef offsetf
  492.  
  493. /*****************************************************************************/
  494.  
  495. /* Backward mixing code */
  496.  
  497. #define offsetf ( (long) ( 32768 - ( (unsigned long) ( offset & 0xffffffffULL ) >> 17 ) ) )
  498.  
  499. LONG
  500. AddByteMonoB( ADDARGS )
  501. {
  502.   BYTE    *src    = Src;
  503.   LONG    *dst    = *Dst;
  504.   Fixed64  offset = *Offset;
  505.   int      i;
  506.   LONG     startpoint, endpoint = 0; // Make compiler happy
  507.   LONG     lastpoint;
  508.  
  509.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  510.  
  511.   for( i = 0; i < Samples; i++)
  512.   {
  513.     if( offseti == FirstOffsetI ) {
  514.       startpoint = *StartPointLeft;
  515.     }
  516.     else
  517.     {
  518.       startpoint = src[ offseti + 1 ] << 8;
  519.     }
  520.  
  521.     endpoint = src[ offseti ] << 8;
  522.  
  523.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  524.  
  525.     if( StopAtZero &&
  526.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  527.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  528.     {
  529.       break;
  530.     }
  531.  
  532.     lastpoint = startpoint;
  533.  
  534.     *dst++ += ScaleLeft * startpoint;
  535.  
  536.     offset -= Add;
  537.   }
  538.  
  539.   *StartPointLeft = endpoint;
  540.  
  541.   *Dst    = dst;
  542.   *Offset = offset;
  543.  
  544.   return i;
  545. }
  546.  
  547.  
  548. LONG
  549. AddByteStereoB( ADDARGS )
  550. {
  551.   BYTE    *src    = Src;
  552.   LONG    *dst    = *Dst;
  553.   Fixed64  offset = *Offset;
  554.   int      i;
  555.   LONG     startpoint, endpoint = 0; // Make compiler happy
  556.   LONG     lastpoint;
  557.  
  558.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  559.   
  560.   for( i = 0; i < Samples; i++)
  561.   {
  562.     if( offseti == FirstOffsetI ) {
  563.       startpoint = *StartPointLeft;
  564.     }
  565.     else
  566.     {
  567.       startpoint = src[ offseti + 1 ] << 8;
  568.     }
  569.  
  570.     endpoint = src[ offseti ] << 8;
  571.  
  572.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  573.  
  574.     if( StopAtZero &&
  575.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  576.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  577.     {
  578.       break;
  579.     }
  580.  
  581.     lastpoint = startpoint;
  582.  
  583.     *dst++ += ScaleLeft * startpoint;
  584.     *dst++ += ScaleRight * startpoint;
  585.  
  586.     offset -= Add;
  587.   }
  588.  
  589.   *StartPointLeft = endpoint;
  590.  
  591.   *Dst    = dst;
  592.   *Offset = offset;
  593.  
  594.   return i;
  595. }
  596.  
  597.  
  598. LONG
  599. AddBytesMonoB( ADDARGS )
  600. {
  601.   BYTE    *src    = Src;
  602.   LONG    *dst    = *Dst;
  603.   Fixed64  offset = *Offset;
  604.   int      i;
  605.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  606.   LONG     lastpointL, lastpointR;
  607.  
  608.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  609.  
  610.   for( i = 0; i < Samples; i++)
  611.   {
  612.     if( offseti == FirstOffsetI ) {
  613.       startpointL = *StartPointLeft;
  614.       startpointR = *StartPointRight;
  615.     }
  616.     else
  617.     {
  618.       startpointL = src[ offseti * 2 + 0 + 2 ] << 8;
  619.       startpointR = src[ offseti * 2 + 1 + 2 ] << 8;
  620.     }
  621.  
  622.     endpointL = src[ offseti * 2 + 0 ] << 8;
  623.     endpointR = src[ offseti * 2 + 1 ] << 8;
  624.  
  625.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  626.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  627.  
  628.     if( StopAtZero &&
  629.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  630.           ( lastpointR < 0 && startpointR >= 0 ) ||
  631.           ( lastpointL > 0 && startpointL <= 0 ) ||
  632.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  633.     {
  634.       break;
  635.     }
  636.  
  637.     lastpointL = startpointL;
  638.     lastpointR = startpointR;
  639.  
  640.     *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
  641.  
  642.     offset -= Add;
  643.   }
  644.  
  645.   *StartPointLeft = endpointL;
  646.   *StartPointRight = endpointR;
  647.  
  648.   *Dst    = dst;
  649.   *Offset = offset;
  650.  
  651.   return i;
  652. }
  653.  
  654.  
  655. LONG
  656. AddBytesStereoB( ADDARGS )
  657. {
  658.   BYTE    *src    = Src;
  659.   LONG    *dst    = *Dst;
  660.   Fixed64  offset = *Offset;
  661.   int      i;
  662.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  663.   LONG     lastpointL, lastpointR;
  664.  
  665.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  666.  
  667.   for( i = 0; i < Samples; i++)
  668.   {
  669.     if( offseti == FirstOffsetI ) {
  670.       startpointL = *StartPointLeft;
  671.       startpointR = *StartPointRight;
  672.     }
  673.     else
  674.     {
  675.       startpointL = src[ offseti * 2 + 0 + 2 ] << 8;
  676.       startpointR = src[ offseti * 2 + 1 + 2 ] << 8;
  677.     }
  678.  
  679.     endpointL = src[ offseti * 2 + 0 ] << 8;
  680.     endpointR = src[ offseti * 2 + 1 ] << 8;
  681.  
  682.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  683.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  684.  
  685.     if( StopAtZero &&
  686.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  687.           ( lastpointR < 0 && startpointR >= 0 ) ||
  688.           ( lastpointL > 0 && startpointL <= 0 ) ||
  689.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  690.     {
  691.       break;
  692.     }
  693.  
  694.     lastpointL = startpointL;
  695.     lastpointR = startpointR;
  696.  
  697.     *dst++ += ScaleLeft * startpointL;
  698.     *dst++ += ScaleRight * startpointR;
  699.  
  700.     offset -= Add;
  701.   }
  702.  
  703.   *StartPointLeft = endpointL;
  704.   *StartPointRight = endpointR;
  705.  
  706.   *Dst    = dst;
  707.   *Offset = offset;
  708.  
  709.   return i;
  710. }
  711.  
  712.  
  713. LONG
  714. AddWordMonoB( ADDARGS )
  715. {
  716.   WORD    *src    = Src;
  717.   LONG    *dst    = *Dst;
  718.   Fixed64  offset = *Offset;
  719.   int      i;
  720.   LONG     startpoint, endpoint = 0; // Make compiler happy
  721.   LONG     lastpoint;
  722.  
  723.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  724.  
  725.   for( i = 0; i < Samples; i++)
  726.   {
  727.     if( offseti == FirstOffsetI ) {
  728.       startpoint = *StartPointLeft;
  729.     }
  730.     else
  731.     {
  732.       startpoint = src[ offseti + 1 ];
  733.     }
  734.  
  735.     endpoint = src[ offseti ];
  736.  
  737.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  738.  
  739.     if( StopAtZero &&
  740.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  741.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  742.     {
  743.       break;
  744.     }
  745.  
  746.     lastpoint = startpoint;
  747.  
  748.     *dst++ += ScaleLeft * startpoint;
  749.  
  750.     offset -= Add;
  751.   }
  752.  
  753.   *StartPointLeft = endpoint;
  754.  
  755.   *Dst    = dst;
  756.   *Offset = offset;
  757.  
  758.   return i;
  759. }
  760.  
  761.  
  762. LONG
  763. AddWordStereoB( ADDARGS )
  764. {
  765.   WORD    *src    = Src;
  766.   LONG    *dst    = *Dst;
  767.   Fixed64  offset = *Offset;
  768.   int      i;
  769.   LONG     startpoint, endpoint = 0; // Make compiler happy
  770.   LONG     lastpoint;
  771.  
  772.   lastpoint = 0;                      // 0 doesn't affect the StopAtZero code
  773.   
  774.   for( i = 0; i < Samples; i++)
  775.   {
  776.     if( offseti == FirstOffsetI ) {
  777.       startpoint = *StartPointLeft;
  778.     }
  779.     else
  780.     {
  781.       startpoint = src[ offseti + 1 ];
  782.     }
  783.  
  784.     endpoint = src[ offseti ];
  785.  
  786.     startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
  787.  
  788.     if( StopAtZero &&
  789.         ( ( lastpoint < 0 && startpoint >= 0 ) ||
  790.           ( lastpoint > 0 && startpoint <= 0 ) ) )
  791.     {
  792.       break;
  793.     }
  794.  
  795.     lastpoint = startpoint;
  796.  
  797.     *dst++ += ScaleLeft * startpoint;
  798.     *dst++ += ScaleRight * startpoint;
  799.  
  800.     offset -= Add;
  801.   }
  802.  
  803.   *StartPointLeft = endpoint;
  804.  
  805.   *Dst    = dst;
  806.   *Offset = offset;
  807.  
  808.   return i;
  809. }
  810.  
  811.  
  812. LONG
  813. AddWordsMonoB( ADDARGS )
  814. {
  815.   WORD    *src    = Src;
  816.   LONG    *dst    = *Dst;
  817.   Fixed64  offset = *Offset;
  818.   int      i;
  819.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  820.   LONG     lastpointL, lastpointR;
  821.  
  822.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  823.  
  824.   for( i = 0; i < Samples; i++)
  825.   {
  826.     if( offseti == FirstOffsetI ) {
  827.       startpointL = *StartPointLeft;
  828.       startpointR = *StartPointRight;
  829.     }
  830.     else
  831.     {
  832.       startpointL = src[ offseti * 2 + 0 + 2 ];
  833.       startpointR = src[ offseti * 2 + 1 + 2 ];
  834.     }
  835.  
  836.     endpointL = src[ offseti * 2 + 0 ];
  837.     endpointR = src[ offseti * 2 + 1 ];
  838.  
  839.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  840.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  841.  
  842.     if( StopAtZero &&
  843.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  844.           ( lastpointR < 0 && startpointR >= 0 ) ||
  845.           ( lastpointL > 0 && startpointL <= 0 ) ||
  846.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  847.     {
  848.       break;
  849.     }
  850.  
  851.     lastpointL = startpointL;
  852.     lastpointR = startpointR;
  853.  
  854.     *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
  855.  
  856.     offset -= Add;
  857.   }
  858.  
  859.   *StartPointLeft = endpointL;
  860.   *StartPointRight = endpointR;
  861.  
  862.   *Dst    = dst;
  863.   *Offset = offset;
  864.  
  865.   return i;
  866. }
  867.  
  868.  
  869. LONG
  870. AddWordsStereoB( ADDARGS )
  871. {
  872.   WORD    *src    = Src;
  873.   LONG    *dst    = *Dst;
  874.   Fixed64  offset = *Offset;
  875.   int      i;
  876.   LONG     startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
  877.   LONG     lastpointL, lastpointR;
  878.  
  879.   lastpointL = lastpointR = 0;        // 0 doesn't affect the StopAtZero code
  880.  
  881.   for( i = 0; i < Samples; i++)
  882.   {
  883.     if( offseti == FirstOffsetI ) {
  884.       startpointL = *StartPointLeft;
  885.       startpointR = *StartPointRight;
  886.     }
  887.     else
  888.     {
  889.       startpointL = src[ offseti * 2 + 0 + 2 ];
  890.       startpointR = src[ offseti * 2 + 1 + 2 ];
  891.     }
  892.  
  893.     endpointL = src[ offseti * 2 + 0 ];
  894.     endpointR = src[ offseti * 2 + 1 ];
  895.  
  896.     startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
  897.     startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
  898.  
  899.     if( StopAtZero &&
  900.         ( ( lastpointL < 0 && startpointL >= 0 ) ||
  901.           ( lastpointR < 0 && startpointR >= 0 ) ||
  902.           ( lastpointL > 0 && startpointL <= 0 ) ||
  903.           ( lastpointR > 0 && startpointR <= 0 ) ) )
  904.     {
  905.       break;
  906.     }
  907.  
  908.     lastpointL = startpointL;
  909.     lastpointR = startpointR;
  910.  
  911.     *dst++ += ScaleLeft * startpointL;
  912.     *dst++ += ScaleRight * startpointR;
  913.  
  914.     offset -= Add;
  915.   }
  916.  
  917.   *StartPointLeft = endpointL;
  918.   *StartPointRight = endpointR;
  919.  
  920.   *Dst    = dst;
  921.   *Offset = offset;
  922.  
  923.   return i;
  924. }
  925.  
  926.  
  927. #undef offseti
  928. #undef offsetf
  929.  
  930. /*****************************************************************************/
  931.