crosfade.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:7k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: crosfade.cpp,v 1.4.32.1 2004/07/09 02:08:08 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. /****************************************************************************
  50.  *
  51.  * Fixed-point crossfade.
  52.  * Uses arbitrary lookup table, with table interpolation.
  53.  *
  54.  */
  55. #include "hxtypes.h"
  56. #include "hxresult.h"
  57. #include "hxassert.h"
  58. #include "hlxclib/stdio.h"
  59. #include "hlxclib/math.h"
  60. #include "crosfade.h"
  61. #include "hxheap.h"
  62. #ifdef _DEBUG
  63. #undef HX_THIS_FILE
  64. static const char HX_THIS_FILE[] = __FILE__;
  65. #endif
  66. //#define GENERATE_TABLE 1
  67. #define TABLE_FILE_NAME     "table.cpp"
  68. CrossFader::CrossFader()
  69.     : tabstep(0)
  70.     , tabacc(0)
  71.     , tabint(0)
  72.     , m_uNumChannels(0)
  73.     , m_bInitialized(FALSE)
  74. {
  75. }
  76. CrossFader::~CrossFader()
  77. {
  78. }
  79. HX_RESULT
  80. CrossFader::Initialize(UINT16 uNumSamplesToFadeOn, UINT16 uNumChannels)
  81. {
  82.     HX_ASSERT(uNumSamplesToFadeOn > 0 && uNumChannels > 0);
  83.     if (uNumSamplesToFadeOn == 0 || uNumChannels == 0)
  84.     {
  85. return HXR_INVALID_PARAMETER;
  86.     }
  87.     tabacc = 0; /* accumulator */
  88.     tabint = 0; /* table index */
  89.     tabstep = (NALPHA << FRACBITS) / uNumSamplesToFadeOn;
  90.     m_uNumChannels = uNumChannels;
  91.     m_bInitialized  = TRUE;
  92.     return HXR_OK;
  93. }
  94. /*
  95.  * Crossfades over nfade samples, operating in-place on sampnew.
  96.  * alpha values are generated from table via linear interpolation.
  97.  */
  98. void
  99. CrossFader::CrossFade(INT16* sampold, INT16* sampnew, UINT16 uNumSamples)
  100. {
  101.     INT32 alerp, sdelta;
  102.     UINT16 n;
  103.     if (!m_bInitialized)
  104.     {
  105. return;
  106.     }
  107. /*  if we are doing more samples than the table is set up for  */
  108. /*  just keep tail of sampnew as is (i.e. reduce uNumSamples we are mixing over) */
  109. if( ((tabacc + (uNumSamples-1)*tabstep)>>FRACBITS) >= NALPHA)
  110. {
  111. uNumSamples = ((1+((((INT32)NALPHA)<<FRACBITS)-tabacc))/tabstep)-1;
  112. }
  113.  
  114.     /* crossfade, stepping thru table in fixed point */
  115.     for (n = 0; n < uNumSamples; n++) 
  116.     {
  117. /* interpolate new alpha */
  118. alerp = alpha[tabint];
  119. alerp += (adelta[tabint] * (tabacc & FRACMASK)) >> FRACBITS;
  120. /* next table step */
  121. tabacc += tabstep;
  122. tabint = tabacc >> FRACBITS;
  123. for (UINT16 uNumChannels = 0; uNumChannels < m_uNumChannels; uNumChannels++)
  124. {
  125.     /* crossfade, using interpolated alpha */
  126.     sdelta = alerp * (*sampold - *sampnew);
  127.     *sampnew += int((sdelta + FRACROUND) >> FRACBITS);
  128.     sampold++;
  129.     sampnew++;
  130. }
  131.     }
  132. }
  133. // XXXNH: CrossFadeInit() *only* appears to be used from the main() in this
  134. // file, which in turn is only used when GENERATE_TABLE is defined.  For
  135. // ordinary circumstances I think it is therefore acceptable to completely
  136. // #ifdef this out.
  137. #ifdef GENERATE_TABLE
  138. /*
  139.  * Initialize crossfade tables.
  140.  * Currently using linear dB, but could be anything...
  141.  * This code is ONLY used to generate static tables.
  142.  */
  143. void
  144. CrossFader::CrossFadeInit(void)
  145. {
  146.     double dbval, dbstep;
  147.     int n;
  148. //#ifdef GENERATE_TABLE
  149.     FILE* fd = fopen(TABLE_FILE_NAME, "w+");
  150.     fprintf(fd, "#ifdef GENERATE_TABLEn");
  151.     fprintf(fd, "static INT32 alpha[NALPHA+1] = {n");
  152.     fprintf(fd, "#elsen");
  153.     fprintf(fd, "static const INT32 alpha[NALPHA+1] = {n");
  154.     fprintf(fd, "#endifn");
  155.     fprintf(fd, "ntttt");
  156. //#endif /*GENERATE_TABLE*/
  157.     /* generate alpha table */
  158.     dbstep = (DBEND - DBSTART) / (NALPHA - 1);
  159.     for (n = 0; n < NALPHA; n++) 
  160.     {
  161. /* linear steps in dB */
  162. dbval = DBSTART + (dbstep * n);
  163. /* store as gains, in fixed point */
  164. alpha[n] = (int) (DB2GAIN(dbval) * (1<<FRACBITS) + 0.5);
  165. //#ifdef GENERATE_TABLE
  166. fprintf(fd, "%d, ", alpha[n]);
  167. if ((n+1) % 5 == 0)
  168. {
  169.     fprintf(fd, "ntttt");
  170. }
  171. //#endif /*GENERATE_TABLE*/
  172.     }
  173.     alpha[n] = alpha[n-1]; /* in case roundoff oversteps */
  174. //#ifdef GENERATE_TABLE
  175.     fprintf(fd, "%dn", alpha[n]);
  176.     fprintf(fd, "};nn");
  177.     fprintf(fd, "#ifdef GENERATE_TABLEn");
  178.     fprintf(fd, "static INT32 adelta[NALPHA] = {n");
  179.     fprintf(fd, "#elsen");
  180.     fprintf(fd, "static const INT32 adelta[NALPHA] = {n");
  181.     fprintf(fd, "#endifn");
  182.     fprintf(fd, "ntttt");
  183. //#endif /*GENERATE_TABLE*/
  184.     /* generate delta table, for fast interpolate */
  185.     for (n = 0; n < NALPHA-1; n++)
  186.     {
  187. adelta[n] = alpha[n+1] - alpha[n];
  188. //#ifdef GENERATE_TABLE
  189. fprintf(fd, "%d, ", adelta[n]);
  190. if ((n+1)%5 == 0)
  191. {
  192.     fprintf(fd, "ntttt");
  193. }
  194. //#endif /*GENERATE_TABLE*/
  195.     }
  196.     adelta[n] = 0; /* in case roundoff oversteps */
  197. //#ifdef GENERATE_TABLE
  198.     fprintf(fd, "%dn", adelta[n]);
  199.     fprintf(fd, "};nn");
  200.     fclose(fd);
  201. //#endif /*GENERATE_TABLE*/
  202. }
  203. #endif /*GENERATE_TABLE*/
  204. /*
  205.  * test app
  206.  */
  207. #ifdef GENERATE_TABLE
  208. #define NMAX 4096
  209. short testold[NMAX];
  210. short testnew[NMAX];
  211. int
  212. main(void)
  213. {
  214. int n;
  215. for (n = 0; n < NMAX; n++) {
  216. testold[n] = -32768;
  217. testnew[n] = 32767;
  218. }
  219. CrossFader cf;
  220. cf.CrossFadeInit();
  221. cf.CrossFade(testold, testnew, 1024);
  222. return 0;
  223. }
  224. #endif /*GENERATE_TABLE*/