FeatureMultipleFileReader.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_FeatureMultipleFileReader_cpp)
00056 #define ALIZE_FeatureMultipleFileReader_cpp
00057 
00058 #include <new>
00059 #include "FeatureMultipleFileReader.h"
00060 #include "Feature.h"
00061 #include "Exception.h"
00062 #include "FeatureFlags.h"
00063 #include "LabelServer.h"
00064 #include "Config.h"
00065 #include <iostream>
00066 using namespace std;
00067 
00068 using namespace alize;
00069 typedef FeatureMultipleFileReader R;
00070 
00071 //-------------------------------------------------------------------------
00072 R::FeatureMultipleFileReader(const XLine& l, const Config& c,
00073      LabelServer* p, BigEndian be, BufferUsage b, unsigned long bufferSize,
00074      HistoricUsage h, unsigned long historicSize)
00075 :FeatureFileReaderAbstract(NULL, c, p, b, bufferSize, h, historicSize),
00076  _fileCounter(0), _fileList(l, c), _bigEndian(be),
00077  _fileCount(_fileList.size()), _readerPtrVect(createReaderPtrVect()),
00078  _bufferPtrVect(createBufferPtrVect()), _memUsed(0),
00079  _featuresAreWritableDefined(false), _lastFeatureIndex(0) {}
00080 //-------------------------------------------------------------------------
00081 FeatureFileReader** R::createReaderPtrVect()
00082 {
00083   FeatureFileReader** p = new (std::nothrow)
00084                           FeatureFileReader*[_fileCount==0?1:_fileCount];
00085   assertMemoryIsAllocated(p, __FILE__, __LINE__);
00086   for (unsigned long i=0; i<_fileCount; i++)
00087     p[i] = NULL;
00088   return p;
00089 }
00090 //-------------------------------------------------------------------------
00091 FloatVector** R::createBufferPtrVect()
00092 {
00093   FloatVector** p = new (std::nothrow)
00094                           FloatVector*[_fileCount==0?1:_fileCount];
00095   assertMemoryIsAllocated(p, __FILE__, __LINE__);
00096   for (unsigned long i=0; i<_fileCount; i++)
00097     p[i] = NULL;
00098   return p;
00099 }
00100 //-------------------------------------------------------------------------
00101 R& R::create(const XLine& list, const Config& c,
00102     LabelServer* ls, BigEndian be, BufferUsage b, unsigned long bufferSize,
00103     HistoricUsage h, unsigned long historicSize)
00104 {
00105   R* p = new (std::nothrow) R(list, c, ls, be, b, bufferSize, h, historicSize);
00106   assertMemoryIsAllocated(p, __FILE__, __LINE__);
00107   return *p;
00108 }
00109 //-------------------------------------------------------------------------
00110 bool R::readFeature(Feature& f, unsigned long s) { return rw(true, f, s); }
00111 //-------------------------------------------------------------------------
00112 bool R::writeFeature(const Feature& f, unsigned long step)
00113 {
00114   // temporary test
00115   if (!_featuresAreWritableDefined)
00116   {
00117     if (_featuresAreWritable)
00118     {
00119       unsigned long m = 0;
00120       if (_bufferUsage == BUFFER_USERDEFINE)
00121         m = _userDefineBufferSize/sizeof(float);
00122       else if (_bufferUsage == BUFFER_AUTO && 
00123                getConfig().existsParam_loadFeatureFileMemAlloc)
00124         m = getConfig().getParam_loadFeatureFileMemAlloc()/sizeof(float);
00125       if (m < getFeatureCount()*getVectSize())
00126         _featuresAreWritable = false;
00127     }
00128     _featuresAreWritableDefined = true;
00129   }
00130   if (!_featuresAreWritable)
00131     throw Exception("Feature writing forbidden", __FILE__, __LINE__);
00132 
00133   return rw(false, const_cast<Feature&>(f), step);
00134 }
00135 //-------------------------------------------------------------------------
00136 bool R::rw(bool read, Feature& f, unsigned long s) // private
00137 {
00138   // _fileCounter = n° du PROCHAIN fichier à lire
00139   unsigned long featureNbr = 0;
00140   unsigned long futureLastFeatureIndex = _lastFeatureIndex;
00141   bool seekWantedInCurrentFile = _seekWanted;
00142 
00143   // _fileCounter = number of file to read
00144   // featureNbr = number of feature to read in the file
00145   // featureNbrGlobal
00146 
00147   if (_seekWanted)
00148   {
00149     _seekWanted = false;
00150     if (_fileCount != 0)
00151     {
00152       unsigned long featureNbrGlobal;
00153       if (_seekWantedSrcName.isEmpty())
00154       {
00155         _fileCounter     = _fileList.getFileIndex(_seekWantedIdx);
00156         featureNbr       = _seekWantedIdx
00157                            - _fileList.getIndexOfFirstFeature(_fileCounter);
00158         featureNbrGlobal = _seekWantedIdx;
00159       }
00160       else
00161       {
00162         _fileCounter     = _fileList.getFileIndex(_seekWantedSrcName);
00163         featureNbr       = _seekWantedIdx;
00164         featureNbrGlobal = _fileList.getIndexOfFirstFeature(_fileCounter)
00165                            + _seekWantedIdx;
00166       }
00167       if (_historicUsage == LIMITED &&
00168           !featureWantedIsInHistoric(featureNbrGlobal))
00169       {
00170         if (!read) // if write
00171           throw Exception("Feature out of historic", __FILE__, __LINE__);
00172         f.setVectSize(K::k, getVectSize());
00173         f.setValidity(false);
00174         _error = FEATURE_OUT_OF_HISTORY;
00175         return true;
00176       }
00177       if (featureNbrGlobal > futureLastFeatureIndex)
00178         futureLastFeatureIndex = featureNbrGlobal;
00179     }
00180     else
00181       _fileCounter = 0;
00182   }
00183   else
00184     futureLastFeatureIndex++;
00185 
00186   while (true)
00187   {
00188     if (_fileCounter >= _fileCount) // end of file list
00189       return false;
00190     FeatureFileReader& r = getReader(_fileCounter);
00191     if (seekWantedInCurrentFile)
00192     {
00193       r.seekFeature(featureNbr);
00194       seekWantedInCurrentFile = false;
00195     }
00196     bool ok;
00197     if (read)
00198       ok = r.readFeature(f, s);
00199     else
00200       ok = r.writeFeature(f, s);
00201     _error = r.getError();
00202     if (ok)
00203     {
00204       _lastFeatureIndex = futureLastFeatureIndex;
00205       return true;
00206     }
00207     _fileCounter++;
00208     featureNbr = 0;
00209     seekWantedInCurrentFile = true;
00210   }
00211 }
00212 //-------------------------------------------------------------------------
00213 bool R::featureWantedIsInHistoric(unsigned long featureNbr) const
00214 {
00215   if (featureNbr > _lastFeatureIndex)
00216     return false;
00217   if (_historicSize > _lastFeatureIndex)
00218     return featureNbr >= 0;
00219   return featureNbr >= _lastFeatureIndex-_historicSize;
00220 }
00221 //-------------------------------------------------------------------------
00222 FeatureFileReader& R::getReader(unsigned long idx) // private
00223 {
00224   assert(idx < _fileCount);
00225   assert(_readerPtrVect != NULL);
00226   //
00227   FeatureFileReader*& pReader = _readerPtrVect[idx];
00228   if (pReader != NULL)
00229     return *pReader;
00230   //
00231   pReader = &FeatureFileReader::create(_fileList.getFileName(idx),
00232                  getConfig(), _pLabelServer, _bigEndian, BUFFER_USERDEFINE, 0);
00233   // <FRANCAIS>
00234   // Creer un buffer
00235   // S'il ne reste pas assez de memoire disponible, détruit les
00236   // readers les plus anciens pour récuperer la memoire des buffers
00237   //
00238   unsigned long memMax = 0;
00239   if (_bufferUsage == BUFFER_USERDEFINE)
00240     memMax = _userDefineBufferSize / sizeof(float);
00241   else if (_bufferUsage == BUFFER_AUTO && 
00242       getConfig().existsParam_loadFeatureFileMemAlloc)
00243     memMax = getConfig().getParam_loadFeatureFileMemAlloc() / sizeof(float);
00244   //
00245   FloatVector*& pBuffer = _bufferPtrVect[idx];
00246   unsigned long memNeeded = pReader->getFeatureCount()*pReader->getVectSize();
00247   //
00248   unsigned long i, m = _memUsed + memNeeded;
00249   for (i=0; i<_memStack.size(); i++)
00250   {
00251     if (m <= memMax)
00252       break;
00253     m -= _memStack[i];
00254     unsigned long j = _readerStack[i];
00255     FeatureFileReader*& p = _readerPtrVect[j];
00256     assert(p != NULL);
00257     delete p;
00258     p = NULL;
00259     FloatVector*& p1 = _bufferPtrVect[j];
00260     assert(p1 != NULL);
00261     delete p1;
00262     p1 = NULL;
00263   }
00264   if (i>0)
00265   {
00266     _memStack.removeValues(0, i-1);
00267     _readerStack.removeValues(0, i-1);
00268   }
00269   if (m >= memMax) // not enough memory
00270   {
00271     memNeeded = memMax;
00272     m = memMax;
00273   }
00274   pBuffer = &FloatVector::create(memNeeded, memNeeded);
00275   //cout << "memNeeded = " << memNeeded << endl;
00276   _readerStack.addValue(idx);
00277   _memStack.addValue(memNeeded);
00278   pReader->setExternalBufferToUse(*pBuffer);
00279   //std::cout << memNeeded << std::endl;
00280   _memUsed = m;
00281   return *pReader;
00282 
00283   //_readerStack.removeValues(0, 0);
00284   unsigned long mem = memNeeded;
00285   //pBuffer->setSize(mem);
00286   _memUsed += mem;
00287   _readerStack.addValue(idx);
00288   return *pReader;
00289 }
00290 //-------------------------------------------------------------------------
00291 unsigned long R::getFeatureCount() { return _fileList.getFeatureCount(); }
00292 //-------------------------------------------------------------------------
00293 unsigned long R::getVectSize() { return _fileList.getVectSize(); }
00294 //-------------------------------------------------------------------------
00295 const FeatureFlags& R::getFeatureFlags()  
00296 { return _fileList.getFeatureFlags(); }
00297 //-------------------------------------------------------------------------
00298 real_t R::getSampleRate() { return _fileList.getSampleRate(); }
00299 //-------------------------------------------------------------------------
00300 unsigned long R::getSourceCount() { return _fileList.size(); }
00301 //-------------------------------------------------------------------------
00302 unsigned long R::getFeatureCountOfASource(unsigned long srcIdx)
00303 { return _fileList.getFeatureCount(srcIdx); }
00304 //-------------------------------------------------------------------------
00305 unsigned long R::getFeatureCountOfASource(const FileName& f)
00306 { return _fileList.getFeatureCount(f); }
00307 //-------------------------------------------------------------------------
00308 unsigned long R::getFirstFeatureIndexOfASource(unsigned long srcIdx)
00309 { return _fileList.getIndexOfFirstFeature(srcIdx); }
00310 //-------------------------------------------------------------------------
00311 unsigned long R::getFirstFeatureIndexOfASource(const FileName& f)
00312 { return _fileList.getIndexOfFirstFeature(f); }
00313 //-------------------------------------------------------------------------
00314 const String& R::getNameOfASource(unsigned long srcIdx)
00315 { return _fileList.getFileName(srcIdx); }
00316 //-------------------------------------------------------------------------
00317 void R::close()
00318 {
00319   for (unsigned long i=0; i<_fileCount; i++)
00320     if (_readerPtrVect[i] != NULL)
00321       _readerPtrVect[i]->close();
00322 }
00323 //-------------------------------------------------------------------------
00324 String R::getClassName() const { return "FeatureMultipleFileReader"; }
00325 //-------------------------------------------------------------------------
00326 String R::toString() const
00327 {
00328   FeatureMultipleFileReader& r = const_cast<FeatureMultipleFileReader&>(*this);
00329   const FeatureFlags flags(r.getFeatureFlags());
00330   return Object::toString()
00331     + "\n  file count   = '" + String::valueOf(_fileList.size())
00332     + "\n  vectSize    = " + String::valueOf(r.getVectSize())
00333     + "\n  feature count = " + String::valueOf(r.getFeatureCount())
00334     + "\n  sample rate   = " + String::valueOf(r.getSampleRate())
00335     + "\n  flag S    = " + String::valueOf(flags.useS)
00336     + "\n  flag E    = " + String::valueOf(flags.useE)
00337     + "\n  flag D    = " + String::valueOf(flags.useD)
00338     + "\n  flag DE     = " + String::valueOf(flags.useDE)
00339     + "\n  flag DD     = " + String::valueOf(flags.useDD)
00340     + "\n  flag DDE    = " + String::valueOf(flags.useDDE);
00341 }
00342 //-------------------------------------------------------------------------
00343 R::~FeatureMultipleFileReader()
00344 {
00345   if (_readerPtrVect != NULL)
00346   {
00347     for (unsigned long i=0; i<_fileCount; i++)
00348       if (_readerPtrVect[i] != NULL)
00349         delete _readerPtrVect[i];
00350     delete [] _readerPtrVect;
00351   }
00352   if (_bufferPtrVect != NULL)
00353   {
00354     for (unsigned long i=0; i<_fileCount; i++)
00355       if (_bufferPtrVect[i] != NULL)
00356         delete _bufferPtrVect[i];
00357     delete [] _bufferPtrVect;
00358   }
00359 }
00360 //-------------------------------------------------------------------------
00361 
00362 #endif // !defined(ALIZE_FeatureMultipleFileReader_cpp)
00363