Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

Spectrum.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Spectrum server
00004     Copyright (C) 1999-2002 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 */
00021 
00022 
00023 #include <stdio.h>
00024 #include <signal.h>
00025 #include <unistd.h>
00026 #include <math.h>
00027 #include <float.h>
00028 #include <limits.h>
00029 #include <sys/time.h>
00030 
00031 #include <Alloc.hh>
00032 
00033 #include "Spectrum.hh"
00034 
00035 
00036 static bool bDebug;
00037 static bool bDaemon;
00038 clSpectrum *Spectrum;
00039 
00040 #define SPECT_NWIN 13
00041 static const char *cpaWindowFuncs[] = {
00042     "Rectangle",
00043     "Bartlett",
00044     "Blackman",
00045     "Blackman-Harris",
00046     "Cosine tapered",
00047     "Exponential",
00048     "Flat-top",
00049     "Generic cosine",
00050     "Hamming",
00051     "Hanning",
00052     "Kaiser",
00053     "Kaiser-Bessel",
00054     "Tukey" };
00055 
00056 
00057 void SigHandler (int iSigNum)
00058 {
00059     switch (iSigNum)
00060     {
00061         case SIGSEGV:
00062             if (bDebug) 
00063             {
00064                 printf("Oops, received SIGSEGV, crash...\n");
00065                 abort();
00066             }
00067             else exit(-1);
00068             break;
00069     }
00070 }
00071 
00072 
00073 int main (int argc, char *argv[])
00074 {
00075     int iRetVal;
00076 
00077     bDebug = false;
00078     bDaemon = false;
00079     signal(SIGPIPE, SIG_IGN);
00080     signal(SIGFPE, SIG_IGN);
00081     signal(SIGSEGV, SigHandler);
00082     if (argc >= 2)
00083     {
00084         if (strcmp(argv[1], "--debug") == 0)
00085         {
00086             bDebug = true;
00087         }
00088         if (strcmp(argv[1], "-D") == 0)
00089         {
00090             bDaemon = true;
00091         }
00092     }
00093     if (bDebug) printf("spectrum: Started\n");
00094     Spectrum = new clSpectrum(3, 4);
00095     iRetVal = Spectrum->Main();
00096     delete Spectrum;
00097     if (bDebug) printf("spectrum: Exit = %i\n", iRetVal);
00098     return iRetVal;
00099 }
00100 
00101 
00102 bool clSpectrum::GetCfg ()
00103 {
00104     Cfg.SetFileName(SD_CFGFILE);
00105     if (!Cfg.GetStr("LocalSocket", cpStreamSocket)) return false;
00106     Cfg.SetFileName(SPECT_CFGFILE);
00107     if (!Cfg.GetInt("FilterSize", &lFilterSize))
00108         lFilterSize = SPECT_DEF_FILTSIZE;
00109     if (!Cfg.GetInt("FilterType", &iFilterType))
00110         iFilterType = clRecDecimator::FILTER_TYPE_FFT;
00111     return true;
00112 }
00113 
00114 
00115 bool clSpectrum::GetRq ()
00116 {
00117     char cpMsgBuf[GLOBAL_HEADER_LEN];
00118 
00119     if (!SOpRequest.ReadSelect(SPECT_REQ_TIMEOUT)) return false;
00120     if (SOpRequest.ReadN(cpMsgBuf, GLOBAL_HEADER_LEN) != GLOBAL_HEADER_LEN)
00121         return false;
00122     Msg.GetRequest(cpMsgBuf, &sReq);
00123     return true;
00124 }
00125 
00126 
00127 bool clSpectrum::ConnectStream ()
00128 {
00129     int iSockH;
00130     stRawDataReq sStreamReq;
00131 
00132     iSockH = SClient.Connect(cpStreamSocket);
00133     if (iSockH < 0) return false;
00134     SOpData.SetHandle(iSockH);
00135     if (!SOpData.ReadSelect(SPECT_RAW1ST_TIMEOUT)) return false;
00136     if (SOpData.ReadN(&sRawHdr, sizeof(sRawHdr)) < (int) sizeof(sRawHdr))
00137         return false;
00138     sStreamReq.iChannel = sReq.iChannel;
00139     if (SOpData.WriteN(&sStreamReq, sizeof(sStreamReq)) < 
00140         (int) sizeof(sStreamReq)) return false;
00141     return true;
00142 }
00143 
00144 
00145 bool clSpectrum::Init ()
00146 {
00147     GDT *fpNullPtr = NULL;
00148 
00149     lInDataCount = abs(lFilterSize) / 2;
00150     iInDataSize = lInDataCount * sizeof(GDT);
00151     InData.Size(iInDataSize);
00152     if (bDebug)
00153     {
00154         printf("spectrum: Filter size %li\n", lFilterSize);
00155         switch (iFilterType)
00156         {
00157             case clRecDecimator::FILTER_TYPE_FFT:
00158                 puts("spectrum: Using FFT decimation filter");
00159                 break;
00160             case clRecDecimator::FILTER_TYPE_FIR:
00161                 puts("spectrum: Using FIR decimation filter");
00162                 break;
00163             case clRecDecimator::FILTER_TYPE_IIR:
00164                 puts("spectrum: Using IIR decimation filter");
00165                 break;
00166         }
00167     }
00168     CreateFilter();
00169     switch (sReq.iType)
00170     {
00171         case MSG_SPECT_TYPE_FFT:
00172             if (bDebug) printf("spectrum: STFT\n");
00173             lSpectPoints = sReq.lLength;
00174             lSpectLen = lSpectPoints / 2 + 1;
00175             FFT.FFTInitialize(lSpectPoints, true);
00176             break;
00177         case MSG_SPECT_TYPE_MRFFT:
00178             printf("spectrum: Multiresolution-STFT not implemented yet\n");
00179             break;
00180         case MSG_SPECT_TYPE_GABOR:
00181             printf("spectrum: Gabor transform not implemented yet\n");
00182             break;
00183         case MSG_SPECT_TYPE_WVD:
00184             if (bDebug) printf("spectrum: Wigner-Ville Distribution\n");
00185             lSpectPoints = sReq.lLength;
00186             lSpectLen = lSpectPoints / 2 + 1;
00187             FFT.FFTInitialize(lSpectPoints, true);
00188             WVDDec.Initialize(2, -128, (GDT *) NULL, (GDT) 0.25, 
00189                 clRecDecimator::FILTER_TYPE_FIR);
00190             sReq.iOverlap = 50;
00191             break;
00192         case MSG_SPECT_TYPE_HANKEL:
00193             if (bDebug) printf("spectrum: Hankel transform\n");
00194             lSpectPoints = sReq.lLength / 2 + 1;
00195             lSpectLen = lSpectPoints;
00196             Hankel.Initialize(sReq.lLength, fpNullPtr);
00197             break;
00198         case MSG_SPECT_TYPE_AUTOCORR:
00199             if (bDebug) printf("spectrum: Autocorrelation\n");
00200             lSpectPoints = sReq.lLength;
00201             lSpectLen = lSpectPoints / 2;
00202             FFT.FFTInitialize(lSpectPoints, true);
00203             break;
00204         case MSG_SPECT_TYPE_CEPSTRUM:
00205             if (bDebug) printf("spectrum: Cepstrum\n");
00206             lSpectPoints = sReq.lLength;
00207             lSpectLen = lSpectPoints / 2;
00208             FFT.FFTInitialize(lSpectPoints, true);
00209             break;
00210         default:
00211             printf("spectrum: unknown transform requested\n");
00212     }
00213     lResSize = GLOBAL_HEADER_LEN + lSpectLen * sizeof(GDT);
00214     SpectIn.Size(lSpectPoints * sizeof(GDT));
00215     SpectOut.Size(lSpectLen * sizeof(GDT));
00216     ResMsg.Size(lResSize);
00217     lOldDataCount = (long) (lSpectPoints * (sReq.iOverlap / 100.0) + 0.5);
00218     lNewDataCount = lSpectPoints - lOldDataCount;
00219     if (lNewDataCount < 1)
00220     {
00221         lNewDataCount = 1;
00222         lOldDataCount = lSpectPoints - lNewDataCount;
00223     }
00224     if (bDebug)
00225     {
00226         printf("spectrum: %li samples old, %li samples new data\n", 
00227             lOldDataCount, lNewDataCount);
00228     }
00229     Window.Size(lSpectPoints * sizeof(GDT));
00230     switch (sReq.iWindow)
00231     {
00232         case MSG_SPECT_WND_RECT:
00233             DSP.Set((GDT *) Window, (GDT) 1, lSpectPoints);
00234             break;
00235         case MSG_SPECT_WND_BARTLETT:
00236             DSP.WinBartlett((GDT *) Window, lSpectPoints);
00237             break;
00238         case MSG_SPECT_WND_BLACKMAN:
00239             DSP.WinExactBlackman((GDT *) Window, lSpectPoints);
00240             break;
00241         case MSG_SPECT_WND_BM_HAR:
00242             DSP.WinBlackmanHarris((GDT *) Window, lSpectPoints);
00243             break;
00244         case MSG_SPECT_WND_COS_TAPER:
00245             DSP.WinCosTapered((GDT *) Window, lSpectPoints);
00246             break;
00247         case MSG_SPECT_WND_EXP:
00248             DSP.WinExp((GDT *) Window, (GDT) sReq.fWinParam, lSpectPoints);
00249             break;
00250         case MSG_SPECT_WND_FLATTOP:
00251             DSP.WinFlatTop((GDT *) Window, lSpectPoints);
00252             break;
00253         case MSG_SPECT_WND_GEN_COS:
00254             DSP.Set((GDT *) Window, (GDT) 1, lSpectPoints);
00255             break;
00256         case MSG_SPECT_WND_HAMMING:
00257             DSP.WinHamming((GDT *) Window, lSpectPoints);
00258             break;
00259         case MSG_SPECT_WND_HANNING:
00260             DSP.WinHanning((GDT *) Window, lSpectPoints);
00261             break;
00262         case MSG_SPECT_WND_KAISER:
00263             DSP.WinKaiser((GDT *) Window, (GDT) sReq.fWinParam, lSpectPoints);
00264             break;
00265         case MSG_SPECT_WND_KAI_BES:
00266             DSP.WinKaiserBessel((GDT *) Window, (GDT) sReq.fWinParam,
00267                 lSpectPoints);
00268             break;
00269         case MSG_SPECT_WND_TUKEY:
00270             DSP.WinTukey((GDT *) Window, lSpectPoints);
00271             break;
00272         default:
00273             printf("spectrum: unknown window function requested\n");
00274     }
00275     if (sReq.iWindow < SPECT_NWIN && bDebug)
00276         printf("spectrum: %s window\n", cpaWindowFuncs[sReq.iWindow]);
00277     return true;
00278 }
00279 
00280 
00281 void clSpectrum::CreateFilter ()
00282 {
00283     int iBandNo;
00284     long lTwosPower;
00285     float fNyquist;
00286     float fBandWidth;
00287     GDT fBandCenter;
00288     GDT *fpNullPtr = NULL;
00289 
00290     fNyquist = (float) sRawHdr.dSampleRate / 2.0f;
00291     if (sReq.iLowFreq == sReq.iHighFreq)
00292     {
00293         sReq.iLowFreq = 0;
00294         sReq.iHighFreq = (int) fNyquist;
00295     }
00296     fBandWidth = sReq.iHighFreq - sReq.iLowFreq;
00297     lTwosPower = (long) (log(fNyquist / fBandWidth) / log(2.0) + 0.5);
00298     lDecimation = (long) pow(2.0, lTwosPower);
00299     fBandWidth = fNyquist / lDecimation;
00300     iBandNo = (int) (sReq.iHighFreq / fBandWidth + 0.5f);
00301     if ((fBandWidth * iBandNo) < (sReq.iLowFreq + fBandWidth / 2.0f))
00302         iBandNo++;
00303     fHighCorner = fBandWidth * iBandNo;
00304     fLowCorner = fHighCorner - fBandWidth;
00305     fBandCenter = (fLowCorner + fBandWidth / 2.0f) / fNyquist;
00306     bReverseOrder = ((iBandNo - 1) % 2 == 0) ? false : true;
00307     if (bDebug) 
00308     {
00309         printf("spectrum: lower corner %.2f higher corner %.2f\n",
00310             fLowCorner, fHighCorner);
00311         printf("spectrum: decimation %li, %s order\n",
00312             lDecimation,
00313             (bReverseOrder) ? "reverse" : "normal");
00314         printf("spectrum: normalized center %f\n", fBandCenter);
00315     }
00316     Decimator.Initialize(lDecimation, lFilterSize, fpNullPtr, fBandCenter, 
00317         iFilterType);
00318 }
00319 
00320 
00321 void clSpectrum::ProcessLoop ()
00322 {
00323     long lSpectCntr;
00324     long lSpectMax;
00325     GDT fScale;
00326     GDT fLogScale;
00327     GDT fPeakLevel;
00328     GDT *fpWindow = Window;
00329     GDT *fpSpectIn = SpectIn;
00330     GDT *fpSpectOut = SpectOut;
00331     GDT *fpOldData;
00332     GDT *fpNewData;
00333     GDT *fpRevBuf;
00334     GDT *fpTemp;
00335     GCDT *spCplxSpect;
00336     clDSPAlloc OldData;
00337     clDSPAlloc NewData;
00338     clDSPAlloc RevBuf;
00339     clDSPAlloc Temp;
00340     clDSPAlloc CplxSpect;
00341 
00342     fpOldData = (GDT *) OldData.Size(lOldDataCount * sizeof(GDT));
00343     DSP.Zero(fpOldData, lOldDataCount);
00344     fpNewData = (GDT *) NewData.Size(lNewDataCount * sizeof(GDT));
00345     fpRevBuf = (GDT *) RevBuf.Size(lSpectLen * sizeof(GDT));
00346     fpTemp = (GDT *) Temp.Size(lSpectPoints * sizeof(GDT));
00347     DSP.Zero(fpTemp, lSpectPoints);
00348     spCplxSpect = (GCDT *) CplxSpect.Size(lSpectPoints * sizeof(GCDT));
00349     DSP.Zero(spCplxSpect, lSpectPoints);
00350     fLogScale = 1.0f / sReq.fDynRange;
00351     while (bRun)
00352     {
00353         if (!GetData())
00354         {
00355             Stop();
00356             break;
00357         }
00358         while (PullData(fpNewData, lNewDataCount) && bRun)
00359         {
00360             DSP.Copy(fpSpectIn, fpOldData, lOldDataCount);
00361             DSP.Copy(&fpSpectIn[lOldDataCount], fpNewData, lNewDataCount);
00362             DSP.Copy(fpOldData, &fpSpectIn[lNewDataCount], lOldDataCount);
00363             fPeakLevel = DSP.PeakLevel(fpSpectIn, lSpectPoints);
00364             switch (sReq.iType)
00365             {
00366                 case MSG_SPECT_TYPE_FFT:
00367                     DSP.Mul(fpSpectIn, fpWindow, lSpectPoints);
00368                     FFT.FFTi(spCplxSpect, fpSpectIn);
00369                     DSP.Magnitude(fpSpectOut, spCplxSpect, lSpectLen);
00370                     break;
00371                 case MSG_SPECT_TYPE_MRFFT:
00372                     break;
00373                 case MSG_SPECT_TYPE_GABOR:
00374                     break;
00375                 case MSG_SPECT_TYPE_WVD:
00376                     /*WVDDec.Put(fpSpectIn, lSpectPoints);
00377                     WVDDec.Get(fpTemp, lSpectPoints / 2);
00378                     DSP.Zero(&fpTemp[lSpectPoints / 2], lSpectPoints / 2);
00379                     DSP.Reverse(fpWindow, fpTemp, lSpectPoints);
00380                     DSP.Mul(fpSpectIn, fpWindow, lSpectPoints);*/
00381                     FFT.FFTi(spCplxSpect, fpSpectIn);
00382                     DSP.MulC(spCplxSpect, spCplxSpect, 
00383                         lSpectPoints / 2 + 1);
00384                     DSP.Magnitude(fpSpectOut, spCplxSpect, lSpectLen);
00385                     DSP.Mul(fpSpectOut, (GDT) 2, lSpectLen);
00386                     break;
00387                 case MSG_SPECT_TYPE_HANKEL:
00388                     DSP.Mul(fpSpectIn, fpWindow, lSpectPoints);
00389                     Hankel.Process0(fpSpectOut, fpSpectIn);  // 0th order
00390                     //Hankel.Process1(fpSpectOut, fpSpectIn);  // 1st order
00391                     break;
00392                 case MSG_SPECT_TYPE_AUTOCORR:
00393                     DSP.Mul(fpSpectIn, fpWindow, lSpectPoints);
00394                     FFT.FFTi(spCplxSpect, fpSpectIn);
00395                     DSP.MulC(spCplxSpect, spCplxSpect, 
00396                         lSpectPoints / 2 + 1);
00397                     FFT.IFFTo(fpTemp, spCplxSpect);
00398                     DSP.Copy(fpSpectOut, fpTemp, lSpectLen);
00399                     break;
00400                 case MSG_SPECT_TYPE_CEPSTRUM:
00401                     DSP.Mul(fpSpectIn, fpWindow, lSpectPoints);
00402                     FFT.FFTi(spCplxSpect, fpSpectIn);
00403                     lSpectMax = lSpectPoints / 2 + 1;
00404                     for (lSpectCntr = 0; 
00405                         lSpectCntr < lSpectMax;
00406                         lSpectCntr++)
00407                     {
00408                         #ifndef HAVE_GLIBC
00409                         spCplxSpect[lSpectCntr].R = log10(sqrt(
00410                             spCplxSpect[lSpectCntr].R * 
00411                             spCplxSpect[lSpectCntr].R +
00412                             spCplxSpect[lSpectCntr].I *
00413                             spCplxSpect[lSpectCntr].I));
00414                         #else
00415                         spCplxSpect[lSpectCntr].R = log10(hypot(
00416                             spCplxSpect[lSpectCntr].R, 
00417                             spCplxSpect[lSpectCntr].I));
00418                         #endif
00419                         spCplxSpect[lSpectCntr].I = 0;
00420                     }
00421                     FFT.IFFTo(fpTemp, spCplxSpect);
00422                     fpTemp[0] = 0;
00423                     fpTemp[1] = 0;
00424                     fScale = (GDT) 2 / (GDT) lSpectPoints;
00425                     DSP.Mul(fpSpectOut, fpTemp, fScale, lSpectLen);
00426                     break;
00427             }
00428             if (!sReq.bLinear)
00429             {
00430                 if (!sReq.bNormalize)
00431                 {
00432                     for (lSpectCntr = 0; 
00433                         lSpectCntr < lSpectLen; 
00434                         lSpectCntr++)
00435                     {
00436                         fpSpectOut[lSpectCntr] = (GDT)
00437                             (20.0 * log10(fpSpectOut[lSpectCntr]) +
00438                             sReq.fDynRange) * fLogScale;
00439                     }
00440                 }
00441                 else
00442                 {
00443                     for (lSpectCntr = 0;
00444                         lSpectCntr < lSpectLen;
00445                         lSpectCntr++)
00446                     {
00447                         fpSpectOut[lSpectCntr] = (GDT)
00448                             (20.0 * log10(fpSpectOut[lSpectCntr]));
00449                     }
00450                 }
00451             }
00452             if (bReverseOrder)
00453             {
00454                 DSP.Copy(fpRevBuf, fpSpectOut, lSpectLen);
00455                 DSP.Reverse(fpSpectOut, fpRevBuf, lSpectLen);
00456             }
00457             if (sReq.bNormalize)
00458             {
00459                 DSP.Scale01(fpSpectOut, lSpectLen);
00460             }
00461             if (sReq.fSlope != 0.0f)
00462             {
00463                 double dSlopeMul = pow(10.0, sReq.fSlope / 20.0);
00464                 double dNyquist = (double) sRawHdr.dSampleRate / 
00465                     (double) lDecimation / 2.0;
00466                 double dFreqRes = dNyquist / (double) lSpectLen;
00467                 for (long lFreqBinCntr = 1; 
00468                     lFreqBinCntr < lSpectLen; 
00469                     lFreqBinCntr++)
00470                 {
00471                     double dBinFreq = dFreqRes * lFreqBinCntr;
00472                     fpSpectOut[lFreqBinCntr] *= (GDT)
00473                         (pow(dSlopeMul, log(dBinFreq) / log(2.0)));
00474                 }
00475             }
00476             if (sReq.fGain != 0.0f)
00477             {
00478                 GDT fGainMul = (GDT) pow(10.0, sReq.fGain / 20.0);
00479                 DSP.Mul(fpSpectOut, fGainMul, lSpectLen);
00480             }
00481             switch (sReq.iRemoveNoise)
00482             {
00483                 case MSG_SPECT_BNER_NONE:
00484                     break;
00485                 case MSG_SPECT_BNER_TPSW:
00486                     RN.TPSW(fpSpectOut, sReq.fAlpha, sReq.lMeanLength,
00487                         sReq.lGapLength, lSpectLen);
00488                     break;
00489                 case MSG_SPECT_BNER_OTA:
00490                     RN.OTA(fpSpectOut, sReq.fAlpha, sReq.lMeanLength,
00491                         lSpectLen);
00492                     break;
00493                 case MSG_SPECT_BNER_DIFF:
00494                     RN.Diff(fpSpectOut, sReq.fAlpha, lSpectLen);
00495                     break;
00496                 case MSG_SPECT_BNER_IDIFF:
00497                     RN.InvDiff(fpSpectOut, sReq.fAlpha, lSpectLen);
00498                     break;
00499                 default:
00500                     // None
00501                     break;
00502             }
00503             gettimeofday(&sResHdr.sTimeStamp, NULL);
00504             sResHdr.iChannel = sReq.iChannel;
00505             sResHdr.lLength = lSpectLen;
00506             sResHdr.iLowFreq = (int) (fLowCorner + 0.5f);
00507             sResHdr.iHighFreq = (int) (fHighCorner + 0.5f);
00508             sResHdr.iSampleRate = (int) (sRawHdr.dSampleRate + 0.5);
00509             sResHdr.bLinear = sReq.bLinear;
00510             sResHdr.fPeakLevel = fPeakLevel;
00511             if (lDecimation > 0)
00512             {
00513                 sResHdr.fLineTime = 
00514                     (float) lNewDataCount / 
00515                     ((float) sRawHdr.dSampleRate / (float) lDecimation);
00516             }
00517             else
00518             {
00519                 sResHdr.fLineTime = (float) lNewDataCount /
00520                     (float) sRawHdr.dSampleRate;
00521             }
00522             Msg.SetResult(ResMsg, &sResHdr, fpSpectOut);
00523             if (SOpResult.WriteN(ResMsg, lResSize) < lResSize)
00524             {
00525                 if (bDebug)
00526                     printf("spectrum: clSockOp::WriteN() error, client disconnected?\n");
00527                 Stop();
00528                 return;
00529             }
00530         }
00531     }
00532 }
00533 
00534 
00535 bool clSpectrum::GetData ()
00536 {
00537     GDT *fpInData = InData;
00538 
00539     if (SOpData.ReadN(InData, iInDataSize) < iInDataSize)
00540     {
00541         if (bDebug)
00542             printf("spectrum: clSockOp::ReadN() error, server disconnected?\n");
00543         return false;
00544     }
00545     if (lDecimation < 2)
00546         ReBuffer.Put(fpInData, lInDataCount);
00547     else
00548         Decimator.Put(fpInData, lInDataCount);
00549     return true;
00550 }
00551 
00552 
00553 bool clSpectrum::PullData (GDT *fpDestBuf, long lDestCount)
00554 {
00555     if (lDecimation < 2)
00556         return ReBuffer.Get(fpDestBuf, lDestCount);
00557     else
00558         return Decimator.Get(fpDestBuf, lDestCount);
00559 }
00560 
00561 
00562 clSpectrum::clSpectrum (int iInHandle, int iOutHandle)
00563 {
00564     bRun = true;
00565     SOpRequest.SetHandle(iInHandle);
00566     SOpResult.SetHandle(iOutHandle);
00567 }
00568 
00569 
00570 clSpectrum::~clSpectrum ()
00571 {
00572 }
00573 
00574 
00575 int clSpectrum::Main ()
00576 {
00577     if (!GetCfg())
00578     {
00579         if (bDebug) printf("spectrum: Error reading configuration\n");
00580         return 1;
00581     }
00582     if (!GetRq())
00583     {
00584         if (bDebug) printf("spectrum: Unable to receive request message\n");
00585         return 1;
00586     }
00587     if (!ConnectStream())
00588     {
00589         if (bDebug) printf("spectrum: Unable to connect to streamdist\n");
00590         return 1;
00591     }
00592     if (!Init())
00593     {
00594         if (bDebug)
00595             printf("spectrum: Direction finding initialization failed\n");
00596         return 1;
00597     }
00598     ProcessLoop();
00599     return 0;
00600 }

Generated on Sun Oct 26 19:11:23 2003 for HASAS by doxygen 1.3.3