SegTools.cpp

Go to the documentation of this file.
00001 /*
00002 This file is part of LIA_RAL which is a set of software based on ALIZE
00003 toolkit for speaker recognition. ALIZE toolkit is required to use LIA_RAL.
00004 
00005 LIA_RAL project is a development project was initiated by the computer
00006 science laboratory of Avignon / France (Laboratoire Informatique d'Avignon -
00007 LIA) [http://lia.univ-avignon.fr <http://lia.univ-avignon.fr/>]. Then it
00008 was supported by two national projects of the French Research Ministry:
00009         - TECHNOLANGUE program [http://www.technolangue.net]
00010         - MISTRAL program [http://mistral.univ-avignon.fr]
00011 
00012 LIA_RAL is free software: you can redistribute it and/or modify
00013 it under the terms of the GNU Lesser General Public License as
00014 published by the Free Software Foundation, either version 3 of
00015 the License, or any later version.
00016 
00017 LIA_RAL is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00020 GNU Lesser General Public License for more details.
00021 
00022 You should have received a copy of the GNU Lesser General Public
00023 License along with LIA_RAL.
00024 If not, see [http://www.gnu.org/licenses/].
00025 
00026 The LIA team as well as the LIA_RAL project team wants to highlight the
00027 limits of voice authentication in a forensic context.
00028 The "Person Authentification by Voice: A Need of Caution" paper
00029 proposes a good overview of this point (cf. "Person
00030 Authentification by Voice: A Need of Caution", Bonastre J.F.,
00031 Bimbot F., Boe L.J., Campbell J.P., Douglas D.A., Magrin-
00032 chagnolleau I., Eurospeech 2003, Genova].
00033 The conclusion of the paper of the paper is proposed bellow:
00034 [Currently, it is not possible to completely determine whether the
00035 similarity between two recordings is due to the speaker or to other
00036 factors, especially when: (a) the speaker does not cooperate, (b) there
00037 is no control over recording equipment, (c) recording conditions are not
00038 known, (d) one does not know whether the voice was disguised and, to a
00039 lesser extent, (e) the linguistic content of the message is not
00040 controlled. Caution and judgment must be exercised when applying speaker
00041 recognition techniques, whether human or automatic, to account for these
00042 uncontrolled factors. Under more constrained or calibrated situations,
00043 or as an aid for investigative purposes, judicious application of these
00044 techniques may be suitable, provided they are not considered as infallible.
00045 At the present time, there is no scientific process that enables one to
00046 uniquely characterize a persones voice or to identify with absolute
00047 certainty an individual from his or her voice.]
00048 
00049 Copyright (C) 2004-2010
00050 Laboratoire d'informatique d'Avignon [http://lia.univ-avignon.fr]
00051 LIA_RAL admin [alize@univ-avignon.fr]
00052 Jean-Francois Bonastre [jean-francois.bonastre@univ-avignon.fr]
00053 */
00054 
00055 #if !defined(ALIZE_SegTools_cpp)
00056 #define ALIZE_SegTools_cpp
00057 
00058 #include "SegTools.h"
00059 #include<iostream>
00060 #include<fstream>
00061 #include<cstdio>
00062 #include<cassert>
00063 #include<cmath>
00064 
00065 using namespace alize;
00066 using namespace std;
00067 
00068 
00069 // Display the cluster
00070 void showCluster(SegCluster& cluster){
00071   cluster.rewind();
00072   Seg *seg;                                                                              
00073   while((seg=cluster.getSeg())!=NULL)
00074     cout<<"Seg File["<<seg->sourceName()<<"]["<<seg->begin()<<","<<seg->length()<<"]"<<endl;
00075 }
00076 // return the number of frame in the cluster
00077 unsigned long totalFrame(SegCluster& cluster)
00078 {
00079   unsigned long time=0;
00080   cluster.rewind();
00081   Seg *seg;                                                                              
00082   while((seg=cluster.getSeg())!=NULL)
00083     time+=seg->length();
00084   return time;
00085 }
00086 
00087 // return the number of frame in the server of segment
00088 unsigned long totalFrame(SegServer& s)
00089 {
00090 unsigned long time=0;
00091 for(unsigned long icluster=0; icluster<s.getClusterCount(); icluster++){
00092   SegCluster& cluster=s.getCluster(icluster);
00093   time+=totalFrame(cluster);
00094 }
00095 return time;
00096 }
00097 
00098 // return the last frame of a segment
00099 unsigned long endSeg(Seg *seg)
00100 {
00101   return seg->begin()+seg->length()-1;
00102 }
00103 //
00104 //------------------------------------------------------------------------------------------------------------------------------
00105 // Output a cluster in a  label file
00106 void outputLabelFile(SegCluster &selectedSeg,String FileName,Config &config)
00107 {
00108   ofstream outFile(FileName.c_str(),ios::out | ios::trunc);                      // Initialise the output file
00109   if (!outFile.good()) 
00110           throw Exception("Can't create label file",__FILE__,__LINE__);
00111   real_t frameLength=config.getParam("frameLength").toDouble();
00112   selectedSeg.rewind();                                                      // Reset the cluster of selected segments
00113   Seg * seg;
00114   while((seg=selectedSeg.getSeg())!=NULL){                                       // For all the segments
00115     outFile <<frameIdxToTime(seg->begin(),frameLength)<<" "<<frameIdxToTime(seg->begin()+seg->length()-1,frameLength)<<" "<<seg->string()<<endl;
00116     if (debug)cout <<frameIdxToTime(seg->begin(),frameLength)<<" "<<frameIdxToTime(seg->begin()+seg->length()-1,frameLength)<<" "<<seg->string()<<endl;
00117   }
00118 }
00119 
00120 
00121 
00122 //******* Create a default cluster with the label labelToAnalyse, including all the input file frames
00123 //** From N Scheffer & JFB
00124 void createDefSeg (SegServer & segServer, FeatureServer & fs, Config & config)
00125 {
00126   unsigned long segLength=fs.getFeatureCount();
00127   unsigned long begin=0;   
00128   // labelCode for selected frame
00129   unsigned long codeSelectedFrame=1;
00130   segServer.createSeg(begin,segLength,codeSelectedFrame);
00131 }
00132 
00133 // From a time to a frame index, taking into account possible bugs on boundaries
00134 // JFB
00135 unsigned long timeToFrameIdx(real_t time,real_t frameLength)
00136 {
00137   double tmpd,res;
00138   res=modf(time/frameLength,&tmpd);
00139   if (res>0.99999)
00140     return (unsigned long)tmpd+1;
00141   else return (unsigned long)tmpd;
00142 }
00143 real_t frameIdxToTime(unsigned long idx,real_t frameLength)
00144 {
00145   unsigned long t= (unsigned long)(idx*1000*frameLength);
00146   real_t res=(real_t)t/1000.0;
00147   return res;
00148 }
00149 //**************************************
00150 // Verify the labels - if a segment is finishing after the last frame, trunc it
00151 void verifyClusterFile(SegServer& segmentsServer,FeatureServer& fs,Config& config)
00152 {
00153   for (unsigned long clusterIdx=0;clusterIdx<segmentsServer.getClusterCount();clusterIdx++){  // For each cluster
00154     if (debug) cout << "(SegTools) verifying label for ["<<clusterIdx<<"]"<<endl; 
00155     SegCluster& cluster=segmentsServer.getCluster(clusterIdx);                                // Get the cluster
00156     if (debug) cout << "(SegTools) verifying label for ["<<cluster.string()<<"]"<<endl; 
00157     Seg* seg;
00158     cluster.rewind();  
00159     while((seg=cluster.getSeg())!=NULL)                                                       // For each segment
00160       if ((seg->begin()+seg->length())>fs.getFeatureCountOfASource(seg->sourceName())){ // The end of the segment is after the last frame
00161                 unsigned long newLength=fs.getFeatureCountOfASource(seg->sourceName())-seg->begin();
00162                 if (debug|| verbose)cout<<"Warning File["<< seg->sourceName()<<"], Truncate Segment begin:"<<seg->begin()<<" length:"<<seg->length()<<
00163                       " file size:"<<fs.getFeatureCountOfASource(seg->sourceName())<<" new length:"<<newLength<<endl;
00164                 seg->setLength(newLength);                    
00165       }
00166   } //End cluster loop
00167 }
00168 
00169 //***************************************
00170 //* Reading a label file and adding the segments in the server. Each label/name is in
00171 //* a separate cluster
00172 //* Dan Istrate, JFB,  november 2004
00173 //***************************************
00174 
00175 
00176 // Add a segment to the server, in an existing cluster - same name or in a new cluster - new name
00177 void addSegment(const Config & config, 
00178                 const String &file,const String &name, unsigned long segFrameBegin, unsigned long segFrameLength,
00179                 LabelServer& labelServer,SegServer& segmentsServer)
00180 {
00181   unsigned long codeLabel,labelCount;     
00182   if (debug ||(verboseLevel > 2)) cout << "add a segment, name["<<name<<"] begin frame["<<segFrameBegin<<"] length in frame["<<segFrameLength<<"]"<<endl;
00183   labelCount=labelServer.size();
00184   Label labelTemp(name);
00185   codeLabel=labelServer.addLabel(labelTemp);
00186   if(codeLabel==labelCount){ // Create a new cluster Cluster
00187       SegCluster& cluster=segmentsServer.createCluster(codeLabel,name," ");
00188       cluster.add(segmentsServer.createSeg(segFrameBegin,segFrameLength,labelServer.addLabel(labelTemp),name,file));
00189     }
00190   else{// the cluster exists, it is first extract and the segment is added
00191     SegCluster& cluster=segmentsServer.getCluster(codeLabel);
00192     cluster.add(segmentsServer.createSeg(segFrameBegin,segFrameLength,labelServer.addLabel(labelTemp),name,file));
00193   }
00194 }
00195 
00196 // Load the segments of a file in one cluster
00197 void  loadLabelFile(SegCluster &cluster,String fileName,String path, String extension,Config &config)
00198 {
00199   if (verboseLevel>1) cout << ">> Proceeding label file reading in one cluster for ["<<fileName<<"] <<"<<endl;
00200   double frameLength = config.getParam("frameLength").toDouble();         // length in s of a frame
00201   String fileLabel=path+fileName+extension;         // build the complete filename
00202   XList labelSet(fileLabel,config);
00203   XLine *segmentp;
00204   while ((segmentp=labelSet.getLine()) != NULL){                             // Get the lines/segment one by one
00205     const String& beginString=segmentp->getElement(0);                     // Get the begin time
00206     const String& endString=segmentp->getElement(1);                       // Get the end time
00207     const String& name=segmentp->getElement(2);                            // Get the label
00208     unsigned long segFrameBegin=timeToFrameIdx(beginString.toDouble(),frameLength); // begin in frame
00209     unsigned long segFrameLength=timeToFrameIdx(endString.toDouble(),frameLength)-segFrameBegin+1;
00210     cluster.add(cluster.getServer().createSeg(segFrameBegin,segFrameLength,0,name,fileName));
00211   }  
00212 }
00213 
00214 
00215 // the main function for loading the labels - do the job for a given file
00216 void loadClusterFile(String &fileName,SegServer& segmentsServer,LabelServer&
00217 labelServer,Config& config)
00218 {
00219    String labelPath="./";
00220   if (config.existsParam("labelFilesPath")) labelPath= config.getParam("labelFilesPath");                     // The path of the lable files
00221   String labelFileExtension=".lbl";     
00222   if(config.existsParam("labelFilesExtension"))  // The extension of the lable files
00223     labelFileExtension=config.getParam("labelFilesExtension");   
00224   double frameLength = config.getParam("frameLength").toDouble();         // length in s of a frame
00225   String inputLabelFormat="LIARAL";
00226   if (config.existsParam("inputLabelFormat"))                            // the label file format is decided by the user (not LIARAL std format)
00227     inputLabelFormat=config.getParam("inputLabelFormat");             
00228   if(debug) cout<<"(SegTools) The label format is "<<inputLabelFormat<<endl;
00229   if (verboseLevel>1)  cout << "(SegTools) >> Proceeding label file reading for ["<<fileName<<"] <<"<<endl;
00230   //  double tmpt;      
00231   bool addDefault=false;
00232   String defaultLabel;
00233   if  (config.existsParam("addDefaultLabel")){
00234     addDefault=true;
00235     defaultLabel=config.getParam("defaultLabel");
00236   }
00237   String fileLabel;
00238   fileLabel=labelPath+fileName+labelFileExtension;         // build the complete filename - to be included in ALIZE default - TODO
00239   
00240 
00241   XList labelSet;
00242   bool noLabelFile=false;
00243   try{
00244     labelSet.load(fileLabel,config);                 // if the file exists, read it in a Xlist - one segment by line
00245   }
00246   catch(FileNotFoundException& e){
00247     noLabelFile=true;
00248   }
00249   if ((noLabelFile)&& (addDefault==false)){
00250     cout<<"(SegTools)  Error: For "<< fileName << "["<<fileLabel<<"]"<<endl;
00251     throw Exception("There is no correspondent label file",__FILE__,__LINE__);          
00252   }
00253   if (noLabelFile){ // no label file and the default option is on - creating a default segment
00254     FeatureServer fsFake(config,fileName);
00255     unsigned long segFrameLength=fsFake.getFeatureCount();
00256     unsigned long segFrameBegin=0;   
00257     if (verbose) cout << "(SegTools) Default label file for ["<<fileName<<"], nb features["<<segFrameLength<<"]"<<endl;
00258     addSegment(config,fileName,defaultLabel,segFrameBegin,segFrameLength,labelServer,segmentsServer); 
00259   } 
00260   else{ // a Label file is existing
00261     bool visit=false;
00262     XLine *segmentp;
00263     while ((segmentp=labelSet.getLine()) != NULL){                             // Get the lines/segment one by one
00264       visit=true;
00265       if (inputLabelFormat=="LIARAL"){                                         // A line is composed by [begin_time end_time name]
00266         const String& beginString=segmentp->getElement(0);                     // Get the Client ID (id)
00267         const String& endString=segmentp->getElement(1);                       // Get the Client ID (id)
00268         const String& name=segmentp->getElement(2);                            // Get the Client ID (id)
00269         unsigned long segFrameBegin=timeToFrameIdx(beginString.toDouble(),frameLength); // begin in frame
00270         unsigned long segFrameLength=timeToFrameIdx(endString.toDouble(),frameLength)-segFrameBegin+1;
00271         addSegment(config,fileName,name,segFrameBegin,segFrameLength,labelServer,segmentsServer); 
00272       }
00273       else if (inputLabelFormat=="mdtm"){// mdtm format. An example[20030418_0700_0800_FRANCEINTER_DGA 1 0.000 5.928 speaker NA male Jean-Jacques_Bernard]
00274         const String& name=segmentp->getElement(7);  
00275         const String& beginString=segmentp->getElement(2); 
00276         const String& lengthString=segmentp->getElement(3);
00277         unsigned long segFrameBegin=timeToFrameIdx(beginString.toDouble(),frameLength);                               // begin in frame
00278         unsigned long segFrameLength=timeToFrameIdx(lengthString.toDouble(),frameLength);                             // length in frame
00279         addSegment(config,fileName,name,segFrameBegin,segFrameLength,labelServer,segmentsServer);       
00280       }
00281       else cout << "label type["<<inputLabelFormat<<"] unknown" <<endl;
00282     }
00283     if (!visit) cout <<"WARNING, label file ["<<fileName <<"] empty"<<endl;
00284   }
00285 }
00286 
00287 
00288 // for a list of file
00289 void initializeClusters(const XLine& listFiles,SegServer& segmentsServer,LabelServer& labelServer,Config& config)
00290 {
00291   listFiles.rewind();
00292   String *filep;
00293   while ((filep=listFiles.getElement()) != NULL){   // for each label file
00294     String file=(*filep);                           // get the filename 
00295     loadClusterFile(file,segmentsServer,labelServer,config);
00296   }//while seg 
00297 }
00298 // For a list of input files, stored into a XList
00299 void initializeClusters(const XList& listXFiles,SegServer& segmentsServer,LabelServer& labelServer,Config& config)
00300 {
00301   XLine &listFiles=listXFiles.getAllElements(); 
00302   initializeClusters(listFiles,segmentsServer,labelServer,config);
00303 }
00304 // For a filename parameter, which could be a feature file or a feature file list with an .lst extention
00305 void initializeClusters(String &file,SegServer& segmentsServer,LabelServer& labelServer,Config&
00306 config)
00307 {
00308    if (file.endsWith(".lst")){                                                                        // If the file parameter is the name of a XList file
00309     XList listXFiles(file,config);                                 // (a text file with a list of filenames)
00310     initializeClusters(listXFiles,segmentsServer,labelServer,config);
00311   }
00312   else                                                                                               // It is a single filename/basename for feature and label files
00313     loadClusterFile(file,segmentsServer,labelServer,config); 
00314 }
00315 
00316 
00317 /************
00318 * Functions mainly used by the LIA_SpkSeg package
00319 ************/
00320 
00321 
00322 // A function for create and initialize a Viterbi accumulator
00323 ViterbiAccum& createAndInitializeViterbiAccum(StatServer &ss, hmm &cHmm){
00324   ViterbiAccum& va=ss.createViterbiAccum(); // CREATE 
00325   for(unsigned int i=0;i<cHmm.getNbState();i++) // Add the states
00326     va.addState(cHmm.getDensity(i));
00327   for(unsigned int i=0;i<cHmm.getNbState();i++) // Set the transitions
00328     for(unsigned int j=0;j<cHmm.getNbState();j++){
00329       va.logTransition(i,j)=log(cHmm.getTransition(i,j));
00330     }
00331   return va;
00332 }
00333 
00334 // accumulateStatViterbi() is used for computing the viterbi path
00335 // TAKE CARE: THE accumulator should be reseted before the call
00336 void   accumulateStatViterbi(FeatureServer &fs,ViterbiAccum &va,unsigned long beginIdx,unsigned long length,Config &config)
00337 {
00338   double fudge=config.getParam("fudge").toDouble();
00339   unsigned long viterbiBufferLength=config.getParam("viterbiBufferLength").toLong();
00340   for(unsigned long ifeature=beginIdx;ifeature<=beginIdx+length-viterbiBufferLength;ifeature+=viterbiBufferLength)
00341     va.computeAndAccumulate(fs, ifeature, viterbiBufferLength,fudge);
00342   if (length%viterbiBufferLength!=0)
00343     va.computeAndAccumulate(fs,beginIdx+(length/viterbiBufferLength*viterbiBufferLength), length%viterbiBufferLength,fudge); // End of the segment
00344 }
00345 // On a segment
00346 void accumulateStatViterbi(FeatureServer &fs,ViterbiAccum &va,Seg *seg,Config &config)
00347 {  
00348   unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());              // Find the index of the first frame of the file in the buffer
00349   accumulateStatViterbi(fs,va,begin,seg->length(),config);
00350 }
00351 
00352 // On a segment with PreSeg
00353 // Dan Istrate juillet 2005
00354 void accumulateStatViterbi(FeatureServer &fs,ViterbiAccum &va,Seg *seg,Config &config,SegServer& TransitSegServer,DoubleVector&
00355 TransitionsFort,DoubleVector& TransitionsFaible,unsigned long NbState)
00356 {  
00357   unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());              // Find the index of the first frame of the file in the buffer
00358   double fudge=config.getParam("fudge").toDouble();
00359   unsigned long viterbiBufferLength=config.getParam("viterbiBufferLength").toLong();
00360   bool drapeauFort=false; 
00361   SegCluster& clusterFort=TransitSegServer.getCluster(0);
00362   unsigned long lc;
00363  
00364   for(unsigned long ifeature=begin;ifeature<=begin+seg->length()-viterbiBufferLength;ifeature+=viterbiBufferLength)
00365   {
00366     if(clusterFort.getFeatureLabelCode(ifeature+(viterbiBufferLength/2),lc)&& !drapeauFort) 
00367     {//passage en transitions fortes
00368         for(unsigned long i=0;i<NbState;i++) // Set the transitions
00369                     for(unsigned long j=0;j<NbState;j++){
00370                       va.logTransition(i,j)=log(TransitionsFort[i+j*NbState]);
00371                 }       
00372         drapeauFort=true;
00373     }
00374     if(!clusterFort.getFeatureLabelCode(ifeature+(viterbiBufferLength/2),lc)&& drapeauFort) 
00375     {//passage en transitions faible
00376         for(unsigned long i=0;i<NbState;i++) // Set the transitions
00377                     for(unsigned long j=0;j<NbState;j++){
00378                       va.logTransition(i,j)=log(TransitionsFaible[i+j*NbState]);
00379                 }       
00380         drapeauFort=false;
00381     }
00382     va.computeAndAccumulate(fs, ifeature, viterbiBufferLength,fudge);  
00383   }
00384   if (seg->length()%viterbiBufferLength!=0)
00385     va.computeAndAccumulate(fs,begin+(seg->length()/viterbiBufferLength*viterbiBufferLength), seg->length()%viterbiBufferLength,fudge); // End of the segment
00386 }
00387     
00388 // Remove all the segments of a cluster
00389 void removeAllSeg(SegServer &segServer,SegCluster &cluster)
00390 {
00391   while(cluster.getCount()!=0){
00392     segServer.remove(cluster.get(0));           
00393   }
00394 }
00395 
00396 
00397 // initialize an existing segmentation by deleting all the segments and creating an empty cluster by state/speaker
00398 void initializeCluster(SegServer &currentSeg,hmm& cHmm,LabelServer &labelServer){
00399 
00400 unsigned long cl;
00401 Label l;
00402 currentSeg.removeAllClusters(); // suppress the clusters (one by speaker/state)
00403 currentSeg.removeAllSegs();     // suppress the segments 
00404 for(unsigned long i=0;i<cHmm.getNbState();i++){
00405         l.setString(cHmm.getStateName(i));
00406         cl=labelServer.addLabel(l);     
00407         currentSeg.createCluster(cl,cHmm.getStateName(i)," ");  
00408 }
00409 }
00410 
00411 
00412 // removePartOfSeg() removes a part of a segment from a cluster
00413 bool removePartOfSeg(SegCluster &clusterSeg,SegServer& segServer,LabelServer &labelServer,
00414                      String segSourceName,unsigned long segStart,unsigned long segLength){
00415 
00416 clusterSeg.rewind();
00417   
00418 for(unsigned long i=0;i<segServer.getSegCount();i++){
00419         Seg& seg=segServer.getSeg(i);
00420 
00421         if((seg.sourceName()==segSourceName)&&(segStart>=seg.begin())&&(segStart+segLength<=seg.begin()+seg.length())){ // Find !!
00422                 unsigned long start=seg.begin();
00423                 unsigned long longueur=seg.length();
00424                 if(start==segStart){                                          // Same begin                      
00425                         if((longueur-segLength)!=0){
00426                                 seg.setBegin(start+segLength);               
00427                                 seg.setLength(longueur-segLength);
00428                         }else{
00429                                 segServer.remove(seg);
00430                                 return true;
00431                         }//else
00432                 }
00433                 else 
00434                         if((segStart+segLength)==(start+longueur)){              // Same end
00435                                 seg.setLength(longueur-segLength);
00436                         }
00437                         else{
00438                                 seg.setLength(segStart-start+1);
00439                                 clusterSeg.add(segServer.createSeg((int)segStart+segLength-1,start+longueur-segStart-segLength+1,
00440                                            labelServer.addLabel(seg.string()),seg.string(),seg.sourceName()));
00441                         }
00442               return true;
00443         }//if
00444     
00445 }//for
00446 return false;
00447 }
00448 
00449 
00450 void displayAllClusters(Config& config, SegServer& seg)
00451 {
00452 
00453 if(seg.getClusterCount()!=0)
00454         for(unsigned long icluster=0;icluster<seg.getClusterCount();icluster++)
00455         {
00456                 SegCluster& clusterT=seg.getCluster(icluster);
00457                 displayOneCluster(config, clusterT);
00458         }
00459 else cout<<"No cluster in Segments Server"<<endl;
00460 }//display
00461 
00462 
00463 void displayOneCluster(Config& config, SegCluster &clusterT)
00464 {
00465   Seg* segment;
00466   double frameLength=config.getParam("frameLength").toDouble();
00467   clusterT.rewind();
00468   if(clusterT.string() != ""){
00469           cout << "Name: " << clusterT.string() << endl;
00470   }
00471   else{
00472           cout << "Name: empty" << endl;  
00473   }
00474   if(clusterT.getCount()!=0)
00475         while(((segment=clusterT.getSeg())!=NULL))
00476         {
00477                 cout << segment->begin()*frameLength << " " << (segment->begin()+segment->length()-1)*frameLength << " " << segment->string() << endl;
00478         }
00479   else cout<<"No segments in cluster "<<clusterT.string()<<endl;
00480 }
00481 
00482 
00483 void displayAllSegments(Config& config, SegServer& seg)
00484 {
00485 double frameLength=config.getParam("frameLength").toDouble();
00486 unsigned long frameCnt=0;
00487 unsigned long iSeg=0;
00488 
00489 if(seg.getSegCount()==0){
00490         cout<<"No segments in Segments Server"<<endl;
00491         return;
00492 }
00493 
00494 // Display of current segmentation in color graphics
00495 unsigned long fileSize = config.getParam("fileSize").toLong();
00496 
00497 while(iSeg < seg.getSegCount()){
00498         Seg& segment=seg.getSeg(iSeg);
00499         unsigned long b=segment.begin();
00500         
00501         // gap between two segments
00502         while((frameCnt < fileSize) && (frameCnt < b)){
00503                 cout << "\033[1m\033[24m\033[0mX";
00504                 frameCnt += 30;
00505         }
00506         while((frameCnt < fileSize) &&(frameCnt < (b+segment.length()-1))){
00507                 String lab = segment.string();
00508                 String s = lab[lab.length()-1];
00509                 try{
00510                         unsigned long c=33+s.toLong();
00511                         cout << "\033[1m\033[24m\033[" << c << "m" << s;
00512                         frameCnt += 30;         
00513                 }
00514                 catch(Exception& e){
00515                         cout << "\033[1m\033[24m\033[0m" << s;
00516                         frameCnt += 30;         
00517                 }
00518         }
00519         iSeg++;
00520 }
00521 while(frameCnt < fileSize){
00522         cout << "\033[1m\033[24m\033[0mX";
00523         frameCnt += 30;
00524 }
00525 
00526 cout << "\033[0m\n\n" << endl << endl;
00527 
00528 // Display of current segmentation in text      
00529 if(verboseLevel == 2){
00530         for(unsigned long iseg=0;iseg<seg.getSegCount();iseg++){
00531                 Seg& segment=seg.getSeg(iseg);
00532                 cout << segment.begin()*frameLength << " " << (segment.begin()+segment.length()-1)*frameLength << " " << segment.string() << endl;
00533         }
00534 }                       
00535 
00536 // if desired, display of reference segmentation
00537 if(config.existsParam("refSegDisplay")){
00538         cout << config.getParam("refSegDisplay") << endl << endl;
00539 }       
00540 }//display
00541 
00542 
00543 void displayAllSegmentsFromRef(Config& config, String &fileInit, unsigned long fileSize)
00544 {
00545 double frameLength=config.getParam("frameLength").toDouble();
00546 unsigned long frameCnt=0;
00547 unsigned long iSeg=0;
00548 String refSegDisplay = "";
00549 
00550 SegServer refSegServer;
00551 LabelServer refLabel;
00552 
00553 // Reference file reading
00554 if(verbose) cout << ">> Reference Segmentation for comparison purpose <<" << endl;
00555 String fileRefPath=config.getParam("fileRefPath");
00556 String lblPath=config.getParam("labelFilesPath");
00557 config.setParam("labelFilesPath",fileRefPath);
00558 initializeClusters(fileInit,refSegServer,refLabel,config);                   // Reading the segmentation files for each feature input file
00559 config.setParam("labelFilesPath",lblPath);
00560 
00561 if(refSegServer.getSegCount()==0){
00562         cout<<"No segments in Segments Server"<<endl;
00563         return;
00564 }
00565 
00566 
00567 while(iSeg < refSegServer.getSegCount()){
00568         Seg& segment=refSegServer.getSeg(iSeg);
00569         unsigned long b=segment.begin();
00570         
00571         // gap between two segments
00572         while((frameCnt < fileSize) && (frameCnt < b)){
00573                 refSegDisplay += "\033[1m\033[24m\033[0mX";
00574                 frameCnt += 30;
00575         }
00576         while((frameCnt < fileSize) &&(frameCnt < (b+segment.length()-1))){
00577                 unsigned long s = segment.labelCode();
00578                 unsigned long c=33+s;
00579                 refSegDisplay += "\033[1m\033[24m\033["+ refSegDisplay.valueOf(c)+"m"+refSegDisplay.valueOf(s);
00580                 frameCnt += 30;         
00581         }
00582         iSeg++;
00583 }
00584 while(frameCnt < fileSize){
00585         refSegDisplay += "\033[1m\033[24m\033[0mX";
00586         frameCnt += 30;
00587 }
00588 
00589 refSegDisplay += "\033[0m\n\n";
00590 
00591 if(verboseLevel == 3){
00592         for(unsigned long iseg=0;iseg<refSegServer.getSegCount();iseg++){
00593                 Seg& segment=refSegServer.getSeg(iseg);
00594                 refSegDisplay += refSegDisplay.valueOf(segment.begin()*frameLength)+" "+refSegDisplay.valueOf((segment.begin()+segment.length()-1)*frameLength)+" "+segment.string()+"\n";
00595         }
00596         refSegDisplay += "\n";
00597 }
00598 config.setParam("refSegDisplay", refSegDisplay);        
00599 
00600 } // display
00601 
00602 
00603 // look for a specific label in a list
00604 long findLabel(XLine classToAnalyse,String labelToFind){
00605 
00606 for(unsigned long i=0;i<classToAnalyse.getElementCount();i++){
00607         if(classToAnalyse.getElement(i)==labelToFind) return(i);
00608 }
00609 
00610 return(-1);//not found
00611 
00612 }//findLabel
00613 
00614 void moveSegmentFromOneClusterToAnother(LabelServer& labelServer, Seg *segment, SegCluster &currentCluster, SegCluster &newCluster){
00615         currentCluster.remove(*segment);
00616         segment->setLabelCode(newCluster.labelCode());  
00617         segment->setString((labelServer.getLabel(newCluster.labelCode())).getString()); 
00618         
00619         newCluster.add(*segment);
00620 }
00621 
00622 /**********************************************************
00623 * longerSegment: search the longer  of a cluster (in terms of time) and return it
00624 * 
00625 * Author C. Fredouille February 2006
00626 ***********************************************************/
00627 Seg *longerSegment(Config& config, SegCluster& cluster){
00628 
00629 DoubleVector time;                                        // The LLR value and the startindex of each of the potential trial
00630 cluster.rewind();
00631 Seg *segment;   
00632 while((segment=cluster.getSeg())!=NULL){
00633                 time.addValue((double)segment->length());
00634 }//while segment
00635 
00636 unsigned long ind = time.getIndexOfLargestValue();
00637 
00638 cluster.rewind();
00639 for (unsigned long i=0; i<=ind; i++){
00640         segment=cluster.getSeg();
00641         
00642 }
00643         
00644 cluster.rewind();
00645 return segment;
00646 }
00647 
00648 /**********************************************************
00649 * findClusterIndex: search the index of a cluster in a segment server
00650 * 
00651 * Author C. Fredouille February 2006
00652 ***********************************************************/
00653 unsigned long findClusterIndex(String name,SegServer& segTmp){
00654   for(unsigned long icluster=0;icluster<segTmp.getClusterCount();icluster++){
00655     SegCluster& cluster=segTmp.getCluster(icluster);    
00656     if(cluster.string()==name)
00657       return icluster;
00658     
00659   }//for i
00660   return -1;
00661 }//findClusterIndex
00662 
00663 
00664 #endif
00665