Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

948 lines
22 KiB

  1. //
  2. // ITU-T G.723 Floating Point Speech Coder ANSI C Source Code. Version 1.00
  3. // copyright (c) 1995, AudioCodes, DSP Group, France Telecom,
  4. // Universite de Sherbrooke, Intel Corporation. All rights reserved.
  5. //
  6. //no return value and unreferenced label are not interesting warnings
  7. //occur in asm dot product because the compiler doesn't look at the asm code.
  8. #pragma warning(4: 4035 4102)
  9. #include "opt.h"
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include <memory.h>
  14. #include "typedef.h"
  15. #include "cst_lbc.h"
  16. #include "sdstruct.h"
  17. #include "coder.h"
  18. #include "decod.h"
  19. #include "tabl_ns.h"
  20. #include "sdstuff.h"
  21. #include "util_lbc.h"
  22. //-----------------------------------------------------
  23. int MyFloor(float x)
  24. {
  25. // Note: We fiddle with the FP control word to force it to round
  26. // to -inf. This way we get the right floor for either positive or
  27. // negative x.
  28. #if OPT_FLOOR
  29. int retu,fc_old,fc;
  30. ASM
  31. {
  32. fnstcw fc_old;
  33. mov eax,fc_old;
  34. and eax, 0f3ffh;
  35. or eax, 00400h;
  36. mov fc,eax;
  37. fldcw fc;
  38. fld x; // do the floor
  39. fistp retu;
  40. fldcw fc_old;
  41. }
  42. return(retu);
  43. #else
  44. float f;
  45. f = (float)floor(x);
  46. return((int) f);
  47. #endif
  48. }
  49. #if NOTMINI
  50. //-----------------------------------------------------
  51. void Read_lbc (float *Dpnt, int Len, FILE *Fp)
  52. {
  53. short Ibuf[Frame];
  54. int i,n;
  55. n = fread (Ibuf, sizeof(short), Len, Fp);
  56. for (i=0; i<n; i++)
  57. Dpnt[i] = (float) Ibuf[i];
  58. for (i=n; i<Len; i++)
  59. Dpnt[i] = 0.0f;
  60. }
  61. //-----------------------------------------------------
  62. void Write_lbc(float *Dpnt, int Len, FILE *Fp)
  63. {
  64. short Obuf[Frame];
  65. int i;
  66. for (i=0; i<Len; i++)
  67. {
  68. if (Dpnt[i] < -32768.)
  69. Obuf[i] = -32768;
  70. else if (Dpnt[i] > 32767)
  71. Obuf[i] = 32767;
  72. else
  73. {
  74. if (Dpnt[i] < 0)
  75. Obuf[i] = (short) (Dpnt[i]-0.5);
  76. else
  77. Obuf[i] = (short) (Dpnt[i]+0.5);
  78. }
  79. }
  80. fwrite(Obuf, sizeof(short), Len, Fp);
  81. }
  82. void Line_Wr( char *Line, FILE *Fp )
  83. {
  84. Word16 FrType ;
  85. int Size ;
  86. FrType = Line[0] & (Word16)0x0003 ;
  87. /* Check for Sid frame */
  88. if ( FrType == (Word16) 0x0002 ) {
  89. return ;
  90. }
  91. if ( FrType == (Word16) 0x0000 )
  92. Size = 24 ;
  93. else
  94. Size = 20 ;
  95. fwrite( Line, Size, 1, Fp ) ;
  96. }
  97. void Line_Rd( char *Line, FILE *Fp )
  98. {
  99. Word16 FrType ;
  100. int Size ;
  101. fread( Line, 1,1, Fp ) ;
  102. FrType = Line[0] & (Word16)0x0003 ;
  103. /* Check for Sid frame */
  104. if ( FrType == (Word16) 0x0002 ) {
  105. Size = 3 ;
  106. fread( &Line[1], Size, 1, Fp ) ;
  107. return ;
  108. }
  109. if ( FrType == (Word16) 0x0000 )
  110. Size = 23 ;
  111. else
  112. Size = 19 ;
  113. fread( &Line[1], Size, 1, Fp ) ;
  114. }
  115. #endif
  116. //-----------------------------------------------------
  117. void Rem_Dc(float *Dpnt, CODDEF *CodStat)
  118. {
  119. int i;
  120. float acc0;
  121. if (CodStat->UseHp)
  122. {
  123. for (i=0; i < Frame; i++)
  124. {
  125. acc0 = (Dpnt[i] - CodStat->HpfZdl)*0.5f;
  126. CodStat->HpfZdl = Dpnt[i];
  127. Dpnt[i] = CodStat->HpfPdl = acc0 + CodStat->HpfPdl*(127.0f/128.0f);
  128. }
  129. }
  130. else
  131. for (i=0; i < Frame; i++)
  132. Dpnt[i] *= 0.5f;
  133. }
  134. //-----------------------------------------------------
  135. void Mem_Shift(float *PrevDat, float *DataBuff)
  136. {
  137. int i;
  138. float Dpnt[Frame+LpcFrame-SubFrLen];
  139. // Form Buffer
  140. for (i=0; i < LpcFrame-SubFrLen; i++)
  141. Dpnt[i] = PrevDat[i];
  142. for (i=0; i < Frame; i++)
  143. Dpnt[i+LpcFrame-SubFrLen] = DataBuff[i];
  144. // Update PrevDat
  145. for (i=0; i < LpcFrame-SubFrLen; i++)
  146. PrevDat[i] = Dpnt[Frame+i];
  147. // Update DataBuff
  148. for (i=0; i < Frame; i++)
  149. DataBuff[i] = Dpnt[(LpcFrame-SubFrLen)/2+i];
  150. }
  151. /*
  152. **
  153. ** Function: Line_Pack()
  154. **
  155. ** Description: Packing coded parameters in bitstream of 16-bit words
  156. **
  157. ** Links to text: Section 4
  158. **
  159. ** Arguments:
  160. **
  161. ** LINEDEF *Line Coded parameters for a frame
  162. ** Word32 *Vout bitstream words
  163. ** Word16 VadAct Voice Activity Indicator
  164. **
  165. ** FILEIO - if defined, bitstream is generated as Big Endian words but little
  166. ** endian bytes. If not, then it is all little endian.
  167. **
  168. ** Outputs:
  169. **
  170. ** Word32 *Vout
  171. **
  172. ** Return value: None
  173. **
  174. */
  175. #define bswap(s) ASM mov eax,s ASM bswap eax ASM mov s,eax
  176. //STUFF n bits of x at bit position k of *lp
  177. // if you fill up *lp, *++lp = leftovers
  178. //WARNING!: as a side effect lp may be changed!
  179. //lp must have an lvalue
  180. //n and k must be compile time constants
  181. #define OPT_STUFF 1
  182. #if OPT_STUFF
  183. #define STUFF(x, lp, n_in, k_in) {\
  184. register unsigned temp;\
  185. const int n = (n_in);\
  186. const int k = (k_in) & 31;\
  187. temp = (x) & ((1 << n) - 1);\
  188. *(lp) |= temp << k;\
  189. if (n+k >= 32)\
  190. *(++lp) |= temp >> (32-k);\
  191. }
  192. #else
  193. #define STUFF(x, lp, n_in, k_in) stuff(x, &(lp), n_in, k_in)
  194. void stuff(unsigned x, unsigned **ptrlp, int n, int k_in) {
  195. unsigned temp;
  196. int k;
  197. k = k_in & 31;
  198. temp = (x) & ((1 << n) - 1);
  199. *(*ptrlp) |= temp << k;
  200. if (n+k >= 32)
  201. *(++*ptrlp) |= temp >> (32-k);
  202. return;
  203. }
  204. #endif
  205. #define DEBUG_DUMPLINE 0
  206. #if DEBUG_DUMPLINE
  207. #define DUMPLINE(lp) dumpline(lp)
  208. void dumpsfs(SFSDEF *sfsptr)
  209. {
  210. fprintf(stdout, "%1x ", sfsptr->AcLg);
  211. fprintf(stdout, "%2x ", sfsptr->AcGn);
  212. fprintf(stdout, "%2x", sfsptr->Mamp);
  213. fprintf(stdout, "%1x", sfsptr->Grid);
  214. fprintf(stdout, "%1x", sfsptr->Tran);
  215. fprintf(stdout, "%1x ", sfsptr->Pamp);
  216. fprintf(stdout, "%3x ", sfsptr->Ppos);
  217. // fprintf(stdout, "\n");
  218. return;
  219. }
  220. void dumpline(LINEDEF *lineptr)
  221. {
  222. fprintf(stdout, "%6x ", lineptr->LspId);
  223. fprintf(stdout, "%2x ", lineptr->Olp[0]);
  224. fprintf(stdout, "%2x ", lineptr->Olp[1]);
  225. // fprintf(stdout, "\n");
  226. dumpsfs(&lineptr->Sfs[0]);
  227. dumpsfs(&lineptr->Sfs[1]);
  228. dumpsfs(&lineptr->Sfs[2]);
  229. dumpsfs(&lineptr->Sfs[3]);
  230. fprintf(stdout, "\n");
  231. return;
  232. }
  233. #else
  234. #define DUMPLINE(lp)
  235. #endif
  236. void Line_Pack( LINEDEF *Line, Word32 *Vout, int *VadBit, enum Crate WrkRate )
  237. //4.0f void Line_Pack( LINEDEF *Line, char *Vout, Word16 VadBit )
  238. {
  239. int i ;
  240. Word32 *Bsp;
  241. Word32 Temp ;
  242. /* Clear the output vector */
  243. if ( WrkRate == Rate63 )
  244. {
  245. for ( i = 0 ; i < 6 ; i ++ )
  246. Vout[i] = 0 ;
  247. }
  248. else
  249. {
  250. for ( i = 0 ; i < 5 ; i ++ )
  251. Vout[i] = 0 ;
  252. }
  253. Bsp = Vout; //running pointer into output buffer as Word32's
  254. /*
  255. Add the coder rate info and the VAD status to the 2 msb
  256. of the first word of the frame.
  257. The signalling is as follows:
  258. 00 : High Rate
  259. 01 : Low Rate
  260. 10 : Non-speech
  261. 11 : Reserved for future use
  262. */
  263. Temp = 0L ;
  264. if ( *VadBit == 1 ) {
  265. if ( WrkRate == Rate63 )
  266. Temp = 0x00000000L ;
  267. else
  268. Temp = 0x00000001L ;
  269. }
  270. /* Serialize Control info */
  271. STUFF( Temp, Bsp, 2, 0 ) ;
  272. /* 24 bit LspId */
  273. Temp = (*Line).LspId ;
  274. STUFF( Temp, Bsp, 24, 2 ) ;
  275. /* Check for Speech/NonSpeech case */
  276. if ( *VadBit == 1 ) {
  277. /*
  278. Do the part common to both rates
  279. */
  280. /* Adaptive code book lags */
  281. Temp = (Word32) (*Line).Olp[0] - (Word32) PitchMin ;
  282. STUFF( Temp, Bsp, 7, 26 ) ;
  283. Temp = (Word32) (*Line).Sfs[1].AcLg ;
  284. STUFF( Temp, Bsp, 2, 33 ) ;
  285. Temp = (Word32) (*Line).Olp[1] - (Word32) PitchMin ;
  286. STUFF( Temp, Bsp, 7, 35 ) ;
  287. Temp = (Word32) (*Line).Sfs[3].AcLg ;
  288. STUFF( Temp, Bsp, 2, 42 ) ;
  289. /* Write combined 12 bit index of all the gains */
  290. Temp = (*Line).Sfs[0].AcGn*NumOfGainLev + (*Line).Sfs[0].Mamp ;
  291. if ( WrkRate == Rate63 )
  292. Temp += (Word32) (*Line).Sfs[0].Tran << 11 ;
  293. STUFF( Temp, Bsp, 12, 44 ) ;
  294. Temp = (*Line).Sfs[1].AcGn*NumOfGainLev + (*Line).Sfs[1].Mamp ;
  295. if ( WrkRate == Rate63 )
  296. Temp += (Word32) (*Line).Sfs[1].Tran << 11 ;
  297. STUFF( Temp, Bsp, 12, 56 ) ;
  298. Temp = (*Line).Sfs[2].AcGn*NumOfGainLev + (*Line).Sfs[2].Mamp ;
  299. if ( WrkRate == Rate63 )
  300. Temp += (Word32) (*Line).Sfs[2].Tran << 11 ;
  301. STUFF( Temp, Bsp, 12, 68 ) ;
  302. Temp = (*Line).Sfs[3].AcGn*NumOfGainLev + (*Line).Sfs[3].Mamp ;
  303. if ( WrkRate == Rate63 )
  304. Temp += (Word32) (*Line).Sfs[3].Tran << 11 ;
  305. STUFF( Temp, Bsp, 12, 80 ) ;
  306. /* Write all the Grid indices */
  307. STUFF( (*Line).Sfs[0].Grid, Bsp, 1, 92 ) ;
  308. STUFF( (*Line).Sfs[1].Grid, Bsp, 1, 93 ) ;
  309. STUFF( (*Line).Sfs[2].Grid, Bsp, 1, 94 ) ;
  310. STUFF( (*Line).Sfs[3].Grid, Bsp, 1, 95 ) ;
  311. /* High rate only part */
  312. if ( WrkRate == Rate63 ) {
  313. /* Write the reserved bit as 0 */
  314. STUFF( 0, Bsp, 1, 96 ) ;
  315. /* Write 13 bit combined position index */
  316. Temp = (*Line).Sfs[0].Ppos >> 16 ;
  317. Temp = Temp * 9 + ( (*Line).Sfs[1].Ppos >> 14) ;
  318. Temp *= 90 ;
  319. Temp += ((*Line).Sfs[2].Ppos >> 16) * 9 + ( (*Line).Sfs[3].Ppos >> 14 ) ;
  320. STUFF( Temp, Bsp, 13, 97 ) ;
  321. /* Write all the pulse positions */
  322. Temp = (*Line).Sfs[0].Ppos & 0x0000ffffL ;
  323. STUFF( Temp, Bsp, 16, 110 ) ;
  324. Temp = (*Line).Sfs[1].Ppos & 0x00003fffL ;
  325. STUFF( Temp, Bsp, 14, 126 ) ;
  326. Temp = (*Line).Sfs[2].Ppos & 0x0000ffffL ;
  327. STUFF( Temp, Bsp, 16, 140 ) ;
  328. Temp = (*Line).Sfs[3].Ppos & 0x00003fffL ;
  329. STUFF( Temp, Bsp, 14, 156 ) ;
  330. /* Write pulse amplitudes */
  331. Temp = (Word32) (*Line).Sfs[0].Pamp ;
  332. STUFF( Temp, Bsp, 6, 170 ) ;
  333. Temp = (Word32) (*Line).Sfs[1].Pamp ;
  334. STUFF( Temp, Bsp, 5, 176 ) ;
  335. Temp = (Word32) (*Line).Sfs[2].Pamp ;
  336. STUFF( Temp, Bsp, 6, 181 ) ;
  337. Temp = (Word32) (*Line).Sfs[3].Pamp ;
  338. STUFF( Temp, Bsp, 5, 187 ) ;
  339. }
  340. /* Low rate only part */
  341. else {
  342. /* Write 12 bits of positions */
  343. STUFF( (*Line).Sfs[0].Ppos, Bsp, 12, 96 ) ;
  344. STUFF( (*Line).Sfs[1].Ppos, Bsp, 12, 108 ) ;
  345. STUFF( (*Line).Sfs[2].Ppos, Bsp, 12, 120 ) ;
  346. STUFF( (*Line).Sfs[3].Ppos, Bsp, 12, 132 ) ;
  347. /* Write 4 bit Pamps */
  348. STUFF( (*Line).Sfs[0].Pamp, Bsp, 4, 144 ) ;
  349. STUFF( (*Line).Sfs[1].Pamp, Bsp, 4, 148 ) ;
  350. STUFF( (*Line).Sfs[2].Pamp, Bsp, 4, 152 ) ;
  351. STUFF( (*Line).Sfs[3].Pamp, Bsp, 4, 156 ) ;
  352. }
  353. }
  354. else {
  355. /* Do Sid frame gain */
  356. }
  357. DUMPLINE(Line);
  358. }
  359. //UNSTUFF n bits of *lp at bit position k into x
  360. // if you run out of *lp, use *++lp for leftovers
  361. //WARNING!: as a side effect lp may be changed!
  362. //lp and x must have an lvalue
  363. //n and k must be compile time constants
  364. //temp must be unsigned for shifts to be logical
  365. #define UNSTUFF(x, lp, n_in, k_in) {\
  366. register unsigned temp;\
  367. const int n = (n_in);\
  368. const int k = (k_in) & 31;\
  369. temp = *(lp);\
  370. temp=temp >> k;\
  371. if (n+k >= 32)\
  372. temp |= *(++lp) << (32-k);\
  373. temp &= ((1 << n) - 1);\
  374. (x) = temp;\
  375. }
  376. /*
  377. **
  378. ** Function: Line_Upck()
  379. **
  380. ** Description: unpacking of bitstream, gets coding parameters for a frame
  381. **
  382. ** Links to text: Section 4
  383. **
  384. ** Arguments:
  385. **
  386. ** Word32 *Vinp bitstream words
  387. ** int *VadAct Voice Activity Indicator
  388. **
  389. ** Outputs:
  390. **
  391. ** Word16 *VadAct
  392. **
  393. ** Return value:
  394. **
  395. ** LINEDEF coded parameters
  396. ** Word16 Crc
  397. ** Word32 LspId
  398. ** Word16 Olp[SubFrames/2]
  399. ** SFSDEF Sfs[SubFrames]
  400. **
  401. */
  402. void Line_Unpk(LINEDEF *LinePtr, Word32 *Vinp, enum Crate *WrkRatePtr, Word16 Crc )
  403. {
  404. Word32 *Bsp;
  405. int FrType ;
  406. Word32 Temp ;
  407. int BadData = 0; //Set to TRUE if invalid data discovered
  408. Word16 Bound_AcGn ;
  409. //short index;
  410. LinePtr->Crc = Crc;
  411. if(Crc !=0) {
  412. *WrkRatePtr = Lost;
  413. return; //This occurs when external erasure file is used
  414. }
  415. Bsp = Vinp;
  416. /* Decode the first two bits */
  417. UNSTUFF( Temp, Bsp, 2, 0 ) ;
  418. FrType = Temp;
  419. /* Decode the LspId */
  420. UNSTUFF( LinePtr->LspId, Bsp, 24, 2 ) ;
  421. switch ( FrType ) {
  422. case 0:
  423. *WrkRatePtr = Rate63;
  424. break;
  425. case 1:
  426. *WrkRatePtr = Rate53;
  427. break;
  428. case 2:
  429. *WrkRatePtr = Silent;
  430. //return; //no need to unpact the rest
  431. //HACK: for SID frame handling
  432. //Keep WrkRate set to whatever the previous frame was
  433. // and decode in a normal fashion
  434. //index=getRand();
  435. //if(*WrkRatePtr==Rate53)
  436. //{
  437. //memcpy((char *)(Vinp),&r53Noise[index*6],24);
  438. //}
  439. //else if(*WrkRatePtr==Rate63)
  440. //{
  441. //memcpy((char *)(Vinp),&r63Noise[index*6],24);
  442. //}
  443. //Burn first two bits again, since we already got the frame type
  444. //UNSTUFF( Temp, Bsp, 2, 0 );
  445. return;
  446. default:
  447. *WrkRatePtr = Lost;
  448. //??? unpack to rest to guess from?
  449. return;
  450. }
  451. /*
  452. Decode the common information to both rates
  453. */
  454. /* Decode the adaptive codebook lags */
  455. UNSTUFF( Temp, Bsp, 7, 26 ) ;
  456. /* TEST if forbidden code */
  457. if( Temp <= 123) {
  458. LinePtr->Olp[0] = (Word16) Temp + (Word16)PitchMin ;
  459. }
  460. else {
  461. /* transmission error */
  462. LinePtr->Crc = 1;
  463. return; /*what happens in the minfilter?*/
  464. }
  465. UNSTUFF( Temp, Bsp, 2, 33 ) ;
  466. LinePtr->Sfs[1].AcLg = Temp ;
  467. UNSTUFF( Temp, Bsp, 7, 35 ) ;
  468. /* TEST if forbidden code */
  469. if( Temp <= 123) {
  470. LinePtr->Olp[1] = (Word16) Temp + (Word16)PitchMin ;
  471. }
  472. else {
  473. /* transmission error */
  474. LinePtr->Crc = 1;
  475. return;
  476. }
  477. //UNSTUFF( Temp, Bsp, 2, 41 ) ;
  478. UNSTUFF( Temp, Bsp, 2, 42 ) ;
  479. LinePtr->Sfs[3].AcLg = (Word16) Temp ;
  480. LinePtr->Sfs[0].AcLg = 1 ;
  481. LinePtr->Sfs[2].AcLg = 1 ;
  482. /* Decode the combined gains accordingly to the rate */
  483. UNSTUFF( Temp, Bsp, 12, 44 ) ;
  484. LinePtr->Sfs[0].Tran = 0 ;
  485. Bound_AcGn = NbFilt170 ;
  486. if ( (*WrkRatePtr == Rate63) && (LinePtr->Olp[0>>1] < (SubFrLen-2) ) ) {
  487. LinePtr->Sfs[0].Tran = (Word16)(Temp >> 11) ;
  488. Temp &= 0x000007ffL ;
  489. Bound_AcGn = NbFilt085 ;
  490. }
  491. LinePtr->Sfs[0].AcGn = (Word16)(Temp / (Word16)NumOfGainLev) ;
  492. if(LinePtr->Sfs[0].AcGn < Bound_AcGn ) {
  493. LinePtr->Sfs[0].Mamp = (Word16)(Temp % (Word16)NumOfGainLev) ;
  494. }
  495. else {
  496. /* error detected */
  497. LinePtr->Crc = 1;
  498. return ;
  499. }
  500. UNSTUFF( Temp, Bsp, 12, 56 ) ;
  501. LinePtr->Sfs[1].Tran = 0 ;
  502. Bound_AcGn = NbFilt170 ;
  503. if ( (*WrkRatePtr == Rate63) && (LinePtr->Olp[1>>1] < (SubFrLen-2) ) ) {
  504. LinePtr->Sfs[1].Tran = (Word16)(Temp >> 11) ;
  505. Temp &= 0x000007ffL ;
  506. Bound_AcGn = NbFilt085 ;
  507. }
  508. LinePtr->Sfs[1].AcGn = (Word16)(Temp / (Word16)NumOfGainLev) ;
  509. if(LinePtr->Sfs[1].AcGn < Bound_AcGn ) {
  510. LinePtr->Sfs[1].Mamp = (Word16)(Temp % (Word16)NumOfGainLev) ;
  511. }
  512. else {
  513. /* error detected */
  514. LinePtr->Crc = 1;
  515. return ;
  516. }
  517. UNSTUFF( Temp, Bsp, 12, 68 ) ;
  518. LinePtr->Sfs[2].Tran = 0 ;
  519. Bound_AcGn = NbFilt170 ;
  520. if ( (*WrkRatePtr == Rate63) && (LinePtr->Olp[2>>1] < (SubFrLen-2) ) ) {
  521. LinePtr->Sfs[2].Tran = (Word16)(Temp >> 11) ;
  522. Temp &= 0x000007ffL ;
  523. Bound_AcGn = NbFilt085 ;
  524. }
  525. LinePtr->Sfs[2].AcGn = (Word16)(Temp / (Word16)NumOfGainLev) ;
  526. if(LinePtr->Sfs[2].AcGn < Bound_AcGn ) {
  527. LinePtr->Sfs[2].Mamp = (Word16)(Temp % (Word16)NumOfGainLev) ;
  528. }
  529. else {
  530. /* error detected */
  531. LinePtr->Crc = 1;
  532. return ;
  533. }
  534. UNSTUFF( Temp, Bsp, 12, 80 ) ;
  535. LinePtr->Sfs[3].Tran = 0 ;
  536. Bound_AcGn = NbFilt170 ;
  537. if ( (*WrkRatePtr == Rate63) && (LinePtr->Olp[3>>1] < (SubFrLen-2) ) ) {
  538. LinePtr->Sfs[3].Tran = (Word16)(Temp >> 11) ;
  539. Temp &= 0x000007ffL ;
  540. Bound_AcGn = NbFilt085 ;
  541. }
  542. LinePtr->Sfs[3].AcGn = (Word16)(Temp / (Word16)NumOfGainLev) ;
  543. if(LinePtr->Sfs[3].AcGn < Bound_AcGn ) {
  544. LinePtr->Sfs[3].Mamp = (Word16)(Temp % (Word16)NumOfGainLev) ;
  545. }
  546. else {
  547. /* error detected */
  548. LinePtr->Crc = 1;
  549. return ;
  550. }
  551. /* Decode the grids */
  552. UNSTUFF( LinePtr->Sfs[0].Grid, Bsp, 1, 92 ) ;
  553. UNSTUFF( LinePtr->Sfs[1].Grid, Bsp, 1, 93 ) ;
  554. UNSTUFF( LinePtr->Sfs[2].Grid, Bsp, 1, 94 ) ;
  555. UNSTUFF( LinePtr->Sfs[3].Grid, Bsp, 1, 95 ) ;
  556. if ( *WrkRatePtr == Rate63 ) {
  557. /* Skip the reserved bit */
  558. UNSTUFF( Temp, Bsp, 1, 96 ) ;
  559. if(Temp != 0)
  560. BadData = 1;
  561. /* Decode 13 bit combined position index */
  562. UNSTUFF( Temp, Bsp, 13, 97 ) ;
  563. LinePtr->Sfs[0].Ppos = ( Temp/90 ) / 9 ;
  564. LinePtr->Sfs[1].Ppos = ( Temp/90 ) % 9 ;
  565. LinePtr->Sfs[2].Ppos = ( Temp%90 ) / 9 ;
  566. LinePtr->Sfs[3].Ppos = ( Temp%90 ) % 9 ;
  567. /* Decode all the pulse positions */
  568. UNSTUFF( Temp, Bsp, 16, 110 ) ;
  569. LinePtr->Sfs[0].Ppos = ( LinePtr->Sfs[0].Ppos << 16 ) + Temp ;
  570. UNSTUFF( Temp, Bsp, 14, 126 ) ;
  571. LinePtr->Sfs[1].Ppos = ( LinePtr->Sfs[1].Ppos << 14 ) + Temp ;
  572. UNSTUFF( Temp, Bsp, 16, 140 ) ;
  573. LinePtr->Sfs[2].Ppos = ( LinePtr->Sfs[2].Ppos << 16 ) + Temp ;
  574. UNSTUFF( Temp, Bsp, 14, 156 ) ;
  575. LinePtr->Sfs[3].Ppos = ( LinePtr->Sfs[3].Ppos << 14 ) + Temp ;
  576. /* Decode pulse amplitudes */
  577. UNSTUFF( LinePtr->Sfs[0].Pamp, Bsp, 6, 170 ) ;
  578. UNSTUFF( LinePtr->Sfs[1].Pamp, Bsp, 5, 176 ) ;
  579. UNSTUFF( LinePtr->Sfs[2].Pamp, Bsp, 6, 181 ) ;
  580. UNSTUFF( LinePtr->Sfs[3].Pamp, Bsp, 5, 187 ) ;
  581. }
  582. else {
  583. /* Decode the positions */
  584. UNSTUFF( LinePtr->Sfs[0].Ppos, Bsp, 12, 96 ) ;
  585. UNSTUFF( LinePtr->Sfs[1].Ppos, Bsp, 12, 108 ) ;
  586. UNSTUFF( LinePtr->Sfs[2].Ppos, Bsp, 12, 120 ) ;
  587. UNSTUFF( LinePtr->Sfs[3].Ppos, Bsp, 12, 132 ) ;
  588. /* Decode the amplitudes */
  589. UNSTUFF( LinePtr->Sfs[0].Pamp, Bsp, 4, 144 ) ;
  590. UNSTUFF( LinePtr->Sfs[1].Pamp, Bsp, 4, 148 ) ;
  591. UNSTUFF( LinePtr->Sfs[2].Pamp, Bsp, 4, 152 ) ;
  592. UNSTUFF( LinePtr->Sfs[3].Pamp, Bsp, 4, 156 ) ;
  593. }
  594. DUMPLINE(LinePtr);
  595. return;
  596. }
  597. //-------------------------------------------
  598. int Rand_lbc(int *p)
  599. {
  600. *p = ((*p)*521L + 259) << 16 >> 16;
  601. return(*p);
  602. }
  603. //-------------------------------------------
  604. //Scale
  605. float DotProd(register const float in1[], register const float in2[], register int npts)
  606. /************************************************************************/
  607. /* in1[],in2[]; Input arrays */
  608. /* npts; Number of samples in each (vector dimension) */
  609. /************************************************************************/
  610. {
  611. #if OPT_DOT
  612. #define array1 esi
  613. #define array2 edi
  614. #define idx ebx
  615. #define prod2(n) ASM fld DP[array1+4*idx+4*n] ASM fmul DP[array2+4*idx+4*n]
  616. #define faddp(n) ASM faddp ST(n),ST(0)
  617. // Do in groups of 8. We do 4 before the loop, then groups
  618. // of 8, and then the final leftovers.
  619. ASM
  620. {
  621. #if 0 //npts of type short
  622. mov idx,0;
  623. mov bx,npts;
  624. #else
  625. mov idx,npts;
  626. #endif
  627. mov array1,in1;
  628. mov array2,in2;
  629. sub idx,12;
  630. jle small;
  631. }
  632. prod2(11);
  633. prod2(10);
  634. prod2(9) fxch(2) faddp(1);
  635. prod2(8) fxch(2) faddp(1);
  636. looop:
  637. prod2(7) fxch(2) faddp(1);
  638. prod2(6) fxch(2) faddp(1);
  639. prod2(5) fxch(2) faddp(1);
  640. prod2(4) fxch(2) faddp(1);
  641. prod2(3) fxch(2) faddp(1);
  642. prod2(2) fxch(2) faddp(1);
  643. prod2(1) fxch(2) faddp(1);
  644. prod2(0) fxch(2) faddp(1);
  645. ASM sub idx,8;
  646. ASM jge looop;
  647. ASM add idx,7;
  648. ASM jl done;
  649. loop2:
  650. prod2(0) fxch(2) faddp(1);
  651. ASM dec idx;
  652. ASM jge loop2;
  653. done:
  654. faddp(1);
  655. ASM jmp alldone;
  656. small: // handle Len<12 cases here
  657. ASM add idx,9
  658. ASM cmp idx,-1
  659. ASM jg MoreThan2
  660. ASM je Exactly2
  661. prod2(2);
  662. ASM jmp alldone;
  663. Exactly2:
  664. prod2(2);
  665. prod2(1);
  666. faddp(1);
  667. ASM jmp alldone;
  668. MoreThan2:
  669. prod2(2);
  670. prod2(1);
  671. ASM jmp loop2;
  672. alldone: ;
  673. #else
  674. register float accum; /* Internal accumulator */
  675. int n=npts,i;
  676. accum = 0.0f;
  677. for (i=0; i<n; i++)
  678. accum += in1[i] * in2[i];
  679. return(accum);
  680. #endif
  681. //Ignore warning C4035 and C4102 for da_dot and da_dotr: due to use of __asm
  682. }
  683. //-------------------------------------------------------------
  684. float DotRev(register const float in1[], register const float in2[], register int npts)
  685. /************************************************************************/
  686. /* in1[],in2[]; Input arrays */
  687. /* npts; Number of samples in each (vector dimension) */
  688. /************************************************************************/
  689. {
  690. #if OPT_REV
  691. #define array1 esi
  692. #define array2 edi
  693. #define idx ebx
  694. #define prod3(n) ASM fld DP[array1+4*idx+4*n] ASM fmul DP[array2-4*n]
  695. #define faddp(n) ASM faddp ST(n),ST(0)
  696. // Do in groups of 8. We do 4 before the loop, then groups
  697. // of 8, and then the final leftovers.
  698. ASM
  699. {
  700. mov idx,npts;
  701. mov array1,in1;
  702. mov array2,in2;
  703. lea array2,[array2+4*11]; // point element array2[11]
  704. sub idx,12; // point to array1[end-11]
  705. jle small;
  706. }
  707. prod3(11);
  708. prod3(10);
  709. prod3(9) fxch(2) faddp(1);
  710. prod3(8) fxch(2) faddp(1);
  711. looop:
  712. prod3(7) fxch(2) faddp(1);
  713. prod3(6) fxch(2) faddp(1);
  714. prod3(5) fxch(2) faddp(1);
  715. prod3(4) fxch(2) faddp(1);
  716. prod3(3) fxch(2) faddp(1);
  717. prod3(2) fxch(2) faddp(1);
  718. prod3(1) fxch(2) faddp(1);
  719. prod3(0) fxch(2) faddp(1);
  720. ASM add array2,32
  721. ASM sub idx,8;
  722. ASM jge looop;
  723. cleanup:
  724. ASM sub array2,28
  725. ASM add idx,7;
  726. ASM jl done;
  727. loop2:
  728. prod3(0) fxch(2) faddp(1);
  729. ASM add array2,4
  730. ASM dec idx;
  731. ASM jge loop2;
  732. done:
  733. faddp(1);
  734. ASM jmp alldone;
  735. small: // handle Len<12 cases here
  736. ASM sub array2,36
  737. ASM add idx,9
  738. ASM cmp idx,-1
  739. ASM jg MoreThan2
  740. ASM je Exactly2
  741. Exactly1:
  742. prod3(2);
  743. ASM jmp alldone;
  744. Exactly2:
  745. prod3(2);
  746. prod3(1);
  747. faddp(1);
  748. ASM jmp alldone;
  749. MoreThan2:
  750. prod3(2);
  751. prod3(1);
  752. ASM jmp loop2;
  753. alldone: ;
  754. #else
  755. register float accum; /* Internal accumulator */
  756. int i;
  757. in2 += npts-1;
  758. accum = 0.0f;
  759. for (i=0; i<npts; i++)
  760. accum += in1[i] * (*in2--);
  761. return(accum);
  762. #endif
  763. //Ignore warning C4035 and C4102 for da_dotr: due to use of __asm
  764. }
  765. //-------------------------------------------------------------
  766. float Dot10(float *in1, float *in2)
  767. {
  768. return(
  769. in1[0]*in2[0] +
  770. in1[1]*in2[1] +
  771. in1[2]*in2[2] +
  772. in1[3]*in2[3] +
  773. in1[4]*in2[4] +
  774. in1[5]*in2[5] +
  775. in1[6]*in2[6] +
  776. in1[7]*in2[7] +
  777. in1[8]*in2[8] +
  778. in1[9]*in2[9]
  779. );
  780. }