Logo Search packages:      
Sourcecode: qsstv version File versions  Download package

fax.cpp

/***************************************************************************
                          fax.cpp  -  QSSTV
                             -------------------
    begin                : Fri Jun 8 2001
    copyright            : (C) 2001 by Johan Maes
    email                : on1mh@pandora.be
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include "fax.h"
#include "sstvrx.h"
#include "qsstvglobal.h"
#include "imageframe.h"
#include <qcombobox.h>
#include "sstvparam.h"
#include "ledbar.h"

//#define DEBUGFAXRX

const char *lpmString[NUMLPM]=
{
      "60",
      "90",
      "100",
      "120",
      "240",
      "480"
};

const char *iocString[NUMIOC]=
{
      "288",
      "576"
};

void sstvRX::slotFAXDecode()
{
      int repos;
      freqResult=FDETECTOK;
      do
            {
                  switch(faxState)
                        {
                              case FAXIDLE:
                                    dsp->setFilter(F600);  // medium bandwidth
                                    dsp->setPostFilter(NARROW);
                                    initAnalyseSync();
                                    leds->setYellowLed(TRUE);
                                    gotoFaxState(FAXAPTSTARTB);
                              //    gotoFaxState(FAXFORCE);
                                    faxRunning=TRUE;
                              break;
                              case FAXFORCE:
                                    lineCounter=0;
                                    imageSampleCounter=0;
                                    dsp->setPostFilter(selectedPostFilter);
                                    dsp->setFilter(selectedFilter);
                                    gotoFaxState(FAXIMAGE);       
                              break;      
                              case FAXAPTSTARTB:
                                    if((freqResult=waitForTonePulse(1650,350,.01))!=FDETECTWAIT)
                                          {
                                                if (freqResult==FDETECTOK)
                                          {
                                                syncArray[AUTODETLEN-1].syncDuration=pulseDuration;
                                                gotoFaxState(FAXAPTSTARTW);
                                          }
                                                else
                                                      {                 
                                                gotoFaxState(FAXIDLE); //force arm frequency
                                                      }
                                          }
                              break;
                              case FAXAPTSTARTW:
                                    if((freqResult=waitForTonePulse(2150,350,.01))!=FDETECTWAIT)
                                          {
                                                if (freqResult==FDETECTOK)
                                          {
                                                syncArray[AUTODETLEN-1].syncDurationW=pulseDuration;
                                                
                                                if(faxAnalyseSync())
                                                      {
                                                            gotoFaxState(FAXSTART);
                                                      }
                                                else
                                                      {
                                                            gotoFaxState(FAXAPTSTARTB);
                                                      }
                                                      
                                          }
                                                else
                                                      {
                                                gotoFaxState(FAXIDLE); //force arm frequency
                                                      }
                                    }
                              break;
                              case FAXSTART:
                                    //start of image detected
                                    if(!faxInversePolarity)
                                          {
                                                repos=(int)(fd1*fRXsamplingrate);
                                          }
                                    else
                                          {
                                                repos=(int)((fd1+fd2)*fRXsamplingrate);
                                          }
                                    lineCounter=0;
                                    reposition(repos);
                                    imageSampleCounter=0;
                                    detectError=0;
                                    gotoFaxState(FAXTOP1);
                                                      
                              break;
                              case FAXTOP1:
                                    // lpm defined - watch topline
                                    if((freqResult=measureFrequency(fd1,fd1/20.))!=FDETECTWAIT)
                                          {
                                                if (testAverageFrequency(ff1,200))
                                                      {
#ifdef DEBUGFAXRX
                                                            lineCounter++;
                                                            debug("fax linecounter %d",lineCounter);
#endif                                                      
                                                            gotoFaxState(FAXTOP2);
                                                      }
                                                else
                                                      {
                                                            if(detectError++>2)
                                                                  {
                                                                        reposition((int)(fd1*fRXsamplingrate));
                                                                        gotoFaxState(FAXTOP4);
                                                                  }
                                                            else
                                                                  {
#ifdef DEBUGFAXRX
                                                                        debug("faxrx:detectError increment");
#endif                                                                        
                                                                        gotoFaxState(FAXTOP2);
                                                                  }
                                                      }
                                          }
                              break;

                              case FAXTOP2:
                                    if((freqResult=measureFrequency(fd2,fd2/20.))!=FDETECTWAIT)
                                          {
                                                if (testAverageFrequency(ff2,200))
                                                      {
                                                            if (detectError>0)
                                                                  {
                                                                        detectError--;
#ifdef DEBUGFAXRX
                                                                        debug("faxrx:detectError decrement");
#endif                                                                                                            
                                                                  }
                                                            gotoFaxState(FAXTOP3);
                                                      }
                                                else
                                                      {
                                                            if(detectError++>2)
                                                                  {
                                                                        reposition((int)((fd1+fd2)*fRXsamplingrate));
                                                                        gotoFaxState(FAXTOP4);
                                                                  }
                                                            else
                                                                  {
#ifdef DEBUGFAXRX
                                                                        debug("faxrx:detectError increment");
#endif                                                                        
                                                                        gotoFaxState(FAXTOP3);
                                                                  }
                                                      }
                                          }
                              break;
                              case FAXTOP3:
                                    if((freqResult=measureFrequency(fd1,fd1/20.))!=FDETECTWAIT)
                                          {
                                                if (testAverageFrequency(ff1,200))
                                                      {
                                                            gotoFaxState(FAXTOP1);
                                                      }
                                                else
                                                      {
                                                            if(detectError++>2)
                                                                  {
                                                                        gotoFaxState(FAXTOP4);
                                                                  }
                                                            else
                                                                  {
#ifdef DEBUGFAXRX
                                                                        debug("faxrx:detectError increment");
#endif                                                                        
                                                                        gotoFaxState(FAXTOP1);
                                                                  }
                                                      
                                                      }
                                          }
                                    
                              break;
                              case FAXTOP4:
                                    lineCounter=0;
                                    imageSampleCounter=0;
                                    dsp->setPostFilter(selectedPostFilter);
                                    dsp->setFilter(selectedFilter);
                                    leds->setGreenLed(TRUE);
                                    gotoFaxState(FAXIMAGE);
                              break;      
                              
                              case FAXIMAGE:
                                    {
                                          freqResult=getFaxPixels();
                                    }
                              break;
                              case FAXAPTSTOP:
                              break;
                              case FAXEND:
                                    //    slotStop();
                                          endOfImage();
                                          gotoFaxState(FAXIDLE);
                              break;
                        }
            }
      while(freqResult!=FDETECTWAIT);
      timer->start(10,TRUE);
}

void sstvRX::buildLUT()
{
      int i;
      int t=colorComboBox->currentItem();
  int mask=1;
  mask=mask<<(t+1);
      int dv=mask-1;
      int step=255/dv;
      int tresh=255/(mask)+1;
      for (i=0;i<256;i++)
            {
                  lut[i]=(i/tresh)*step;
            }
}

efreqReturn sstvRX::getFaxPixels()
{
      uint colr;
      while (getData())
            {
            double et=(double)imageSampleCounter/(double)fRXsamplingrate;
            if(et>(lineTime*(double)(lineCounter+1)))
                  {
#ifdef DEBUGFAXRX
                        debug("fax: next line");
#endif                        
                        canvas->showLine(pixelsPerLine,lineCounter);                      
                        // new line
                        lineCounter++;
                        linePixelCounter=0;
                        videoBuffer0=canvas->getLineAddress(lineCounter);
                        if(videoBuffer0==NULL)
                              {
                                    gotoFaxState(FAXEND);
                                    return FDETECTOK;
                              }
                  }
            if((double)pixelCounter*time1PerPixel<et)
                  {
                        //put pixel
                        sampleSum+=sample;
                        pcounter++;
                        sample=sampleSum/pcounter;
                        sample=(sample<1500 ? 1500 : sample);
            sample=(sample>=2300 ? 2300-2300/10000 : sample);
            colr=(uint)(((sample-1500)*255)/(2300-1500));
            colr=lut[colr];
                        videoBuffer0[linePixelCounter]=qRgb(colr,colr,colr);
                        pixelCounter++;
                        linePixelCounter++;
                        pcounter=0; sampleSum=0;
                  }     
            else
                  {
                        sampleSum+=sample;
                        pcounter++;
                  }
      }
      return FDETECTWAIT;
}     

void sstvRX::gotoFaxState(efaxState s)
{
      armFrequencyDetection();
      stateSampleCounter=0;
      if(faxState!=s)
            {
                  faxState=s;
                  state=(eTxRxState)faxState; // for debug purpose
#ifdef DEBUGFAXRX
                  debug("fax: state=%s",faxStateString[s]);
#endif
            }     
}

bool sstvRX::faxAnalyseSync()
{     
      float t=0;
      float lpm;
      float tw=0;
      float tb=0;
      int i;
      if(++syncDetectCounter< AUTODETLEN)
            {
                  shiftSyncArray();
                  return FALSE;
            }
      //compute lpm
      for (i=0;i<AUTODETLEN;i++)
            {
                  tb+=syncArray[i].syncDuration;
                  tw+=syncArray[i].syncDurationW;
            }
      tb/=AUTODETLEN;
      tw/=AUTODETLEN;
      t=tb+tw;
      if(t>1.01) // slower than 60 lpm
            {
                  shiftSyncArray();
                  return FALSE;
            }
      lpm=60./t;
            
      if(!faxInversePolarity)
            {
                  for (i=0;i<AUTODETLEN;i++)
                        {
                              if(syncArray[i].syncDuration<(t*0.9))
                                    {
                                          shiftSyncArray();
                                          return FALSE;
                                    }
                              else if (syncArray[i].syncDurationW>(t*0.08))
                                    {
                                          shiftSyncArray();
                                          return FALSE;
                                    }
                        }
                  ff1=2300;
                  ff2=1500;
                  fd1=tw/2;
                  fd2=tb;
            }
      else
            {
                  for (i=0;i<AUTODETLEN;i++)
                        {
                              if(syncArray[i].syncDuration>(t*0.08))
                                    {
                                          shiftSyncArray();
                                          return FALSE;
                                    }
                              else if (syncArray[i].syncDurationW<(t*0.9))
                                    {
                                          shiftSyncArray();
                                          return FALSE;
                                    }
                        }
                  ff1=1500;
                  ff2=2300;
                  fd1=tb/2;
                  fd2=tw;
            }
      lineTime=60./(((int)(lpm*1.1/60))*60);
      time1PerPixel=lineTime/pixelsPerLine;
      return TRUE;
}

Generated by  Doxygen 1.6.0   Back to index