/* encode.c: this file contains the encoding decoding routines. */

#include "raw_proto.h"

/* endian_test ****************
 * returns 0 for little endian *
 *         1 for big endian    *
 ******************************/
int endian_test()
{
  long int in = 1;
  char *cp;
  
  cp = (char *) &in;
  
  if(*cp) return 0;
  return 1;
}

/* vos_real6_to_float ***********
* convert a VOS REAL*6 to float *
********************************/
float vos_real6_to_float(char *a)
{
  long int mant, expon;
  char *amant, *aexpon;
  double outmant;

  amant = (char *) &mant;
  aexpon = (char *) &expon;

  if(endian_test())
  {
    amant[1] = a[0];
    amant[2] = a[1];
    amant[3] = a[2];
    
    aexpon[3] = a[5];        /* real*6 has only an 8-bit mantissa */
    
    amant[0] = (a[0]&0x80) ? 0xff : 0x00;
    aexpon[0] = aexpon[1] = aexpon[2] = (a[5]&0x80) ? 0xff : 0x00;
  }
  else
  {
    amant[2] = a[0];
    amant[1] = a[1];
    amant[0] = a[2];
    
    aexpon[0] = a[5];        /* real*6 has only an 8-bit mantissa */
    
    amant[3] = (a[0]&0x80) ? 0xff : 0x00;
    aexpon[3] = aexpon[2] = aexpon[1] = (a[5]&0x80) ? 0xff : 0x00;
  }

#define two_tothe_23 8388608.0
  outmant = (double) (mant / two_tothe_23);
#undef  two_tothe_23

  return (float) (ldexp(outmant, expon));

}

/* convert_ao_data ******************************************
* INPUT:    data    pointer to data buffer                  *
*           ah      header for current raw data             *
*           pns     pointer to float numbers array          *
* OUTPUT:   count   long int count of floats converted.     *
* PURPOSE:                                                  *
* converts AO-ISR raw VOS real6 data into floating point    *
************************************************************/
long int convert_ao_data(char *data, HarrisAOHeader *ah, float *pns)
{
	long int i,j,n;
	n = VOS_WORD_SIZE;
	j = ah->nwords2 * n - CUPRI_VOS_HEADER_SIZE;
	n *= 2;
	for(i=0;i<j;i+= n)
	{
		*(pns++) = vos_real6_to_float(data + i);
	}
	return (j / n);
}

/* convert_data *********************************************
* INPUT:    data    pointer to data buffer                  *
*           ch      header for current raw data             *
*           rx      desired receiver id, 0,1,2,...etc       *
*           pVrx    pointer to complex number array         *
* PURPOSE:                                                  *
* converts CUPRI raw data into floating point complex data  *
************************************************************/
void convert_data(char *data, HarrisHeader *ch, InputParms *ip, ComplexFloat *pVrx)
{
    int i,imax;
    long int range, index;
    long int rnci,rci;
    long int nipp, ippsize;

    /* multiple channels only for coherence */
    imax = (ip->pm == 3) ? ch->nchanls/2: 1;
    
    ippsize = ch->tu_ng * ch->nchanls;

    switch(ch->nsbits)
    {
        case 8:
#ifdef DEBUG_ENC
            printf("encode: convert_data: 8-bit data conversion for %d rx\n",imax);
#endif /* DEBUG_ENC */
            /* 8-bit deep data no difference mac & mips */
            for(i=0;i<imax;i++)
            {
                rci = ((ip->rx + i)%3) * 2;
                for(range=0;range<ch->tu_ng;range++)
                {
                    rnci = range * ch->nchanls + rci;
                    for(nipp=0;nipp<ip->fftwdth;nipp++)
                    {
                        index = nipp * ippsize + rnci;
                        pVrx->r = (!ip->maxrecs ? 0:data[index]);
                        pVrx->i = (ip->maxrecs == 1 ? 0:data[index+1]);
                        pVrx++;
                    }
                }
            }
            break;
        default:
            printf_exit("encode: convert_data: No conversion for %ld bit data\n",
                ch->nsbits);
            break;
    }
}

/* convert_ao_header ********************************
* INPUT:    buf          start of Harris Raw Header *
* RETURNS:  RawHeader    converted raw header       *
****************************************************/
RawAOHeader convert_ao_header(char *buf)
{
    RawAOHeader ah;
    long int i, *n;
    char *pc,*pbuf, *next;
    int endt;

    pbuf = buf;
    n = ah.hdr;
    endt = endian_test();

    for(i=0;i<CUPRI_HEADER_SIZE;i++)
    {

      if(endt)
      {
        next = (char *) (n + 1);
        for(pc = (char *)n;pc<next;pc++)
        {
            if(pc == (char *)n) *pc++ = (*pbuf & 0x80) ? 0xff : 0;
            *pc = *pbuf++;
        }
      }
      else
      {
        next = (char *)(n+1);
        for(pc = next - 1;pc>=(char *)n;pc--)
        {
            if(pc == next - 1) *pc-- = (*pbuf & 0x80) ? 0xff : 0;
            *pc = *pbuf++;
        }
      }

      n++;
    }
    /* fix float angles in ah.header */
    ah.h.start_zen = vos_real6_to_float(buf + 48);
    ah.h.start_az = vos_real6_to_float(buf + 54);
    ah.h.end_zen = vos_real6_to_float(buf + 60);
    ah.h.end_az = vos_real6_to_float(buf + 66);

    /* fix strings in ah.header using ch.h.ident# and copy directly from buf */
    pc = ah.h.ident1;
    pbuf = buf;
    strncpy(pc,pbuf,9);
    pc[9] = '\0';

    pc = ah.h.progname;
    pbuf = buf + 15;
    strncpy(pc,pbuf,9);
    pc[9] = '\0';
    
    pc = ah.h.msa_txmod;
    pbuf = buf + 144;
    strncpy(pc,pbuf,6);
    pc[6] = '\0';

    pc = ah.h.txcode;
    pbuf = buf + 165;
    strncpy(pc,pbuf,3);
    pc[3] = '\0';


#ifdef DEBUG_ENC
    dump_ao_header(ah);
#endif /* DEBUG_ENC */

    return(ah);
}

/* convert_header ***********************************
* INPUT:    buf          start of Harris Raw Header *
* RETURNS:  RawHeader    converted raw header       *
****************************************************/
RawHeader convert_header(char *buf)
{
    RawHeader ch;
    long int i, *n;
    char *pc,*pbuf, *next;
    int endt;

    pbuf = buf;
    n = ch.hdr;
    endt = endian_test();

    for(i=0;i<CUPRI_HEADER_SIZE;i++)
    {

      if(endt)
      {
        next = (char *) (n + 1);
        for(pc = (char *)n;pc<next;pc++)
        {
            if(pc == (char *)n) *pc++ = (*pbuf & 0x80) ? 0xff : 0;
            *pc = *pbuf++;
        }
      }
      else
      {
	next = (char *)(n+1);
	for(pc = next - 1;pc>=(char *)n;pc--)
	{
	  if(pc == next - 1) *pc-- = (*pbuf & 0x80) ? 0xff : 0;
	  *pc = *pbuf++;
	}
      }

      n++;
    }
    
    /* fix strings in ch.header using ch.h.ident# and copy directly from buf */
    pc = ch.h.ident1;
    pbuf = buf;
    strncpy(pc,pbuf,9);
    pc[9] = '\0';

    pc = ch.h.ident2;
    pbuf = buf +180;
    strncpy(pc,pbuf,60);
    pc[60] = '\0';
    
    pc = ch.h.ident3;
    pbuf = buf + 240;
    strncpy(pc,pbuf,60);
    pc[60] = '\0';

#ifdef DEBUG_ENC
    dump_header(ch);
#endif /* DEBUG_ENC */

    return(ch);
}

#ifdef DEBUG_ENC

/* dump_ao_header ***********************************
* INPUT:    ah    the current converted raw header  *
* PURPOSE:                                          *
* Items in the header are printed                   *
****************************************************/
void dump_ao_header(RawAOHeader ah)
{
    printf("encode: dump_ao_header: raw header dump\n");
    printf("ident1     : %11s ::progname   : %11s\n",ah.h.ident1,ah.h.progname);
    printf("msa_txmod  : %11s ::txcode     : %11s\n",ah.h.msa_txmod,ah.h.txcode);
    printf("harris_date: %11ld ::harris_time: %11ld\n",
           ah.h.harris_date_time[0],ah.h.harris_date_time[1]);
    printf("rec_number : %11ld ::scan_number: %11ld\n",ah.h.rec_number,ah.h.scan_number);
    printf("start_time : %11ld ::stop_time  : %11ld\n",ah.h.start_time,ah.h.stop_time);
    printf("start_zen  : %11.3f ::start_az   : %11.3f\n",ah.h.start_zen,ah.h.start_az);
    printf("end_zen    : %11.3f ::end_az     : %11.3f\n",ah.h.end_zen,ah.h.end_az);
    printf("ngates     : %11ld ::nlags      : %11ld\n",ah.h.ngates,ah.h.nlags);
    printf("n_tx_smp   : %11ld ::n_sig_smp  : %11ld ::n_nx_smp   : %11ld\n",
           ah.h.n_tx_smp,ah.h.n_sig_smp,ah.h.n_nx_smp);
    printf("npulses    : %11ld ::spacing    : %11ld ::nippsave   : %11ld\n",
           ah.h.npulses,ah.h.spacing,ah.h.nippsave);
    printf("ipp        : %11ld ::bw         : %11ld ::rf         : %11ld\n",
           ah.h.ipp,ah.h.bw,ah.h.rf);
    printf("sd1        : %11ld ::si1        : %11ld\n",ah.h.sd1,ah.h.si1);
    printf("sd2        : %11ld ::si2        : %11ld\n",ah.h.sd2,ah.h.si2);
    printf("ncodestat  : %11ld ::gatewidth  : %11ld ::nbauds     : %11ld\n",
           ah.h.ncodestat,ah.h.gatewidth,ah.h.nbauds);
    printf("caltemp    : %11ld ::nippsperbuf: %11ld\n",ah.h.caltemp,ah.h.nippsperbuf);
    printf("nwords     : %11ld ::nwords2    : %11ld\n",ah.h.nwords,ah.h.nwords2);

/* Ignoring 0's
    printf("notused10  : %11ld\n",ah.h.notused10);
    printf("notused14  : %11ld\n",ah.h.notused14[0]);
    printf("notused15  : %11ld\n",ah.h.notused14[1]);
    printf("notused16  : %11ld\n",ah.h.notused14[2]);
    printf("notused25  : %11ld\n",ah.h.notused25[0]);
    printf("notused26  : %11ld\n",ah.h.notused25[1]);
    printf("notused27  : %11ld\n",ah.h.notused25[2]);
    printf("notused29  : %11ld\n",ah.h.notused25[4]);
    printf("notused32  : %11ld\n",ah.h.notused32[0]);
    printf("notused33  : %11ld\n",ah.h.notused32[1]);
    printf("notused34  : %11ld\n",ah.h.notused32[2]);
    printf("notused40  : %11ld\n",ah.h.notused38[2]);
    printf("notused42  : %11ld\n",ah.h.notused38[4]);
    printf("notused43  : %11ld\n",ah.h.notused38[5]);
    printf("notused44  : %11ld\n",ah.h.notused38[6]);
    printf("notused45  : %11ld\n",ah.h.notused38[7]);
    printf("notused46  : %11ld\n",ah.h.notused38[8]);
    printf("notused60  : %11ld\n",ah.h.notused60[0]);
    printf("notused62  : %11ld\n",ah.h.notused60[2]);
    printf("notused63  : %11ld\n",ah.h.notused60[3]);
    printf("notused64  : %11ld\n",ah.h.notused60[4]);
    printf("notused65  : %11ld\n",ah.h.notused60[5]);
    printf("notused66  : %11ld\n",ah.h.notused60[6]);
    printf("notused67  : %11ld\n",ah.h.notused60[7]);
    printf("notused68  : %11ld\n",ah.h.notused60[8]);
    printf("notused69  : %11ld\n",ah.h.notused60[9]);
    printf("notused72  : %11ld\n",ah.h.notused71[1]);
    printf("notused73  : %11ld\n",ah.h.notused71[2]);
    printf("notused74  : %11ld\n",ah.h.notused71[3]);
    printf("notused75  : %11ld\n",ah.h.notused71[4]);
    printf("notused76  : %11ld\n",ah.h.notused71[5]);
    printf("notused77  : %11ld\n",ah.h.notused71[6]);
    printf("notused78  : %11ld\n",ah.h.notused71[7]);
    printf("notused79  : %11ld\n",ah.h.notused71[8]);
    printf("notused80  : %11ld\n",ah.h.notused71[9]);
    printf("notused81  : %11ld\n",ah.h.notused71[10]);
    printf("notused82  : %11ld\n",ah.h.notused71[11]);
    printf("notused83  : %11ld\n",ah.h.notused71[12]);
    printf("notused84  : %11ld\n",ah.h.notused71[13]);
    printf("notused85  : %11ld\n",ah.h.notused71[14]);
    printf("notused86  : %11ld\n",ah.h.notused71[15]);
    printf("notused87  : %11ld\n",ah.h.notused71[16]);
    printf("notused88  : %11ld\n",ah.h.notused71[17]);
    printf("notused89  : %11ld\n",ah.h.notused71[18]);
    printf("notused90  : %11ld\n",ah.h.notused71[19]);
    printf("notused91  : %11ld\n",ah.h.notused71[20]);
    printf("notused94  : %11ld\n",ah.h.notused94[0]);
    printf("notused97  : %11ld\n",ah.h.notused94[3]);
    printf("notused98  : %11ld\n",ah.h.notused94[4]);
    printf("notused99  : %11ld\n",ah.h.notused94[5]);
    printf("notused100 : %11ld\n",ah.h.notused94[6]);
    printf("notused101 : %11ld\n",ah.h.notused94[7]);
    printf("notused104 : %11ld\n",ah.h.notused104);
    printf("notused106 : %11ld\n",ah.h.notused106[0]);
    printf("notused108 : %11ld\n",ah.h.notused106[2]);
    printf("notused109 : %11ld\n",ah.h.notused106[3]);
    printf("notused111 : %11ld\n",ah.h.notused111);
*/

    printf("notused28  : %11ld ::notused38  : %11ld ::notused39  : %11ld\n",
           ah.h.notused25[3],ah.h.notused38[0],ah.h.notused38[1]);
    printf("notused41  : %11ld ::notused61  : %11ld\n",
           ah.h.notused38[3],ah.h.notused60[1]);
    printf("notused71  : %11ld ::notused95  : %11ld\n",
           ah.h.notused71[1],ah.h.notused94[1]);
    printf("notused96  : %11ld ::notused102 : %11ld ::notused107 : %11ld\n",
           ah.h.notused94[2],ah.h.notused94[8],ah.h.notused106[1]);
}

/* dump_header **************************************
* INPUT:    ch    the current converted raw header  *
* PURPOSE:                                          *
* Items in the header are printed                   *
****************************************************/
void dump_header(RawHeader ch)
{
    printf("encode: dump_header: %s raw header dump\n",ch.h.ident1);
    printf("Ident2    : %s\n",ch.h.ident2);
    printf("Ident3    : %s\n",ch.h.ident3);
    printf("seq_number: %ld\n",ch.h.seq_number);
    printf("rec_number: %ld\n",ch.h.rec_number);
    printf("start_time: %ld\n",ch.h.start_time);
    printf("stop_time : %ld\n",ch.h.stop_time);
    printf("tu_nippsf : %ld\n",ch.h.tu_nippsf);
    printf("tu_ipp    : %ld\n",ch.h.tu_ipp);
    printf("tu_pw     : %ld\n",ch.h.tu_pw);
    printf("tu_ng     : %ld\n",ch.h.tu_ng);
    printf("tu_si     : %ld\n",ch.h.tu_si);
    printf("tu_sd     : %ld\n",ch.h.tu_sd);
    printf("tu_tau    : %ld\n",ch.h.tu_tau);
    printf("nchanls   : %ld\n",ch.h.nchanls);
    printf("nsbits    : %ld\n",ch.h.nsbits);
    printf("irig      : %ld\n",ch.h.irig);
    printf("nippstw   : %ld\n",ch.h.nippstw);
    printf("nbaudp    : %ld\n",ch.h.nbaudp);
    printf("n_tx_smp  : %ld\n",ch.h.n_tx_smp);
    printf("n_nx_smp  : %ld\n",ch.h.n_nx_smp);
    printf("mcd_ipp   : %ld\n",ch.h.mcd_ipp);
    printf("mcd_pw    : %ld\n",ch.h.mcd_pw);
    printf("mcd_ng    : %ld\n",ch.h.mcd_ng);
    printf("mcd_si    : %ld\n",ch.h.mcd_si);
    printf("mcd_sd    : %ld\n",ch.h.mcd_sd);
    printf("rt_rec    : %ld\n",ch.h.rt_rec);
    printf("mtu_rec   : %ld\n",ch.h.mtu_rec);
    printf("nwords    : %ld\n",ch.h.nwords);
    printf("totnwrds  : %ld\n",ch.h.totnwrds);
    printf("start_seg : %ld\n",ch.h.start_seg);
    printf("stop_seg  : %ld\n",ch.h.stop_seg);
}

/* dump_proc_hdr ************************************
* INPUT:    ph    the current processed data header *
* PURPOSE:                                          *
* Items in the header are printed                   *
****************************************************/
void dump_proc_hdr(ProcHeader *ph)
{
    printf("encode: dump_proc_hdr: Processed Data Header:\n");
    printf("pd_rec       : %ld\n",ph->pd_rec);
    printf("mode         : %ld\n",ph->mode);
    printf("size         : %ld\n",ph->size);
    printf("fh_date      : %ld\n",ph->fh_date);
    printf("fh_time      : %ld\n",ph->fh_time);
    printf("fh_rec_number: %ld\n",ph->fh_rec_number);
    printf("fh_seg       : %ld\n",ph->fh_seg);
    printf("lh_date      : %ld\n",ph->lh_date);
    printf("lh_time      : %ld\n",ph->lh_time);
    printf("lh_rec_number: %ld\n",ph->lh_rec_number);
    printf("lh_seg       : %ld\n",ph->lh_seg);
    printf("n_tx_smp     : %ld\n",ph->n_tx_smp);
    printf("tu_ipp       : %ld\n",ph->tu_ipp);
    printf("tu_ng        : %ld\n",ph->tu_ng);
    printf("tu_si        : %ld\n",ph->tu_si);
    printf("tu_sd        : %ld\n",ph->tu_sd);
    printf("tu_tau       : %ld\n",ph->tu_tau);
    printf("nippstw      : %ld\n",ph->nippstw);
    printf("fftwdth      : %ld\n",ph->fftwdth);
    printf("nbaudp       : %ld\n",ph->nbaudp);
    printf("n_tx_smp     : %ld\n",ph->n_tx_smp);
    printf("n_nx_smp     : %ld\n",ph->n_nx_smp);
    printf("n_rx_smp     : %ld\n",ph->n_rx_smp);
    printf("first_w      : %ld\n",ph->first_w);
    printf("last_w       : %ld\n",ph->last_w);
    printf("nrx          : %ld\n",ph->nrx);
    printf("nave         : %ld\n",ph->nave);
}

/* dump_ao_proc_hdr *********************************
* INPUT:    ph    the current processed data header *
* PURPOSE:                                          *
* Items in the header are printed                   *
****************************************************/
void dump_ao_proc_hdr(AOProcHeader *ph)
{
    printf("encode: dump_ao_proc_hdr: Processed Data Header:\n");
    printf("pd_rec       : %ld\n",ph->pd_rec);
    printf("mode         : %ld\n",ph->mode);
    printf("date         : %ld\n",ph->date);
    printf("start_time   : %ld\n",ph->start_time);
    printf("stop_time    : %ld\n",ph->stop_time);
    printf("ipp          : %ld\n",ph->ipp);
    printf("gatewidth    : %ld\n",ph->gatewidth);
    printf("ngates       : %ld\n",ph->ngates);
    printf("sd           : %ld\n",ph->sd);
    printf("nave         : %ld\n",ph->nave);
    printf("nbytes       : %ld\n",ph->nbytes);
    printf("size         : %ld\n",ph->size);
    printf("totnbyts     : %ld\n",ph->totnbyts);
    printf("noise        : %.2f\n",ph->noise);
    printf("start_zen    : %.2f\n",ph->start_zen);
    printf("end_zen      : %.2f\n",ph->end_zen);
    printf("start_az     : %.2f\n",ph->start_az);
    printf("end_az       : %.2f\n",ph->end_az);
}

#endif /* DEBUG_ENC */

/* fix_procAOHdr ***************************************
* INPUT:  fh    pointer to RawAOHeader from tape data. *
*         ph    pointer to processed data header.      *
*         wrec  number of record to write.             *
* PURPOSE:                                             *
* to configure basic parameters in the output header.  *
*******************************************************/
void fix_procAOHdr(RawAOHeader *ah, AOProcHeader *ph,
               long int wrec, float noise, long int mode)
{
    ph->pd_rec = wrec;
    ph->mode = mode;
    ph->date = ah->h.harris_date_time[0];
    ph->start_time = ah->h.harris_date_time[1];
    ph->stop_time = ah->h.stop_time;
    ph->ipp = ah->h.ipp;
    ph->gatewidth = ah->h.gatewidth;
    ph->ngates = ah->h.n_sig_smp;
    ph->sd = ah->h.sd1;
    ph->nave = ah->h.nippsave;
    ph->nbytes = ah->h.n_sig_smp * 4;
    ph->size = sizeof(AOProcHeader);
    ph->totnbyts = ph->nbytes + ph->size;
    ph->noise = noise;
    ph->start_zen = ah->h.start_zen;
    ph->end_zen = ah->h.end_zen;
    ph->start_az = ah->h.start_az;
    ph->end_az = ah->h.end_az;
    
#ifdef DEBUG_ENC
    dump_ao_proc_hdr(ph);
#endif /* DEBUG_ENC */

}

/* fix_procHdr ******************************************************
* INPUT:  fh    pointer to first RawHeader from tape data averaged. *
*         lh    pointer to last RawHeader from tape data averaged.  *
*         ph    pointer to processed data header.                   *
*         ip    pointer to input parameters structure.              *
*         wrec  number of record to write.                          *
*         rrec  number of full fft records averaged.                *
* PURPOSE:                                                          *
* to configure basic parameters in the output header.               *
********************************************************************/
void fix_procHdr(RawHeader *fh, RawHeader *lh, ProcHeader *ph, InputParms *ip, long int wrec, int rrec)
{
    DateTime dt;
    
    ph->pd_rec = wrec;
    ph->mode = ip->pm;

    dt = decode_harris_time(fh->hdr);
    get_day_in_month(&dt);
    ph->fh_date = decimal_date(&dt);
    ph->fh_time = decimal_time(&dt);
    ph->fh_rec_number = fh->h.mtu_rec;
    ph->fh_seg = fh->h.start_seg;

    dt = decode_harris_time(lh->hdr);
    get_day_in_month(&dt);
    ph->lh_date = decimal_date(&dt);
    ph->lh_time = decimal_time(&dt);
    ph->lh_rec_number = lh->h.mtu_rec;
    ph->lh_seg = lh->h.stop_seg;

    ph->n_tx_smp = fh->h.n_tx_smp;
    ph->tu_ipp = fh->h.tu_ipp;
    ph->tu_ng = fh->h.tu_ng;
    ph->tu_si = fh->h.tu_si;
    ph->tu_sd = fh->h.tu_sd;
    ph->tu_tau = fh->h.tu_tau;
    ph->nippstw = fh->h.nippstw;
    ph->fftwdth = ip->fftwdth;
    ph->nbaudp = fh->h.nbaudp;
    ph->n_tx_smp = fh->h.n_tx_smp;
    ph->inc_tx = ip->inc_tx == 1;
    ph->n_nx_smp = fh->h.n_nx_smp;
    ph->inc_nx = ip->inc_nx == 1;
    ph->n_rx_smp = fh->h.tu_ng 
                 - fh->h.n_tx_smp
                 - fh->h.n_nx_smp
                 - (fh->h.tu_tau/fh->h.tu_si)
                 - ((fh->h.nbaudp) ? fh->h.nbaudp - 1:0);
    get_range_bins(ph,ip);
    ph->nrx = fh->h.nchanls/2;
    ph->nave = rrec;
    ph->size = sizeof(ProcHeader);
    
#ifdef DEBUG_ENC
    dump_proc_hdr(ph);
#endif /* DEBUG_ENC */

}

void get_range_bins(ProcHeader *ph, InputParms *ip)
{
    long int fr,lr;
    
    fr = (ip->first_r / 0.15 - ph->tu_sd) / ph->tu_si;
    lr = (ip->last_r / 0.15 - ph->tu_sd) / ph->tu_si;
    
    if(lr < fr)
    {
        lr = ph->n_rx_smp;
    }
    else if(lr == fr)
    {
        lr++;
    }
    
    if(lr<1) lr = -1;
    if(lr>ph->n_rx_smp) lr = ph->n_rx_smp;

    if(fr < 0) fr = 0;
    if(fr >= ph->n_rx_smp)
    {
        lr = -1;
        fr = ph->n_rx_smp;
    }
    
    ph->first_w = fr;
    ph->last_w = lr;
}
