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

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.  * Polyphase sampling rate conversion.
  37.  * Rational mode.
  38.  *
  39.  * by Ken Cooke
  40.  */
  41. #include "hlxclib/stdlib.h"
  42. #include "hlxclib/string.h"
  43. //#include <stdio.h>
  44. #include "allresamplers.h"
  45. #include "kaiser.h"
  46. #include "mymath.h"
  47. /* leave a trace of the C source version in the object code */
  48. static const char VERSION[] = "$Revision: 1.8 $" ;
  49. #undef ASSERT
  50. #define ASSERT(x)
  51. /* filter state */
  52. typedef struct {
  53. int up;
  54. int dn;
  55. int inrate;
  56. int outrate;
  57. int nchans;
  58. int nwing;
  59. int nhist;
  60. int phase;
  61. int offset;
  62. int isCloned;
  63. float *histbuf;
  64. float *pcmbuf;
  65. float *filter;
  66. uchar *pcmstep;
  67. int *nextphase;
  68. } state_t;
  69. void *
  70. RAInitResamplerRat(int inrate, int outrate, int nchans,
  71.   float atten, float passband, float stopband, float dcgain)
  72. {
  73. state_t *s;
  74. int divisor, up, dn;
  75. int ntaps, nwing, nfilter, nhist;
  76. float beta, fpass, fstop;
  77. double *lpfilt;
  78. int i, phase;
  79. /* use defaults for values <= 0 */
  80. if (atten <= 0.0f)
  81. atten = DEF_ATTEN;
  82. if (passband <= 0.0f)
  83. passband = DEF_PASSBAND;
  84. if (stopband <= 0.0f)
  85. stopband = DEF_STOPBAND;
  86. if (dcgain <= 0.0f)
  87. dcgain = DEF_DCGAIN;
  88. if (nchans < 1 || nchans > 2)
  89. return NULL;
  90. if (passband >= stopband)
  91. return NULL;
  92. /* reduce to smallest fraction */
  93. divisor = gcd(inrate, outrate);
  94. up = outrate / divisor;
  95. dn = inrate / divisor;
  96. if (up > 1280)
  97. return NULL; /* supports standard rates to 96000Hz */
  98. if (nchans * ((dn + up-1) / up) > 255)
  99. return NULL; /* pcmstep exceeds uchar */
  100. /* compute the filter specs */
  101. fstop = 1.0f / MAX(up, dn);
  102. fpass = passband * fstop;
  103. fstop = stopband * fstop;
  104. KaiserEstim(fpass, fstop, atten, &nfilter, &beta);
  105. ntaps = (nfilter + up-1) / up; /* length of each filter phase */
  106. nwing = (ntaps + 1) / 2;
  107. ntaps = nwing * 2; /* update ntaps */
  108. nfilter = nwing * up; /* update nfilter */
  109. nhist = nchans * ntaps;
  110. // printf("up=%d down=%d ntaps=%d beta=%.2f atten=%.1fdB pass=%.0fHz stop=%.0fHzn",
  111. // up, dn, ntaps, beta, atten, 0.5*outrate*fpass*dn, 0.5*outrate*fstop*dn);
  112. /* malloc buffers */
  113. lpfilt = (double *) malloc(nfilter * sizeof(double));
  114. s = (state_t *) malloc(sizeof(state_t));
  115. s->filter = (float *) malloc(nfilter * sizeof(float));
  116. s->isCloned = 0;
  117. s->pcmstep = (uchar *) malloc(up * sizeof(uchar));
  118. s->nextphase = (int *) malloc(up * sizeof(int));
  119. s->histbuf = (float *) calloc((NBLOCK + nhist), sizeof(float));
  120. s->pcmbuf = s->histbuf + nhist;
  121. /* create the lowpass filter */
  122. KaiserLowpass(nfilter, 0.5f * (fpass + fstop), beta, (dcgain * up), lpfilt);
  123. /* deinterleave into phases */
  124. for (phase = 0; phase < up; phase++) {
  125. for (i = 0; i < nwing; i++) {
  126. s->filter[phase*nwing + i] = (float) lpfilt[i*up + phase];
  127. }
  128. }
  129. /* lookup tables, driven by phase */
  130. for (i = 0; i < up; i++) {
  131. phase = (i * dn) % up;
  132. s->pcmstep[phase] = nchans * ((((i+1) * dn) / up) - ((i * dn) / up));
  133. s->nextphase[phase] = ((i+1) * dn) % up;
  134. }
  135. /* filter init */
  136. s->inrate = inrate;
  137. s->outrate = outrate;
  138. s->up = up;
  139. s->dn = dn;
  140. s->nchans = nchans;
  141. s->nwing = nwing;
  142. s->nhist = nhist;
  143. s->phase = 0;
  144. s->offset = 0;
  145. free(lpfilt);
  146. return (void *) s;
  147. }
  148. void *
  149. RAInitResamplerCopyRat(int nchans, const void *inst)
  150. {
  151. int i;
  152. state_t *s_in = (state_t *)inst;
  153. state_t *s_out = (state_t *)malloc(sizeof(state_t));
  154. if (s_in == NULL || s_out == NULL)
  155. return NULL;
  156. *s_out = *s_in ;
  157. s_out->isCloned = 1;
  158. s_out->nchans = nchans;
  159. s_out->nhist = s_in->nhist / s_in->nchans * nchans;
  160. s_out->histbuf = (float *) calloc((NBLOCK + s_out->nhist), sizeof(float));
  161. s_out->pcmstep = (uchar *) malloc(s_out->up * sizeof(uchar));
  162. if (s_out->histbuf == NULL || s_out->pcmstep == NULL)
  163. return NULL;
  164. s_out->pcmbuf = s_out->histbuf + s_out->nhist;
  165. for (i = 0; i < s_out->up; i++) {
  166. s_out->pcmstep[i] = s_in->pcmstep[i] / s_in->nchans * nchans ;
  167. }
  168. return s_out;
  169. }
  170. void
  171. RAFreeResamplerRat(void *inst)
  172. {
  173. state_t *s = (state_t *)inst;
  174. if (s != NULL) {
  175. if (!s->isCloned)
  176. {
  177. if (s->filter)
  178. free(s->filter);
  179. if (s->nextphase)
  180. free(s->nextphase);
  181. }
  182. if (s->pcmstep)
  183. free(s->pcmstep);
  184. if (s->histbuf)
  185. free(s->histbuf);
  186. free(s);
  187. }
  188. }
  189. int
  190. RAResampleStereoRat(void *inbuf, int insamps, tConverter *pCvt, short *outbuf, int outstride, void *inst)
  191. {
  192. state_t *s = (state_t *)inst;
  193. float *pcmptr, *pcmend;
  194. float *rwingptr, *lwingptr;
  195. short *outptr;
  196. float acc0, acc1;
  197. int i;
  198. int up = s->up;
  199. int phase = s->phase;
  200. int nwing = s->nwing;
  201. uchar *pcmstep = s->pcmstep;
  202. int *nextphase = s->nextphase;
  203. // TICK();
  204. // ASSERT(!(insamps & 0x1)); /* stereo must be even */
  205. /* convert input to float */
  206. insamps = pCvt->pfCvt(s->pcmbuf,inbuf,insamps,pCvt->pStateMachine) ;
  207. /* restore filter state */
  208. pcmptr = s->pcmbuf - STEREO * (nwing-1);
  209. pcmend = pcmptr + insamps;
  210. pcmptr += s->offset;
  211. outptr = outbuf;
  212. /* filter */
  213. while (pcmptr < pcmend) {
  214. rwingptr = s->filter + nwing * phase;
  215. lwingptr = s->filter + nwing * (up-1-phase);
  216. acc0 = acc1 = 0.0f;
  217. for (i = 0; i < nwing; i++) {
  218. int j = STEREO * i;
  219. acc0 += pcmptr[-j-2] * rwingptr[i];
  220. acc1 += pcmptr[-j-1] * rwingptr[i];
  221. acc0 += pcmptr[+j+0] * lwingptr[i];
  222. acc1 += pcmptr[+j+1] * lwingptr[i];
  223. }
  224. pcmptr += pcmstep[phase];
  225. phase = nextphase[phase];
  226. outptr[0] = RoundFtoS(acc0);
  227. outptr[1] = RoundFtoS(acc1);
  228. outptr += outstride;
  229. }
  230. /* save filter state */
  231. s->phase = phase;
  232. s->offset = pcmptr - pcmend;
  233. memmove(s->histbuf, s->histbuf + insamps, s->nhist * sizeof(float));
  234. // TOCK(outptr - outbuf);
  235. return (outptr - outbuf);
  236. }
  237. int
  238. RAResampleMonoRat(void *inbuf, int insamps, tConverter *pCvt, short *outbuf, int outstride, void *inst)
  239. {
  240.     state_t *s = (state_t *)inst;
  241. float *pcmptr, *pcmend;
  242. float *rwingptr, *lwingptr;
  243. short *outptr;
  244. float acc0, acc1;
  245. int i;
  246. int up = s->up;
  247. int phase = s->phase;
  248. int nwing = s->nwing;
  249. uchar *pcmstep = s->pcmstep;
  250. int *nextphase = s->nextphase;
  251. // TICK();
  252. /* convert input to float */
  253. insamps = pCvt->pfCvt(s->pcmbuf,inbuf,insamps,pCvt->pStateMachine) ;
  254. /* restore filter state */
  255. pcmptr = s->pcmbuf - (nwing-1);
  256. pcmend = pcmptr + insamps;
  257. pcmptr += s->offset;
  258. outptr = outbuf;
  259. /* filter */
  260. while (pcmptr < pcmend) {
  261. rwingptr = s->filter + nwing * phase;
  262. lwingptr = s->filter + nwing * (up-1-phase);
  263. acc0 = acc1 = 0.0f;
  264. for (i = 0; i < nwing; i++) {
  265. acc0 += pcmptr[-i-1] * rwingptr[i];
  266. acc1 += pcmptr[+i+0] * lwingptr[i];
  267. }
  268. acc0 += acc1;
  269. pcmptr += pcmstep[phase];
  270. phase = nextphase[phase];
  271. outptr[0] = RoundFtoS(acc0);
  272. outptr += outstride;
  273. }
  274. /* save filter state */
  275. s->phase = phase;
  276. s->offset = pcmptr - pcmend;
  277. memmove(s->histbuf, s->histbuf + insamps, s->nhist * sizeof(float));
  278. // TOCK(outptr - outbuf);
  279. return (outptr - outbuf);
  280. }
  281. int
  282. RAGetMaxOutputRat(int insamps, void *inst)
  283. {
  284.     state_t *s = (state_t *)inst;
  285. int inframes, outframes, outsamps;
  286. inframes = (insamps + (s->nchans-1)) / s->nchans;
  287. outframes = (int) myCeil((double)inframes * s->outrate / s->inrate);
  288. outsamps = outframes * s->nchans;
  289. return outsamps;
  290. }
  291. int
  292. RAGetMinInputRat(int outsamps, void *inst)
  293. {
  294.     state_t *s = (state_t *)inst;
  295. int inframes, outframes, insamps;
  296. outframes = (outsamps + (s->nchans-1)) / s->nchans;
  297. inframes = (int) myCeil((double)outframes * s->inrate / s->outrate);
  298. insamps = inframes * s->nchans;
  299. return insamps;
  300. }
  301. int
  302. RAGetDelayRat(void *inst)
  303. {
  304. state_t *s = (state_t *)inst;
  305. return (int)(s->nwing * (float)s->outrate / s->inrate) ;
  306. }