FeatureFileReaderSPro3.cpp

Go to the documentation of this file.
00001 /*
00002         This file is part of ALIZE which is an open-source tool for 
00003         speaker recognition.
00004 
00005     ALIZE is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU Lesser General Public License as 
00007     published by the Free Software Foundation, either version 3 of 
00008     the License, or any later version.
00009 
00010     ALIZE is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public 
00016     License along with ALIZE.
00017     If not, see <http://www.gnu.org/licenses/>.
00018         
00019         ALIZE is a development project initiated by the ELISA consortium
00020         [alize.univ-avignon.fr/] and funded by the French Research 
00021         Ministry in the framework of the TECHNOLANGUE program 
00022         [www.technolangue.net]
00023 
00024         The ALIZE project team wants to highlight the limits of voice
00025         authentication in a forensic context.
00026         The "Person  Authentification by Voice: A Need of Caution" paper 
00027         proposes a good overview of this point (cf. "Person  
00028         Authentification by Voice: A Need of Caution", Bonastre J.F., 
00029         Bimbot F., Boe L.J., Campbell J.P., Douglas D.A., Magrin-
00030         chagnolleau I., Eurospeech 2003, Genova].
00031         The conclusion of the paper of the paper is proposed bellow:
00032         [Currently, it is not possible to completely determine whether the 
00033         similarity between two recordings is due to the speaker or to other 
00034         factors, especially when: (a) the speaker does not cooperate, (b) there 
00035         is no control over recording equipment, (c) recording conditions are not 
00036         known, (d) one does not know whether the voice was disguised and, to a 
00037         lesser extent, (e) the linguistic content of the message is not 
00038         controlled. Caution and judgment must be exercised when applying speaker 
00039         recognition techniques, whether human or automatic, to account for these 
00040         uncontrolled factors. Under more constrained or calibrated situations, 
00041         or as an aid for investigative purposes, judicious application of these 
00042         techniques may be suitable, provided they are not considered as infallible.
00043         At the present time, there is no scientific process that enables one to 
00044         uniquely characterize a person=92s voice or to identify with absolute 
00045         certainty an individual from his or her voice.]
00046         Contact Jean-Francois Bonastre for more information about the licence or
00047         the use of ALIZE
00048 
00049         Copyright (C) 2003-2010
00050         Laboratoire d'informatique d'Avignon [lia.univ-avignon.fr]
00051         ALIZE admin [alize@univ-avignon.fr]
00052         Jean-Francois Bonastre [jean-francois.bonastre@univ-avignon.fr]
00053 */
00054 
00055 #if !defined(ALIZE_FeatureFileReaderSPro3_cpp)
00056 #define ALIZE_FeatureFileReaderSPro3_cpp
00057 
00058 #include <new>
00059 #include "FeatureFileReaderSPro3.h"
00060 #include "FileReader.h"
00061 #include "Feature.h"
00062 #include "Exception.h"
00063 #include "LabelServer.h"
00064 #include "Label.h"
00065 #include "Config.h"
00066 
00067 static const int WITHE = 0x01; /* Data is with log energy         */
00068 static const int WITHZ = 0x02; /* Data as mean suppressed
00069                            (static const only)*/
00070 static const int WITHN = 0x04; /* Absolute log energy suppressed    */
00071 static const int WITHD = 0x08; /* Data as delta coefficients      */
00072 static const int WITHA = 0xa0; /* Data contains delta-delta coeffs    */
00073 static const int WITHNODE = 0x10; /* */
00074 
00075 using namespace alize;
00076 typedef FeatureFileReaderSPro3 R;
00077 
00078 //-------------------------------------------------------------------------
00079 R::FeatureFileReaderSPro3(const FileName& f, const Config& c,
00080                    LabelServer* p, BufferUsage b, unsigned long bufferSize,
00081                    HistoricUsage h, unsigned long historicSize)
00082 :FeatureFileReaderSingle(&FileReader::create(f, getPath(f, c), getExt(f, c),
00083  false /* endian auto detected */), NULL, c, p, b, bufferSize, h, historicSize),
00084  _paramDefined(false) {}
00085 //-------------------------------------------------------------------------
00086 R& FeatureFileReaderSPro3::create(const FileName& f, const Config& c,
00087               LabelServer* l, BufferUsage b, unsigned long bufferSize,
00088               HistoricUsage h, unsigned long historicSize)
00089 {
00090   FeatureFileReaderSPro3* p
00091         = new (std::nothrow) FeatureFileReaderSPro3(f, c, l, b, bufferSize,
00092         h, historicSize);
00093   assertMemoryIsAllocated(p, __FILE__, __LINE__);
00094   return *p;
00095 }
00096 //-------------------------------------------------------------------------
00097 void R::readParams() // private
00098 {
00099   assert(_pReader != NULL);
00100   _pReader->open(); // can throw FileNotFoundException
00101 
00102   if (!readHeader())
00103   {
00104     _pReader->close();
00105     throw InvalidDataException("Wrong header", __FILE__, __LINE__,
00106                   _pReader->getFullFileName());
00107   }
00108 }
00109 //-------------------------------------------------------------------------
00110 unsigned long R::getFeatureCount()
00111 {
00112   if (!_paramDefined)
00113     readParams();  // can throw FileNotFoundException
00114   return _featureCount;
00115 }
00116 //-------------------------------------------------------------------------
00117 unsigned long R::getVectSize()
00118 {
00119   if (!_paramDefined)
00120     readParams(); // can throw FileNotFoundException
00121   return _vectSize;
00122 }
00123 //-------------------------------------------------------------------------
00124 const FeatureFlags& R::getFeatureFlags()
00125 {
00126   if (!_paramDefined)
00127     readParams(); // can throw FileNotFoundException
00128   return _flags;
00129 }
00130 //-------------------------------------------------------------------------
00131 real_t R::getSampleRate()
00132 { return getConfig().getParam_sampleRate(); } // TODO : or 100 ?
00133 //-------------------------------------------------------------------------
00134 String R::getClassName() const
00135 { return "FeatureFileReaderSPro3"; }
00136 //-------------------------------------------------------------------------
00137 unsigned long R::getHeaderLength()
00138 {
00139   if (!_paramDefined)
00140     readParams(); // can throw FileNotFoundException
00141   return _headerLength;
00142 }
00143 //-------------------------------------------------------------------------
00162 bool R::readHeader()
00163 {
00164   // Modifie le 4 juin 2004 pour gerer les long et unsigned long sur 8
00165   // octets sur IA 64
00166   assert(_pReader != NULL);
00167   if (sizeof(unsigned long) == 4)
00168   {
00169     typedef unsigned int flag_t; /* Flag for qualifiers       */
00170     SPRO3DataKind kind, kindInv;
00171     unsigned long dim, dimInv, n, nInv;
00172     flag_t flag, flagInv;
00173     short OK_kind, OK_reste;
00174     unsigned long nbElem, tailleReelle, tailleCalculee, tailleCalcInv;
00175     _headerLength = sizeof(SPRO3DataKind) + sizeof(unsigned long) + 
00176       sizeof(unsigned long) + sizeof(flag_t);
00177   
00178     /* Lecture de l'en-tete */
00179     kind = (SPRO3DataKind)_pReader->readInt4();
00180     dim = _pReader->readUInt4();
00181     n = _pReader->readUInt4();
00182     flag = _pReader->readUInt4();
00183   
00184     /* Verification du format */
00185     /* Test sur kind */
00186     OK_kind = 0;
00187     _pReader->swap4Bytes(&kind, &kindInv); // king -> kindInv
00188     if ((kind <= SPRO3DataKind_LAR) && (kind >= SPRO3DataKind_OTHER)) // ???
00189       OK_kind++;
00190     if ((kindInv <= SPRO3DataKind_LAR) && (kindInv >= SPRO3DataKind_OTHER))
00191       OK_kind--;
00192     else
00193       if (OK_kind == 0) // si dans aucun des cas on n'a une valeur
00194         return false; // correcte c'est que le fichier n'est pas bon.
00195   
00196     /* Test sur dim, n, flag */
00197 
00198     OK_reste = 0;
00199 
00200     // determine taille reelle du fichier
00201 
00202     tailleReelle = _pReader->getFileLength();
00203 
00204     // calcule taille theorique du fichier
00205   
00206     nbElem = dim;
00207     if (flag & WITHE)
00208       nbElem++;
00209     if (flag & WITHD) {
00210       if (flag & WITHA) {
00211         nbElem *= 3;
00212       }
00213       else {
00214         nbElem += nbElem;
00215       }
00216     }
00217     if (flag & WITHN)
00218       nbElem--;
00219     nbElem *= n;
00220     tailleCalculee = nbElem*sizeof(param_t) + sizeof(SPRO3DataKind)
00221                + 2*sizeof(unsigned long) + sizeof(flag_t);
00222 
00223     // compare les tailles theorique et reelle du fichier
00224   
00225     if (tailleCalculee == tailleReelle)
00226       OK_reste++;
00227 
00228     _pReader->swap4Bytes(&dim,&dimInv);
00229     _pReader->swap4Bytes(&n,&nInv);
00230     _pReader->swap4Bytes(&flag,&flagInv);
00231 
00232     // calcule taille theorique du fichier (apres swap des donnees)
00233 
00234     nbElem = dimInv;
00235     if (flagInv & WITHE)
00236       nbElem++;
00237     if (flagInv & WITHD) {
00238       if (flagInv & WITHA) {
00239         nbElem *= 3;
00240       }
00241       else {
00242         nbElem += nbElem;
00243       }
00244     }
00245     if (flagInv & WITHN)
00246       nbElem--;
00247     nbElem *= nInv;
00248     tailleCalcInv = nbElem*sizeof(param_t) + sizeof(SPRO3DataKind)
00249             + 2*sizeof(unsigned long) + sizeof(flag_t);
00250 
00251     // compare les tailles theorique (apres swap) et reelle du fichier
00252 
00253     if (tailleCalcInv == tailleReelle)
00254       OK_reste--;
00255     else
00256       if (OK_reste == 0) // si dans aucun cas on ne retombe sur la bonne
00257         return false;  // bonne c'est que le fichier n'est pas bon.
00258 
00259     /* Decision */
00260     /* OK_kind + OK_reste > 0  => pas de byte swap */
00261     /* OK_kind + OK_reste < 0  => byte swap */
00262     /* OK_kind + OK_reste = 0  => indetermine, ou fichier foireux */
00263 
00264     if ((OK_kind + OK_reste == 0) && (OK_kind != OK_reste))
00265       return false;
00266 
00267     if (OK_kind + OK_reste < 0)
00268     {
00269       kind = kindInv;
00270       dim = dimInv;
00271       n = nInv;
00272       flag = flagInv;
00273       _pReader->swap() = true;
00274     }
00275   
00276     /* Valeurs de retour */
00277     _kind = kind;
00278     _featureCount = n;
00279     _vectSize = dim;
00280 
00281     _flags.useS = true;
00282   
00283     /* version Teva
00284     if (flag & WITHE)
00285       _vectSize++;
00286     if (flag & WITHD)
00287       if (flag & WITHA)
00288         _vectSize *= 3;
00289       else
00290         _vectSize *= 2;
00291     if (flag & WITHN)
00292       _vectSize--;*/
00293 
00294     /* version Sylvain */
00295     if ((flag & WITHE) != 0)
00296     {
00297       _flags.useE = true;
00298       _vectSize++;
00299       if ((flag & WITHD) != 0)
00300       {
00301         _flags.useD = true;
00302         _vectSize += dim;
00303         if ((flag & WITHNODE) == 0)
00304         {
00305           _flags.useDE = true;
00306           _vectSize++;
00307         }
00308         if ((flag & WITHA) != 0)
00309         {
00310           _flags.useDD = true;
00311           _flags.useDDE = true;
00312           _vectSize += dim;
00313           _vectSize++;
00314         }
00315       }
00316       else
00317       {
00318         if ((flag & WITHA) != 0)
00319         {
00320           _flags.useD = true;
00321           _flags.useDE = true;
00322           _vectSize += dim;
00323           _vectSize++;
00324         }
00325       }
00326     }
00327     else
00328     {
00329       if ((flag & WITHD) != 0)
00330       {
00331         _flags.useD = true;
00332         _vectSize += dim;
00333         if ((flag & WITHA) != 0)
00334         {
00335           _flags.useDD = true;
00336           _vectSize += dim;
00337         }
00338       }
00339       else
00340         if ((flag & WITHA) != 0)
00341         {
00342           _flags.useDD = true;
00343           _vectSize += dim;
00344         }
00345     }
00346     _paramDefined = true;
00347     return true;
00348   }
00349   else if (sizeof(unsigned int) == 4)
00350   {
00351     typedef unsigned int flag_t; /* Flag for qualifiers       */
00352     SPRO3DataKind kind, kindInv;
00353     unsigned int dim, dimInv, n, nInv;
00354     flag_t flag, flagInv;
00355     short OK_kind, OK_reste;
00356     unsigned int nbElem, tailleReelle, tailleCalculee, tailleCalcInv;
00357     _headerLength = sizeof(SPRO3DataKind) + sizeof(unsigned int) + 
00358       sizeof(unsigned int) + sizeof(flag_t);
00359   
00360     /* Lecture de l'en-tete */
00361     kind = (SPRO3DataKind)_pReader->readInt4();
00362     dim = _pReader->readUInt4();
00363     n = _pReader->readUInt4();
00364     flag = _pReader->readUInt4();
00365   
00366     /* Verification du format */
00367     /* Test sur kind */
00368     OK_kind = 0;
00369     _pReader->swap4Bytes(&kind, &kindInv); // king -> kindInv
00370     if ((kind <= SPRO3DataKind_LAR) && (kind >= SPRO3DataKind_OTHER)) // ???
00371       OK_kind++;
00372     if ((kindInv <= SPRO3DataKind_LAR) && (kindInv >= SPRO3DataKind_OTHER))
00373       OK_kind--;
00374     else
00375       if (OK_kind == 0) // si dans aucun des cas on n'a une valeur
00376         return false; // correcte c'est que le fichier n'est pas bon.
00377   
00378     /* Test sur dim, n, flag */
00379 
00380     OK_reste = 0;
00381 
00382     // determine taille reelle du fichier
00383 
00384     tailleReelle = _pReader->getFileLength();
00385 
00386     // calcule taille theorique du fichier
00387   
00388     nbElem = dim;
00389     if (flag & WITHE)
00390       nbElem++;
00391     if (flag & WITHD) {
00392       if (flag & WITHA) {
00393         nbElem *= 3;
00394       }
00395       else {
00396         nbElem += nbElem;
00397       }
00398     }
00399     if (flag & WITHN)
00400       nbElem--;
00401     nbElem *= n;
00402     tailleCalculee = nbElem*sizeof(param_t) + sizeof(SPRO3DataKind)
00403                + 2*sizeof(unsigned int) + sizeof(flag_t);
00404 
00405     // compare les tailles theorique et reelle du fichier
00406   
00407     if (tailleCalculee == tailleReelle)
00408       OK_reste++;
00409 
00410     _pReader->swap4Bytes(&dim,&dimInv);
00411     _pReader->swap4Bytes(&n,&nInv);
00412     _pReader->swap4Bytes(&flag,&flagInv);
00413 
00414     // calcule taille theorique du fichier (apres swap des donnees)
00415 
00416     nbElem = dimInv;
00417     if (flagInv & WITHE)
00418       nbElem++;
00419     if (flagInv & WITHD) {
00420       if (flagInv & WITHA) {
00421         nbElem *= 3;
00422       }
00423       else {
00424         nbElem += nbElem;
00425       }
00426     }
00427     if (flagInv & WITHN)
00428       nbElem--;
00429     nbElem *= nInv;
00430     tailleCalcInv = nbElem*sizeof(param_t) + sizeof(SPRO3DataKind)
00431             + 2*sizeof(unsigned int) + sizeof(flag_t);
00432 
00433     // compare les tailles theorique (apres swap) et reelle du fichier
00434 
00435     if (tailleCalcInv == tailleReelle)
00436       OK_reste--;
00437     else
00438       if (OK_reste == 0) // si dans aucun cas on ne retombe sur la bonne
00439         return false;  // bonne c'est que le fichier n'est pas bon.
00440 
00441     /* Decision */
00442     /* OK_kind + OK_reste > 0  => pas de byte swap */
00443     /* OK_kind + OK_reste < 0  => byte swap */
00444     /* OK_kind + OK_reste = 0  => indetermine, ou fichier foireux */
00445 
00446     if ((OK_kind + OK_reste == 0) && (OK_kind != OK_reste))
00447       return false;
00448 
00449     if (OK_kind + OK_reste < 0)
00450     {
00451       kind = kindInv;
00452       dim = dimInv;
00453       n = nInv;
00454       flag = flagInv;
00455       _pReader->swap() = true;
00456     }
00457   
00458     /* Valeurs de retour */
00459     _kind = kind;
00460     _featureCount = n;
00461     _vectSize = dim;
00462 
00463     _flags.useS = true;
00464   
00465     /* version Teva
00466     if (flag & WITHE)
00467       _vectSize++;
00468     if (flag & WITHD)
00469       if (flag & WITHA)
00470         _vectSize *= 3;
00471       else
00472         _vectSize *= 2;
00473     if (flag & WITHN)
00474       _vectSize--;*/
00475 
00476     /* version Sylvain */
00477     if ((flag & WITHE) != 0)
00478     {
00479       _flags.useE = true;
00480       _vectSize++;
00481       if ((flag & WITHD) != 0)
00482       {
00483         _flags.useD = true;
00484         _vectSize += dim;
00485         if ((flag & WITHNODE) == 0)
00486         {
00487           _flags.useDE = true;
00488           _vectSize++;
00489         }
00490         if ((flag & WITHA) != 0)
00491         {
00492           _flags.useDD = true;
00493           _flags.useDDE = true;
00494           _vectSize += dim;
00495           _vectSize++;
00496         }
00497       }
00498       else
00499       {
00500         if ((flag & WITHA) != 0)
00501         {
00502           _flags.useD = true;
00503           _flags.useDE = true;
00504           _vectSize += dim;
00505           _vectSize++;
00506         }
00507       }
00508     }
00509     else
00510     {
00511       if ((flag & WITHD) != 0)
00512       {
00513         _flags.useD = true;
00514         _vectSize += dim;
00515         if ((flag & WITHA) != 0)
00516         {
00517           _flags.useDD = true;
00518           _vectSize += dim;
00519         }
00520       }
00521       else
00522         if ((flag & WITHA) != 0)
00523         {
00524           _flags.useDD = true;
00525           _vectSize += dim;
00526         }
00527     }
00528     _paramDefined = true;
00529     return true;
00530   }
00531   else
00532     return false; // la y'a un probleme !
00533 }
00534 //-------------------------------------------------------------------------
00535 R::~FeatureFileReaderSPro3() {}
00536 //-------------------------------------------------------------------------
00537 
00538 #endif // !defined(ALIZE_FeatureFileReaderSPro3_cpp)
00539