2012-10-30 03:52:39 +00:00
# include "cmPrefix.h"
# include "cmGlobal.h"
# include "cmFloatTypes.h"
# include "cmComplexTypes.h"
# include "cmRpt.h"
# include "cmErr.h"
# include "cmCtx.h"
# include "cmMem.h"
# include "cmMallocDebug.h"
# include "cmLinkedHeap.h"
# include "cmSymTbl.h"
# include "cmMath.h"
# include "cmFile.h"
# include "cmAudioFile.h"
# include "cmJson.h"
# include "cmFileSys.h"
2013-12-15 23:14:27 +00:00
# include "cmTime.h"
2012-10-30 03:52:39 +00:00
# include "cmMidi.h"
# include "cmProcObj.h"
# include "cmProcTemplateMain.h"
# include "cmProc.h"
# include "cmProc2.h"
# include "cmVectOps.h"
# include "cmFrameFile.h"
# include "cmFeatFile.h"
# include "cmSerialize.h"
# define kConstQThresh (0.0054)
enum
{
kFrameTypeFtId = 1 ,
kFrameStreamFtId = 1 ,
kStatRecdVectCnt = 8 // count of vectors in cmFtSumm_t
} ;
// master control record
typedef struct
{
cmErr_t err ;
cmCtx_t ctx ;
cmJsonH_t jsH ; //
cmSrH_t srH ; // file header serializer
cmFtAttr_t * attrArray ; //
unsigned attrCnt ; //
cmFtParam_t * paramArray ; //
unsigned paramCnt ; //
cmCtx * ctxPtr ; // process context object
cmAudioFileRd * afRdPtr ; // audio file reader object
cmPvAnl * pvocPtr ; // phase vocoder object
cmBfcc * bfccPtr ; // BFCC generator
cmMfcc * mfccPtr ; // MFCC generator
cmCeps * cepsPtr ; // Cepstrum generator
cmConstQ * constqPtr ; // Const Q generator
unsigned progParamIdx ;
unsigned progPassIdx ;
unsigned progSmpCnt ;
unsigned progSmpIdx ;
} _cmFt_t ;
// static feature values
typedef struct
{
unsigned order ; // determines the order the feature extractors are init'd and exec'd
const char * label ; // feature label
unsigned id ; // feature id
unsigned ffMtxId ; // cmFrameFile matrix type id
unsigned ffUnitsId ; // cmFrameFile data unit id
unsigned srcId ; // id of the source vector for this secondary feature (or kInvalidFtId if no src)
bool bipolarFl ; // this feature is bipolar
unsigned maxCnt ; // maximum feature vector element count (scalar==1 no max==0)
} _cmFtLabel_t ;
// analysis control record - one recd per feature
typedef struct _cmFtAttr_str
{
cmFtAttr_t * ap ; // user supplied feature parameters
const _cmFtLabel_t * lp ; // static feature parameters
cmFtSumm_t * sr ; // summary record assoc'd with this feature
struct _cmFtAttr_str * sp ; // sourcePtr (used by secondary feats to locate primary feature)
cmReal_t * v ; // v[ap->cnt*2] feature vector memory used by cvp and pvp
cmReal_t * cvp ; // current feat vect
cmReal_t * pvp ; // previous feat vect
} _cmFtAnl_t ;
// internal feature desc record
typedef struct
{
const cmFtAttr_t * ap ;
const _cmFtLabel_t * lp ;
cmFtSumm_t * sr ;
} _cmFtDesc_t ;
// internal feature file control record - file handle record
typedef struct
{
cmFtH_t h ; // feat file library handle
cmFrameFileH_t ffH ; // handle for the frame file
cmFtInfo_t info ; // file hdr recd
_cmFtDesc_t * descArray ; // descArray[infoPtr->attrCnt] internal feature desc data
void * hdrBuf ; // memory used to hold the serialized header
} _cmFtFile_t ;
cmFtH_t cmFtNullHandle = { NULL } ;
cmFtFileH_t cmFtFileNullHandle = { NULL } ;
_cmFtLabel_t _cmFtLabelArray [ ] =
{
{ 0 , " ampl " , kAmplFtId , kMagMId , kAmplUId , kInvalidFtId , false , 0 } ,
{ 1 , " db_ampl " , kDbAmplFtId , kMagMId , k20DbUId , kAmplFtId , false , 0 } ,
{ 2 , " pow " , kPowFtId , kMagMId , kPowUId , kInvalidFtId , false , 0 } ,
{ 3 , " db_pow " , kDbPowFtId , kMagMId , k10DbUId , kPowFtId , false , 0 } ,
{ 4 , " phase " , kPhaseFtId , kPhsMId , kRadsUId , kInvalidFtId , false , 0 } ,
{ 5 , " bfcc " , kBfccFtId , kBfccMId , kBfccUId , kInvalidFtId , false , kDefaultBarkBandCnt } ,
{ 6 , " mfcc " , kMfccFtId , kMfccMId , kMfccUId , kInvalidFtId , false , kDefaultMelBandCnt } ,
{ 7 , " ceps " , kCepsFtId , kCepsMId , kCepsUId , kInvalidFtId , false , 0 } ,
{ 8 , " constq " , kConstQFtId , kConstqMId , kAmplUId , kInvalidFtId , false , 0 } ,
{ 9 , " log_constq " , kLogConstQFtId , kConstqMId , k20DbUId , kConstQFtId , false , 0 } ,
{ 10 , " rms " , kRmsFtId , kRmsMId , kAmplUId , kInvalidFtId , false , 1 } ,
{ 11 , " db_rms " , kDbRmsFtId , kRmsMId , k20DbUId , kRmsFtId , false , 1 } ,
{ 12 , " d1_ampl " , kD1AmplFtId , kMagMId , kAmplUId | kD1UFl , kAmplFtId , true , 0 } ,
{ 13 , " d1_db_ampl " , kD1DbAmplFtId , kMagMId , k20DbUId | kD1UFl , kDbAmplFtId , true , 0 } ,
{ 14 , " d1_pow " , kD1PowFtId , kMagMId , kPowUId | kD1UFl , kPowFtId , true , 0 } ,
{ 15 , " d1_db_pow " , kD1DbPowFtId , kMagMId , k10DbUId | kD1UFl , kDbPowFtId , true , 0 } ,
{ 16 , " d1_phase " , kD1PhaseFtId , kPhsMId , kRadsUId | kD1UFl , kPhaseFtId , true , 0 } ,
{ 17 , " d1_bfcc " , kD1BfccFtId , kBfccMId , kBfccUId | kD1UFl , kBfccFtId , true , kDefaultBarkBandCnt } ,
{ 18 , " d1_mfcc " , kD1MfccFtId , kMfccMId , kMfccUId | kD1UFl , kMfccFtId , true , kDefaultMelBandCnt } ,
{ 19 , " d1_ceps " , kD1CepsFtId , kCepsMId , kCepsUId | kD1UFl , kCepsFtId , true , 0 } ,
{ 20 , " d1_constq " , kD1ConstQFtId , kConstqMId , kAmplUId | kD1UFl , kConstQFtId , true , 0 } ,
{ 21 , " d1_log_constq " , kD1LogConstQFtId , kConstqMId , k20DbUId | kD1UFl , kLogConstQFtId , true , 0 } ,
{ 22 , " d1_rms " , kD1RmsFtId , kRmsMId , kAmplUId | kD1UFl , kRmsFtId , true , 1 } ,
{ 23 , " d1_db_rms " , kD1DbRmsFtId , kRmsMId , k20DbUId | kD1UFl , kDbRmsFtId , true , 1 } ,
{ 24 , " <invalid> " , kInvalidFtId , kInvalidMId , kInvalidUId , kInvalidFtId , true , 0 }
} ;
void _cmFtPrint ( _cmFt_t * p , const char * fmt , . . . )
{
va_list vl ;
va_start ( vl , fmt ) ;
cmRptVPrintf ( & p - > ctx . rpt , fmt , vl ) ;
va_end ( vl ) ;
}
cmFtRC_t _cmFtErrorV ( cmFtRC_t rc , _cmFt_t * p , const char * fmt , va_list vl )
{ return cmErrVMsg ( & p - > err , rc , fmt , vl ) ; }
cmFtRC_t _cmFtError ( cmFtRC_t rc , _cmFt_t * p , const char * fmt , . . . )
{
va_list vl ;
va_start ( vl , fmt ) ;
_cmFtErrorV ( rc , p , fmt , vl ) ;
va_end ( vl ) ;
return rc ;
}
_cmFt_t * _cmFtHandleToPtr ( cmFtH_t h )
{
assert ( h . h ! = NULL ) ;
return ( _cmFt_t * ) h . h ;
}
_cmFtFile_t * _cmFtFileHandleToPtr ( cmFtFileH_t h )
{
assert ( h . h ! = NULL ) ;
return ( _cmFtFile_t * ) h . h ;
}
_cmFtLabel_t * _cmFtIdToLabelPtr ( unsigned id )
{
unsigned i = 0 ;
for ( i = 0 ; _cmFtLabelArray [ i ] . id ! = kInvalidFtId ; + + i )
if ( _cmFtLabelArray [ i ] . id = = id )
return _cmFtLabelArray + i ;
assert ( 0 ) ;
return NULL ;
}
enum
{
kInfoSrFtId = kStructSrId ,
kParamSrFtId ,
kSkipSrFtId ,
kAttrSrFtId ,
kStatSrFtId ,
kHdrSrFtId ,
kSkipVSrFtId = kSkipSrFtId + kArraySrFl ,
kAttrVSrFtId = kAttrSrFtId + kArraySrFl ,
kStatVSrFtId = kStatSrFtId + kArraySrFl
} ;
cmFtRC_t _cmFtFormatFileHdr ( _cmFt_t * p )
{
cmFtRC_t rc = kOkFtRC ;
cmSrH_t h = p - > srH ;
cmSrGetAndClearLastErrorCode ( h ) ;
if ( cmSrFmtReset ( h ) ! = kOkSrRC )
{
rc = _cmFtError ( kSerialFailFtRC , p , " Serializer format reset failed. " ) ;
goto errLabel ;
}
// cmFtSkip_t smpIdx smpCnt
cmSrDefFmt ( h , kSkipSrFtId , kUIntSrId , kUIntSrId , kInvalidSrId ) ;
// cmFtAttr_t featId vect cnt normFl
cmSrDefFmt ( h , kAttrSrFtId , kUIntSrId , kUIntSrId , kBoolSrId , kInvalidSrId ) ;
// cmFtParam_t
cmSrDefFmt ( h , kParamSrFtId ,
// audioFn featFn chIdx
kCharVSrId , kCharVSrId , kUIntSrId ,
// wndMs hopFact normAudFl cqMinPitch cqMaxPitch
kRealSrId , kUIntSrId , kBoolSrId , kUCharSrId , kUCharSrId ,
// cqBins minDb skipV attrV
kUIntSrId , kRealSrId , kSkipVSrFtId , kAttrVSrFtId , kInvalidSrId ) ;
// cmFtInfo_t
cmSrDefFmt ( h , kInfoSrFtId ,
// frmCnt srate fftSmpCnt hopSmpCnt binCnt skipFrmCnt floorFrmCnt param
kUIntSrId , kRealSrId , kUIntSrId , kUIntSrId , kUIntSrId , kUIntSrId , kUIntSrId , kParamSrFtId , kInvalidSrId ) ;
// cmFtSumm_t
cmSrDefFmt ( h , kStatSrFtId ,
// id cnt
kUIntSrId , kUIntSrId ,
// raw minV maxV avgV std-dev
kRealVSrId , kRealVSrId , kRealVSrId , kRealVSrId ,
// raw min max
kRealSrId , kRealSrId ,
// norm minV maxV avgV std-dev
kRealVSrId , kRealVSrId , kRealVSrId , kRealVSrId ,
// raw min max
kRealSrId , kRealSrId , kInvalidSrId ) ;
// master header record info stat array
cmSrDefFmt ( h , kHdrSrFtId , kInfoSrFtId , kStatVSrFtId , kInvalidSrId ) ;
if ( cmSrLastErrorCode ( h ) ! = kOkSrRC )
rc = _cmFtError ( kSerialFailFtRC , p , " Serializer formatting failed. " ) ;
errLabel :
return rc ;
}
cmFtRC_t _cmFtSerializeFileHdr ( _cmFt_t * p , cmFtInfo_t * f , cmFtParam_t * pp , cmFtSumm_t * summArray , void * * bufPtrPtr , unsigned * bufByteCntPtr )
{
cmFtRC_t rc = kOkFtRC ;
cmSrH_t h = p - > srH ;
unsigned i ;
cmSrWrReset ( h ) ;
cmSrWrStructBegin ( h , kHdrSrFtId ) ;
// info record
cmSrWrStruct ( h , kInfoSrFtId , 1 ) ;
cmSrWrStructBegin ( h , kInfoSrFtId ) ;
cmSrWrUInt ( h , f - > frmCnt ) ;
cmSrWrReal ( h , f - > srate ) ;
cmSrWrUInt ( h , f - > fftSmpCnt ) ;
cmSrWrUInt ( h , f - > hopSmpCnt ) ;
cmSrWrUInt ( h , f - > binCnt ) ;
cmSrWrUInt ( h , f - > skipFrmCnt ) ;
cmSrWrUInt ( h , f - > floorFrmCnt ) ;
// param recd
cmSrWrStruct ( h , kParamSrFtId , 1 ) ;
cmSrWrStructBegin ( h , kParamSrFtId ) ;
cmSrWrCharV ( h , pp - > audioFn , strlen ( pp - > audioFn ) + 1 ) ;
cmSrWrCharV ( h , pp - > featFn , strlen ( pp - > featFn ) + 1 ) ;
cmSrWrUInt ( h , pp - > chIdx ) ;
cmSrWrReal ( h , pp - > wndMs ) ;
cmSrWrUInt ( h , pp - > hopFact ) ;
cmSrWrBool ( h , pp - > normAudioFl ) ;
cmSrWrUChar ( h , pp - > constQMinPitch ) ;
cmSrWrUChar ( h , pp - > constQMaxPitch ) ;
cmSrWrUInt ( h , pp - > constQBinsPerOctave ) ;
cmSrWrReal ( h , pp - > minDb ) ;
// skip array
cmSrWrStruct ( h , kSkipSrFtId , pp - > skipCnt ) ;
for ( i = 0 ; i < pp - > skipCnt ; + + i )
{
cmSrWrStructBegin ( h , kSkipSrFtId ) ;
cmSrWrUInt ( h , pp - > skipArray [ i ] . smpIdx ) ;
cmSrWrUInt ( h , pp - > skipArray [ i ] . smpCnt ) ;
cmSrWrStructEnd ( h ) ;
}
// attr array
cmSrWrStruct ( h , kAttrSrFtId , pp - > attrCnt ) ;
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
cmSrWrStructBegin ( h , kAttrSrFtId ) ;
cmSrWrUInt ( h , pp - > attrArray [ i ] . id ) ;
cmSrWrUInt ( h , pp - > attrArray [ i ] . cnt ) ;
cmSrWrBool ( h , pp - > attrArray [ i ] . normFl ) ;
cmSrWrStructEnd ( h ) ;
}
cmSrWrStructEnd ( h ) ; // end param
cmSrWrStructEnd ( h ) ; // end info
// write the status array
cmSrWrStruct ( h , kStatSrFtId , pp - > attrCnt ) ;
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
assert ( summArray [ i ] . id = = pp - > attrArray [ i ] . id ) ;
cmSrWrStructBegin ( h , kStatSrFtId ) ;
cmSrWrUInt ( h , summArray [ i ] . id ) ;
cmSrWrUInt ( h , summArray [ i ] . cnt ) ;
cmSrWrRealV ( h , summArray [ i ] . rawMinV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrRealV ( h , summArray [ i ] . rawMaxV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrRealV ( h , summArray [ i ] . rawAvgV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrRealV ( h , summArray [ i ] . rawSdvV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrReal ( h , summArray [ i ] . rawMin ) ;
cmSrWrReal ( h , summArray [ i ] . rawMax ) ;
cmSrWrRealV ( h , summArray [ i ] . normMinV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrRealV ( h , summArray [ i ] . normMaxV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrRealV ( h , summArray [ i ] . normAvgV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrRealV ( h , summArray [ i ] . normSdvV , pp - > attrArray [ i ] . cnt ) ;
cmSrWrReal ( h , summArray [ i ] . normMin ) ;
cmSrWrReal ( h , summArray [ i ] . normMax ) ;
cmSrWrStructEnd ( h ) ;
}
if ( cmSrLastErrorCode ( h ) ! = kOkSrRC )
{
rc = _cmFtError ( kSerialFailFtRC , p , " Header serialization failed. " ) ;
goto errLabel ;
}
if ( ( * bufPtrPtr = cmSrWrAllocBuf ( h , bufByteCntPtr ) ) = = NULL )
{
rc = _cmFtError ( kSerialFailFtRC , p , " Header serializer failed on write buffer allocation. " ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
cmFtRC_t _cmDeserializeFileHdr ( _cmFt_t * p , _cmFtFile_t * fp , void * buf , unsigned bufByteCnt )
{
cmFtRC_t rc = kOkFtRC ;
cmSrH_t h = p - > srH ;
unsigned n , i ;
cmFtInfo_t * f = & fp - > info ;
cmFtParam_t * pp = & fp - > info . param ;
// do endian swap
if ( cmSrRdProcessBuffer ( h , buf , bufByteCnt ) ! = kOkSrRC )
{
rc = _cmFtError ( kSerialFailFtRC , p , " Deserializatoin buffer pre-process failed. " ) ;
goto errLabel ;
}
// duplciate the buffer - this will allow us to use memory in the buffer to hold header objects.
fp - > hdrBuf = cmMemResize ( char , fp - > hdrBuf , bufByteCnt ) ;
memcpy ( fp - > hdrBuf , buf , bufByteCnt ) ;
// setup the serializer reader
if ( cmSrRdSetup ( h , fp - > hdrBuf , bufByteCnt ) ! = kOkSrRC )
{
rc = _cmFtError ( kSerialFailFtRC , p , " Deserialization buffer setup failed. " ) ;
goto errLabel ;
}
cmSrRdStructBegin ( h , kHdrSrFtId ) ;
// info record
cmSrReadStruct ( h , kInfoSrFtId , & n ) ; assert ( n = = 1 ) ;
cmSrRdStructBegin ( h , kInfoSrFtId ) ;
cmSrReadUInt ( h , & f - > frmCnt ) ;
cmSrReadReal ( h , & f - > srate ) ;
cmSrReadUInt ( h , & f - > fftSmpCnt ) ;
cmSrReadUInt ( h , & f - > hopSmpCnt ) ;
cmSrReadUInt ( h , & f - > binCnt ) ;
cmSrReadUInt ( h , & f - > skipFrmCnt ) ;
cmSrReadUInt ( h , & f - > floorFrmCnt ) ;
// param recd
cmSrReadStruct ( h , kParamSrFtId , & n ) ; assert ( n = = 1 ) ;
cmSrRdStructBegin ( h , kParamSrFtId ) ;
cmSrReadCharCV ( h , & pp - > audioFn , & n ) ;
cmSrReadCharCV ( h , & pp - > featFn , & n ) ;
cmSrReadUInt ( h , & pp - > chIdx ) ;
cmSrReadReal ( h , & pp - > wndMs ) ;
cmSrReadUInt ( h , & pp - > hopFact ) ;
cmSrReadBool ( h , & pp - > normAudioFl ) ;
cmSrReadUChar ( h , & pp - > constQMinPitch ) ;
cmSrReadUChar ( h , & pp - > constQMaxPitch ) ;
cmSrReadUInt ( h , & pp - > constQBinsPerOctave ) ;
cmSrReadReal ( h , & pp - > minDb ) ;
// skip array
cmSrReadStruct ( h , kSkipSrFtId , & pp - > skipCnt ) ;
pp - > skipArray = cmMemResizeZ ( cmFtSkip_t , pp - > skipArray , pp - > skipCnt ) ;
for ( i = 0 ; i < pp - > skipCnt ; + + i )
{
cmSrRdStructBegin ( h , kSkipSrFtId ) ;
cmSrReadUInt ( h , & pp - > skipArray [ i ] . smpIdx ) ;
cmSrReadUInt ( h , & pp - > skipArray [ i ] . smpCnt ) ;
cmSrRdStructEnd ( h ) ;
}
// attr array
cmSrReadStruct ( h , kAttrSrFtId , & pp - > attrCnt ) ;
pp - > attrArray = cmMemResizeZ ( cmFtAttr_t , pp - > attrArray , pp - > attrCnt ) ;
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
cmSrRdStructBegin ( h , kAttrSrFtId ) ;
cmSrReadUInt ( h , & pp - > attrArray [ i ] . id ) ;
cmSrReadUInt ( h , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadBool ( h , & pp - > attrArray [ i ] . normFl ) ;
cmSrRdStructEnd ( h ) ;
}
cmSrRdStructEnd ( h ) ; // end param
cmSrRdStructEnd ( h ) ; // end info
// read the status array
cmSrReadStruct ( h , kStatSrFtId , & n ) ;
assert ( n = = pp - > attrCnt ) ;
fp - > info . summArray = cmMemResizeZ ( cmFtSumm_t , fp - > info . summArray , pp - > attrCnt ) ;
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
cmSrRdStructBegin ( h , kStatSrFtId ) ;
cmSrReadUInt ( h , & fp - > info . summArray [ i ] . id ) ;
assert ( fp - > info . summArray [ i ] . id = = pp - > attrArray [ i ] . id ) ;
cmSrReadUInt ( h , & fp - > info . summArray [ i ] . cnt ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . rawMinV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . rawMaxV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . rawAvgV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . rawSdvV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadReal ( h , & fp - > info . summArray [ i ] . rawMin ) ;
cmSrReadReal ( h , & fp - > info . summArray [ i ] . rawMax ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . normMinV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . normMaxV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . normAvgV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadRealV ( h , & fp - > info . summArray [ i ] . normSdvV , & pp - > attrArray [ i ] . cnt ) ;
cmSrReadReal ( h , & fp - > info . summArray [ i ] . normMin ) ;
cmSrReadReal ( h , & fp - > info . summArray [ i ] . normMax ) ;
cmSrRdStructEnd ( h ) ;
}
if ( cmSrLastErrorCode ( h ) ! = kOkSrRC )
{
rc = _cmFtError ( kSerialFailFtRC , p , " Deserialization failed. " ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
unsigned cmFtFeatLabelToId ( const char * label )
{
unsigned i = 0 ;
for ( i = 0 ; _cmFtLabelArray [ i ] . id ! = kInvalidFtId ; + + i )
if ( strcmp ( label , _cmFtLabelArray [ i ] . label ) = = 0 )
return _cmFtLabelArray [ i ] . id ;
return kInvalidFtId ;
}
const char * cmFtFeatIdToLabel ( unsigned id )
{
unsigned i = 0 ;
for ( i = 0 ; _cmFtLabelArray [ i ] . id ! = kInvalidFtId ; + + i )
if ( _cmFtLabelArray [ i ] . id = = id )
return _cmFtLabelArray [ i ] . label ;
return NULL ;
}
cmFtRC_t cmFtInitialize ( cmFtH_t * hp , cmCtx_t * ctx )
{
cmFtRC_t rc ;
if ( ( rc = cmFtFinalize ( hp ) ) ! = kOkFtRC )
return rc ;
_cmFt_t * p = cmMemAllocZ ( _cmFt_t , 1 ) ;
cmErrSetup ( & p - > err , & ctx - > rpt , " Feature file " ) ;
p - > ctx = * ctx ;
p - > jsH = cmJsonNullHandle ;
p - > progParamIdx = cmInvalidIdx ;
p - > progPassIdx = 0 ;
p - > progSmpIdx = 0 ;
p - > progSmpCnt = 0 ;
// initialize the serializer
if ( cmSrAlloc ( & p - > srH , ctx ) ! = kOkSrRC )
{
rc = _cmFtError ( kSerialFailFtRC , p , " The serializer allocation failed. " ) ;
goto errLabel ;
}
// setup the serializer format
if ( ( rc = _cmFtFormatFileHdr ( p ) ) ! = kOkFtRC )
goto errLabel ;
// create the proc context object
if ( ( p - > ctxPtr = cmCtxAlloc ( NULL , & p - > ctx . rpt , cmLHeapNullHandle , cmSymTblNullHandle ) ) = = NULL )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The ctx compoenent allocation failed. " ) ;
goto errLabel ;
}
// create the audio file reader
if ( ( p - > afRdPtr = cmAudioFileRdAlloc ( p - > ctxPtr , NULL , 0 , NULL , cmInvalidIdx , 0 , cmInvalidIdx ) ) = = NULL )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The audio file reader allocation failed. " ) ;
goto errLabel ;
}
// create the phase vocoder
if ( ( p - > pvocPtr = cmPvAnlAlloc ( p - > ctxPtr , NULL , 0 , 0 , 0 , 0 , 0 ) ) = = NULL )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The phase vocoder allocation failed. " ) ;
goto errLabel ;
}
// create the BFCC transformer
if ( ( p - > bfccPtr = cmBfccAlloc ( p - > ctxPtr , NULL , 0 , 0 , 0 ) ) = = NULL )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The BFCC generator allocation failed. " ) ;
goto errLabel ;
}
// create the MFCC generator
if ( ( p - > mfccPtr = cmMfccAlloc ( p - > ctxPtr , NULL , 0 , 0 , 0 , 0 ) ) = = NULL )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The MFCC generator allocation failed. " ) ;
goto errLabel ;
}
// create the Cepstrum transformer
if ( ( p - > cepsPtr = cmCepsAlloc ( p - > ctxPtr , NULL , 0 , 0 ) ) = = NULL )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The Cepstrum generator allocation failed. " ) ;
goto errLabel ;
}
// create the Constant Q generator
if ( ( p - > constqPtr = cmConstQAlloc ( p - > ctxPtr , NULL , 0 , 0 , 0 , 0 , 0 ) ) = = NULL )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The Constant-Q generator allocation failed. " ) ;
goto errLabel ;
}
hp - > h = p ;
errLabel :
return rc ;
}
cmFtRC_t cmFtFinalize ( cmFtH_t * hp )
{
cmFtRC_t rc = kOkFsRC ;
unsigned i ;
assert ( hp ! = NULL ) ;
if ( hp - > h = = NULL )
return kOkFsRC ;
_cmFt_t * p = _cmFtHandleToPtr ( * hp ) ;
for ( i = 0 ; i < p - > paramCnt ; + + i )
cmMemPtrFree ( & p - > paramArray [ i ] . skipArray ) ;
cmMemPtrFree ( & p - > attrArray ) ;
p - > attrCnt = 0 ;
cmMemPtrFree ( & p - > paramArray ) ;
p - > paramCnt = 0 ;
if ( cmConstQFree ( & p - > constqPtr ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " Constant-Q generator free failed. " ) ;
goto errLabel ;
}
if ( cmCepsFree ( & p - > cepsPtr ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " Cepstrum generator free failed. " ) ;
goto errLabel ;
}
if ( cmMfccFree ( & p - > mfccPtr ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " MFCC generator free failed. " ) ;
goto errLabel ;
}
if ( cmBfccFree ( & p - > bfccPtr ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " BFCC generator free failed. " ) ;
goto errLabel ;
}
if ( cmPvAnlFree ( & p - > pvocPtr ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " Phase voocoder free failed. " ) ;
goto errLabel ;
}
if ( cmAudioFileRdFree ( & p - > afRdPtr ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " Audio file reader failed. " ) ;
goto errLabel ;
}
if ( cmCtxFree ( & p - > ctxPtr ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " Context proc failed. " ) ;
goto errLabel ;
}
if ( cmJsonFinalize ( & p - > jsH ) ! = kOkJsRC )
{
rc = _cmFtError ( kJsonFailFtRC , p , " The JSON system object finalization failed. " ) ;
goto errLabel ;
}
if ( cmSrFree ( & p - > srH ) ! = kOkSrRC )
{
rc = _cmFtError ( kSerialFailFtRC , p , " The serializer free failed. " ) ;
goto errLabel ;
}
cmMemPtrFree ( & p ) ;
hp - > h = NULL ;
errLabel :
return rc ;
}
bool cmFtIsValid ( cmFtH_t h )
{ return h . h ! = NULL ; }
cmFtRC_t cmFtParse ( cmFtH_t h , const char * cfgFn )
{
cmFtRC_t rc = kOkFtRC ;
cmJsRC_t jsRC = kOkJsRC ;
cmJsonNode_t * rootPtr = NULL ;
const char * errLabelPtr = NULL ;
const char * outDir = NULL ;
cmReal_t wndMs = 0 ;
unsigned hopFact = 0 ;
bool normAudioFl = false ;
const char * constQMinPitchStr = NULL ;
const char * constQMaxPitchStr = NULL ;
unsigned constQBinsPerOctave = 0 ;
cmMidiByte_t constQMinPitch = 0 ;
cmMidiByte_t constQMaxPitch = 0 ;
cmReal_t minDb = 0 ;
cmReal_t floorThreshDb = 0 ;
cmJsonNode_t * featArrayNodePtr = NULL ;
cmJsonNode_t * audioFnArrayNodePtr = NULL ;
_cmFt_t * p = _cmFtHandleToPtr ( h ) ;
unsigned i , j ;
assert ( cfgFn ! = NULL ) ;
// parse file
if ( cmJsonInitializeFromFile ( & p - > jsH , cfgFn , & p - > ctx ) ! = kOkJsRC )
{
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. file parse failed on: '%s' " , cfgFn ) ;
goto errLabel ;
}
// get the json cfg root
if ( ( rootPtr = cmJsonRoot ( p - > jsH ) ) = = NULL )
{
rc = _cmFtError ( kCfgParseFailFtRC , p , " The cfg. file '%s' appears to be empty. " , cfgFn ) ;
goto errLabel ;
}
// read the cfg file header
if ( ( jsRC = cmJsonMemberValues ( rootPtr , & errLabelPtr ,
" outDir " , kStringTId , & outDir ,
" wndMs " , kRealTId , & wndMs ,
" hopFact " , kIntTId , & hopFact ,
" normAudioFl " , kTrueTId , & normAudioFl ,
" constQMinPitch " , kStringTId , & constQMinPitchStr ,
" constQMaxPitch " , kStringTId , & constQMaxPitchStr ,
" constQBinsPerOctave " , kIntTId , & constQBinsPerOctave ,
" minDb " , kRealTId , & minDb ,
" floorThreshDb " , kRealTId , & floorThreshDb ,
" featArray " , kArrayTId , & featArrayNodePtr ,
" audioFnArray " , kArrayTId , & audioFnArrayNodePtr ,
NULL ) ) ! = kOkJsRC )
{
if ( jsRC = = kNodeNotFoundJsRC )
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. field not found:'%s' in file:'%s'. " , cmStringNullGuard ( errLabelPtr ) , cmStringNullGuard ( cfgFn ) ) ;
else
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. header parse failed '%s'. " , cmStringNullGuard ( cfgFn ) ) ;
goto errLabel ;
}
// convert the min const-q sci pitch string to a midi pitch value
if ( ( constQMinPitch = cmSciPitchToMidi ( constQMinPitchStr ) ) = = kInvalidMidiPitch )
{
rc = _cmFtError ( kCfgParseFailFtRC , p , " The const-Q min. pitch ('%s') is invalid. " , cmStringNullGuard ( constQMinPitchStr ) ) ;
goto errLabel ;
}
// convert the max const-q sci pitch string to a midi pitch value
if ( ( constQMaxPitch = cmSciPitchToMidi ( constQMaxPitchStr ) ) = = kInvalidMidiPitch )
{
rc = _cmFtError ( kCfgParseFailFtRC , p , " The const-Q max. pitch ('%s') is invalid. " , cmStringNullGuard ( constQMaxPitchStr ) ) ;
goto errLabel ;
}
unsigned parseAttrCnt = cmJsonChildCount ( featArrayNodePtr ) ;
p - > attrArray = cmMemAllocZ ( cmFtAttr_t , parseAttrCnt ) ;
// read the attribute array
for ( i = 0 , j = 0 ; i < parseAttrCnt ; + + i )
{
const char * featLabel ;
// set default values
p - > attrArray [ j ] . cnt = 0 ;
p - > attrArray [ j ] . enableFl = true ;
if ( ( jsRC = cmJsonMemberValues ( cmJsonArrayElement ( featArrayNodePtr , i ) , & errLabelPtr ,
" feat " , kStringTId , & featLabel ,
" cnt " , kIntTId | kOptArgJsFl , & p - > attrArray [ j ] . cnt ,
" normFl " , kTrueTId , & p - > attrArray [ j ] . normFl ,
" enableFl " , kTrueTId | kOptArgJsFl , & p - > attrArray [ j ] . enableFl ,
NULL ) ) ! = kOkJsRC )
{
if ( jsRC = = kNodeNotFoundJsRC )
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. feature attribute field:'%s' not found at index %i in file:'%s'. " , cmStringNullGuard ( errLabelPtr ) , i , cmStringNullGuard ( cfgFn ) ) ;
else
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. feature attribute parse failed at index %i in '%s'. " , i , cmStringNullGuard ( cfgFn ) ) ;
goto errLabel ;
}
if ( p - > attrArray [ j ] . enableFl )
{
// convert the feature label to an id
if ( ( p - > attrArray [ j ] . id = cmFtFeatLabelToId ( featLabel ) ) = = kInvalidFtId )
{
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. feature '%s' was not found at featArray index %i in '%s'. " , featLabel , i , cmStringNullGuard ( cfgFn ) ) ;
goto errLabel ;
}
+ + j ;
}
}
p - > attrCnt = j ;
p - > paramCnt = cmJsonChildCount ( audioFnArrayNodePtr ) ;
p - > paramArray = cmMemAllocZ ( cmFtParam_t , p - > paramCnt ) ;
// read the audio file array
for ( i = 0 ; i < p - > paramCnt ; + + i )
{
cmJsonNode_t * skipArrayNodePtr = NULL ;
// read the audio file read
if ( ( jsRC = cmJsonMemberValues ( cmJsonArrayElement ( audioFnArrayNodePtr , i ) , & errLabelPtr ,
" audioFn " , kStringTId , & p - > paramArray [ i ] . audioFn ,
" featFn " , kStringTId , & p - > paramArray [ i ] . featFn ,
" skipArray " , kArrayTId | kOptArgJsFl , & skipArrayNodePtr ,
" chIdx " , kIntTId , & p - > paramArray [ i ] . chIdx ,
NULL ) ) ! = kOkJsRC )
{
if ( jsRC = = kNodeNotFoundJsRC )
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. audio file field :'%s' not found at index %i in file:'%s'. " , cmStringNullGuard ( errLabelPtr ) , i , cmStringNullGuard ( cfgFn ) ) ;
else
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. audio file parse failed at index %i in '%s'. " , i , cmStringNullGuard ( cfgFn ) ) ;
goto errLabel ;
}
p - > paramArray [ i ] . wndMs = wndMs ;
p - > paramArray [ i ] . hopFact = hopFact ;
p - > paramArray [ i ] . normAudioFl = normAudioFl ;
p - > paramArray [ i ] . constQBinsPerOctave = constQBinsPerOctave ;
p - > paramArray [ i ] . constQMinPitch = constQMinPitch ;
p - > paramArray [ i ] . constQMaxPitch = constQMaxPitch ;
p - > paramArray [ i ] . minDb = minDb ;
p - > paramArray [ i ] . floorThreshDb = floorThreshDb ;
p - > paramArray [ i ] . attrArray = p - > attrArray ;
p - > paramArray [ i ] . attrCnt = p - > attrCnt ;
p - > paramArray [ i ] . skipCnt = skipArrayNodePtr = = NULL ? 0 : cmJsonChildCount ( skipArrayNodePtr ) ;
p - > paramArray [ i ] . skipArray = skipArrayNodePtr = = NULL ? NULL : cmMemAllocZ ( cmFtSkip_t , p - > paramArray [ i ] . skipCnt ) ;
// read the skip array in the audio file recd
for ( j = 0 ; j < p - > paramArray [ i ] . skipCnt ; + + j )
{
if ( ( jsRC = cmJsonMemberValues ( cmJsonArrayElement ( skipArrayNodePtr , j ) , & errLabelPtr ,
" smpIdx " , kIntTId , & p - > paramArray [ i ] . skipArray [ j ] . smpIdx ,
" smpCnt " , kIntTId , & p - > paramArray [ i ] . skipArray [ j ] . smpCnt ,
NULL ) ) ! = kOkJsRC )
{
if ( jsRC = = kNodeNotFoundJsRC )
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. audio file skip field '%s' not found at index %i in file:'%s'. " , cmStringNullGuard ( errLabelPtr ) , j , cmStringNullGuard ( cfgFn ) ) ;
else
rc = _cmFtError ( kCfgParseFailFtRC , p , " Cfg. audio file skip parse failed at index %i in '%s'. " , j , cmStringNullGuard ( cfgFn ) ) ;
goto errLabel ;
}
}
// if the audio file does not exist
if ( cmFsIsFile ( p - > paramArray [ i ] . audioFn ) = = false )
{
rc = _cmFtError ( kFileNotFoundFtRC , p , " The audio file '%s' was not found. " , p - > paramArray [ i ] . audioFn ) ;
goto errLabel ;
}
// form the feature file name for this file
if ( ( p - > paramArray [ i ] . featFn = cmFsMakeFn ( outDir , p - > paramArray [ i ] . featFn , NULL , NULL ) ) = = NULL )
{
rc = _cmFtError ( kFileSysFailFtRC , p , " The attempt to create the feature file name for '%s' failed. " , cmStringNullGuard ( p - > paramArray [ i ] . featFn ) ) ;
goto errLabel ;
}
}
// if the output directory does not exist then create it
if ( cmFsIsDir ( outDir ) = = false )
if ( cmFsMkDir ( outDir ) ! = kOkFsRC )
{
rc = _cmFtError ( kDirCreateFailFtRC , p , " The attempt to create the output directory '%s' failed. " , outDir ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
bool _cmFtZeroSkipSamples ( const cmFtParam_t * pp , cmSample_t * v , unsigned vn , unsigned begSmpIdx )
{
unsigned endSmpIdx = begSmpIdx + vn - 1 ;
bool retFl = false ;
unsigned i = 0 ;
const cmFtSkip_t * sp = pp - > skipArray ;
// for each skipArray[] record
for ( i = 0 ; i < pp - > skipCnt ; + + sp , + + i )
if ( sp - > smpCnt ! = 0 )
{
unsigned bi = 0 ;
unsigned ei = vn - 1 ;
unsigned sp_endIdx ;
// if sp->smpCnt is negative then skip to end of file
if ( sp - > smpCnt = = - 1 )
sp_endIdx = endSmpIdx ;
else
sp_endIdx = sp - > smpIdx + sp - > smpCnt - 1 ;
// begSmpIdx:endSmpIdx indicate the index range of v[]
// sp->smpIdx:sp_endIdx indicate the skip index range
// if the skip range is entirely before or after v[]
if ( sp_endIdx < begSmpIdx | | sp - > smpIdx > endSmpIdx )
continue ;
// if sp->smpIdx is inside v[]
if ( sp - > smpIdx > begSmpIdx )
bi = sp - > smpIdx - begSmpIdx ;
// if sp_endIdx is inside v[]
if ( sp_endIdx < endSmpIdx )
{
assert ( endSmpIdx - sp_endIdx < = ei ) ;
ei - = endSmpIdx - sp_endIdx ;
}
assert ( bi < = ei ) ;
assert ( bi < vn & & ei < vn ) ;
// zero the samples which are inside the skip range
cmVOS_Zero ( v + bi , ( ei - bi ) + 1 ) ;
retFl = true ;
}
return retFl ;
}
cmFtRC_t _cmFtProcInit ( _cmFt_t * p , cmFtInfo_t * f , cmFtParam_t * pp , _cmFtAnl_t * anlArray )
{
cmFtRC_t rc = kOkFtRC ;
unsigned i ;
// initialize the phase vocoder
if ( cmPvAnlInit ( p - > pvocPtr , f - > hopSmpCnt , f - > srate , f - > fftSmpCnt , f - > hopSmpCnt , kNoCalcHzPvaFl ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The phase vocoder initialization failed. " ) ;
goto errLabel ;
}
assert ( f - > binCnt = = p - > pvocPtr - > binCnt ) ;
cmReal_t binHz = f - > srate / f - > fftSmpCnt ;
// initialize each requested feature extractor
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
_cmFtAnl_t * a = anlArray + i ;
assert ( a - > lp ! = NULL ) ;
switch ( a - > ap - > id )
{
case kAmplFtId :
case kDbAmplFtId :
case kPowFtId :
case kDbPowFtId :
case kPhaseFtId :
if ( a - > ap - > cnt > f - > binCnt )
{
rc = _cmFtError ( kParamRangeFtRC , p , " The '%s' cnt value: %i must be less than the bin count: %i. " , a - > lp - > label , a - > ap - > cnt , f - > binCnt + 1 ) ;
goto errLabel ;
}
if ( a - > ap - > cnt = = 0 )
a - > ap - > cnt = f - > binCnt ;
break ;
case kBfccFtId : // initialize the BFCC generator
if ( a - > ap - > cnt > kDefaultBarkBandCnt )
{
rc = _cmFtError ( kParamRangeFtRC , p , " The BFCC feature vector length (%i) must be less than (%i). " , a - > ap - > cnt , kDefaultBarkBandCnt + 1 ) ;
goto errLabel ;
}
if ( a - > ap - > cnt = = 0 )
a - > ap - > cnt = kDefaultBarkBandCnt ;
if ( cmBfccInit ( p - > bfccPtr , kDefaultBarkBandCnt , p - > pvocPtr - > binCnt , binHz ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The BFCC generator initialization failed. " ) ;
goto errLabel ;
}
break ;
case kMfccFtId : // initialize the MFCC generator
if ( a - > ap - > cnt > kDefaultMelBandCnt )
{
rc = _cmFtError ( kParamRangeFtRC , p , " The MFCC feature vector length (%i) must be less than (%i). " , a - > ap - > cnt , kDefaultMelBandCnt + 1 ) ;
goto errLabel ;
}
if ( a - > ap - > cnt = = 0 )
a - > ap - > cnt = kDefaultMelBandCnt ;
if ( cmMfccInit ( p - > mfccPtr , f - > srate , kDefaultMelBandCnt , a - > ap - > cnt , p - > pvocPtr - > binCnt ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The MFCC generator initialization failed. " ) ;
goto errLabel ;
}
break ;
case kCepsFtId : // initialize the cepstrum generator
if ( a - > ap - > cnt > f - > binCnt )
{
rc = _cmFtError ( kParamRangeFtRC , p , " The '%s' cnt value: %i must be less than the bin count: %i. " , a - > lp - > label , a - > ap - > cnt , f - > binCnt + 1 ) ;
goto errLabel ;
}
if ( a - > ap - > cnt = = 0 )
a - > ap - > cnt = f - > binCnt ;
if ( cmCepsInit ( p - > cepsPtr , p - > pvocPtr - > binCnt , a - > ap - > cnt ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The Cepstrum generator initialization failed. " ) ;
goto errLabel ;
}
break ;
case kConstQFtId : // initialize the constant Q generator
case kLogConstQFtId :
if ( cmConstQInit ( p - > constqPtr , f - > srate , pp - > constQMinPitch , pp - > constQMaxPitch , pp - > constQBinsPerOctave , kConstQThresh ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The constant-q generator initialization failed. " ) ;
goto errLabel ;
}
if ( a - > ap - > cnt > p - > constqPtr - > constQBinCnt )
{
rc = _cmFtError ( kParamRangeFtRC , p , " The '%s' cnt value: %i must be less than the bin count: %i. " , a - > lp - > label , a - > ap - > cnt , p - > constqPtr - > constQBinCnt + 1 ) ;
goto errLabel ;
}
if ( a - > ap - > cnt = = 0 )
a - > ap - > cnt = p - > constqPtr - > constQBinCnt ;
break ;
case kRmsFtId :
case kDbRmsFtId :
a - > ap - > cnt = 1 ; // scalars must have a cnt == 1
break ;
case kD1AmplFtId :
case kD1DbAmplFtId :
case kD1PowFtId :
case kD1DbPowFtId :
case kD1PhaseFtId :
case kD1BfccFtId :
case kD1MfccFtId :
case kD1CepsFtId :
case kD1ConstQFtId :
case kD1LogConstQFtId :
if ( a - > ap - > cnt = = 0 )
a - > ap - > cnt = a - > sp - > ap - > cnt ;
break ;
case kD1RmsFtId :
case kD1DbRmsFtId :
a - > ap - > cnt = 1 ;
break ;
default :
{ assert ( 0 ) ; }
} // end switch
// setup the feature label record and allocate the feature vector
if ( a - > ap - > cnt )
{
// 2==cvp and pvp + kStatRecdVectCnt==count of summary vectors
unsigned nn = a - > ap - > cnt * ( 2 + kStatRecdVectCnt ) ;
unsigned n = 0 ;
assert ( a - > v = = NULL ) ;
a - > v = cmMemAllocZ ( cmReal_t , nn ) ;
a - > cvp = a - > v + n ; n + = a - > ap - > cnt ;
a - > pvp = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > cnt = a - > ap - > cnt ;
a - > sr - > rawMinV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > rawMaxV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > rawAvgV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > rawSdvV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > rawMin = cmReal_MAX ;
a - > sr - > rawMax = - cmReal_MAX ;
cmVOR_Fill ( a - > sr - > rawMinV , a - > ap - > cnt , cmReal_MAX ) ;
cmVOR_Fill ( a - > sr - > rawMaxV , a - > ap - > cnt , - cmReal_MAX ) ;
a - > sr - > normMinV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > normMaxV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > normAvgV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > normSdvV = a - > v + n ; n + = a - > ap - > cnt ;
a - > sr - > normMin = cmReal_MAX ;
a - > sr - > normMax = - cmReal_MAX ;
cmVOR_Fill ( a - > sr - > normMinV , a - > ap - > cnt , cmReal_MAX ) ;
cmVOR_Fill ( a - > sr - > normMaxV , a - > ap - > cnt , - cmReal_MAX ) ;
assert ( n = = nn ) ;
}
if ( a - > sp ! = NULL )
{
if ( a - > sp - > ap - > cnt > a - > ap - > cnt )
{
rc = _cmFtError ( kParamRangeFtRC , p , " The feature element count '%i' for '%s' is greater than the source vector '%s' '%i'. " , a - > ap - > cnt , a - > lp - > label , a - > sp - > lp - > label , a - > sp - > ap - > cnt ) ;
goto errLabel ;
}
}
} // end for
errLabel :
return rc ;
}
cmFtRC_t _cmFtProcExec ( _cmFt_t * p , cmFtInfo_t * f , cmFtParam_t * pp , cmFrameFileH_t ffH , _cmFtAnl_t * anlArray , const cmSample_t * audV )
{
cmFtRC_t rc = kOkFtRC ;
unsigned i ;
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
_cmFtAnl_t * a = anlArray + i ;
// swap current and previous pointer
cmReal_t * tp = a - > cvp ;
a - > cvp = a - > pvp ;
a - > pvp = tp ;
switch ( a - > lp - > id )
{
case kAmplFtId :
cmVOR_Copy ( a - > cvp , a - > ap - > cnt , p - > pvocPtr - > magV ) ;
break ;
case kDbAmplFtId :
cmVOR_AmplToDbVV ( a - > cvp , a - > ap - > cnt , p - > pvocPtr - > magV , pp - > minDb ) ;
break ;
case kPowFtId :
cmVOR_PowVVS ( a - > cvp , a - > ap - > cnt , p - > pvocPtr - > magV , 2.0 ) ;
break ;
case kDbPowFtId :
cmVOR_PowToDbVV ( a - > cvp , a - > ap - > cnt , a - > sp - > cvp , pp - > minDb ) ;
break ;
case kPhaseFtId :
cmVOR_Copy ( a - > cvp , a - > ap - > cnt , p - > pvocPtr - > phsV ) ;
break ;
case kBfccFtId :
{
cmBfccExec ( p - > bfccPtr , p - > pvocPtr - > magV , p - > pvocPtr - > binCnt ) ;
cmVOR_Copy ( a - > cvp , a - > ap - > cnt , p - > bfccPtr - > outV ) ;
}
break ;
case kMfccFtId :
{
cmMfccExecAmplitude ( p - > mfccPtr , p - > pvocPtr - > magV , p - > pvocPtr - > binCnt ) ;
cmVOR_Copy ( a - > cvp , a - > ap - > cnt , p - > mfccPtr - > outV ) ;
}
break ;
case kCepsFtId :
{
cmCepsExec ( p - > cepsPtr , p - > pvocPtr - > magV , p - > pvocPtr - > phsV , p - > pvocPtr - > binCnt ) ;
cmVOR_Copy ( a - > cvp , a - > ap - > cnt , p - > cepsPtr - > outV ) ;
}
break ;
case kConstQFtId :
{
// convert from float complex to double complex
cmComplexR_t tmp0 [ p - > pvocPtr - > binCnt ] ;
unsigned j ;
for ( j = 0 ; j < p - > pvocPtr - > binCnt ; + + j )
tmp0 [ j ] = p - > pvocPtr - > ft . complexV [ j ] ;
cmConstQExec ( p - > constqPtr , tmp0 , p - > pvocPtr - > binCnt ) ;
cmVOR_Copy ( a - > cvp , a - > ap - > cnt , p - > constqPtr - > magV ) ;
}
break ;
case kLogConstQFtId :
cmVOR_LogV ( a - > cvp , a - > ap - > cnt , p - > constqPtr - > magV ) ;
break ;
case kRmsFtId :
a - > cvp [ 0 ] = cmVOS_RMS ( audV , p - > afRdPtr - > outN , p - > afRdPtr - > outN ) ;
break ;
case kDbRmsFtId :
cmVOR_AmplToDbVV ( a - > cvp , 1 , a - > sp - > cvp , pp - > minDb ) ;
break ;
case kD1AmplFtId :
case kD1DbAmplFtId :
case kD1PowFtId :
case kD1DbPowFtId :
case kD1PhaseFtId :
case kD1BfccFtId :
case kD1MfccFtId :
case kD1CepsFtId :
case kD1ConstQFtId :
case kD1LogConstQFtId :
case kD1RmsFtId :
case kD1DbRmsFtId :
cmVOR_SubVVV ( a - > cvp , a - > ap - > cnt , a - > sp - > pvp , a - > sp - > cvp ) ;
break ;
default :
assert ( 0 ) ;
break ;
} // end switch
if ( cmFrameFileWriteMtxReal ( ffH , a - > lp - > ffMtxId , a - > lp - > ffUnitsId , a - > cvp , a - > ap - > cnt , 1 ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameWriteFailFtRC , p , " Matrix write failed (feature:%s size:%i). " , a - > lp - > label , a - > ap - > cnt ) ;
goto errLabel ;
}
}
errLabel :
return rc ;
}
unsigned _cmFtWriteField ( char * buf , unsigned bufByteCnt , unsigned bufIdx , const void * s , unsigned srcByteCnt )
{
assert ( bufIdx + srcByteCnt < = bufByteCnt ) ;
memcpy ( buf + bufIdx , s , srcByteCnt ) ;
return bufIdx + srcByteCnt ;
}
cmFtRC_t _cmFtWriteFileHdr ( _cmFt_t * p , cmFtInfo_t * f , cmFtParam_t * pp , cmFrameFileH_t ffH , cmFtSumm_t * summArray , bool updateFl )
{
cmFtRC_t rc = kOkFtRC ;
void * buf ;
unsigned bufByteCnt ;
// serialize the file header
if ( ( rc = _cmFtSerializeFileHdr ( p , f , pp , summArray , & buf , & bufByteCnt ) ) ! = kOkFtRC )
goto errLabel ;
if ( updateFl )
{
const cmFfMtx_t * mp = NULL ;
void * hdrPtr = NULL ;
if ( ( hdrPtr = cmFrameFileMtxBlob ( ffH , kDataMId , kNoUnitsUId , & mp ) ) = = NULL )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file header read before update failed. " ) ;
goto errLabel ;
}
assert ( mp - > rowCnt = = bufByteCnt ) ;
memcpy ( hdrPtr , buf , bufByteCnt ) ;
}
else
{
if ( cmFrameFileWriteMtxBlob ( ffH , kDataMId , kNoUnitsUId , buf , bufByteCnt , 1 ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameWriteFailFtRC , p , " Header write failed. " ) ;
goto errLabel ;
}
}
errLabel :
return rc ;
}
// Interface to the _cmFtProcFile() user programmable process function.
// This function is called once per each feature vector in the feature file.
// v[fn] points to the feature file.
// Return true if the feature has been modified and should be written back to disk.
typedef bool ( * _cmFtProcFunc_t ) ( _cmFt_t * p , _cmFtAnl_t * a , cmReal_t * v , unsigned vn ) ;
// Iterate through each frame and each frame matrix call procFunc().
cmFtRC_t _cmFtProcFile ( _cmFt_t * p , cmFrameFileH_t ffH , cmFtParam_t * pp , _cmFtAnl_t * anlArray , _cmFtProcFunc_t procFunc )
{
cmFtRC_t rc = kOkFtRC ;
cmFfRC_t ffRC = kOkFfRC ;
unsigned i , j ;
+ + p - > progPassIdx ;
p - > progSmpIdx = 0 ;
p - > progSmpCnt = cmFrameFileDesc ( ffH ) - > frameCnt ;
// rewind the frame file
if ( cmFrameFileRewind ( ffH ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Normalize rewind failed on '%s'. " , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
// load the next data frame
for ( i = 0 ; ( ffRC = cmFrameFileFrameLoadNext ( ffH , kFrameTypeFtId , kFrameStreamFtId , NULL ) ) = = kOkFfRC ; + + i , + + p - > progSmpIdx )
{
bool updateFl = false ;
// for each feature matrix
for ( j = 0 ; j < pp - > attrCnt ; + + j )
{
unsigned dn ;
cmReal_t * dp ;
const cmFfMtx_t * mtxDescPtr = NULL ;
_cmFtAnl_t * a = anlArray + j ;
// get a pointer to the matrix data
if ( ( dp = cmFrameFileMtxReal ( ffH , a - > lp - > ffMtxId , a - > lp - > ffUnitsId , & mtxDescPtr ) ) = = NULL )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Data access failed during post processing on feature:'%s' in '%s'. " , a - > lp - > label , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
// get the lenth of the feature vector
dn = mtxDescPtr - > rowCnt * mtxDescPtr - > colCnt ;
// processes this feature
if ( procFunc ( p , a , dp , dn ) )
updateFl = true ;
}
// write the frame back to disk
if ( updateFl )
if ( cmFrameFileFrameUpdate ( ffH ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Post procssing failed on record index %i in '%s'. " , i , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
}
if ( ffRC ! = kEofFfRC & & ffRC ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Post processing iterationg failed on record index %i in '%s'. " , i , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
// Sum the feature vector into a->sr->rawAvg and track the global min/max value.
bool _cmFtProcRawMinMaxSum ( _cmFt_t * p , _cmFtAnl_t * a , cmReal_t * v , unsigned vn )
{
assert ( vn = = a - > ap - > cnt ) ;
cmVOR_AddVV ( a - > sr - > rawAvgV , vn , v ) ; // track vector sum for use in avg
cmVOR_MinVV ( a - > sr - > rawMinV , vn , v ) ; // track min/max per vector dim
cmVOR_MaxVV ( a - > sr - > rawMaxV , vn , v ) ;
a - > sr - > rawMin = cmMin ( a - > sr - > rawMin , cmVOR_Min ( v , vn , 1 ) ) ; // track global min/max
a - > sr - > rawMax = cmMax ( a - > sr - > rawMax , cmVOR_Max ( v , vn , 1 ) ) ;
return false ;
}
// Sum the the squared diff. between feature value and feature avg into rawSdvV[]
bool _cmFtProcRawStdDev ( _cmFt_t * p , _cmFtAnl_t * a , cmReal_t * v , unsigned vn )
{
cmReal_t t [ vn ] ;
assert ( vn = = a - > ap - > cnt ) ;
cmVOR_SubVVV ( t , a - > ap - > cnt , v , a - > sr - > rawAvgV ) ;
cmVOR_PowVS ( t , a - > ap - > cnt , 2.0 ) ;
cmVOR_AddVV ( a - > sr - > rawSdvV , a - > ap - > cnt , t ) ;
return false ;
}
bool _cmFtProcNormMinMaxSum ( _cmFt_t * p , _cmFtAnl_t * a , cmReal_t * v , unsigned vn )
{
assert ( a - > ap - > cnt = = vn ) ;
if ( a - > ap - > normFl = = false )
{
cmVOR_Zero ( a - > sr - > normMaxV , vn ) ;
cmVOR_Zero ( a - > sr - > normMinV , vn ) ;
a - > sr - > normMin = 0 ;
a - > sr - > normMax = 0 ;
}
else
{
if ( a - > lp - > bipolarFl )
{
// subtract mean and divide by std-dev
cmVOR_SubVV ( v , vn , a - > sr - > rawAvgV ) ;
cmVOR_DivVVZ ( v , vn , a - > sr - > rawSdvV ) ;
}
else
{
// scale feature into unit range based on file wide min/max
cmVOR_SubVS ( v , vn , a - > sr - > rawMin ) ;
if ( a - > sr - > rawMax - a - > sr - > rawMin > 0 )
cmVOR_DivVS ( v , vn , a - > sr - > rawMax - a - > sr - > rawMin ) ;
else
cmVOR_Zero ( v , vn ) ;
// convert to unit total energy (UTE)
// (this makes the vector sum to one (like a prob. distrib))
if ( vn > 1 )
{
cmReal_t sum = cmVOR_Sum ( v , vn ) ;
if ( sum > 0 )
cmVOR_DivVS ( v , vn , sum ) ;
else
cmVOR_Zero ( v , vn ) ;
}
}
cmVOR_AddVV ( a - > sr - > normAvgV , a - > ap - > cnt , v ) ; // track norm sum
cmVOR_MinVV ( a - > sr - > normMinV , vn , v ) ; // track norm min/max per dim
cmVOR_MaxVV ( a - > sr - > normMaxV , vn , v ) ;
a - > sr - > normMin = cmMin ( a - > sr - > normMin , cmVOR_Min ( v , vn , 1 ) ) ; // track norm global min/max
a - > sr - > normMax = cmMax ( a - > sr - > normMax , cmVOR_Max ( v , vn , 1 ) ) ;
return true ;
}
return false ;
}
// calc squared diff into a->sr->normSdv[]
bool _cmFtNormStdDev ( _cmFt_t * p , _cmFtAnl_t * a , cmReal_t * v , unsigned vn )
{
if ( a - > ap - > normFl )
{
assert ( a - > ap - > cnt = = vn ) ;
cmReal_t t [ vn ] ;
cmVOR_SubVVV ( t , a - > ap - > cnt , v , a - > sr - > normAvgV ) ;
cmVOR_PowVS ( t , a - > ap - > cnt , 2.0 ) ;
cmVOR_AddVV ( a - > sr - > normSdvV , a - > ap - > cnt , t ) ;
}
return false ;
}
// anlArray[] sorting function
int _cmFtAnlCompare ( const void * pp0 , const void * pp1 )
{
const _cmFtAnl_t * p0 = ( const _cmFtAnl_t * ) pp0 ;
const _cmFtAnl_t * p1 = ( const _cmFtAnl_t * ) pp1 ;
assert ( p0 ! = NULL & & p0 - > lp ! = NULL & & p1 ! = NULL & & p1 - > lp ! = NULL ) ;
return p0 - > lp - > order - p1 - > lp - > order ;
}
cmFtRC_t _cmFtValidateAttrArray ( _cmFt_t * p )
{
cmFtRC_t rc = kOkFtRC ;
unsigned i , j ;
for ( i = 0 ; i < p - > attrCnt ; + + i )
{
_cmFtLabel_t * lp = _cmFtIdToLabelPtr ( p - > attrArray [ i ] . id ) ;
assert ( lp ! = NULL ) ;
// check for duplicate features
for ( j = 0 ; j < p - > attrCnt ; + + j )
if ( i ! = j & & p - > attrArray [ i ] . id = = p - > attrArray [ j ] . id )
{
rc = _cmFtError ( kParamErrorFtRC , p , " The attribute '%s' has duplicate entries in the attribute array. " , cmStringNullGuard ( lp - > label ) ) ;
goto errLabel ;
}
// verify that the source id for this secondary feature was specified
if ( lp - > srcId ! = kInvalidFtId )
{
for ( j = 0 ; j < p - > attrCnt ; + + j )
if ( p - > attrArray [ j ] . id = = lp - > srcId )
break ;
if ( j = = p - > attrCnt )
{
rc = _cmFtError ( kParamErrorFtRC , p , " The primary feature '%s' must be specified in order to use the secondary feature '%s'. " , cmStringNullGuard ( _cmFtIdToLabelPtr ( lp - > srcId ) - > label ) , lp - > label ) ;
goto errLabel ;
}
}
}
errLabel :
return rc ;
}
cmFtRC_t cmFtAnalyzeFile ( cmFtH_t h , cmFtParam_t * pp )
{
cmFtRC_t rc = kOkFtRC ;
_cmFt_t * p = _cmFtHandleToPtr ( h ) ;
cmSample_t minSmp , maxSmp , meanSmp ;
cmReal_t audioSigNormFact ;
cmFtInfo_t f ;
unsigned frameIdx , sampleIdx ;
cmFrameFileH_t ffH = cmFrameFileNullHandle ;
cmAudioFileInfo_t afInfo ;
_cmFtAnl_t * anlArray = NULL ;
cmFtSumm_t * summArray = NULL ;
unsigned i ;
cmReal_t floorThreshAmpl ;
if ( ( rc = _cmFtValidateAttrArray ( p ) ) ! = kOkFtRC )
goto errLabel ;
cmVOR_DbToAmplVV ( & floorThreshAmpl , 1 , & pp - > floorThreshDb ) ;
// get the audio file header information
if ( cmAudioFileGetInfo ( pp - > audioFn , & afInfo , & p - > ctx . rpt ) ! = kOkAfRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The audio file open failed on '%s'. " , cmStringNullGuard ( pp - > audioFn ) ) ;
goto errLabel ;
}
p - > progSmpCnt = afInfo . frameCnt ;
p - > progSmpIdx = 0 ;
f . srate = afInfo . srate ;
f . smpCnt = afInfo . frameCnt ;
f . fftSmpCnt = cmNearPowerOfTwo ( ( unsigned ) floor ( pp - > wndMs * f . srate / 1000 ) ) ;
f . binCnt = f . fftSmpCnt / 2 + 1 ;
f . hopSmpCnt = f . fftSmpCnt / pp - > hopFact ;
f . frmCnt = 0 ;
f . skipFrmCnt = 0 ;
f . floorFrmCnt = 0 ;
// verify that the audio channel index is valid
if ( pp - > chIdx > = afInfo . chCnt )
{
rc = _cmFtError ( kChIdxInvalidFtRC , p , " The channel index (%i) specified for audio file '%s' is greater than the audio file channel count. " , pp - > chIdx , pp - > audioFn , afInfo . chCnt ) ;
goto errLabel ;
}
// initialize the audio file reader
if ( cmAudioFileRdOpen ( p - > afRdPtr , f . hopSmpCnt , pp - > audioFn , pp - > chIdx , 0 , cmInvalidIdx ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " The audio file reader open failed. " ) ;
goto errLabel ;
}
// get the range of sample values from this audio file for later normalization
if ( cmAudioFileRdMinMaxMean ( p - > afRdPtr , pp - > chIdx , & minSmp , & maxSmp , & meanSmp ) ! = cmOkRC )
{
rc = _cmFtError ( kDspProcFailFtRC , p , " Audio file min/max/mean processing failed on the audio file:'%s'. " , cmStringNullGuard ( pp - > audioFn ) ) ;
goto errLabel ;
}
audioSigNormFact = cmMax ( fabs ( minSmp ) , fabs ( maxSmp ) ) ;
// allocate anlArray[]
anlArray = cmMemAllocZ ( _cmFtAnl_t , pp - > attrCnt ) ;
summArray = cmMemAllocZ ( cmFtSumm_t , pp - > attrCnt ) ;
// iniitalize anlArray[]
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
_cmFtAnl_t * a = anlArray + i ;
a - > ap = pp - > attrArray + i ;
a - > lp = _cmFtIdToLabelPtr ( a - > ap - > id ) ;
a - > sr = summArray + i ;
a - > sr - > id = a - > lp - > id ;
}
// sort anlArray[] into init and exec order
qsort ( anlArray , pp - > attrCnt , sizeof ( anlArray [ 0 ] ) , _cmFtAnlCompare ) ;
// set the anlArray[i] source attribute pointer for secondary features (feat's based on other feat's)
for ( i = 0 ; i < pp - > attrCnt ; + + i )
if ( anlArray [ i ] . lp - > srcId ! = kInvalidFtId )
{
unsigned j ;
for ( j = 0 ; j < pp - > attrCnt ; + + j )
if ( i ! = j & & anlArray [ j ] . lp - > id = = anlArray [ i ] . lp - > srcId )
{
anlArray [ i ] . sp = anlArray + j ;
break ;
}
assert ( j ! = pp - > attrCnt ) ;
}
// initialize the feature extractors and allocate feature vector memory
if ( ( rc = _cmFtProcInit ( p , & f , pp , anlArray ) ) ! = kOkFtRC )
goto errLabel ;
// create the output frame file
if ( cmFrameFileCreate ( & ffH , pp - > featFn , f . srate , & p - > ctx ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " The feature file '%s' could not be created. " , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
// read the next block of samples from the audio file
for ( frameIdx = 0 , sampleIdx = 0 ; cmAudioFileRdRead ( p - > afRdPtr ) ! = cmEofRC ; sampleIdx + = f . hopSmpCnt )
{
cmSample_t aV [ p - > afRdPtr - > outN ] ;
cmSample_t * audV = aV ;
cmSample_t rms ;
p - > progSmpIdx = sampleIdx ;
// if this audio buffer is fully or paritally marked as 'skip'
if ( _cmFtZeroSkipSamples ( pp , p - > afRdPtr - > outV , p - > afRdPtr - > outN , p - > afRdPtr - > curFrmIdx - p - > afRdPtr - > lastReadFrmCnt ) )
{
+ + f . skipFrmCnt ;
continue ;
}
// if the audio buffer is zero - skip it
if ( ( rms = cmVOS_RMS ( p - > afRdPtr - > outV , p - > afRdPtr - > outN , p - > afRdPtr - > outN ) ) < floorThreshAmpl )
{
+ + f . floorFrmCnt ;
continue ;
}
// normalize the audio
if ( pp - > normAudioFl )
cmVOS_MultVVS ( audV , p - > afRdPtr - > outN , p - > afRdPtr - > outV , audioSigNormFact ) ;
else
audV = p - > afRdPtr - > outV ;
// execute the phase vocoder
if ( cmPvAnlExec ( p - > pvocPtr , audV , p - > afRdPtr - > outN ) = = false )
continue ;
// create an empty frame
if ( cmFrameFileFrameCreate ( ffH , kFrameTypeFtId , kFrameStreamFtId , sampleIdx , 0 ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame creation failed for frame index:%i on frame file:'%s'. " , frameIdx , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
// include the incomplete file header record in the first frame
if ( frameIdx = = 0 )
if ( ( rc = _cmFtWriteFileHdr ( p , & f , pp , ffH , summArray , false ) ) ! = kOkFtRC )
goto errLabel ;
// execute each of the feature extractors and store the result
if ( ( rc = _cmFtProcExec ( p , & f , pp , ffH , anlArray , audV ) ) ! = kOkFtRC )
goto errLabel ;
// close and write the current frame
if ( cmFrameFileFrameClose ( ffH ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame write failed for frame index:%i on frame file:'%s'. " , frameIdx , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
+ + frameIdx ;
}
f . frmCnt = frameIdx ;
// update the rawAvgV[] for each feature
if ( f . frmCnt > 0 )
{
// sum feature value into a->sr->rawAvgV[]
if ( ( rc = _cmFtProcFile ( p , ffH , pp , anlArray , _cmFtProcRawMinMaxSum ) ) ! = kOkFtRC )
goto errLabel ;
// complete the a->sr->rawAvgV[] calc
for ( i = 0 ; i < pp - > attrCnt ; + + i )
cmVOR_DivVS ( anlArray [ i ] . sr - > rawAvgV , anlArray [ i ] . ap - > cnt , f . frmCnt ) ;
// calc sum of squared diff into a->sr->rawSdvV[]
if ( ( rc = _cmFtProcFile ( p , ffH , pp , anlArray , _cmFtProcRawStdDev ) ) ! = kOkFtRC )
goto errLabel ;
// complete calc of std-dev
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
_cmFtAnl_t * a = anlArray + i ;
cmVOR_DivVS ( a - > sr - > rawSdvV , a - > ap - > cnt , f . frmCnt ) ;
cmVOR_PowVS ( a - > sr - > rawSdvV , a - > ap - > cnt , 0.5 ) ;
}
// make the initial normalized vector calculation (min/max/sum)
if ( ( rc = _cmFtProcFile ( p , ffH , pp , anlArray , _cmFtProcNormMinMaxSum ) ) ! = kOkFtRC )
goto errLabel ;
// complete the a->sr->normAvgV[] calculation
for ( i = 0 ; i < pp - > attrCnt ; + + i )
cmVOR_DivVS ( anlArray [ i ] . sr - > normAvgV , anlArray [ i ] . ap - > cnt , f . frmCnt ) ;
// calc squared of squared diff into a->sr->normSdvV[]
if ( ( rc = _cmFtProcFile ( p , ffH , pp , anlArray , _cmFtNormStdDev ) ) ! = kOkFtRC )
goto errLabel ;
// complete the calc of norm std-dev
for ( i = 0 ; i < pp - > attrCnt ; + + i )
{
_cmFtAnl_t * a = anlArray + i ;
cmVOR_DivVS ( a - > sr - > normSdvV , a - > ap - > cnt , f . frmCnt ) ;
cmVOR_PowVS ( a - > sr - > normSdvV , a - > ap - > cnt , 0.5 ) ;
}
}
//-------------------------------------------------------------------------
//
// rewrite the updated feature file header into the first frame
//
// rewind to the first frame
if ( cmFrameFileRewind ( ffH ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file rewind failed during header update on '%s'. " , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
// make the first frame current and load it into the cmFrameFiles current frame buffer
if ( cmFrameFileFrameLoadNext ( ffH , kFrameTypeFtId , kFrameStreamFtId , NULL ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file load next frme failed during header update on '%s'. " , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
// copy the update header record into the current frame buffer
if ( ( rc = _cmFtWriteFileHdr ( p , & f , pp , ffH , summArray , true ) ) ! = kOkFtRC )
goto errLabel ;
// write the updated frame back to disk
if ( cmFrameFileFrameUpdate ( ffH ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file frame update failed during header update on '%s'. " , cmStringNullGuard ( pp - > featFn ) ) ;
goto errLabel ;
}
errLabel :
if ( anlArray ! = NULL )
for ( i = 0 ; i < pp - > attrCnt ; + + i )
cmMemPtrFree ( & anlArray [ i ] . v ) ;
cmMemPtrFree ( & anlArray ) ;
cmMemPtrFree ( & summArray ) ;
cmFrameFileClose ( & ffH ) ;
return rc ;
}
cmFtRC_t cmFtAnalyze ( cmFtH_t h )
{
cmFtRC_t rc = kOkFtRC ;
_cmFt_t * p = _cmFtHandleToPtr ( h ) ;
unsigned i ;
for ( i = 0 ; i < p - > paramCnt ; + + i )
{
p - > progParamIdx = i ;
p - > progPassIdx = 0 ;
if ( ( rc = cmFtAnalyzeFile ( h , p - > paramArray + i ) ) ! = kOkFtRC )
break ;
}
return rc ;
}
const char * cmFtAnalyzeProgress ( cmFtH_t h , unsigned * passPtr , cmReal_t * percentPtr )
{
_cmFt_t * p = _cmFtHandleToPtr ( h ) ;
if ( percentPtr ! = NULL )
* percentPtr = 0 ;
if ( passPtr ! = NULL )
* passPtr = 0 ;
if ( p - > progParamIdx = = cmInvalidIdx )
return NULL ;
if ( percentPtr ! = NULL & & p - > progSmpCnt > 0 )
* percentPtr = 100.0 * p - > progSmpIdx / p - > progSmpCnt ;
if ( passPtr ! = NULL )
* passPtr = p - > progPassIdx ;
return p - > paramArray [ p - > progParamIdx ] . audioFn ;
}
cmFtRC_t _cmFtReaderClose ( _cmFtFile_t * fp )
{
cmFtRC_t rc = kOkFtRC ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
/*
unsigned i ;
if ( cmPlviewIsValid ( p - > plvH ) )
for ( i = 0 ; i < fp - > info . param . attrCnt ; + + i )
if ( cmPlviewFreeSource ( p - > plvH , fp - > descArray [ i ] . ap - > id ) ! = kOkPlvRC )
{
rc = _cmFtError ( kPlviewFailFtRC , p , " Plview source free failed on feature '%s'. " , fp - > descArray [ i ] . lp - > label ) ;
goto errLabel ;
}
*/
if ( cmFrameFileClose ( & fp - > ffH ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file close failed. " ) ;
goto errLabel ;
}
cmMemPtrFree ( & fp - > descArray ) ;
cmMemPtrFree ( & fp - > info . summArray ) ;
cmMemPtrFree ( & fp - > info . param . skipArray ) ;
cmMemPtrFree ( & fp - > info . param . attrArray ) ;
cmMemPtrFree ( & fp - > hdrBuf ) ;
cmMemPtrFree ( & fp ) ;
errLabel :
return rc ;
}
/*
// Fill buf[rowCnt,colCnt] with data from the source submatrix located at rowIdx,colIdx.
// Return the count of elements actually copied into buf[].
unsigned cmFtPlviewSrcFunc ( void * userPtr , unsigned srcId , unsigned binIdx , unsigned frmIdx , cmReal_t * buf , unsigned binCnt , unsigned frmCnt )
{
assert ( userPtr ! = NULL ) ;
_cmFtFile_t * fp = ( _cmFtFile_t * ) userPtr ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
cmFfRC_t rc = kOkFfRC ;
const cmFfFrame_t * frmDescPtr = NULL ;
const cmFfMtx_t * mtxDescPtr = NULL ;
unsigned i ;
// seek to frmIdx
if ( ( rc = cmFrameFileSeek ( fp - > ffH , frmIdx ) ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Seek failed on plot data cmcess. " ) ;
goto errLabel ;
}
// load the frame
for ( i = 0 ; i < frmCnt & & ( rc = cmFrameFileFrameLoadNext ( fp - > ffH , kFrameTypeFtId , kFrameStreamFtId , & frmDescPtr ) ) = = kOkFfRC ; + + i )
{
const cmReal_t * dp ;
const _cmFtLabel_t * lp = _cmFtIdToLabelPtr ( srcId ) ;
assert ( lp ! = NULL ) ;
if ( ( dp = cmFrameFileMtxReal ( fp - > ffH , lp - > ffMtxId , lp - > ffUnitsId , kRealFmtId , & mtxDescPtr ) ) = = NULL )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Mtx data cmcess failed on plot data access. " ) ;
goto errLabel ;
}
cmVOR_Copy ( buf + ( i * binCnt ) , binCnt , dp ) ;
return binCnt ;
}
errLabel :
return 0 ;
}
*/
cmFtRC_t cmFtReaderOpen ( cmFtH_t h , cmFtFileH_t * hp , const char * featFn , const cmFtInfo_t * * infoPtrPtr )
{
cmFfRC_t ffRC = kOkFfRC ;
const cmFfFile_t * fileDescPtr = NULL ;
const cmFfFrame_t * frameDescPtr = NULL ;
cmFtRC_t rc = kOkFtRC ;
_cmFt_t * p = _cmFtHandleToPtr ( h ) ;
_cmFtFile_t * fp = cmMemAllocZ ( _cmFtFile_t , 1 ) ;
const cmFfMtx_t * mp = NULL ;
void * buf = NULL ;
unsigned i , j ;
//cmPlvSrc_t plvSrc;
if ( infoPtrPtr ! = NULL )
* infoPtrPtr = NULL ;
fp - > h = h ;
fp - > ffH = cmFrameFileNullHandle ;
// open the frame file
if ( cmFrameFileOpen ( & fp - > ffH , featFn , & p - > ctx , & fileDescPtr ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file open failed. " ) ;
goto errLabel ;
}
// load the first frame
if ( ( ffRC = cmFrameFileFrameLoadNext ( fp - > ffH , kFrameTypeFtId , kFrameStreamFtId , & frameDescPtr ) ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file load failed. " ) ;
goto errLabel ;
}
// read the file header
if ( ( buf = cmFrameFileMtxBlob ( fp - > ffH , kDataMId , kNoUnitsUId , & mp ) ) = = NULL )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file header read failed. " ) ;
goto errLabel ;
}
// parse the file header into fp->infoPtr
if ( ( rc = _cmDeserializeFileHdr ( p , fp , buf , mp - > rowCnt * mp - > colCnt ) ) ! = kOkFtRC )
goto errLabel ;
fp - > descArray = cmMemAllocZ ( _cmFtDesc_t , fp - > info . param . attrCnt ) ;
// for each feature
for ( i = 0 ; i < fp - > info . param . attrCnt ; + + i )
{
// setup the desc array
fp - > descArray [ i ] . ap = fp - > info . param . attrArray + i ;
fp - > descArray [ i ] . lp = _cmFtIdToLabelPtr ( fp - > descArray [ i ] . ap - > id ) ;
// sync descArray[] to summArray[] by matching the feature id's
for ( j = 0 ; j < fp - > info . param . attrCnt ; + + j )
if ( fp - > info . summArray [ j ] . id = = fp - > descArray [ i ] . lp - > id )
{
fp - > descArray [ i ] . sr = fp - > info . summArray + j ;
break ;
}
/*
plvSrc . id = fp - > descArray [ i ] . lp - > id ;
plvSrc . label = fp - > descArray [ i ] . lp - > label ;
plvSrc . rn = fp - > descArray [ i ] . ap - > cnt ;
plvSrc . cn = fp - > info . frmCnt ;
plvSrc . userPtr = fp ;
plvSrc . srcFuncPtr = cmFtPlviewSrcFunc ;
plvSrc . worldExts . xMin = 0 ;
plvSrc . worldExts . xMax = fp - > info . frmCnt ;
plvSrc . worldExts . yMin = fp - > descArray [ i ] . ap - > cnt < = 1 ? fp - > descArray [ i ] . sr - > rawMin : 0 ;
plvSrc . worldExts . yMax = fp - > descArray [ i ] . ap - > cnt < = 1 ? fp - > descArray [ i ] . sr - > rawMax : fp - > descArray [ i ] . ap - > cnt ;
if ( cmPlviewIsValid ( p - > plvH ) )
if ( cmPlviewAllocSource ( p - > plvH , & plvSrc ) ! = kOkPlvRC )
{
rc = _cmFtError ( kPlviewFailFtRC , p , " Plview source allocattion failed for feature '%s'. " , fp - > descArray [ i ] . lp - > label ) ;
goto errLabel ;
}
*/
}
// rewind to the frame file
if ( ( ffRC = cmFrameFileRewind ( fp - > ffH ) ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file rewind failed. " ) ;
goto errLabel ;
}
hp - > h = fp ;
if ( infoPtrPtr ! = NULL )
* infoPtrPtr = & fp - > info ;
errLabel :
if ( rc ! = kOkFtRC )
_cmFtReaderClose ( fp ) ;
return rc ;
}
cmFtRC_t cmFtReaderClose ( cmFtFileH_t * hp )
{
cmFtRC_t rc = kOkFtRC ;
if ( cmFtReaderIsValid ( * hp ) = = false )
return rc ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( * hp ) ;
if ( ( rc = _cmFtReaderClose ( fp ) ) ! = kOkFtRC )
goto errLabel ;
hp - > h = NULL ;
errLabel :
return rc ;
}
bool cmFtReaderIsValid ( cmFtFileH_t h )
{ return h . h ! = NULL ; }
unsigned cmFtReaderFeatCount ( cmFtFileH_t h )
{
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
return fp - > info . param . attrCnt ;
}
unsigned cmFtReaderFeatId ( cmFtFileH_t h , unsigned index )
{
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
assert ( index < fp - > info . param . attrCnt ) ;
return fp - > descArray [ index ] . lp - > id ;
}
cmFtRC_t cmFtReaderRewind ( cmFtFileH_t h )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
if ( cmFrameFileRewind ( fp - > ffH ) ! = kOkFfRC )
{
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file advance failed. " ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
cmFtRC_t cmFtReaderSeek ( cmFtFileH_t h , unsigned frmIdx )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
if ( cmFrameFileSeek ( fp - > ffH , kFrameStreamFtId , frmIdx ) ! = kOkFtRC )
{
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file seek failed. " ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
cmFtRC_t cmFtReaderAdvance ( cmFtFileH_t h , cmFtFrameDesc_t * fdp )
{
cmFfRC_t ffRC = kOkFfRC ;
const cmFfFrame_t * frameDescPtr = NULL ;
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
if ( ( ffRC = cmFrameFileFrameLoadNext ( fp - > ffH , kFrameTypeFtId , kFrameStreamFtId , & frameDescPtr ) ) ! = kOkFfRC )
{
if ( ffRC = = kEofFfRC )
rc = kEofFtRC ;
else
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame file advance failed. " ) ;
goto errLabel ;
}
}
errLabel :
if ( fdp ! = NULL )
{
if ( rc = = kOkFtRC )
{
2015-11-16 19:59:27 +00:00
fdp - > smpIdx = frameDescPtr - > tm . sampleIdx ;
2012-10-30 03:52:39 +00:00
fdp - > frmIdx = cmFrameFileFrameLoadedIndex ( fp - > ffH ) ;
}
else
{
fdp - > smpIdx = cmInvalidIdx ;
fdp - > frmIdx = cmInvalidIdx ;
}
}
return rc ;
}
cmReal_t * cmFtReaderData ( cmFtFileH_t h , unsigned id , unsigned * cntPtr )
{
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
cmReal_t * dp = NULL ;
_cmFtLabel_t * lp = _cmFtIdToLabelPtr ( id ) ;
const cmFfMtx_t * mdp = NULL ;
assert ( lp ! = NULL ) ;
if ( cntPtr ! = NULL )
* cntPtr = 0 ;
if ( ( dp = cmFrameFileMtxReal ( fp - > ffH , lp - > ffMtxId , lp - > ffUnitsId , & mdp ) ) = = NULL )
return NULL ;
if ( cntPtr ! = NULL )
* cntPtr = mdp - > rowCnt * mdp - > colCnt ;
return dp ;
}
cmFtRC_t cmFtReaderCopy ( cmFtFileH_t h , unsigned featId , unsigned frmIdx , cmReal_t * buf , unsigned frmCnt , unsigned elePerFrmCnt , unsigned * outEleCntPtr )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
_cmFtLabel_t * lp = _cmFtIdToLabelPtr ( featId ) ;
assert ( lp ! = NULL ) ;
if ( cmFrameFileMtxLoadReal ( fp - > ffH , kFrameStreamFtId , lp - > ffMtxId , lp - > ffUnitsId , frmIdx , frmCnt , buf , frmCnt * elePerFrmCnt , outEleCntPtr ) ! = kOkFfRC )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Frame load matrix failed. " ) ;
goto errLabel ;
}
errLabel :
return rc ;
}
cmFtRC_t cmFtReaderMultiSetup ( cmFtFileH_t h , cmFtMulti_t * multiArray , unsigned multiCnt , unsigned * featVectEleCntPtr )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
unsigned i , j ;
assert ( featVectEleCntPtr ! = NULL ) ;
* featVectEleCntPtr = 0 ;
for ( i = 0 ; i < multiCnt ; + + i )
{
const _cmFtLabel_t * lp ;
// locate the static parameters assoc'd with this feature
if ( ( lp = _cmFtIdToLabelPtr ( multiArray [ i ] . featId ) ) = = NULL )
{
rc = _cmFtError ( kInvalidFeatIdFtRC , p , " Invalid feature id %i. " , multiArray [ i ] . featId ) ;
goto errLabel ;
}
// locate the feature info assoc'd with this file
for ( j = 0 ; j < fp - > info . param . attrCnt ; + + j )
{
if ( fp - > info . param . attrArray [ j ] . id = = multiArray [ i ] . featId )
{
// if the multi ele cnt is -1 then use all avail ele's
if ( multiArray [ i ] . cnt = = - 1 )
multiArray [ i ] . cnt = fp - > info . param . attrArray [ j ] . cnt ;
// verify the feature element count
if ( fp - > info . param . attrArray [ j ] . cnt < multiArray [ i ] . cnt )
{
rc = _cmFtError ( kInvalidFeatIdFtRC , p , " The requested feature element count %i is greater than the actual feature count %i in feature file '%s'. " , multiArray [ i ] . cnt , fp - > info . param . attrArray [ j ] . cnt , fp - > info . param . featFn ) ;
goto errLabel ;
}
break ;
}
}
// verify that the feature attr recd was found
if ( j > = fp - > info . param . attrCnt )
{
rc = _cmFtError ( kInvalidFeatIdFtRC , p , " The feature %i was not used in the feature file '%s'. " , multiArray [ i ] . featId , fp - > info . param . featFn ) ;
goto errLabel ;
}
multiArray [ i ] . id0 = lp - > ffMtxId ;
multiArray [ i ] . id1 = lp - > ffUnitsId ;
* featVectEleCntPtr + = multiArray [ i ] . cnt ;
}
errLabel :
return rc ;
}
cmFtRC_t cmFtReaderMultiData ( cmFtFileH_t h , const cmFtMulti_t * multiArray , unsigned multiCnt , cmReal_t * outV , unsigned outN )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
unsigned i ;
unsigned n = 0 ;
for ( i = 0 ; i < multiCnt ; + + i )
{
const cmFfMtx_t * mdp = NULL ;
const cmFtMulti_t * m = multiArray + i ;
cmReal_t * dp = NULL ;
if ( ( dp = cmFrameFileMtxReal ( fp - > ffH , m - > id0 , m - > id1 , & mdp ) ) = = NULL )
{
rc = _cmFtError ( kFrameFileFailFtRC , p , " Matrix read failed on feature file '%s'. " , fp - > info . param . featFn ) ;
goto errLabel ;
}
assert ( m - > cnt < = mdp - > rowCnt * mdp - > colCnt ) ;
assert ( n + m - > cnt < = outN ) ;
cmVOR_Copy ( outV , m - > cnt , dp ) ;
outV + = m - > cnt ;
n + = m - > cnt ;
}
errLabel :
return rc ;
}
cmFtSumm_t * _cmFtReaderFindSummPtr ( _cmFtFile_t * fp , unsigned featId )
{
unsigned i ;
const cmFtParam_t * pp = & fp - > info . param ;
for ( i = 0 ; i < pp - > attrCnt ; + + i )
if ( fp - > info . summArray [ i ] . id = = featId )
return fp - > info . summArray + i ;
return NULL ;
}
cmFtRC_t cmFtReaderReport ( cmFtFileH_t h , unsigned featId )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
const cmFtInfo_t * ip = & fp - > info ;
const cmFtParam_t * pp = & ip - > param ;
unsigned i ;
cmFtSumm_t * s ;
_cmFtPrint ( p , " ch:%i audio:%s \n " , pp - > chIdx , pp - > audioFn ) ;
_cmFtPrint ( p , " wndMs:%f hopFact:%i normAudioFl:%i \n " , pp - > wndMs , pp - > hopFact , pp - > normAudioFl ) ;
_cmFtPrint ( p , " skip: \n " ) ;
for ( i = 0 ; i < pp - > skipCnt ; + + i )
_cmFtPrint ( p , " idx:%10i cnt:%10i \n " , pp - > skipArray [ i ] . smpIdx , pp - > skipArray [ i ] . smpCnt ) ;
_cmFtPrint ( p , " attr: \n " ) ;
for ( i = 0 ; i < pp - > attrCnt ; + + i )
_cmFtPrint ( p , " cnt:%4i normFl:%i raw min:%12f max:%12f norm min:%12f max:%12f %s \n " , pp - > attrArray [ i ] . cnt , pp - > attrArray [ i ] . normFl , fp - > descArray [ i ] . sr - > rawMin , fp - > descArray [ i ] . sr - > rawMax , fp - > descArray [ i ] . sr - > normMin , fp - > descArray [ i ] . sr - > normMax , cmFtFeatIdToLabel ( pp - > attrArray [ i ] . id ) ) ;
_cmFtPrint ( p , " frmCnt:%i skipFrmCnt:%i floorFrmCnt:%i srate:%f fftSmpCnt:%i hopSmpCnt:%i binCnt:%i binHz:%f \n " , ip - > frmCnt , ip - > skipFrmCnt , ip - > floorFrmCnt , ip - > srate , ip - > fftSmpCnt , ip - > hopSmpCnt , ip - > binCnt , ip - > srate / ip - > fftSmpCnt ) ;
if ( featId ! = kInvalidFtId )
{
if ( ( s = _cmFtReaderFindSummPtr ( fp , featId ) ) = = NULL )
return _cmFtError ( kInvalidFeatIdFtRC , p , " The feature id %i is not valid. " , featId ) ;
_cmFtPrint ( p , " feature:%s \n " , _cmFtIdToLabelPtr ( featId ) - > label ) ;
cmVOR_PrintLE ( " raw min: " , & p - > ctx . rpt , 1 , s - > cnt , s - > rawMinV ) ;
cmVOR_PrintLE ( " raw max: " , & p - > ctx . rpt , 1 , s - > cnt , s - > rawMaxV ) ;
cmVOR_PrintLE ( " raw avg: " , & p - > ctx . rpt , 1 , s - > cnt , s - > rawAvgV ) ;
cmVOR_PrintLE ( " raw sdv: " , & p - > ctx . rpt , 1 , s - > cnt , s - > rawSdvV ) ;
cmVOR_PrintLE ( " norm min: " , & p - > ctx . rpt , 1 , s - > cnt , s - > normMinV ) ;
cmVOR_PrintLE ( " norm max: " , & p - > ctx . rpt , 1 , s - > cnt , s - > normMaxV ) ;
cmVOR_PrintLE ( " norm avg: " , & p - > ctx . rpt , 1 , s - > cnt , s - > normAvgV ) ;
cmVOR_PrintLE ( " norm sdv: " , & p - > ctx . rpt , 1 , s - > cnt , s - > normSdvV ) ;
}
return rc ;
}
cmFtRC_t cmFtReaderReportFn ( cmFtH_t h , const cmChar_t * fn , unsigned featId )
{
cmFtRC_t rc0 , rc1 ;
cmFtFileH_t fh = cmFtFileNullHandle ;
if ( ( rc0 = cmFtReaderOpen ( h , & fh , fn , NULL ) ) ! = kOkFtRC )
return rc0 ;
rc0 = cmFtReaderReport ( fh , featId ) ;
rc1 = cmFtReaderClose ( & fh ) ;
return rc0 ! = kOkFtRC ? rc0 : rc1 ;
}
cmFtRC_t cmFtReaderReportFeature ( cmFtFileH_t h , unsigned featId , unsigned frmIdx , unsigned frmCnt )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
unsigned i ;
cmFtFrameDesc_t ftFrameDesc ;
if ( ( rc = cmFtReaderSeek ( h , frmIdx ) ) ! = kOkFtRC )
return rc ;
for ( i = 0 ; i < frmCnt & & ( rc = cmFtReaderAdvance ( h , & ftFrameDesc ) ) = = kOkFtRC ; + + i )
{
cmReal_t * dp = NULL ;
unsigned cnt = 0 ;
if ( ( dp = cmFtReaderData ( h , featId , & cnt ) ) = = NULL )
break ;
// print first element
_cmFtPrint ( p , " %f " , * dp ) ;
}
return rc ;
}
cmFtRC_t cmFtReaderToBinary ( cmFtFileH_t h , unsigned featId , unsigned frmIdx , unsigned frmCnt , const cmChar_t * outFn )
{
cmFtRC_t rc = kOkFtRC ;
_cmFtFile_t * fp = _cmFtFileHandleToPtr ( h ) ;
_cmFt_t * p = _cmFtHandleToPtr ( fp - > h ) ;
unsigned i ;
cmFtFrameDesc_t ftFrameDesc ;
cmFileH_t fH ;
unsigned hdr [ ] = { 0 , 0 , 0 } ;
unsigned maxCnt = 0 ;
// create the output file
if ( cmFileOpen ( & fH , outFn , kWriteFileFl , p - > err . rpt ) ! = kOkFileRC )
return _cmFtError ( kFileFailFtRC , p , " Feature to binary file '%s' failed on output file creation. " , outFn ) ;
// if frmCnt is not valid then set it to all frames past frmIdx
if ( frmCnt = = cmInvalidCnt )
frmCnt = cmFrameFileFrameCount ( fp - > ffH , kFrameStreamFtId ) ;
// validate frm idx
if ( frmIdx > frmCnt )
{
rc = _cmFtError ( kInvalidFrmIdxFtRC , p , " Frame index %i is invalid for frame count = %i. " , frmIdx , frmCnt ) ;
goto errLabel ;
}
// seek to the location first output frame
if ( ( rc = cmFtReaderSeek ( h , frmIdx ) ) ! = kOkFtRC )
goto errLabel ;
hdr [ 0 ] = frmCnt ; // count of frames
hdr [ 1 ] = 0 ; // count of elements per frame
hdr [ 2 ] = sizeof ( cmReal_t ) ;
// write the file header
if ( cmFileWrite ( fH , hdr , sizeof ( hdr ) ) ! = kOkFileRC )
{
rc = _cmFtError ( kFileFailFtRC , p , " The output file header write failed. " ) ;
goto errLabel ;
}
// iterate through each frame
for ( i = 0 ; i < frmCnt & & ( rc = cmFtReaderAdvance ( h , & ftFrameDesc ) ) = = kOkFtRC ; + + i )
{
cmReal_t * dp = NULL ;
unsigned cnt = 0 ;
// get a pointer to the data for the requested feature
if ( ( dp = cmFtReaderData ( h , featId , & cnt ) ) = = NULL )
break ;
// write the count of elements in this frame
if ( cmFileWrite ( fH , & cnt , sizeof ( cnt ) ) ! = kOkFileRC )
{
rc = _cmFtError ( kFileFailFtRC , p , " Output write failed on frame header at frame index %i. " , i ) ;
goto errLabel ;
}
// write the data
if ( cmFileWrite ( fH , dp , sizeof ( * dp ) * cnt ) ! = kOkFileRC )
{
rc = _cmFtError ( kFileFailFtRC , p , " Output data write failed on frame index %i. " , i ) ;
goto errLabel ;
}
if ( cnt > maxCnt )
maxCnt = cnt ;
}
// rewind to the beginning of the file
if ( cmFileSeek ( fH , kBeginFileFl , 0 ) ! = kOkFileRC )
{
rc = _cmFtError ( kFileFailFtRC , p , " Output file rewind failed. " ) ;
goto errLabel ;
}
// rewrite the header
hdr [ 1 ] = maxCnt ;
if ( cmFileWrite ( fH , hdr , sizeof ( hdr ) ) ! = kOkFileRC )
{
rc = _cmFtError ( kFileFailFtRC , p , " The output file header re-write failed. " ) ;
goto errLabel ;
}
errLabel :
if ( cmFileIsValid ( fH ) )
if ( cmFileClose ( & fH ) ! = kOkFileRC )
_cmFtError ( kFileFailFtRC , p , " Output file close failed. " ) ;
return rc ;
}
cmFtRC_t cmFtReaderToBinaryFn ( cmFtH_t h , const cmChar_t * fn , unsigned featId , unsigned frmIdx , unsigned frmCnt , const cmChar_t * outFn )
{
cmFtRC_t rc = kOkFtRC ;
cmFtFileH_t fH = cmFtFileNullHandle ;
if ( ( rc = cmFtReaderOpen ( h , & fH , fn , NULL ) ) ! = kOkFtRC )
return rc ;
rc = cmFtReaderToBinary ( fH , featId , frmIdx , frmCnt , outFn ) ;
cmFtRC_t rc1 = cmFtReaderClose ( & fH ) ;
return rc = = kOkFtRC ? rc1 : rc ;
}