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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hermite.c,v 1.9.32.1 2004/07/09 02:01:17 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.  * Sampling rate conversion, by polynomial interpolation.
  51.  * Ken Cooke (kenc@real.com)
  52.  */
  53. #include "hlxclib/stdlib.h"
  54. #include "hxtypes.h"
  55. #include "allresamplers.h"
  56. #include "math64.h"
  57. #define MAXRATE ((1<<23) - 1) /* sampling rates cannot exceed MAXRATE */
  58. #define MAXSAMPS ((1<<23) - 1) /* max outsamps for GetMinInput() */
  59. #define MAXCHANS 2
  60. /* interpolator state */
  61. typedef struct { 
  62. int inrate;
  63. int outrate;
  64. int nchans;
  65. int time_i;
  66. UINT time_f;
  67. UINT step_i;
  68. UINT step_f;
  69. short hist[3*MAXCHANS]; /* input history */
  70. } STATE;
  71. /* Initialize Hermite resampler
  72.  * 
  73.  * Parameters
  74.  * ----------
  75.  * int inrate              sample rate of input (Hz)
  76.  * int outrate             desired sample rate of output (Hz)
  77.  * int nchans              number of channels
  78.  * 
  79.  * return value            instance pointer which will be passed in all future RAXXXHermite() function calls, 0 if error
  80.  *
  81.  * Notes
  82.  * -----
  83.  * - inrate, outrate, nchans must be within valid ranges (see below)
  84.  * - inrate < outrate (i.e. upsampling only!)
  85.  */
  86. void *
  87. RAInitResamplerHermite(int inrate, int outrate, int nchans)
  88. {
  89. STATE *s;
  90. UINT step_i, step_f, ratio, rem;
  91. int i;
  92. /* validate params */
  93. if ((inrate <= 0) || (inrate > MAXRATE) ||
  94.             (outrate <= 0) || (outrate > MAXRATE))
  95. return 0;
  96.         /* only allow downsampling on certain platforms
  97.          * until we have a fixed point resampler that can
  98.          * downsample properly. */
  99. #ifndef _SYMBIAN
  100.         /* XXXgfw remove this when the new resampler is available. */
  101.         if( inrate > outrate )
  102.         {
  103.             return 0;
  104.         }
  105. #endif        
  106.         
  107. if ((nchans < 1) || (nchans > MAXCHANS))
  108. return 0;
  109. /* create interpolator state */
  110. s = (STATE *) malloc(sizeof(STATE));
  111. if (!s)
  112. return 0;
  113. /* Compute 64-bit timestep, as a signed integer and 32-bit fraction */
  114. step_i = inrate / outrate; /* integer part */
  115. rem = inrate;
  116. step_f = 0 ;
  117. for (i = 0; i < 4; i++) {
  118. rem <<= 8;
  119. ratio = rem / outrate;
  120. rem -= ratio * outrate;
  121. step_f = (step_f << 8) | (ratio & 0xff); /* 8 more fraction bits */
  122. }
  123. ASSERT(step_i == (UINT)((double)inrate/outrate));
  124. ASSERT(step_f == (UINT)(65536.*65536.*((double)inrate/outrate - step_i)));
  125. s->inrate = inrate;
  126. s->outrate = outrate;
  127. s->nchans = nchans;
  128. s->time_i = 0;
  129. s->time_f = 0;
  130. s->step_i = step_i;
  131. s->step_f = step_f;
  132. for (i = 0; i < (3*MAXCHANS); i++)
  133. s->hist[i] = 0;
  134. return (void *)s;
  135. }
  136. /* Initialize Hermite resampler from a copy, using its parameters.
  137.  * 
  138.  * Parameters
  139.  * ----------
  140.  * inst                    instance pointer to a resampler to be used as template
  141.  * 
  142.  * return value            instance pointer which will be passed in all future RAXXXHermite() function calls, 0 if error
  143.  */
  144. void *
  145. RAInitResamplerCopyHermite(int nchans, const void *inst)
  146. {
  147. STATE *s_in = (STATE *)inst;
  148. STATE *s_out = (STATE *)malloc(sizeof(STATE));
  149. if (s_in == 0 || s_out == 0)
  150. return 0;
  151. *s_out = *s_in ;
  152. s_out->nchans = nchans;
  153. return s_out;
  154. }
  155. /* Free memory associated with Hermite resampler
  156.  * 
  157.  * Parameters
  158.  * ----------
  159.  * void *inst              instance pointer 
  160.  * 
  161.  * return value            none
  162.  *
  163.  * Notes
  164.  * -----
  165.  */
  166. void
  167. RAFreeResamplerHermite(void *inst)
  168. {
  169. STATE *s = (STATE *)inst;
  170. free(s);
  171. }
  172. /* Get max possible outsamps given insamps input
  173.  * 
  174.  * Parameters
  175.  * ----------
  176.  * int insamps             number of input samples
  177.  * void *inst              instance pointer 
  178.  * 
  179.  * return value            maximum number of output samples generated by resampling insamps samples, -1 if error
  180.  *
  181.  * Notes
  182.  * -----
  183.  * - some alternate implementations are included as comments
  184.  *     these might be useful, depending on the target platform
  185.  * - insamps must be even for stereo, function will exit with error if not
  186.  */
  187. int RAGetMaxOutputHermite(int insamps, void *inst)
  188. {
  189. /* do an empty (null) resample of insamps samples */
  190. int inframes, outframes;
  191. UINT i, f;
  192. STATE *s = (STATE *)inst;
  193. if (s->nchans == 2 && insamps & 0x01)
  194. return -1;
  195. inframes = (s->nchans == 2 ? insamps >> 1 : insamps);
  196. for (i = f = outframes = 0; i < (UINT)inframes; outframes++) {
  197. f += s->step_f;
  198. i += s->step_i + (f < s->step_f); /* add with carry */
  199. }
  200. return (int)(outframes * s->nchans);
  201.     /* equivalent method using __int64 
  202.  * 
  203.  * inframes = (s->nchans == 2 ? insamps >> 1 : insamps);
  204.  * step64 = ((__int64)s->step_i << 32) + (__int64)s->step_f;
  205.  * outframes = ( ((__int64)inframes << 32) + step64 - 1) / step64; COMMENT: ceiling
  206.  * return (int)(outframes * s->nchans);
  207.  */
  208.     /* equivalent method using double-precision floats
  209.  * 
  210.  * double step;
  211.  * inframes = (s->nchans == 2 ? insamps >> 1 : insamps);
  212.  * step = s->step_i + (s->step_f / 4294967296.0);
  213.  * outframes = (int) ceil((double)inframes / step);
  214.  * return (outframes * s->nchans);
  215.  */
  216. }
  217. /* Get minimum number of input samples required to generate outsamps output samples
  218.  * 
  219.  * Parameters
  220.  * ----------
  221.  * int outsamps            number of desired output samples
  222.  * void *inst              instance pointer 
  223.  * 
  224.  * return value            minimum number of input samples required to generate outsamps output samples, -1 if error
  225.  *
  226.  * Notes
  227.  * -----
  228.  * - some alternate implementations are included as comments
  229.  *     these might be useful, depending on the target platform
  230.  * - outsamps must be even for stereo, function will exit with error if not
  231.  */
  232. int
  233. RAGetMinInputHermite(int outsamps, void *inst)
  234. {
  235. UINT outframes;
  236. STATE *s = (STATE *)inst;
  237. UINT inframes, f, i;
  238. /* to ensure no overflow in multiply */
  239. if (outsamps > MAXSAMPS)
  240. return -1;
  241. if (s->nchans == 2 && outsamps & 0x01)
  242. return -1;
  243. outframes = (UINT)(s->nchans == 2 ? outsamps >> 1 : outsamps);
  244. inframes = 0;
  245. /* fractional part */
  246. f = s->step_f;
  247. for (i = 0; i < 4; i++) {
  248. inframes += outframes * (f & 0xff); /* add 24x8 partial product */
  249. inframes = (inframes + 0xff) >> 8; /* shift, rounding up */
  250. f >>= 8;
  251. }
  252. /* integer part */
  253. inframes += outframes * s->step_i;
  254. return (int)(inframes * s->nchans);
  255.     /* equivalent method using __int64 
  256.  * 
  257.  * step64 = ((__int64)s->step_i << 32) + (__int64)s->step_f;
  258.  * inframes = ( (__int64)outframes * step64);
  259.  * inframes += (__int64)(0x00000000ffffffff); COMMENT: (add 1.0 - 2^-32 to 32.32 number)
  260.  * return (int)((inframes >> 32) * s->nchans);
  261.  */
  262.     /* equivalent method using double-precision floats
  263.  * 
  264.  * double step;
  265.  * outframes = (s->nchans == 2 ? outsamps >> 1 : outsamps);
  266.  * step = s->step_i + (s->step_f / 4294967296.0);
  267.  * inframes = (int) ceil((double)outframes * step);
  268.  * return (inframes * s->nchans);
  269.  */
  270.     /* equivalent method using an empty (null) resample 
  271.  * 
  272.  * outframes = (s->nchans == 2 ? outsamps >> 1 : outsamps);
  273.  * for (i = f = currOut = 0; currOut < outframes; currOut++) {
  274.  *  f += s->step_f;
  275.  *  i += s->step_i + (f < s->step_f); COMMENT: add with carry 
  276.  * }
  277.  * if (f) COMMENT: ceiling (if any fractional part, round up) 
  278.  *  i++;
  279.  * return (int)(i * s->nchans);
  280.  */
  281. }
  282. /* Get number of frames of delay in the Hermite resampler
  283.  * 
  284.  * Parameters
  285.  * ----------
  286.  * void *inst              instance pointer 
  287.  * 
  288.  * return value            frames of delay
  289.  *
  290.  * Notes
  291.  * -----
  292.  * - always two frames of delay (2 samples per channel)
  293.  */
  294. int
  295. RAGetDelayHermite(void *inst)
  296. {
  297. return 2;
  298. }
  299. /* Cubic Hermite interpolation - one channel
  300.  * 
  301.  * Parameters
  302.  * ----------
  303.  * void *inbuf             pointer to buffer of input data (16-bit PCM)
  304.  * int insamps             number of samples in inbuf
  305.  * cvtFunctionType cvt     conversion function pointer, ignored
  306.  * short *outbuf           output buffer, must be large enough to hold RAGetMaxOutputHermite(insamps) samples
  307.  * void *inst              instance pointer 
  308.  * 
  309.  * return value            number of output samples generated and placed in outbuf, -1 if error
  310.  *
  311.  * Notes
  312.  * -----
  313.  * - no restrictions on number of insamps
  314.  * - inbuf MUST contain 16-bit PCM data, the cvt function is ignored
  315.  */
  316. int
  317. RAResampleMonoHermite(void *inbuf, int insamps, tConverter *pCvt, short *outbuf, int outstride, void *inst)
  318. {
  319. STATE *s = (STATE *)inst;
  320. UINT f, step_i, step_f;
  321. int outsamps, i, acc0;
  322. int x0, x1, x2, x3, frac;
  323. short *inptr;
  324. /* restore state */
  325. i = s->time_i;
  326. f = s->time_f;
  327. step_i = s->step_i;
  328. step_f = s->step_f;
  329. outsamps = 0;
  330. inptr = (short *)inbuf;
  331. if (s->nchans != 1 || outstride != 1)
  332. return -1;
  333. /* mono */
  334. while (i < insamps) {
  335. if (i < 3) {
  336. x3 = (i < 3 ? s->hist[i+0] : inptr[i-3]) << 12;
  337. x2 = (i < 2 ? s->hist[i+1] : inptr[i-2]) << 12;
  338. x1 = (i < 1 ? s->hist[i+2] : inptr[i-1]) << 12;
  339. } else {
  340. x3 = inptr[i-3] << 12;
  341. x2 = inptr[i-2] << 12;
  342. x1 = inptr[i-1] << 12;
  343. }
  344. x0 = inptr[i] << 12;
  345. frac = f >> 1;
  346. /* 4-tap Hermite, using Farrow structure */
  347. acc0 = (3 * (x2 - x1) + x0 - x3) >> 1;
  348. acc0 = MulShift31(acc0, frac);
  349. acc0 += 2 * x1 + x3 - ((5 * x2 + x0) >> 1);
  350. acc0 = MulShift31(acc0, frac);
  351. acc0 += (x1 - x3) >> 1;
  352. acc0 = MulShift31(acc0, frac);
  353. acc0 += x2;
  354. f += step_f;
  355. i += step_i + (f < step_f); /* add with carry */
  356. acc0 = (acc0 + (1<<11)) >> 12;
  357. if (acc0 > +32767) acc0 = +32767;
  358. if (acc0 < -32768) acc0 = -32768;
  359. outbuf[outsamps++] = (short)acc0;
  360. }
  361. /* save delay samples for next time (hist[0] = oldest, hist[2] = newest) */
  362. s->hist[0] = (insamps < 3 ? s->hist[insamps+0] : inptr[insamps-3]);
  363. s->hist[1] = (insamps < 2 ? s->hist[insamps+1] : inptr[insamps-2]);
  364. s->hist[2] = (insamps < 1 ? s->hist[insamps+2] : inptr[insamps-1]);
  365. /* save state */
  366. s->time_f = f;
  367. s->time_i = i - insamps;
  368. return outsamps;
  369. }
  370. /* Cubic Hermite interpolation - two channels
  371.  * 
  372.  * Parameters
  373.  * ----------
  374.  * void *inbuf             pointer to buffer of input data (16-bit PCM, interleaved LRLRLR...)
  375.  * int insamps             number of samples in inbuf
  376.  * cvtFunctionType cvt     conversion function pointer, ignored
  377.  * short *outbuf           output buffer, must be large enough to hold RAGetMaxOutputHermite(insamps) samples
  378.  * void *inst              instance pointer 
  379.  * 
  380.  * return value            number of output samples generated and placed in outbuf, -1 if error
  381.  *
  382.  * Notes
  383.  * -----
  384.  * - no restrictions on number of insamps
  385.  * - inbuf MUST contain 16-bit PCM data, the cvt function is ignored
  386.  * - insamps must be even, function will exit with error if not
  387.  */
  388. int
  389. RAResampleStereoHermite(void *inbuf, int insamps, tConverter *pCvt, short *outbuf, int outstride, void *inst)
  390. {
  391. STATE *s = (STATE *)inst;
  392. UINT f, step_i, step_f;
  393. int outsamps, i, acc0, acc1, j;
  394. int x0, x1, x2, x3, frac;
  395. short *inptr;
  396. /* restore state */
  397. i = s->time_i;
  398. f = s->time_f;
  399. step_i = s->step_i;
  400. step_f = s->step_f;
  401. outsamps = 0;
  402. inptr = (short *)inbuf;
  403. /* fail if odd number of input samples */
  404. if (s->nchans != 2 || insamps & 0x01 || outstride != 2)
  405. return -1;
  406. /* stereo - assume insamps is even */
  407. insamps /= 2; /* number of stereo frames - consume samples two at a time */
  408. while (i < insamps) {
  409. frac = f >> 1;
  410. j = 2*i;
  411. /* left */
  412. if (i < 3) {
  413. x3 = (i < 3 ? s->hist[j+0] : inptr[j-6]) << 12;
  414. x2 = (i < 2 ? s->hist[j+2] : inptr[j-4]) << 12;
  415. x1 = (i < 1 ? s->hist[j+4] : inptr[j-2]) << 12;
  416. } else {
  417. x3 = inptr[j-6] << 12;
  418. x2 = inptr[j-4] << 12;
  419. x1 = inptr[j-2] << 12;
  420. }
  421. x0 = inptr[j] << 12;
  422. /* 4-tap Hermite, using Farrow structure */
  423. acc0 = (3 * (x2 - x1) + x0 - x3) >> 1;
  424. acc0 = MulShift31(acc0, frac);
  425. acc0 += 2 * x1 + x3 - ((5 * x2 + x0) >> 1);
  426. acc0 = MulShift31(acc0, frac);
  427. acc0 += (x1 - x3) >> 1;
  428. acc0 = MulShift31(acc0, frac);
  429. acc0 += x2;
  430. /* right */
  431. if (i < 3) {
  432. x3 = (i < 3 ? s->hist[j+1] : inptr[j-5]) << 12;
  433. x2 = (i < 2 ? s->hist[j+3] : inptr[j-3]) << 12;
  434. x1 = (i < 1 ? s->hist[j+5] : inptr[j-1]) << 12;
  435. } else {
  436. x3 = inptr[j-5] << 12;
  437. x2 = inptr[j-3] << 12;
  438. x1 = inptr[j-1] << 12;
  439. }
  440. x0 = inptr[j+1] << 12;
  441. /* 4-tap Hermite, using Farrow structure */
  442. acc1 = (3 * (x2 - x1) + x0 - x3) >> 1;
  443. acc1 = MulShift31(acc1, frac);
  444. acc1 += 2 * x1 + x3 - ((5 * x2 + x0) >> 1);
  445. acc1 = MulShift31(acc1, frac);
  446. acc1 += (x1 - x3) >> 1;
  447. acc1 = MulShift31(acc1, frac);
  448. acc1 += x2;
  449. f += step_f;
  450. i += step_i + (f < step_f); /* add with carry */
  451. acc0 = (acc0 + (1<<11)) >> 12;
  452. if (acc0 > +32767) acc0 = +32767;
  453. if (acc0 < -32768) acc0 = -32768;
  454. outbuf[outsamps++] = (short)acc0;
  455. acc1 = (acc1 + (1<<11)) >> 12;
  456. if (acc1 > +32767) acc1 = +32767;
  457. if (acc1 < -32768) acc1 = -32768;
  458. outbuf[outsamps++] = (short)acc1;
  459. }
  460. /* save delay samples for next time (hist[0] = oldest left, hist[1] = oldest right, ...) */
  461. s->hist[0] = (insamps < 3 ? s->hist[2*(insamps+0) + 0] : inptr[2*(insamps-3) + 0]);
  462. s->hist[2] = (insamps < 2 ? s->hist[2*(insamps+1) + 0] : inptr[2*(insamps-2) + 0]);
  463. s->hist[4] = (insamps < 1 ? s->hist[2*(insamps+2) + 0] : inptr[2*(insamps-1) + 0]);
  464. s->hist[1] = (insamps < 3 ? s->hist[2*(insamps+0) + 1] : inptr[2*(insamps-3) + 1]);
  465. s->hist[3] = (insamps < 2 ? s->hist[2*(insamps+1) + 1] : inptr[2*(insamps-2) + 1]);
  466. s->hist[5] = (insamps < 1 ? s->hist[2*(insamps+2) + 1] : inptr[2*(insamps-1) + 1]);
  467. /* save state */
  468. s->time_f = f;
  469. s->time_i = i - insamps;
  470. return outsamps;
  471. }