xfade.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include <stdlib.h>
  36. #include "xfade.h"
  37. #include "math64.h"
  38. #ifndef MIN
  39. #define MIN(a,b) ((a)<=(b)?(a):(b))
  40. #endif
  41. #define HEADROOM 0
  42. #define NALPHA 256
  43. #define FRACBITS 16
  44. #define EXTRABITS 8
  45. #define FRACMASK ((1<<FRACBITS) - 1)
  46. #define FRACROUND (1<<(FRACBITS-1))
  47. #define BATCHSIZE 512
  48. struct XFADER_STATE
  49. {
  50.     int nChannels ;
  51.     int batchSize ;
  52.     unsigned int tabacc ;
  53.     unsigned int tabstep ;
  54.     const struct COEFF *coeff ;
  55. };
  56. XFADER_STATE* XFader_init(int sampleRate, int nChannels, const struct COEFF* coeff)
  57. {
  58.     XFADER_STATE* instance = (XFADER_STATE*) calloc(1,sizeof(XFADER_STATE)) ;
  59.     if (instance)
  60.     {
  61.         instance->nChannels = nChannels ;
  62.         instance->coeff = coeff ;
  63.         instance->tabacc = NALPHA << FRACBITS ; // end of fade
  64.         // make sure batchsize is divisible by nChannels
  65.         instance->batchSize = BATCHSIZE - BATCHSIZE % nChannels ;
  66.     }
  67.     return instance ;
  68. }
  69. void XFader_free(XFADER_STATE* instance)
  70. {
  71.     if (instance) free(instance) ;
  72. }
  73. void XFader_start(int nSamples, XFADER_STATE* instance)
  74. {
  75.     nSamples /= instance->nChannels ;
  76.     instance->tabacc = 0 ;
  77.     if (nSamples < 1) nSamples = 1 ;
  78.     // (tabstep * nSamples) >> FRACBITS = NALPHA
  79. //    instance->tabstep = ((NALPHA << FRACBITS) + nSamples - 1) / nSamples ; // round up
  80.     instance->tabstep = ((NALPHA << FRACBITS) + nSamples/2) / nSamples ; // round nearest
  81. }
  82. int XFader_active(XFADER_STATE* instance)
  83. {
  84.     unsigned int tabacc = instance->tabacc ;
  85.     unsigned int tabint = tabacc >> FRACBITS ;
  86.     return (tabint < NALPHA) ;
  87. }
  88. /* In-place crossfading functionality currently untested */
  89. #if 0
  90. static int XFader_feed_mono(const INT32* in, INT32* inout, int nSamples, XFADER_STATE* instance)
  91. {
  92.     int i ;
  93.     unsigned int tabacc = instance->tabacc ;
  94.     unsigned int tabstep = instance->tabstep ;
  95.     unsigned int tabint = tabacc >> FRACBITS ;
  96.     for (i = 0 ; i < nSamples && tabint < NALPHA ; i++)
  97.     {
  98.         INT32 gain1, gain2 ;
  99.         /* interpolate new alpha */
  100.         gain1 = instance->coeff[tabint].gain ;
  101.         gain1 += (instance->coeff[tabint].delta * (signed)(tabacc & FRACMASK)) >> (FRACBITS - EXTRABITS) ;
  102.         gain2 = instance->coeff[tabint+NALPHA+1].gain ;
  103.         gain2 += (instance->coeff[tabint+NALPHA+1].delta * (signed)(tabacc & FRACMASK)) >> (FRACBITS - EXTRABITS) ;
  104.         /* next table step */
  105.         tabacc += tabstep;
  106.         tabint = tabacc >> FRACBITS;
  107.         // creates one guard bit
  108.         *inout = MulShift31(*in++, gain1) + MulShift31(*inout, gain2) ;
  109.         inout++ ;
  110.     }
  111.     instance->tabacc = tabacc ;
  112.     return nSamples ;
  113. }
  114. static int XFader_feed_stereo(const INT32* in, INT32* inout, int nSamples, XFADER_STATE* instance)
  115. {
  116.     int i ;
  117.     unsigned int tabacc = instance->tabacc ;
  118.     unsigned int tabstep = instance->tabstep ;
  119.     unsigned int tabint = tabacc >> FRACBITS ;
  120.     for (i = 0 ; i < nSamples && tabint < NALPHA ; i+=2)
  121.     {
  122.         INT32 gain1, gain2 ;
  123.         /* interpolate new alpha */
  124.         gain1 = instance->coeff[tabint].gain ;
  125.         gain1 += (instance->coeff[tabint].delta * (signed)(tabacc & FRACMASK)) >> (FRACBITS - EXTRABITS) ;
  126.         gain2 = instance->coeff[tabint+NALPHA+1].gain ;
  127.         gain2 += (instance->coeff[tabint+NALPHA+1].delta * (signed)(tabacc & FRACMASK)) >> (FRACBITS - EXTRABITS) ;
  128.         /* next table step */
  129.         tabacc += tabstep;
  130.         tabint = tabacc >> FRACBITS;
  131.         // creates one guard bit
  132.         *inout = MulShift31(*in++, gain1) + MulShift31(*inout, gain2) ;
  133.         inout++ ;
  134.         *inout = MulShift31(*in++, gain1) + MulShift31(*inout, gain2) ;
  135.         inout++ ;
  136.     }
  137.     instance->tabacc = tabacc ;
  138.     return nSamples ;
  139. }
  140. static const INT32 silence[BATCHSIZE] ; // a bunch of zeros
  141. int XFader_feed(const INT32* in, INT32* inout, int nSamples, XFADER_STATE* instance)
  142. {
  143.     int nRead = 0 ;
  144.     while (nRead < nSamples)
  145.     {
  146.         int nBatch = MIN(nSamples - nRead, instance->batchSize) ;
  147.         const INT32 *in1 = in ? (in + nRead) : silence ;
  148.         int i ;
  149.         switch (instance->nChannels)
  150.         {
  151.         case 1:
  152.             i = XFader_feed_mono  (in1, inout + nRead, nBatch, instance) ;
  153.             break ;
  154.         case 2:
  155.             i = XFader_feed_stereo(in1, inout + nRead, nBatch, instance) ;
  156.             break ;
  157.         }
  158. #if HEADROOM > 0
  159.         for (; i < nBatch ; i++)
  160.         {
  161.             inout[nRead + i] >>= HEADROOM ;
  162.         }
  163. #endif
  164.         nRead += nBatch ;
  165.     }
  166.     return nSamples ;
  167. }
  168. #endif
  169. int Fader_feed_mono(INT32 *inout, int nSamples, int fadeout, XFADER_STATE* instance)
  170. {
  171.     int i ;
  172.     unsigned int tabacc = instance->tabacc ;
  173.     unsigned int tabstep = instance->tabstep ;
  174.     unsigned int tabint = tabacc >> FRACBITS ;
  175.     const struct COEFF *coeff = instance->coeff + (fadeout ? 0 : (NALPHA+1)) ;
  176.     for (i = 0 ; i < nSamples && tabint < NALPHA ; i++)
  177.     {
  178.         /* interpolate new alpha */
  179.         INT32 gain = coeff[tabint].gain ;
  180.         gain += (coeff[tabint].delta * (signed)(tabacc & FRACMASK)) >> (FRACBITS - EXTRABITS) ;
  181.         /* next table step */
  182.         tabacc += tabstep;
  183.         tabint = tabacc >> FRACBITS;
  184.         inout[0] = MulShift30(inout[0], gain) ;
  185.         inout++ ;
  186.     }
  187.     instance->tabacc = tabacc ;
  188.     return i ;
  189. }
  190. int Fader_feed_stereo(INT32 *inout, int nSamples, int fadeout, XFADER_STATE* instance)
  191. {
  192.     int i ;
  193.     unsigned int tabacc = instance->tabacc ;
  194.     unsigned int tabstep = instance->tabstep ;
  195.     unsigned int tabint = tabacc >> FRACBITS ;
  196.     const struct COEFF *coeff = instance->coeff + (fadeout ? 0 : (NALPHA+1)) ;
  197.     for (i = 0 ; i < nSamples && tabint < NALPHA ; i+=2)
  198.     {
  199.         /* interpolate new alpha */
  200.         INT32 gain = coeff[tabint].gain ;
  201.         gain += (coeff[tabint].delta * (signed)(tabacc & FRACMASK)) >> (FRACBITS - EXTRABITS) ;
  202.         /* next table step */
  203.         tabacc += tabstep;
  204.         tabint = tabacc >> FRACBITS;
  205.         inout[0] = MulShift30(inout[0], gain) ;
  206.         inout[1] = MulShift30(inout[1], gain) ;
  207.         inout+=2 ;
  208.     }
  209.     instance->tabacc = tabacc ;
  210.     return i ;
  211. }
  212. int Fader_feed(INT32 *inout, int nSamples, int fadeout, XFADER_STATE* instance)
  213. {
  214.     int i ;
  215.     ASSERT(fadeout ==1 || fadeout==0);
  216.     switch (instance->nChannels)
  217.     {
  218.     case 1:
  219.         i = Fader_feed_mono  (inout, nSamples, fadeout, instance) ;
  220.         break ;
  221.     case 2:
  222.         i = Fader_feed_stereo(inout, nSamples, fadeout, instance) ;
  223.         break ;
  224.     }
  225.     if (fadeout)
  226.         for (; i < nSamples ; i++) inout[i] = 0 ;
  227. #if HEADROOM > 0
  228.     else
  229.         for (; i < nSamples ; i++) inout[i] >>= HEADROOM ;
  230. #endif
  231.     return nSamples ;
  232. }
  233. #if 0 // use just for table initialization
  234. static void setupDelta(struct COEFF* c)
  235. {
  236.     int i ;
  237.     for (i = 0 ; i < NALPHA ; i++)
  238.     {
  239.         c[i].delta = (c[i+1].gain - c[i].gain + (1<<(EXTRABITS-1))) >> EXTRABITS ;
  240.         assert(c[i].delta < (1<<(31-FRACBITS)));
  241.         c[i+NALPHA+1].delta = (c[i+NALPHA+2].gain - c[i+NALPHA+1].gain + (1<<(EXTRABITS-1))) >> EXTRABITS ;
  242.         assert(c[i+NALPHA+1].delta < (1<<(31-FRACBITS)));
  243.     }
  244.     c[i].delta = c[i+NALPHA+1].delta = 0 ;
  245. }
  246. #include <math.h>
  247. #include <assert.h>
  248. #include <stdio.h>
  249. #ifndef M_PI
  250. #define M_PI 3.14159265358979323846
  251. #endif
  252. struct COEFF* sintab(void)
  253. {
  254.     int i ;
  255.     struct COEFF* c = (struct COEFF*) calloc(NALPHA+1, 2*sizeof(struct COEFF)) ;
  256.     for (i = 0 ; i <= NALPHA ; i++)
  257.     {
  258.         double x = i * 0.5 * M_PI / NALPHA ;
  259.         double x1 = cos(x) ;
  260.         double x2 = sin(x) ;
  261.         x1 *= x1 ;
  262.         x2 *= x2 ;
  263.         c[i].gain          = (int)floor(0.5 + x1*(1L<<(30-HEADROOM))) ;
  264.         c[i+NALPHA+1].gain = (int)floor(0.5 + x2*(1L<<(30-HEADROOM))) ;
  265.     }
  266.     setupDelta(c) ;
  267.     {
  268.       FILE *f = fopen("c:\temp\table.c","w") ;
  269.       fprintf(f,"const struct COEFF XFader_sin2tab[2*%d] = {n /* fade out table */n",
  270.         NALPHA+1) ;
  271.       for (i=0; i<NALPHA; i+=2)
  272.       {
  273.         fprintf(f," 0x%08lx, -0x%08lx, 0x%08lx, -0x%08lx,n",
  274.           c[i+0].gain, -c[i+0].delta,
  275.           c[i+1].gain, -c[i+1].delta
  276.           );
  277.       }
  278.       fprintf(f," 0x%08lx, -0x%08lx,n /* fade in table */n",
  279.           c[NALPHA].gain, -c[NALPHA].delta) ;
  280.       for (i=NALPHA+1; i<2*NALPHA+1; i+=2)
  281.       {
  282.         fprintf(f," 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx,n",
  283.           c[i+0].gain, c[i+0].delta,
  284.           c[i+1].gain, c[i+1].delta
  285.           );
  286.       }
  287.       fprintf(f," 0x%08lx, 0x%08lx,n",
  288.           c[2*NALPHA+1].gain, c[2*NALPHA+1].delta) ;
  289.       fprintf(f,"};n");
  290.       fclose(f) ;
  291.     }
  292.     return c ;
  293. }
  294. #endif