crosfade.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:7k
源码类别:

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. /****************************************************************************
  36.  *
  37.  * Fixed-point crossfade.
  38.  * Uses arbitrary lookup table, with table interpolation.
  39.  *
  40.  */
  41. #include "hxtypes.h"
  42. #include "hxresult.h"
  43. #include "hxassert.h"
  44. #include "hlxclib/stdio.h"
  45. #include "hlxclib/math.h"
  46. #include "crosfade.h"
  47. #include "hxheap.h"
  48. #ifdef _DEBUG
  49. #undef HX_THIS_FILE
  50. static const char HX_THIS_FILE[] = __FILE__;
  51. #endif
  52. //#define GENERATE_TABLE 1
  53. #define TABLE_FILE_NAME     "table.cpp"
  54. CrossFader::CrossFader()
  55.     : tabstep(0)
  56.     , tabacc(0)
  57.     , tabint(0)
  58.     , m_uNumChannels(0)
  59.     , m_bInitialized(FALSE)
  60. {
  61. }
  62. CrossFader::~CrossFader()
  63. {
  64. }
  65. HX_RESULT
  66. CrossFader::Initialize(UINT16 uNumSamplesToFadeOn, UINT16 uNumChannels)
  67. {
  68.     HX_ASSERT(uNumSamplesToFadeOn > 0 && uNumChannels > 0);
  69.     if (uNumSamplesToFadeOn == 0 || uNumChannels == 0)
  70.     {
  71. return HXR_INVALID_PARAMETER;
  72.     }
  73.     tabacc = 0; /* accumulator */
  74.     tabint = 0; /* table index */
  75.     tabstep = (NALPHA << FRACBITS) / uNumSamplesToFadeOn;
  76.     m_uNumChannels = uNumChannels;
  77.     m_bInitialized  = TRUE;
  78.     return HXR_OK;
  79. }
  80. /*
  81.  * Crossfades over nfade samples, operating in-place on sampnew.
  82.  * alpha values are generated from table via linear interpolation.
  83.  */
  84. void
  85. CrossFader::CrossFade(INT16* sampold, INT16* sampnew, UINT16 uNumSamples)
  86. {
  87.     INT32 alerp, sdelta;
  88.     UINT16 n;
  89.     if (!m_bInitialized)
  90.     {
  91. return;
  92.     }
  93. /*  if we are doing more samples than the table is set up for  */
  94. /*  just keep tail of sampnew as is (i.e. reduce uNumSamples we are mixing over) */
  95. if( ((tabacc + (uNumSamples-1)*tabstep)>>FRACBITS) >= NALPHA)
  96. {
  97. uNumSamples = ((1+((((INT32)NALPHA)<<FRACBITS)-tabacc))/tabstep)-1;
  98. }
  99.  
  100.     /* crossfade, stepping thru table in fixed point */
  101.     for (n = 0; n < uNumSamples; n++) 
  102.     {
  103. /* interpolate new alpha */
  104. alerp = alpha[tabint];
  105. alerp += (adelta[tabint] * (tabacc & FRACMASK)) >> FRACBITS;
  106. /* next table step */
  107. tabacc += tabstep;
  108. tabint = tabacc >> FRACBITS;
  109. for (UINT16 uNumChannels = 0; uNumChannels < m_uNumChannels; uNumChannels++)
  110. {
  111.     /* crossfade, using interpolated alpha */
  112.     sdelta = alerp * (*sampold - *sampnew);
  113.     *sampnew += int((sdelta + FRACROUND) >> FRACBITS);
  114.     sampold++;
  115.     sampnew++;
  116. }
  117.     }
  118. }
  119. // XXXNH: CrossFadeInit() *only* appears to be used from the main() in this
  120. // file, which in turn is only used when GENERATE_TABLE is defined.  For
  121. // ordinary circumstances I think it is therefore acceptable to completely
  122. // #ifdef this out.
  123. #ifdef GENERATE_TABLE
  124. /*
  125.  * Initialize crossfade tables.
  126.  * Currently using linear dB, but could be anything...
  127.  * This code is ONLY used to generate static tables.
  128.  */
  129. void
  130. CrossFader::CrossFadeInit(void)
  131. {
  132.     double dbval, dbstep;
  133.     int n;
  134. //#ifdef GENERATE_TABLE
  135.     FILE* fd = fopen(TABLE_FILE_NAME, "w+");
  136.     fprintf(fd, "#ifdef GENERATE_TABLEn");
  137.     fprintf(fd, "static INT32 alpha[NALPHA+1] = {n");
  138.     fprintf(fd, "#elsen");
  139.     fprintf(fd, "static const INT32 alpha[NALPHA+1] = {n");
  140.     fprintf(fd, "#endifn");
  141.     fprintf(fd, "ntttt");
  142. //#endif /*GENERATE_TABLE*/
  143.     /* generate alpha table */
  144.     dbstep = (DBEND - DBSTART) / (NALPHA - 1);
  145.     for (n = 0; n < NALPHA; n++) 
  146.     {
  147. /* linear steps in dB */
  148. dbval = DBSTART + (dbstep * n);
  149. /* store as gains, in fixed point */
  150. alpha[n] = (int) (DB2GAIN(dbval) * (1<<FRACBITS) + 0.5);
  151. //#ifdef GENERATE_TABLE
  152. fprintf(fd, "%d, ", alpha[n]);
  153. if ((n+1) % 5 == 0)
  154. {
  155.     fprintf(fd, "ntttt");
  156. }
  157. //#endif /*GENERATE_TABLE*/
  158.     }
  159.     alpha[n] = alpha[n-1]; /* in case roundoff oversteps */
  160. //#ifdef GENERATE_TABLE
  161.     fprintf(fd, "%dn", alpha[n]);
  162.     fprintf(fd, "};nn");
  163.     fprintf(fd, "#ifdef GENERATE_TABLEn");
  164.     fprintf(fd, "static INT32 adelta[NALPHA] = {n");
  165.     fprintf(fd, "#elsen");
  166.     fprintf(fd, "static const INT32 adelta[NALPHA] = {n");
  167.     fprintf(fd, "#endifn");
  168.     fprintf(fd, "ntttt");
  169. //#endif /*GENERATE_TABLE*/
  170.     /* generate delta table, for fast interpolate */
  171.     for (n = 0; n < NALPHA-1; n++)
  172.     {
  173. adelta[n] = alpha[n+1] - alpha[n];
  174. //#ifdef GENERATE_TABLE
  175. fprintf(fd, "%d, ", adelta[n]);
  176. if ((n+1)%5 == 0)
  177. {
  178.     fprintf(fd, "ntttt");
  179. }
  180. //#endif /*GENERATE_TABLE*/
  181.     }
  182.     adelta[n] = 0; /* in case roundoff oversteps */
  183. //#ifdef GENERATE_TABLE
  184.     fprintf(fd, "%dn", adelta[n]);
  185.     fprintf(fd, "};nn");
  186.     fclose(fd);
  187. //#endif /*GENERATE_TABLE*/
  188. }
  189. #endif /*GENERATE_TABLE*/
  190. /*
  191.  * test app
  192.  */
  193. #ifdef GENERATE_TABLE
  194. #define NMAX 4096
  195. short testold[NMAX];
  196. short testnew[NMAX];
  197. int
  198. main(void)
  199. {
  200. int n;
  201. for (n = 0; n < NMAX; n++) {
  202. testold[n] = -32768;
  203. testnew[n] = 32767;
  204. }
  205. CrossFader cf;
  206. cf.CrossFadeInit();
  207. cf.CrossFade(testold, testnew, 1024);
  208. return 0;
  209. }
  210. #endif /*GENERATE_TABLE*/