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 "Direction3.hh"
00031
00032
00033 static bool bDebug;
00034 static bool bDaemon;
00035 clDirection3 *Direction3;
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("direction3: Started\n");
00075 Direction3 = new clDirection3(3, 4);
00076 iRetVal = Direction3->Main();
00077 delete Direction3;
00078 if (bDebug) printf("direction3: Exit = %i\n", iRetVal);
00079 return iRetVal;
00080 }
00081
00082
00083 bool clDirection3::GetCfg ()
00084 {
00085 Cfg.SetFileName(SD_CFGFILE);
00086 if (!Cfg.GetStr("LocalSocket", cpStreamSocket)) return false;
00087 Cfg.SetFileName(DIR3_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 = DIR3_DEF_FILT_SIZE;
00093
00094
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 clDirection3::GetRq ()
00104 {
00105 char cpMsgBuf[GLOBAL_HEADER_LEN];
00106
00107 if (!SOpRequest.ReadSelect(DIR3_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 clDirection3::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(DIR3_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 clDirection3::InitDir ()
00134 {
00135 if (bDebug) printf("direction3: Initializing spectrum algorithm\n");
00136 switch (iArrayType)
00137 {
00138 case DIR3_ARRAY_TYPE_DIPOLE:
00139 if (bDebug)
00140 printf("direction3: Dipole array\n");
00141 SDDipole = new clSpectDirDipole2(fSensorSpacing, sReq.fSoundSpeed,
00142 sRawHdr.dSampleRate, lFilterSize, iFilterType,
00143 sReq.lWindowSize, sReq.fIntegrationTime, bDebug);
00144 break;
00145 case DIR3_ARRAY_TYPE_TRIANGLE:
00146 if (bDebug)
00147 printf("direction3: Triangular array not supported yet\n");
00148 break;
00149 case DIR3_ARRAY_TYPE_LINE:
00150 if (bDebug)
00151 printf("direction3: Line array\n");
00152 SDLine = new clSpectDirLine2(lSensorCount, fSensorSpacing,
00153 sReq.fSoundSpeed, sRawHdr.dSampleRate, lFilterSize, iFilterType,
00154 sReq.lWindowSize, sReq.fIntegrationTime, bDebug);
00155 break;
00156 case DIR3_ARRAY_TYPE_PLANE:
00157 if (bDebug)
00158 printf("direction3: Planar array not supported yet\n");
00159 break;
00160 case DIR3_ARRAY_TYPE_CYLINDER:
00161 if (bDebug)
00162 printf("direction3: Cylindral array not supported yet\n");
00163 break;
00164 case DIR3_ARRAY_TYPE_SPHERE:
00165 if (bDebug)
00166 printf("direction3: Spherical array not supported yet\n");
00167 break;
00168 default:
00169 if (bDebug)
00170 printf("direction3: Unknown array type\n");
00171 }
00172 if (bDebug)
00173 {
00174 switch (iFilterType)
00175 {
00176 case clRecDecimator::FILTER_TYPE_FFT:
00177 puts("direction3: Using FFT filter");
00178 break;
00179 case clRecDecimator::FILTER_TYPE_FIR:
00180 puts("direction3: Using FIR filter");
00181 break;
00182 case clRecDecimator::FILTER_TYPE_IIR:
00183 puts("direction3: Using IIR filter");
00184 break;
00185 }
00186 }
00187 return true;
00188 }
00189
00190
00191 void clDirection3::ProcessLoop ()
00192 {
00193 int iInSize;
00194 int iResSize = 0;
00195 int iMsgSize;
00196 long lTotalSamples;
00197 char *cpMsgBuf;
00198 GDT *fpProcData;
00199 stSpectDir2RN sRemoveNoise;
00200 clAlloc ProcBuf;
00201 clAlloc MsgBuf;
00202
00203 lTotalSamples = abs(lFilterSize) / 2 * sRawHdr.iChannels;
00204 iInSize = lTotalSamples * sizeof(GDT);
00205 switch (iArrayType)
00206 {
00207 case DIR3_ARRAY_TYPE_DIPOLE:
00208 iResSize = SDDipole->GetResultCount() * sizeof(GDT);
00209 break;
00210 case DIR3_ARRAY_TYPE_TRIANGLE:
00211 break;
00212 case DIR3_ARRAY_TYPE_LINE:
00213 iResSize = SDLine->GetResultCount() * sizeof(GDT);
00214 break;
00215 case DIR3_ARRAY_TYPE_PLANE:
00216 case DIR3_ARRAY_TYPE_CYLINDER:
00217 case DIR3_ARRAY_TYPE_SPHERE:
00218 break;
00219 }
00220 iMsgSize = GLOBAL_HEADER_LEN + iResSize * 2;
00221 sRemoveNoise.iType = sReq.iRemoveNoise;
00222 sRemoveNoise.fAlpha = sReq.fAlpha;
00223 sRemoveNoise.lMeanLength = sReq.lMeanLength;
00224 sRemoveNoise.lGapLength = sReq.lGapLength;
00225 fpProcData = (GDT *) ProcBuf.Size(lTotalSamples * sizeof(GDT));
00226 cpMsgBuf = (char *) MsgBuf.Size(iMsgSize);
00227 SOpData.SetRecvBufSize(iInSize * 3);
00228 SOpResult.SetSendBufSize(iMsgSize * 3);
00229 if (bDebug) printf("direction3: Buffer size %i/%i bytes\n",
00230 iInSize * 3, iMsgSize * 3);
00231 if (bDebug) printf("direction3: Entering processing loop\n");
00232 while (bRun)
00233 {
00234 if (SOpData.ReadN(fpProcData, iInSize) != iInSize) return;
00235 gettimeofday(&sResHdr.sTimeStamp, NULL);
00236 sResHdr.fPeakLevel = DSP.PeakLevel(fpProcData, lTotalSamples);
00237 switch (iArrayType)
00238 {
00239 case DIR3_ARRAY_TYPE_DIPOLE:
00240 SDDipole->PutData(fpProcData, lTotalSamples, lStartChannel,
00241 sRawHdr.iChannels);
00242 while (SDDipole->GetResults(NULL, NULL, sReq.fLowFreqLimit,
00243 sReq.iScaling, &sRemoveNoise) && bRun)
00244 {
00245 sResHdr.lMinBin = SDDipole->GetMinBin();
00246 sResHdr.lMaxBin = SDDipole->GetMaxBin();
00247 sResHdr.fFreqResolution = SDDipole->GetFreqResolution();
00248 sResHdr.lResultCount = SDDipole->GetResultCount();
00249 sResHdr.fIntegrationTime = SDDipole->GetIntegrationTime();
00250 Msg.SetResult(cpMsgBuf, &sResHdr, SDDipole->GetLevels(),
00251 SDDipole->GetDirections());
00252 if (SOpResult.WriteN(cpMsgBuf, iMsgSize) != iMsgSize)
00253 return;
00254 }
00255 break;
00256 case DIR3_ARRAY_TYPE_TRIANGLE:
00257 break;
00258 case DIR3_ARRAY_TYPE_LINE:
00259 SDLine->PutData(fpProcData, lTotalSamples, lStartChannel,
00260 sRawHdr.iChannels);
00261 while (SDLine->GetResults(NULL, NULL, sReq.fLowFreqLimit,
00262 sReq.iScaling, &sRemoveNoise) && bRun)
00263 {
00264 sResHdr.lMinBin = SDLine->GetMinBin();
00265 sResHdr.lMaxBin = SDLine->GetMaxBin();
00266 sResHdr.fFreqResolution = SDLine->GetFreqResolution();
00267 sResHdr.lResultCount = SDLine->GetResultCount();
00268 sResHdr.fIntegrationTime = SDLine->GetIntegrationTime();
00269 Msg.SetResult(cpMsgBuf, &sResHdr, SDLine->GetLevels(),
00270 SDLine->GetDirections());
00271 if (SOpResult.WriteN(cpMsgBuf, iMsgSize) != iMsgSize)
00272 return;
00273 }
00274 break;
00275 case DIR3_ARRAY_TYPE_PLANE:
00276 case DIR3_ARRAY_TYPE_CYLINDER:
00277 case DIR3_ARRAY_TYPE_SPHERE:
00278 break;
00279 }
00280 }
00281 }
00282
00283
00284 clDirection3::clDirection3 (int iInHandle, int iOutHandle)
00285 {
00286 bRun = true;
00287 SOpRequest.SetHandle(iInHandle);
00288 SOpResult.SetHandle(iOutHandle);
00289 }
00290
00291
00292 clDirection3::~clDirection3 ()
00293 {
00294 }
00295
00296
00297 int clDirection3::Main ()
00298 {
00299 if (!GetCfg())
00300 {
00301 if (bDebug) printf("direction3: Error reading configuration\n");
00302 return 1;
00303 }
00304 if (!GetRq())
00305 {
00306 if (bDebug) printf("direction3: Unable to receive request message\n");
00307 return 1;
00308 }
00309 if (!ConnectStream())
00310 {
00311 if (bDebug) printf("direction3: Unable to connect to streamdist\n");
00312 return 1;
00313 }
00314 if (!InitDir())
00315 {
00316 if (bDebug)
00317 printf("direction3: Direction finding initialization failed\n");
00318 return 1;
00319 }
00320 ProcessLoop();
00321 return 0;
00322 }
00323