cmProc2.h/c : Added cmFrqTrk,cmWhFilt, and cmVectArray.

Initial addition of cmFrqTrk to cmSpecDist. (not yet tested).
This commit is contained in:
Kevin Larke 2014-08-10 13:02:51 -07:00
parent e1ab740d82
commit 133bdea685
2 changed files with 1776 additions and 3 deletions

1542
cmProc2.c

File diff suppressed because it is too large Load Diff

237
cmProc2.h
View File

@ -764,6 +764,238 @@ extern "C" {
cmRC_t cmNmfExec( cmNmf_t* p, const cmReal_t* v, unsigned cn );
//------------------------------------------------------------------------------------------------------------
// cmVectArray buffers row vectors of arbitrary lenght in memory.
// The buffers may then be access using the cmVectArrayGetXXX() functions.
// The entire contents of the file may be written to a file using atVectArrayWrite().
// The file may then be read in back into memory using cmVectArrayAllocFromFile()
// or in octave via readVectArray.m.
// A rectantular matrix in memory may be written to a VectArray file in one operation
// via the function cmVectArrayWriteMatrixXXX().
typedef struct cmVectArrayVect_str
{
unsigned n; // length of this vector in values (not bytes)
union
{
char* v; // raw memory vector pointer
double* dV; // dV[n] vector of doubles
float* fV; // fV[n] vecotr of floats
cmSample_t* sV; // sV[n] vector of cmSample_t
} u;
struct cmVectArrayVect_str* link; // link to next element record
} cmVectArrayVect_t;
enum
{
kFloatVaFl = 0x01,
kDoubleVaFl = 0x02,
kSampleVaFl = 0x04,
kRealVaFl = 0x08,
kIntVaFl = 0x02, // int and uint is converted to double
kUIntVaFl = 0x02 //
};
typedef struct
{
cmObj obj;
cmVectArrayVect_t* bp; // first list element
cmVectArrayVect_t* ep; // last list element
unsigned vectCnt; // count of elements in linked list
unsigned flags; // data vector type (See: kFloatVaFl, kDoubleVaFl, ... )
unsigned typeByteCnt; // size of a single data vector value (e.g. 4=float 8=double)
unsigned maxEleCnt; // length of the longest data vector
double* tempV;
cmVectArrayVect_t* cur;
} cmVectArray_t;
// Flags must be set to one of the kXXXVAFl flag values.
cmVectArray_t* cmVectArrayAlloc( cmCtx* ctx, unsigned flags );
cmVectArray_t* cmVectArrayAllocFromFile(cmCtx* ctx, const char* fn );
cmRC_t cmVectArrayFree( cmVectArray_t** pp );
// Release all the stored vectors but do not release the object.
cmRC_t cmVectArrayClear( cmVectArray_t* p );
// Return the count of vectors contained in the vector array.
cmRC_t cmVectArrayCount( const cmVectArray_t* p );
// Store a new vector by appending it to the end of the internal vector list.
cmRC_t cmVectArrayAppendS( cmVectArray_t* p, const cmSample_t* v, unsigned vn );
cmRC_t cmVectArrayAppendR( cmVectArray_t* p, const cmReal_t* v, unsigned vn );
cmRC_t cmVectArrayAppendF( cmVectArray_t* p, const float* v, unsigned vn );
cmRC_t cmVectArrayAppendD( cmVectArray_t* p, const double* v, unsigned vn );
cmRC_t cmVectArrayAppendI( cmVectArray_t* p, const int* v, unsigned vn );
cmRC_t cmVectArrayAppendU( cmVectArray_t* p, const unsigned* v, unsigned vn );
// Write a vector array in a format that can be read by readVectArray.m.
cmRC_t cmVectArrayWrite( cmVectArray_t* p, const char* fn );
typedef cmRC_t (*cmVectArrayForEachFuncS_t)( void* arg, unsigned idx, const cmSample_t* xV, unsigned xN );
unsigned cmVectArrayForEachS( cmVectArray_t* p, unsigned idx, unsigned cnt, cmVectArrayForEachFuncS_t func, void* arg );
cmRC_t cmVectArrayWriteVectorS( cmCtx* ctx, const char* fn, const cmSample_t* v, unsigned vn );
cmRC_t cmVectArrayWriteVectorI( cmCtx* ctx, const char* fn, const int* v, unsigned vn );
// Write the column-major matrix m[rn,cn] to the file 'fn'. Note that the matrix is transposed as it is
// written and therefore will be read back as a 'cn' by 'rn' matrix.
cmRC_t cmVectArrayWriteMatrixS( cmCtx* ctx, const char* fn, const cmSample_t* m, unsigned rn, unsigned cn );
cmRC_t cmVectArrayWriteMatrixI( cmCtx* ctx, const char* fn, const int* m, unsigned rn, unsigned cn );
cmRC_t cmVectArrayRewind( cmVectArray_t* p );
cmRC_t cmVectArrayAdvance( cmVectArray_t* p, unsigned n );
bool cmVectArrayIsEOL( const cmVectArray_t* p );
unsigned cmVectArrayEleCount( const cmVectArray_t* p );
cmRC_t cmVectArrayGetF( cmVectArray_t* p, float* v, unsigned* vnRef );
cmRC_t cmVectArrayGetD( cmVectArray_t* p, double* v, unsigned* vnRef );
cmRC_t cmVectArrayGetI( cmVectArray_t* p, int* v, unsigned* vnRef );
cmRC_t cmVectArrayGetU( cmVectArray_t* p, unsigned* v, unsigned* vnRef );
// If a vector array is composed of repeating blocks of 'groupCnt' sub-vectors
// where the concatenated ith sub-vectors in each group form a single super-vector then
// this function will return the super-vector. Use cmMemFree(*vRef) to release
// the returned super-vector.
cmRC_t cmVectArrayFormVectF( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, float** vRef, unsigned* vnRef );
cmRC_t cmVectArrayFormVectColF( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, float** vRef, unsigned* vnRef );
cmRC_t cmVectArrayFormVectColU( cmVectArray_t* p, unsigned groupIdx, unsigned groupCnt, unsigned colIdx, unsigned** vRef, unsigned* vnRef );
cmRC_t cmVectArrayTest( cmCtx* ctx, const char* fn );
#if CM_FLOAT_SMP == 1
#define cmVectArrayGetS cmVectArrayGetF
#define cmVectArrayFormVectS cmVectArrayFormVectF
#else
#define cmVectArrayGetS cmVectArrayGetD
#define cmVectArrayFormVectS cmVectArrayFormVectD
#endif
//-----------------------------------------------------------------------------------------------------------------------
// Spectral whitening filter.
// Based on: Klapuri, A., 2006: Multiple fundamental frequency estimation by summing
// harmonic amplitudes.
typedef struct
{
cmObj obj;
unsigned binCnt; //
cmReal_t binHz; //
unsigned bandCnt; //
cmReal_t coeff; //
cmReal_t* whiV; // whiV[bandCnt+2] - fractional bin index of each center frequency
cmReal_t* whM; // whM[binCnt,bandCnt]
cmReal_t* iV; // iV[ binCnt ] - working memory
} cmWhFilt;
cmWhFilt* cmWhFiltAlloc( cmCtx* c, cmWhFilt* p, unsigned binCnt, cmReal_t binHz, cmReal_t coeff, cmReal_t maxHz );
cmRC_t cmWhFiltFree( cmWhFilt** pp );
cmRC_t cmWhFiltInit( cmWhFilt* p, unsigned binCnt, cmReal_t binHz, cmReal_t coeff, cmReal_t maxHz );
cmRC_t cmWhFiltFinal( cmWhFilt* p );
cmRC_t cmWhFiltExec( cmWhFilt* p, const cmReal_t* xV, cmReal_t* yV, unsigned xyN );
//-----------------------------------------------------------------------------------------------------------------------
typedef struct
{
double srate; // system sample rate
unsigned chCnt; // tracking channel count
unsigned binCnt; // count of spectrum elements passed in each call to cmFrqTrkExec()
unsigned hopSmpCnt; // phase vocoder hop count in samples
cmReal_t stRange; // maximum allowable semi-tones between a tracker and a peak
cmReal_t wndSecs; // duration of the
cmReal_t minTrkSec; // minimum track length before track is considered stable
cmReal_t maxTrkDeadSec; // maximum length of time a tracker may fail to connect to a peak before being declared disconnected.
cmReal_t pkThreshDb; // minimum amplitide in Decibels of a selected spectral peak.
cmReal_t pkAtkThreshDb; // minimum amplitude in Decibels for the first frame of a new track.
cmReal_t pkAtkMaxHz; // maximum frequency for a new track.
const char* logFn; // log file name or NULL if no file is to be written
const char* levelFn; // level file name or NULL if no file is to be written
const char* specFn; // spectrum file name or NULL if no file is to be written
} cmFrqTrkArgs_t;
typedef struct
{
bool activeFl;
unsigned id;
unsigned tN; // age of this track in frames
unsigned dN; // count of consecutive times this ch has not connected
cmReal_t hz; // current center frequency
cmReal_t db; // current magnitude
cmReal_t* dbV; // dbV[]
cmReal_t* hzV; // hzV[]
unsigned si;
unsigned sn;
cmReal_t db_mean;
cmReal_t db_std;
cmReal_t hz_mean;
cmReal_t hz_std;
} cmFrqTrkCh_t;
struct cmBinMtxFile_str;
typedef struct cmFrqTrk_str
{
cmObj obj;
cmFrqTrkArgs_t a;
cmFrqTrkCh_t* ch; // ch[ a.chCnt ]
unsigned hN; // count of magnitude buffer frames
unsigned sN; // count of frames in channel statistics buffers
unsigned bN; // count of bins in peak matrices
cmReal_t* dbM; // dbM[ hN, bN ]
unsigned hi; // next row of dbM to fill
unsigned fN; // total count of frames processed.
cmReal_t binHz;
cmReal_t* dbV;
unsigned* pkiV;
unsigned deadN_max; // max. count of hops a tracker may fail to connect before being set to inactive
unsigned minTrkN; // minimum track length in hops
unsigned nextTrkId;
unsigned newTrkCnt;
unsigned curTrkCnt;
unsigned deadTrkCnt;
cmWhFilt* wf;
cmVectArray_t* logVa;
cmVectArray_t* levelVa;
cmVectArray_t* specVa;
cmChar_t* logFn;
cmChar_t* levelFn;
cmChar_t* specFn;
} cmFrqTrk;
//
// 1. Calculate the mean spectral magnitude profile over the last hN frames.
// 2. Locate the peaks in the profile.
// 3. Allow each active tracker to select the closest peak to extend its life.
// a) The distance between the trackers current location and a given
// peak is measured based on magnitude and frequency over time.
// b) There is a frequency range limit outside of which a given track-peak
// connection may not go.
// c) There is an amplitude threshold below which a track may not fall.
cmFrqTrk* cmFrqTrkAlloc( cmCtx* c, cmFrqTrk* p, const cmFrqTrkArgs_t* a );
cmRC_t cmFrqTrkFree( cmFrqTrk** pp );
cmRC_t cmFrqTrkInit( cmFrqTrk* p, const cmFrqTrkArgs_t* a );
cmRC_t cmFrqTrkFinal( cmFrqTrk* p );
cmRC_t cmFrqTrkExec( cmFrqTrk* p, const cmReal_t* magV, const cmReal_t* phsV, const cmReal_t* hzV );
void cmFrqTrkPrint( cmFrqTrk* p );
//------------------------------------------------------------------------------------------------------------
enum
@ -787,6 +1019,8 @@ extern "C" {
cmPvAnl* pva;
cmPvSyn* pvs;
cmFrqTrk* ft;
unsigned mode;
double thresh;
@ -869,6 +1103,9 @@ extern "C" {
// colCntV[colCnt] is optional.
cmRC_t cmBinMtxFileRead( cmCtx_t* ctx, const cmChar_t* fn, unsigned rowCnt, unsigned colCnt, unsigned eleByteCnt, void* buf, unsigned* colCntV );
#ifdef __cplusplus
}
#endif