00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <signal.h>
00025 #include <unistd.h>
00026 #include <sys/time.h>
00027
00028 #include <Alloc.hh>
00029
00030 #include "Direction2.hh"
00031
00032
00033 static bool bDebug;
00034 static bool bDaemon;
00035 clDirection2 *Direction2;
00036
00037
00038 void SigHandler (int iSigNum)
00039 {
00040 switch (iSigNum)
00041 {
00042 case SIGSEGV:
00043 if (bDebug)
00044 {
00045 printf("Oops, received SIGSEGV, crash...\n");
00046 abort();
00047 }
00048 else exit(-1);
00049 break;
00050 }
00051 }
00052
00053
00054 int main (int argc, char *argv[])
00055 {
00056 int iRetVal;
00057
00058 bDebug = false;
00059 bDaemon = false;
00060 signal(SIGPIPE, SIG_IGN);
00061 signal(SIGFPE, SIG_IGN);
00062 signal(SIGSEGV, SigHandler);
00063 if (argc >= 2)
00064 {
00065 if (strcmp(argv[1], "--debug") == 0)
00066 {
00067 bDebug = true;
00068 }
00069 if (strcmp(argv[1], "-D") == 0)
00070 {
00071 bDaemon = true;
00072 }
00073 }
00074 if (bDebug) printf("direction2: Started\n");
00075 Direction2 = new clDirection2(3, 4);
00076 iRetVal = Direction2->Main();
00077 delete Direction2;
00078 if (bDebug) printf("direction2: Exit = %i\n", iRetVal);
00079 return iRetVal;
00080 }
00081
00082
00083 bool clDirection2::GetCfg ()
00084 {
00085 Cfg.SetFileName(SD_CFGFILE);
00086 if (!Cfg.GetStr("LocalSocket", cpStreamSocket)) return false;
00087 Cfg.SetFileName(DIR2_CFGFILE);
00088 if (!Cfg.GetInt("ArrayType", &iArrayType)) return false;
00089 if (!Cfg.GetInt("SensorCount", &lSensorCount)) return false;
00090 if (!Cfg.GetFlt("SensorSpacing", &fSensorSpacing)) return false;
00091 if (!Cfg.GetInt("FilterSize", &lFilterSize))
00092 lFilterSize = DIR2_DEF_FILT_SIZE;
00093 if (!Cfg.GetInt("WindowSize", &lWindowSize))
00094 lWindowSize = DIR2_DEF_FFT_SIZE;
00095 if (!Cfg.GetInt("StartChannel", &lStartChannel))
00096 lStartChannel = 0l;
00097 if (!Cfg.GetInt("FilterType", &iFilterType))
00098 iFilterType = clRecDecimator::FILTER_TYPE_FFT;
00099 return true;
00100 }
00101
00102
00103 bool clDirection2::GetRq ()
00104 {
00105 char cpMsgBuf[GLOBAL_HEADER_LEN];
00106
00107 if (!SOpRequest.ReadSelect(DIR2_REQ_TIMEOUT)) return false;
00108 if (SOpRequest.ReadN(cpMsgBuf, GLOBAL_HEADER_LEN) != GLOBAL_HEADER_LEN)
00109 return false;
00110 Msg.GetRequest(cpMsgBuf, &sReq);
00111 return true;
00112 }
00113
00114
00115 bool clDirection2::ConnectStream ()
00116 {
00117 int iSockH;
00118 stRawDataReq sDataReq;
00119
00120 iSockH = SClient.Connect(cpStreamSocket);
00121 if (iSockH < 0) return false;
00122 SOpData.SetHandle(iSockH);
00123 if (!SOpData.ReadSelect(DIR2_RAW1ST_TIMEOUT)) return false;
00124 if (SOpData.ReadN(&sRawHdr, sizeof(sRawHdr)) < (int) sizeof(sRawHdr))
00125 return false;
00126 sDataReq.iChannel = -1;
00127 if (SOpData.WriteN(&sDataReq, sizeof(sDataReq)) < (int) sizeof(sDataReq))
00128 return false;
00129 return true;
00130 }
00131
00132
00133 bool clDirection2::InitDir ()
00134 {
00135 switch (sReq.iAlgorithm)
00136 {
00137 case MSG_DIR_ALG_SPECT:
00138 if (bDebug)
00139 printf("direction2: Initializing spectrum algorithm\n");
00140 switch (iArrayType)
00141 {
00142 case DIR2_ARRAY_TYPE_DIPOLE:
00143 if (bDebug)
00144 printf("direction2: Dipole array\n");
00145 SDDipole = new clSpectDirDipole(fSensorSpacing,
00146 sReq.fSoundSpeed, sRawHdr.dSampleRate,
00147 lFilterSize, iFilterType, lWindowSize,
00148 sReq.lSectorCount, sReq.fIntegrationTime, bDebug);
00149 break;
00150 case DIR2_ARRAY_TYPE_TRIANGLE:
00151 if (bDebug)
00152 printf("direction2: Triangle array not supported yet\n");
00153 break;
00154 case DIR2_ARRAY_TYPE_LINE:
00155 if (bDebug)
00156 printf("direction2: Line array\n");
00157 SDLine = new clSpectDirLine(lSensorCount, fSensorSpacing,
00158 sReq.fSoundSpeed, sRawHdr.dSampleRate, lFilterSize,
00159 iFilterType, lWindowSize, sReq.lSectorCount,
00160 sReq.fIntegrationTime, bDebug);
00161 break;
00162 case DIR2_ARRAY_TYPE_PLANE:
00163 if (bDebug)
00164 printf("direction2: Planar array not supported yet\n");
00165 break;
00166 case DIR2_ARRAY_TYPE_CYLINDER:
00167 if (bDebug)
00168 printf("direction2: Cylinder array not supported yet\n");
00169 break;
00170 case DIR2_ARRAY_TYPE_SPHERE:
00171 if (bDebug)
00172 printf("direction2: Spherical array not supported yet\n");
00173 break;
00174 default:
00175 if (bDebug)
00176 printf("direction2: Unknown array type\n");
00177 }
00178 if (bDebug)
00179 {
00180 switch (iFilterType)
00181 {
00182 case clRecDecimator::FILTER_TYPE_FFT:
00183 puts("direction2: Using FFT filter");
00184 break;
00185 case clRecDecimator::FILTER_TYPE_FIR:
00186 puts("direction2: Using FIR filter");
00187 break;
00188 case clRecDecimator::FILTER_TYPE_IIR:
00189 puts("direction2: Using IIR filter");
00190 break;
00191 }
00192 }
00193 break;
00194 default:
00195 if (bDebug)
00196 {
00197 printf("direction2: Unknown algorithm requested\n");
00198 return false;
00199 }
00200 }
00201 return true;
00202 }
00203
00204
00205 void clDirection2::ProcessLoop ()
00206 {
00207 int iInSize;
00208 int iResSize;
00209 int iMsgSize;
00210 long lTotalSamples;
00211 char *cpMsgBuf;
00212 GDT *fpProcData;
00213 GDT *fpResData;
00214 stSpectDirRN sRemoveNoise;
00215 clAlloc ProcBuf;
00216 clAlloc ResBuf;
00217 clAlloc MsgBuf;
00218
00219 lTotalSamples = abs(lFilterSize) / 2 * sRawHdr.iChannels;
00220 iInSize = lTotalSamples * sizeof(GDT);
00221 iResSize = sReq.lSectorCount * sizeof(GDT);
00222 iMsgSize = GLOBAL_HEADER_LEN + iResSize;
00223 sRemoveNoise.iType = sReq.iRemoveNoise;
00224 sRemoveNoise.fAlpha = sReq.fAlpha;
00225 sRemoveNoise.lMeanLength = sReq.lMeanLength;
00226 sRemoveNoise.lGapLength = sReq.lGapLength;
00227 ProcBuf.Size(lTotalSamples * sizeof(GDT));
00228 ResBuf.Size(iResSize);
00229 MsgBuf.Size(iMsgSize);
00230 fpProcData = ProcBuf;
00231 fpResData = ResBuf;
00232 cpMsgBuf = MsgBuf;
00233 SOpData.SetRecvBufSize(iInSize * 3);
00234 SOpResult.SetSendBufSize(iMsgSize * 3);
00235 if (bDebug) printf("direction2: Buffer size %i/%i bytes\n",
00236 iInSize * 3, iMsgSize * 3);
00237 if (bDebug) printf("direction2: Entering processing loop\n");
00238 while (bRun)
00239 {
00240 if (SOpData.ReadN(fpProcData, iInSize) != iInSize) return;
00241 gettimeofday(&sResHdr.sTimeStamp, NULL);
00242 sResHdr.fPeakLevel = DSP.PeakLevel(fpProcData, lTotalSamples);
00243 switch (iArrayType)
00244 {
00245 case DIR2_ARRAY_TYPE_DIPOLE:
00246 SDDipole->PutData(fpProcData, lTotalSamples, lStartChannel,
00247 sRawHdr.iChannels);
00248 while (SDDipole->GetResults(fpResData, sReq.fLowFreqLimit,
00249 sReq.iScaling, &sRemoveNoise) && bRun)
00250 {
00251 SDDipole->ResetResults();
00252 sResHdr.fIntegrationTime = SDDipole->GetIntegrationTime();
00253 sResHdr.b3DArray = false;
00254 sResHdr.fHighFreqLimit = 0.0f;
00255 sResHdr.lSectorCount = sReq.lSectorCount;
00256 Msg.SetResult(cpMsgBuf, &sResHdr, fpResData);
00257 if (SOpResult.WriteN(cpMsgBuf, iMsgSize) != iMsgSize)
00258 return;
00259 }
00260 break;
00261 case DIR2_ARRAY_TYPE_TRIANGLE:
00262 break;
00263 case DIR2_ARRAY_TYPE_LINE:
00264 SDLine->PutData(fpProcData, lTotalSamples, lStartChannel,
00265 sRawHdr.iChannels);
00266 while (SDLine->GetResults(fpResData, sReq.fLowFreqLimit,
00267 sReq.iScaling, &sRemoveNoise) && bRun)
00268 {
00269 SDLine->ResetResults();
00270 sResHdr.fIntegrationTime = SDLine->GetIntegrationTime();
00271 sResHdr.b3DArray = false;
00272 sResHdr.fHighFreqLimit = 0.0f;
00273 sResHdr.lSectorCount = sReq.lSectorCount;
00274 Msg.SetResult(cpMsgBuf, &sResHdr, fpResData);
00275 if (SOpResult.WriteN(cpMsgBuf, iMsgSize) != iMsgSize)
00276 return;
00277 }
00278 break;
00279 case DIR2_ARRAY_TYPE_PLANE:
00280 case DIR2_ARRAY_TYPE_CYLINDER:
00281 case DIR2_ARRAY_TYPE_SPHERE:
00282 break;
00283 }
00284 }
00285 }
00286
00287
00288 clDirection2::clDirection2 (int iInHandle, int iOutHandle)
00289 {
00290 bRun = true;
00291 SOpRequest.SetHandle(iInHandle);
00292 SOpResult.SetHandle(iOutHandle);
00293 }
00294
00295
00296 clDirection2::~clDirection2 ()
00297 {
00298 }
00299
00300
00301 int clDirection2::Main ()
00302 {
00303 if (!GetCfg())
00304 {
00305 if (bDebug) printf("direction2: Error reading configuration\n");
00306 return 1;
00307 }
00308 if (!GetRq())
00309 {
00310 if (bDebug) printf("direction2: Unable to receive request message\n");
00311 return 1;
00312 }
00313 if (!ConnectStream())
00314 {
00315 if (bDebug) printf("direction2: Unable to connect to streamdist\n");
00316 return 1;
00317 }
00318 if (!InitDir())
00319 {
00320 if (bDebug)
00321 printf("direction2: Direction finding initialization failed\n");
00322 return 1;
00323 }
00324 ProcessLoop();
00325 return 0;
00326 }
00327