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.
 
 
 
 
 

212 line
4.3 KiB

  1. /*
  2. * Atpdec
  3. * Copyright (c) 2003 by Thierry Leconte (F4DWV)
  4. *
  5. * $Id$
  6. *
  7. * This library is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Library General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Library General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. *
  21. */
  22. #include <math.h>
  23. #include <filter.h>
  24. #include <filtercoeff.h>
  25. #define Fe 11025
  26. #define PixelLine 2080
  27. #define Fp (2*PixelLine)
  28. #define RSMULT 265
  29. #define Fi (Fp*RSMULT)
  30. static double FreqOsc=2400.0/Fe;
  31. static double FreqLine=1.0;
  32. extern int getsample(float *inbuff ,int nb);
  33. static float pll(float Iv, float Qv)
  34. {
  35. /* pll coeff */
  36. #define K1 5e-3
  37. #define K2 3e-6
  38. static double PhaseOsc=0.0;
  39. double DPhi;
  40. double DF;
  41. double I,Q;
  42. double Io,Qo;
  43. /* quadrature oscillator */
  44. Io=cos(PhaseOsc); Qo=sin(PhaseOsc);
  45. /* phase detector */
  46. I=Iv*Io+Qv*Qo;
  47. Q=Qv*Io-Iv*Qo;
  48. DPhi=atan2(Q,I)/M_PI;
  49. /* update */
  50. DF=K1*DPhi+FreqOsc;
  51. FreqOsc+=K2*DPhi;
  52. PhaseOsc+=2.0*M_PI*DF;
  53. if (PhaseOsc > M_PI) PhaseOsc-=2.0*M_PI;
  54. if (PhaseOsc <= -M_PI) PhaseOsc+=2.0*M_PI;
  55. return (float)I;
  56. }
  57. static double fr=2400.0/Fe;
  58. static double offset=0.0;
  59. getamp(float *ambuff,int nb)
  60. {
  61. #define BLKIN 4096
  62. static float inbuff[BLKIN];
  63. static int nin=0;
  64. static int idxin=0;
  65. int n;
  66. for(n=0;n<nb;n++) {
  67. float I,Q;
  68. if(nin<IQFilterLen) {
  69. int res;
  70. memmove(inbuff,&(inbuff[idxin]),nin*sizeof(float));
  71. idxin=0;
  72. res=getsample(&(inbuff[nin]),BLKIN-nin);
  73. nin+=res;
  74. if(nin<IQFilterLen) return(n);
  75. }
  76. iqfir(&(inbuff[idxin]),Icoeff,Qcoeff,IQFilterLen,&I,&Q);
  77. ambuff[n]=pll(I,Q);
  78. fr=0.25*FreqOsc+0.75*fr;
  79. idxin++;nin--;
  80. }
  81. return(nb);
  82. }
  83. int getpixelv(float *pvbuff,int nb)
  84. {
  85. #define BLKAMP 256
  86. static float ambuff[BLKAMP];
  87. static int nam=0;
  88. static int idxam=0;
  89. int n;
  90. for(n=0;n<nb;n++) {
  91. double mult;
  92. int shift;
  93. if(nam<15) {
  94. int res;
  95. memmove(ambuff,&(ambuff[idxam]),nam*sizeof(float));
  96. idxam=0;
  97. res=getamp(&(ambuff[nam]),BLKAMP-nam);
  98. nam+=res;
  99. if(nam<15) return(n);
  100. }
  101. mult=(double)Fi*fr/2400.0*FreqLine;
  102. pvbuff[n]=rsfir(&(ambuff[idxam]),rsfilter,RSFilterLen,offset,mult)*mult*256.0;
  103. shift=(int)((RSMULT-offset+mult-1)/mult);
  104. offset=shift*mult+offset-RSMULT;
  105. idxam+=shift;nam-=shift;
  106. }
  107. return(nb);
  108. }
  109. int getpixelrow(float *pixelv)
  110. {
  111. static float pixels[PixelLine+SyncFilterLen];
  112. static int npv=0;
  113. static int synced=0;
  114. static double max=0.0;
  115. float corr,scorr;
  116. double ph;
  117. int n,res;
  118. if(npv>0)
  119. memmove(pixelv,pixels,npv*sizeof(float));
  120. if(npv<SyncFilterLen) {
  121. res=getpixelv(&(pixelv[npv]),SyncFilterLen-npv);
  122. npv+=res;
  123. if(npv<SyncFilterLen)
  124. return(0);
  125. }
  126. /* test sync */
  127. corr=fir(pixelv,Sync,SyncFilterLen);
  128. scorr=fir(&(pixelv[1]),Sync,SyncFilterLen);
  129. FreqLine=1.0-scorr/corr/PixelLine/4.0;
  130. if(corr < 0.75*max) {
  131. synced=0;
  132. FreqLine=1.0;
  133. }
  134. max=corr;
  135. if(synced<8) {
  136. int shift,mshift;
  137. if(npv<PixelLine+SyncFilterLen) {
  138. res=getpixelv(&(pixelv[npv]),PixelLine+SyncFilterLen-npv);
  139. npv+=res;
  140. if(npv<PixelLine+SyncFilterLen)
  141. return(0);
  142. }
  143. /* lookup sync start */
  144. mshift=0;
  145. for(shift=1;shift<PixelLine;shift++) {
  146. double corr;
  147. corr=fir(&(pixelv[shift]),Sync,SyncFilterLen);
  148. if(corr>max) {
  149. mshift=shift;
  150. max=corr;
  151. }
  152. }
  153. if(mshift !=0) {
  154. memmove(pixelv,&(pixelv[mshift]),(npv-mshift)*sizeof(float));
  155. npv-=mshift;
  156. synced=0;
  157. FreqLine=1.0;
  158. } else
  159. synced+=1;
  160. }
  161. if(npv<PixelLine) {
  162. res=getpixelv(&(pixelv[npv]),PixelLine-npv);
  163. npv+=res;
  164. if(npv<PixelLine) return(0);
  165. }
  166. if(npv==PixelLine) {
  167. npv=0;
  168. } else {
  169. memmove(pixels,&(pixelv[PixelLine]),(npv-PixelLine)*sizeof(float));
  170. npv-=PixelLine;
  171. }
  172. return (1);
  173. }