core.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.  * Fixed-point sampling rate conversion library
  37.  * Developed by Ken Cooke (kenc@real.com)
  38.  * May 2003
  39.  *
  40.  * Core filtering functions, generic version.
  41.  * This version is fairly optimized for ARMv4.
  42.  */
  43. #include "core.h"
  44. #if defined (_M_IX86) || (defined (_SYMBIAN) && defined (__WINS__))
  45. __inline int MULHI(int a, int b) {
  46. __asm mov eax, a
  47. __asm imul b
  48. __asm mov eax, edx
  49. }
  50. #elif defined (__CC_ARM)
  51. __inline int MULHI(int a, int b) {
  52. int low;
  53. __asm { smull low, a, b, a }
  54. return a;
  55. }
  56. #else
  57. /* a fast MULHI is important, so verify this compiles well */
  58. #define MULHI(a,b) ((int)(((__int64)(a) * (__int64)(b)) >> 32))
  59. #endif
  60. short *
  61. RATCoreMono(short *pcmptr, short *pcmend, short *outptr, state_t *s)
  62. {
  63. short *rwgptr, *lwgptr, *revptr;
  64. int acc;
  65. int i, sign;
  66. int *tab;
  67. rwgptr = s->rwing;
  68. lwgptr = s->lwing;
  69. pcmptr += s->offset;
  70. while (pcmptr < pcmend) {
  71. revptr = pcmptr - 1;
  72. acc = 1 << 14;
  73. /* FIR filter */
  74. for (i = s->nwing >> 1; i != 0; i--) {
  75. acc += (*pcmptr++) * (*lwgptr++);
  76. acc += (*pcmptr++) * (*lwgptr++);
  77. acc += (*revptr--) * (*rwgptr++);
  78. acc += (*revptr--) * (*rwgptr++);
  79. }
  80. if (s->nwing & 0x1) {
  81. acc += (*pcmptr++) * (*lwgptr++);
  82. acc += (*revptr--) * (*rwgptr++);
  83. }
  84. acc >>= 15;
  85. /* saturate */
  86. if ((sign = (acc >> 31)) != (acc >> 15))
  87. acc = sign ^ ((1<<15)-1);
  88. *outptr++ = (short) acc;
  89. /* step phase by N */
  90. tab = (rwgptr > s->stepNptr ? s->stepNbak : s->stepNfwd);
  91. rwgptr += tab[0];
  92. lwgptr += tab[1];
  93. pcmptr += tab[2];
  94. }
  95. s->offset = pcmptr - pcmend;
  96. s->rwing = rwgptr;
  97. s->lwing = lwgptr;
  98. return outptr;
  99. }
  100. short *
  101. RATCoreStereo(short *pcmptr, short *pcmend, short *outptr, state_t *s)
  102. {
  103. short *rwgptr, *lwgptr, *revptr;
  104. int acc0, acc1;
  105. int i, sign;
  106. int *tab;
  107. rwgptr = s->rwing;
  108. lwgptr = s->lwing;
  109. pcmptr += s->offset;
  110. while (pcmptr+1 < pcmend) {
  111. revptr = pcmptr - 1;
  112. acc0 = acc1 = 1 << 14;
  113. /* FIR filter */
  114. for (i = s->nwing >> 1; i != 0; i--) {
  115. acc0 += (*pcmptr++) * (*lwgptr);
  116. acc1 += (*pcmptr++) * (*lwgptr++);
  117. acc0 += (*pcmptr++) * (*lwgptr);
  118. acc1 += (*pcmptr++) * (*lwgptr++);
  119. acc1 += (*revptr--) * (*rwgptr);
  120. acc0 += (*revptr--) * (*rwgptr++);
  121. acc1 += (*revptr--) * (*rwgptr);
  122. acc0 += (*revptr--) * (*rwgptr++);
  123. }
  124. if (s->nwing & 0x1) {
  125. acc0 += (*pcmptr++) * (*lwgptr);
  126. acc1 += (*pcmptr++) * (*lwgptr++);
  127. acc1 += (*revptr--) * (*rwgptr);
  128. acc0 += (*revptr--) * (*rwgptr++);
  129. }
  130. acc0 >>= 15;
  131. acc1 >>= 15;
  132. /* saturate */
  133. if ((sign = (acc0 >> 31)) != (acc0 >> 15))
  134. acc0 = sign ^ ((1<<15)-1);
  135. if ((sign = (acc1 >> 31)) != (acc1 >> 15))
  136. acc1 = sign ^ ((1<<15)-1);
  137. *outptr++ = (short) acc0;
  138. *outptr++ = (short) acc1;
  139. /* step phase by N */
  140. tab = (rwgptr > s->stepNptr ? s->stepNbak : s->stepNfwd);
  141. rwgptr += tab[0];
  142. lwgptr += tab[1];
  143. pcmptr += tab[2];
  144. }
  145. s->offset = pcmptr - pcmend;
  146. s->rwing = rwgptr;
  147. s->lwing = lwgptr;
  148. return outptr;
  149. }
  150. short *
  151. ARBCoreMono(short *pcmptr, short *pcmend, short *outptr, state_t *s)
  152. {
  153. short *rwgptr, *lwgptr, *revptr;
  154. short *rwgptr1, *lwgptr1;
  155. int acc0, acc1;
  156. int pcmstep, i, sign;
  157. int *tab;
  158. uint phasef;
  159. rwgptr = s->rwing;
  160. lwgptr = s->lwing;
  161. phasef = s->phasef;
  162. pcmptr += s->offset;
  163. /* phase+1 */
  164. tab = (rwgptr >= s->step1ptr ? s->step1bak : s->step1fwd);
  165. rwgptr1 = rwgptr + tab[0];
  166. lwgptr1 = lwgptr + tab[1];
  167. pcmstep = tab[2];
  168. while (pcmptr+pcmstep < pcmend) {
  169. revptr = pcmptr - 1;
  170. acc0 = acc1 = 1 << 14;
  171. if (!pcmstep) {
  172. for (i = s->nwing; i != 0; i--) {
  173. register short pcm, rev;
  174. pcm = (*pcmptr++);
  175. rev = (*revptr--);
  176. acc0 += pcm * (*lwgptr++);
  177. acc1 += pcm * (*lwgptr1++);
  178. acc0 += rev * (*rwgptr++);
  179. acc1 += rev * (*rwgptr1++);
  180. }
  181. } else {
  182. for (i = s->nwing; i != 0; i--) {
  183. register short pcm0, pcm1;
  184. pcm0 = (*pcmptr++);
  185. pcm1 = *(pcmptr+0);
  186. acc0 += pcm0 * (*lwgptr++);
  187. acc1 += pcm1 * (*lwgptr1++);
  188. pcm1 = *(revptr+1);
  189. pcm0 = (*revptr--);
  190. acc0 += pcm0 * (*rwgptr++);
  191. acc1 += pcm1 * (*rwgptr1++);
  192. }
  193. }
  194. /* interpolate */
  195. acc0 = (acc0 >> 1) + MULHI(acc1 - acc0, phasef >> 1);
  196. acc0 >>= 14;
  197. /* saturate */
  198. if ((sign = (acc0 >> 31)) != (acc0 >> 15))
  199. acc0 = sign ^ ((1<<15)-1);
  200. *outptr++ = (short) acc0;
  201. /* step phase fraction */
  202. phasef += s->stepf;
  203. if (phasef < s->stepf) {
  204. rwgptr = rwgptr1;
  205. lwgptr = lwgptr1;
  206. pcmptr += pcmstep;
  207. }
  208. /* step phase by N */
  209. tab = (rwgptr > s->stepNptr ? s->stepNbak : s->stepNfwd);
  210. rwgptr += tab[0];
  211. lwgptr += tab[1];
  212. pcmptr += tab[2];
  213. /* phase+1 */
  214. tab = (rwgptr >= s->step1ptr ? s->step1bak : s->step1fwd);
  215. rwgptr1 = rwgptr + tab[0];
  216. lwgptr1 = lwgptr + tab[1];
  217. pcmstep = tab[2];
  218. }
  219. s->offset = pcmptr - pcmend;
  220. s->rwing = rwgptr;
  221. s->lwing = lwgptr;
  222. s->phasef = phasef;
  223. return outptr;
  224. }
  225. short *
  226. ARBCoreStereo(short *pcmptr, short *pcmend, short *outptr, state_t *s)
  227. {
  228. register short *rwgptr, *lwgptr, *revptr;
  229. register short *rwgptr1, *lwgptr1;
  230. register int acc0, acc1, acc2, acc3;
  231. int pcmstep, i, sign;
  232. int *tab;
  233. uint phasef;
  234. rwgptr = s->rwing;
  235. lwgptr = s->lwing;
  236. phasef = s->phasef;
  237. pcmptr += s->offset;
  238. /* phase+1 */
  239. tab = (rwgptr >= s->step1ptr ? s->step1bak : s->step1fwd);
  240. rwgptr1 = rwgptr + tab[0];
  241. lwgptr1 = lwgptr + tab[1];
  242. pcmstep = tab[2];
  243. while (pcmptr+pcmstep+1 < pcmend) {
  244. revptr = pcmptr - 1;
  245. acc0 = acc1 = acc2 = acc3 = 1 << 14;
  246. if (!pcmstep) {
  247. for (i = s->nwing; i != 0; i--) {
  248. register short pcm0, pcm1;
  249. pcm0 = (*pcmptr++);
  250. pcm1 = (*pcmptr++);
  251. acc0 += pcm0 * (*lwgptr);
  252. acc1 += pcm1 * (*lwgptr++);
  253. acc2 += pcm0 * (*lwgptr1);
  254. acc3 += pcm1 * (*lwgptr1++);
  255. pcm1 = (*revptr--);
  256. pcm0 = (*revptr--);
  257. acc3 += pcm1 * (*rwgptr1);
  258. acc2 += pcm0 * (*rwgptr1++);
  259. acc1 += pcm1 * (*rwgptr);
  260. acc0 += pcm0 * (*rwgptr++);
  261. }
  262. } else {
  263. for (i = s->nwing; i != 0; i--) {
  264. acc0 += (*pcmptr++) * (*lwgptr);
  265. acc1 += (*pcmptr++) * (*lwgptr++);
  266. acc2 += *(pcmptr+0) * (*lwgptr1);
  267. acc3 += *(pcmptr+1) * (*lwgptr1++);
  268. acc3 += *(revptr+2) * (*rwgptr1);
  269. acc2 += *(revptr+1) * (*rwgptr1++);
  270. acc1 += (*revptr--) * (*rwgptr);
  271. acc0 += (*revptr--) * (*rwgptr++);
  272. }
  273. }
  274. /* interpolate */
  275. acc0 = (acc0 >> 1) + MULHI(acc2 - acc0, phasef >> 1);
  276. acc0 >>= 14;
  277. acc1 = (acc1 >> 1) + MULHI(acc3 - acc1, phasef >> 1);
  278. acc1 >>= 14;
  279. /* saturate */
  280. if ((sign = (acc0 >> 31)) != (acc0 >> 15))
  281. acc0 = sign ^ ((1<<15)-1);
  282. if ((sign = (acc1 >> 31)) != (acc1 >> 15))
  283. acc1 = sign ^ ((1<<15)-1);
  284. *outptr++ = (short) acc0;
  285. *outptr++ = (short) acc1;
  286. /* step phase fraction */
  287. phasef += s->stepf;
  288. if (phasef < s->stepf) {
  289. rwgptr = rwgptr1;
  290. lwgptr = lwgptr1;
  291. pcmptr += pcmstep;
  292. }
  293. /* step phase by N */
  294. tab = (rwgptr > s->stepNptr ? s->stepNbak : s->stepNfwd);
  295. rwgptr += tab[0];
  296. lwgptr += tab[1];
  297. pcmptr += tab[2];
  298. /* phase+1 */
  299. tab = (rwgptr >= s->step1ptr ? s->step1bak : s->step1fwd);
  300. rwgptr1 = rwgptr + tab[0];
  301. lwgptr1 = lwgptr + tab[1];
  302. pcmstep = tab[2];
  303. }
  304. s->offset = pcmptr - pcmend;
  305. s->rwing = rwgptr;
  306. s->lwing = lwgptr;
  307. s->phasef = phasef;
  308. return outptr;
  309. }