From 7b32da2c04e186f228711180a97d2623e3ec478e Mon Sep 17 00:00:00 2001 From: kevin Date: Thu, 15 Oct 2020 11:59:12 -0400 Subject: [PATCH] Many documentation string additions and updates. --- src/app/cmMidiScoreFollow.h | 12 + src/app/cmScoreMatchGraphic.h | 4 + src/app/cmXScore.h | 13 + src/cmApBuf.c | 10 +- src/cmAudioPort.h | 2 +- src/cmAudioSys.c | 12 +- src/cmJson.c | 5 +- src/cmKeyboard.h | 2 +- src/cmMidiPort.h | 2 +- src/cmPP_NARG.h | 5 +- src/cmPrefix.h | 3 +- src/cmProcTest.c | 1 - src/cmProcTest.h | 4 + src/cmRptFile.h | 4 + src/cmSerialPort.h | 4 + src/cmSvgWriter.h | 5 + src/cmSyncRecd.h | 5 +- src/cmVectOpsDocOut.h | 990 ++++++++++++++++++++++++++++++++ src/cmXml.h | 4 + src/dsp/cmDspBuiltIn.h | 4 + src/dsp/cmDspCtx.h | 4 + src/dsp/cmDspFx.h | 4 + src/dsp/cmDspPgm.h | 4 +- src/dsp/cmDspPgmKr.h | 4 + src/dsp/cmDspPgmKrChain.h | 3 + src/dsp/cmDspPgmPPMain.h | 3 + src/dsp/cmDspUi.h | 2 + src/vop/cmVectOpsDoc.h | 13 +- src/vop/cmVectOpsRICode.h | 196 ++++--- src/vop/cmVectOpsRIHdr.h | 182 ++++-- src/vop/cmVectOpsTemplateCode.h | 763 ++++++++++++------------ src/vop/cmVectOpsTemplateHdr.h | 733 +++++++++++++---------- 32 files changed, 2131 insertions(+), 871 deletions(-) create mode 100644 src/cmVectOpsDocOut.h diff --git a/src/app/cmMidiScoreFollow.h b/src/app/cmMidiScoreFollow.h index 838c728..8796c20 100644 --- a/src/app/cmMidiScoreFollow.h +++ b/src/app/cmMidiScoreFollow.h @@ -5,6 +5,17 @@ #ifdef __cplusplus extern "C" { #endif + + //( { file_desc:"Score follow a MIDI files." kw[score] } + // + // This function uses a CSV score file generated from cmXScoreTest() to score follow a MIDI file. + // Output filesL + // - MIDI file with velocities from the score applied to the associated notes in the MIDI file. + // - A text file, for use with cmTimeLine, which describes the bar positions as absolute times into the score. + // - An SVG file which shows the score match results over time for each note in the score. + // - A report file which lists the score match status over time. + + enum { @@ -24,6 +35,7 @@ extern "C" { const cmChar_t* midiOutFn, // (optional) midiFn with apply sostenuto and velocities from the score to the MIDI file const cmChar_t* tlBarOutFn // (optional) bar positions sutiable for use in a cmTimeLine description file. ); + //) #ifdef __cplusplus } diff --git a/src/app/cmScoreMatchGraphic.h b/src/app/cmScoreMatchGraphic.h index 130d315..02258fc 100644 --- a/src/app/cmScoreMatchGraphic.h +++ b/src/app/cmScoreMatchGraphic.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Implements the functionality of cmMidiScoreFollowMain()." kw[score] } + enum { kOkSmgRC = cmOkRC, @@ -34,6 +36,8 @@ extern "C" { // from from score into MIDI file and then write the updated MIDI // file to 'newMidiFn'. cmSmgRC_t cmScoreMatchGraphicUpdateMidiFromScore( cmCtx_t* ctx, cmSmgH_t h, const cmChar_t* newMidiFn ); + + //) #ifdef __cplusplus } diff --git a/src/app/cmXScore.h b/src/app/cmXScore.h index c412368..b7bb049 100644 --- a/src/app/cmXScore.h +++ b/src/app/cmXScore.h @@ -5,6 +5,17 @@ extern "C" { #endif + //( { file_desc:"Process a Music XML score in a variety of ways." kw[score] } + + //$ + // cmScoreTest() performs a the following functions: + // - Parses Music XML files into a text (edit) file. + // - The 'edit' file can then be manually edited to modify and add information to the score. + // - The modified 'edit' file can then be used to generate a CSV file + // suitable for use with cmScore(), a MIDI file which can render the modified score, + // and a SVG file which will display the score as a piano roll. + // + enum { kOkXsRC = cmOkRC, @@ -73,6 +84,8 @@ extern "C" { // Set begMeasNumb to the first measure the to be written to the output csv, MIDI and SVG files. // Set begBPM to 0 to use the tempo from the score otherwise set it to the tempo at begMeasNumb. cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* reorderFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn, const cmChar_t* svgOutFn, bool reportFl, int begMeasNumb, int begBPM, bool svgStandAloneFl, bool svgPanZoomFl, bool damperRptFl ); + + //) #ifdef __cplusplus } diff --git a/src/cmApBuf.c b/src/cmApBuf.c index 4617a83..7036054 100644 --- a/src/cmApBuf.c +++ b/src/cmApBuf.c @@ -1071,7 +1071,12 @@ void cmApBufReport( cmRpt_t* rpt ) } } -/// [cmApBufExample] +//{ { label:cmApBufExample } +//( +// cmApBufTest() demonstrates the audio buffer usage. +//) + +//( void cmApBufTest( cmRpt_t* rpt ) { @@ -1172,6 +1177,7 @@ void cmApBufTest( cmRpt_t* rpt ) cmApBufFinalize(); } -/// [cmApBufExample] +//) +//} diff --git a/src/cmAudioPort.h b/src/cmAudioPort.h index 21fe271..4eedbd1 100644 --- a/src/cmAudioPort.h +++ b/src/cmAudioPort.h @@ -1,4 +1,4 @@ -//( { file_desc: "Cross platform audio device interface." kw:[audio rt] } +//( { file_desc: "Cross platform audio device interface." kw:[audio rt devices] } // // This interface provides data declarations for platform dependent // audio I/O functions. The implementation for the functions are diff --git a/src/cmAudioSys.c b/src/cmAudioSys.c index 215390f..8fe484a 100644 --- a/src/cmAudioSys.c +++ b/src/cmAudioSys.c @@ -1157,11 +1157,16 @@ unsigned cmAudioSysSubSystemCount( cmAudioSysH_t h ) //=========================================================================================================================== // -// cmAsTest() +// cmAudioSysTest() // -/// [cmAudioSysTest] +//{ { label:cmAudioSysTest } +//( +// cmAudioSysTest() demonstrates the audio system usage. +//) +//( + typedef struct { double hz; // current synth frq @@ -1463,4 +1468,5 @@ void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] ) } -/// [cmAudioSysTest] +//) +//} diff --git a/src/cmJson.c b/src/cmJson.c index 58c210b..701bbdd 100644 --- a/src/cmJson.c +++ b/src/cmJson.c @@ -3994,7 +3994,8 @@ void _cmJsonTestPrint( void* userPtr, const cmChar_t* text ) //( // cmJsonTest() demonstrates some JSON tree operations. //) -//[ + +//( cmJsRC_t cmJsonTest( const char* fn, cmCtx_t* ctx ) { cmJsRC_t rc = kOkJsRC; @@ -4076,5 +4077,5 @@ cmJsRC_t cmJsonTest( const char* fn, cmCtx_t* ctx ) return rc == kOkJsRC ? rc1 : rc; } -//] +//) //} diff --git a/src/cmKeyboard.h b/src/cmKeyboard.h index 13e9a93..1ca3ade 100644 --- a/src/cmKeyboard.h +++ b/src/cmKeyboard.h @@ -5,7 +5,7 @@ extern "C" { #endif - //( { file_desc:"Query and get keypresses directly from the console." kw:[system] } + //( { file_desc:"Query and get keypresses directly from the console." kw:[system devices] } enum { diff --git a/src/cmMidiPort.h b/src/cmMidiPort.h index bb4a2aa..abb44b1 100644 --- a/src/cmMidiPort.h +++ b/src/cmMidiPort.h @@ -5,7 +5,7 @@ extern "C" { #endif - //( { file_desc:"Device independent MIDI port related code." kw:[midi]} + //( { file_desc:"Device independent MIDI port related code." kw:[midi devices]} typedef unsigned cmMpRC_t; diff --git a/src/cmPP_NARG.h b/src/cmPP_NARG.h index edf54ec..498d0e2 100644 --- a/src/cmPP_NARG.h +++ b/src/cmPP_NARG.h @@ -1,7 +1,8 @@ #ifndef cmPP_NARG_H #define cmPP_NARG_H - +//( { file_desc:"Var-args argument counter. " kw:[base] } +// // Taken from here: // https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s // and here: @@ -43,3 +44,5 @@ 9,8,7,6,5,4,3,2,1,0 #endif + +//) diff --git a/src/cmPrefix.h b/src/cmPrefix.h index 948fcda..4a88c53 100644 --- a/src/cmPrefix.h +++ b/src/cmPrefix.h @@ -5,8 +5,9 @@ extern "C" { #endif + //( { file_desc:"Global prefix header for the 'cm' library. Currently empty." kw:[base] } - + //) #ifdef __cplusplus } diff --git a/src/cmProcTest.c b/src/cmProcTest.c index 81da1e3..890dd26 100644 --- a/src/cmProcTest.c +++ b/src/cmProcTest.c @@ -28,7 +28,6 @@ #include // time() - void cmTestPrint( cmRpt_t* rpt, const char* fmt, ... ) { va_list vl; diff --git a/src/cmProcTest.h b/src/cmProcTest.h index f508853..23d7d0b 100644 --- a/src/cmProcTest.h +++ b/src/cmProcTest.h @@ -5,10 +5,14 @@ extern "C" { #endif + //( { file_desc: "Some obsolete test stub functions. See the cmtools project for a complete set of test and example functions." kw:[proc]} + void cmProcTestNoInit( cmCtx_t* ctx ); void cmProcTestGnuPlot( cmCtx_t* ctx ); void cmProcTest( cmCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/src/cmRptFile.h b/src/cmRptFile.h index 0821fd5..d8d9109 100644 --- a/src/cmRptFile.h +++ b/src/cmRptFile.h @@ -4,6 +4,8 @@ #ifdef __cplusplus extern "C" { #endif + + //( { file_desc: "The cmRptFile provides a cmRpt class which outputs to a file." kw:[base]} enum { @@ -23,6 +25,8 @@ extern "C" { cmRpt_t* cmRptFileRpt( cmRptFileH_t h ); + //) + #ifdef __cplusplus } #endif diff --git a/src/cmSerialPort.h b/src/cmSerialPort.h index 3ed5dc2..a44c614 100644 --- a/src/cmSerialPort.h +++ b/src/cmSerialPort.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Serial port interface." kw[system devices rt] } + typedef unsigned cmSeRC_t; enum @@ -86,6 +88,8 @@ extern "C" { cmSeRC_t cmSePortTest(cmCtx_t* ctx); + //) + #ifdef __cplusplus } #endif diff --git a/src/cmSvgWriter.h b/src/cmSvgWriter.h index d8a4ec9..0e9db43 100644 --- a/src/cmSvgWriter.h +++ b/src/cmSvgWriter.h @@ -5,6 +5,9 @@ extern "C" { #endif + //( { file_desc:"SVG file writer." kw[file plot] } + + enum { kOkSvgRC = cmOkRC, @@ -31,6 +34,8 @@ enum // Both the CSS file and svg-pan-zoom.min.js should therefore be in the same directory // as the output HTML file. cmSvgRC_t cmSvgWriterWrite( cmSvgH_t h, const cmChar_t* cssFn, const cmChar_t* outFn, bool standaloneFl, bool panZoomFl ); + + //) #ifdef __cplusplus } diff --git a/src/cmSyncRecd.h b/src/cmSyncRecd.h index d5fdd1d..f4d18dd 100644 --- a/src/cmSyncRecd.h +++ b/src/cmSyncRecd.h @@ -4,6 +4,8 @@ #ifdef __cplusplus extern "C" { #endif + + //( { file_desc:"Generate time-alignment data between an audio and MIDI file. See cmDspSyncRecd_t." kw[proc] } enum { @@ -27,7 +29,8 @@ extern "C" { cmSyRC_t cmSyncRecdTest( cmCtx_t* ctx ); - + //) + #ifdef __cplusplus } #endif diff --git a/src/cmVectOpsDocOut.h b/src/cmVectOpsDocOut.h new file mode 100644 index 0000000..8f9c189 --- /dev/null +++ b/src/cmVectOpsDocOut.h @@ -0,0 +1,990 @@ +//( { file_desc:"Math vector operations." kw:[vop math] } +//) +//( { label:misc desc:"Miscellaneous vector operations." kw:[vop] } + +// Compute the cummulative sum of sbp[dn]. Equivalent to Matlab cumsum(). +T_t* cmVOT_CumSum(T_t* dbp, unsigned dn, const T_t* sbp ); + +// Returns true if all values in each vector are equal. +bool cmVOT_Equal( const T_t* s0p, const T_t* s1p, unsigned sn ); + +// Same as Matlab linspace() v[i] = i * (limit-1)/n +T_t* cmVOT_LinSpace( T_t* dbp, unsigned dn, T_t base, T_t limit ); + +//====================================================================================================================== +//) + + +//( { label:Print desc:"Vector printing functions." kw:[vop] } +// Setting fieldWidth or decPltCnt to to negative values result in fieldWidth == 10 or decPlCnt == 4 +// +void cmVOT_Printf( cmRpt_t* rpt, unsigned rn, unsigned cn, const T_t* dbp, int fieldWidth, int decPlCnt, const char* fmt, unsigned flags ); +void cmVOT_Print( cmRpt_t* rpt, unsigned rn, unsigned cn, const T_t* dbp ); +void cmVOT_PrintE( cmRpt_t* rpt, unsigned rn, unsigned cn, const T_t* dbp ); + +void cmVOT_PrintLf( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const T_t* dbp, unsigned fieldWidth, unsigned decPlCnt, const char* fmt ); +void cmVOT_PrintL( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const T_t* dbp ); +void cmVOT_PrintLE( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const T_t* dbp ); +//====================================================================================================================== +//) + + +//( { label:Normalization desc:"Normalization and standardization functions." kw:[vop] } + +// Normalize the vector of proabilities by dividing through by the sum. +// This leaves the relative proportions of each value unchanged while producing a total probability of 1.0. +// +T_t* cmVOT_NormalizeProbabilityVV(T_t* dbp, unsigned dn, const T_t* sbp); +T_t* cmVOT_NormalizeProbability(T_t* dbp, unsigned dn); +T_t* cmVOT_NormalizeProbabilityN(T_t* dbp, unsigned dn, unsigned stride); +// +// Standardize the columns of the matrix by subtracting the mean and dividing by the standard deviation. +// uV[dcn] returns the mean of the data and is optional. +// sdV[dcn] return the standard deviation of the data and is optional. +T_t* cmVOT_StandardizeRows( T_t* dbp, unsigned drn, unsigned dcn, T_t* uV, T_t* sdV ); +T_t* cmVOT_StandardizeCols( T_t* dbp, unsigned drn, unsigned dcn, T_t* uV, T_t* sdV ); +// +// Normalize by dividing through by the max. value. +// dp[] ./= max(dp). Returns the index of the max value. +unsigned cmVOT_NormToMax( T_t* dp, unsigned dn ); +// +// Normalize by dividing through by the max. absolute value. +// db[] .*= fact / abs(max(dp)); +unsigned cmVOT_NormToAbsMax( T_t* dp, unsigned dn, T_t fact ); +//====================================================================================================================== +//) + + +//( { label:"Mean and variance" desc:"Compute mean and variance." kw:[vop] } + +T_t cmVOT_Mean( const T_t* sp, unsigned sn ); +T_t cmVOT_MeanN( const T_t* sp, unsigned sn, unsigned stride ); +// +// Take the mean of each column/row of a matrix. +// Set 'dim' to 0 to return mean of columns else return mean of rows. +T_t* cmVOT_MeanM( T_t* dp, const T_t* sp, unsigned srn, unsigned scn, unsigned dim ); +// +// Take the mean of the first 'cnt' element of each column/row of a matrix. +// Set 'dim' to 0 to return mean of columns else return mean of rows. +// If 'cnt' is greater than the number of elements in the column/row then 'cnt' is +// reduced to the number of elements in the column/row. +T_t* cmVOT_MeanM2( T_t* dp, const T_t* sp, unsigned srn, unsigned scn, unsigned dim, unsigned cnt ); +// +// Find the mean of the data points returned by srcFuncPtr(argPtr,i) and return it in dp[dim]. +// 'dim' is both the size of dp[] and the length of each data point returned by srcFuncPtr(). +// srcFuncPtr() will be called 'cnt' times but it may return NULL on some calls if the associated +// data point should not be included in the mean calculation. +T_t* cmVOT_Mean2( T_t* dp, const T_t* (*srcFuncPtr)(void* arg, unsigned idx ), unsigned dim, unsigned cnt, void* argPtr ); +// +// avgPtr is optional - set to NULL to compute the average +T_t cmVOT_Variance( const T_t* sp, unsigned sn, const T_t* avgPtr ); +T_t cmVOT_VarianceN(const T_t* sp, unsigned sn, unsigned stride, const T_t* avgPtr ); +// +// Set dim=0 to return variance of columns otherwise return variance or rows. +T_t* cmVOT_VarianceM(T_t* dp, const T_t* sp, unsigned srn, unsigned scn, const T_t* avgPtr, unsigned dim ); +//====================================================================================================================== +//) + + +//( { label:"Covariance" desc:"Matrix covariance" kw:[vop] } + +// Calculate the sample covariance matrix from a set of Gaussian distributed multidimensional data. +// sp[dn,scn] is the data set. +// dn is the dimensionality of the data. +// scn is the count of data points +// up[dn] is an optional mean vector. If up == NULL then the mean of the data is calculated internally. +// selIdxV[scn] can be used to select a subset of datapoints to process. +// If selIdxV[] is non-NULL then only columns where selIdxV[i]==selKey will be processed. +// +// dp[dn,dn] = covar( sp[dn,scn], u[dn] ) +void cmVOT_GaussCovariance(T_t* dp, unsigned dn, const T_t* sp, unsigned scn, const T_t* up, const unsigned* selIdxV, unsigned selKey ); + +// Calculate the sample covariance matrix. +// dp[ dn*dn ] - output matrix +// dn - dimensionality of the data +// srcFuncPtr - User defined function which is called to return a pointer to a data vector at index 'idx'. +// The returned data vector must contain 'dn' elements. The function should return NULL +// if the data point associated with 'idx' should not be included in the covariance calculation. +// sn - count of data vectors +// userPtr - User arg. passed to srcFuncPtr. +// uV[ dn ] - mean of the data set (optional) +// Note that this function computes the covariance matrix in 2 serial passes (1 if the mean vector is given) +// through the 'sn' data points. +// The result of this function are identical to the octave cov() function. +void cmVOT_GaussCovariance2(T_t* dp, unsigned dn, const T_t* (*srcFuncPtr)(void* userPtr, unsigned idx), unsigned sn, void* userPtr, const T_t* uV, const unsigned* selIdxV, unsigned selKey ); +//====================================================================================================================== +//) + +//( { label:"Float point normal" desc:"Evaluate the 'normalness of floating point values." kw:[vop] } + +// Returns true if all values are 'normal' according the the C macro 'isnormal'. +// This function will return false if any of the values are zero. +bool cmVOT_IsNormal( const T_t* sp, unsigned sn ); + +// Returns true if all values are 'normal' or zero according the the C macro 'isnormal'. +// This function accepts zeros as normal. +bool cmVOT_IsNormalZ(const T_t* sp, unsigned sn ); + +// Set dp[dn] to the indexes of the non-normal numbers in sp[dn]. +// Returns the count of indexes stored in dp[]. +unsigned cmVOT_FindNonNormal( unsigned* dp, unsigned dn, const T_t* sp ); +unsigned cmVOT_FindNonNormalZ( unsigned* dp, unsigned dn, const T_t* sp ); +//====================================================================================================================== +//) + + +//( { label:"Measure" desc:"Measure features of a vector." kw:[vop] } + +// Successive call to to ZeroCrossCount should preserve the value pointed to by delaySmpPtr. +unsigned cmVOT_ZeroCrossCount( const T_t* sp, unsigned n, T_t* delaySmpPtr); + +// Calculuate the sum of the squares of all elements in bp[bn]. +T_t cmVOT_SquaredSum( const T_t* bp, unsigned bn ); + +// sn must be <= wndSmpCnt. If sn < wndSmpCnt then sp[sn] is treated as a +// a partially filled buffer padded with wndSmpCnt-sn zeros. +// rms = sqrt( sum(sp[1:sn] .* sp[1:sn]) / wndSmpCnt ) +T_t cmVOT_RMS( const T_t* sp, unsigned sn, unsigned wndSmpCnt ); + +// This function handles the case were sn is not an integer multiple of +// wndSmpCnt or hopSmpCnt. In this case the function computes zero +// padded RMS values for windows which go past the end of sp[sn]. +T_t* cmVOT_RmsV( T_t* dp, unsigned dn, const T_t* sp, unsigned sn, unsigned wndSmpCnt, unsigned hopSmpCnt ); + +// Return the magnitude (Euclidean Norm) of a vector. +T_t cmVOT_EuclidNorm( const T_t* sp, unsigned sn ); + +T_t cmVOT_AlphaNorm(const T_t* sp, unsigned sn, T_t alpha ); + +//====================================================================================================================== +//) + + + +//( { label:"Distance" desc:"Calculate various vector distances." kw:[vop] } + +// Return the Itakura-Saito distance between a modelled power spectrum (up) and another power spectrum (sp). +T_t cmVOT_ItakuraDistance( const T_t* up, const T_t* sp, unsigned sn ); + +// Return the cosine distance between two vectors. +T_t cmVOT_CosineDistance( const T_t* s0P, const T_t* s1p, unsigned sn ); + +// Return the Euclidean distance between two vectors +T_t cmVOT_EuclidDistance( const T_t* s0p, const T_t* s1p, unsigned sn ); + +// Return the Manhattan distance between two vectors +T_t cmVOT_L1Distance( const T_t* s0p, const T_t* s1p, unsigned sn ); + +// Return the Mahalanobis distance between a vector and the mean of the distribution. +// The mean vector could be replaced with another vector drawn from the same distribution in which +// case the returned value would reflect the distance between the two vectors. +// 'sn' is the dimensionality of the data. +// up[D] and invCovM[sn,sn] are the mean and inverse of the covariance matrix of the distribution from +// which sp[D] is drawn. +T_t cmVOT_MahalanobisDistance( const T_t* sp, unsigned sn, const T_t* up, const T_t* invCovM ); + +// Return the KL distance between two probability distributions up[sn] and sp[sn]. +// Since up[] and sp[] are probability distributions they must sum to 1.0. +T_t cmVOT_KL_Distance( const T_t* up, const T_t* sp, unsigned sn ); + +// Return the KL distance between a prototype vector up[sn] and another vector sp[sn]. +// This function first normalizes the two vectors to sum to 1.0 before calling +// cmVOT_KL_Distance(up,sp,sn); +T_t cmVOT_KL_Distance2( const T_t* up, const T_t* sp, unsigned sn ); + + +// Measure the Euclidean distance between a vector and all the columns in a matrix. +// If dv[scn] is no NULL then return the Euclidean distance from sv[scn] to each column of sm[srn,scn]. +// The function returns the index of the closest data point (column) in sm[]. +unsigned cmVOT_EuclidDistanceVM( T_t* dv, const T_t* sv, const T_t* sm, unsigned srn, unsigned scn ); + +// Measure the distance between each column in s0M[ rn, s0cn ] and +// each column in s1M[rn, s1cn ]. If dM is non-NULL store the +// result in dM[s1cn, s0cn]. The difference between s0M[:,0] and s1M[:,0] +// is stored in dM[0,0], the diff. between s0M[:,1] and s1M[:,1] is stored +// in dM[1,0], etc. If mvV[s0cn] is non-NULL then minV[i] is set with +// the distance from s0M[:,i] to the nearest column in s1M[]. If miV[s0cn] +// is non-NULL then it is set with the column index of s1M[] which is +// closest to s0M[:,i]. In other words mvV[i] gives the distance to column +// miV[i] from column s0M[:,i]. +// In those cases where the distane from a prototype (centroid) to the data point +// is not the same as from the data point to the centroid then s1M[] is considered +// to hold the prototypes and s0M[] is considered to hold the data points. +// The distance function returns the distance from a prototype 'cV[dimN]' to +// an datapoint dV[dimN]. 'dimN' is the dimensionality of the data vector +// and is threfore equal to 'rn'. +void cmVOT_DistVMM( + T_t* dM, // dM[s1cn,s0cn] return distance mtx (optional) + T_t* mvV, // mvV[s0cn] distance to closest data point in s0M[]. (optional) + unsigned* miV, // miV[s0cn] column index into s1M[] of closest data point to s0M[:,i]. (optional) + unsigned rn, // dimensionality of the data and the row count for s0M[] and s1M[] + const T_t* s0M, // s0M[rn,s0cn] contains one data point per column + unsigned s0cn, // count of data points (count of columns in s0M[] + const T_t* s1M, // s1M[rn,s1cn] contains one prototype per column + unsigned s1cn, // count of prototypes (count of columns in s1m[] + T_t (*distFunc)( void* userPtr, const T_t* cV, const T_t* dV, unsigned dimN ), + void* userPtr ); + +//====================================================================================================================== +//) + +//( { label:"Select columns" desc:"Select columns based on distance." kw:[vop] } + +// Select 'selIdxN' columns from sM[srn,scn]. +// dM[srn,selIdxN] receives copies of the selected columns. +// selIdxV[selIdxN] receives the column indexes of the selected columns. +// Both dM[] and selIdxV[] are optional. +// In each case the first selected point is chosen at random. +// SelectRandom() then selects the following selIdxN-1 points at random. +// SelectMaxDist() selects the next selIdxN-1 points by selecting +// the point whose combined distance to the previously selected points +// is greatest. SelectMaxAvgDist() selectes the points whose combined +// average distance is greatest relative the the previously selected +// points. +void cmVOT_SelectRandom( T_t* dM, unsigned* selIdxV, unsigned selIdxN, const T_t* sM, unsigned srn, unsigned scn ); +void cmVOT_SelectMaxDist( T_t* dM, unsigned* selIdxV, unsigned selIdxN, const T_t* sM, unsigned srn, unsigned scn, T_t (*distFunc)( void* userPtr, const T_t* s0V, const T_t* s1V, unsigned sn ), void* distUserPtr ); +void cmVOT_SelectMaxAvgDist( T_t* dM, unsigned* selIdxV, unsigned selIdxN, const T_t* sM, unsigned srn, unsigned scn, T_t (*distFunc)( void* userPtr, const T_t* s0V, const T_t* s1V, unsigned sn ), void* distUserPtr ); + +//====================================================================================================================== +//) + +//( { label:"Matrix multiplication" desc:"Various matrix multiplication operations." kw:[vop] } + +// Return the sum of the products (dot product) +T_t cmVOT_MultSumVV( const T_t* s0p, const T_t* s1p, unsigned sn ); +T_t cmVOT_MultSumVS( const T_t* s0p, unsigned sn, T_t s ); + +// Number of elements in the dest vector is expected to be the same +// as the number of source matrix rows. +// mcn gives the number of columns in the source matrix which is +// expected to match the number of elements in the source vector. +// dbp[dn,1] = mp[dn,mcn] * vp[mcn,1] +T_t* cmVOT_MultVMV( T_t* dbp, unsigned dn, const T_t* mp, unsigned mcn, const T_t* vp ); + +// Multiply a row vector with a matrix to produce a row vector. +// dbp[1,dn] = v[1,vn] * m[vn,dn] +T_t* cmVOT_MultVVM( T_t* dbp, unsigned dn, const T_t* vp, unsigned vn, const T_t* mp ); + +// Same as MultVMtV() except M is transposed as part of the multiply. +// mrn gives the number of rows in m[] and number of elements in vp[] +// dpb[dn] = mp[mrn,dn] * vp[mrn] +T_t* cmVOT_MultVMtV( T_t* dbp, unsigned dn, const T_t* mp, unsigned mrn, const T_t* vp ); + +// Same as MultVMV() but where the matrix is diagonal. +T_t* cmVOT_MultDiagVMV( T_t* dbp, unsigned dn, const T_t* mp, unsigned mcn, const T_t* vp ); + +// Generalized matrix multiply. +// If transposition is selected for M0 or M1 then the given dimension represent the size of the matrix 'after' the transposion. +// d[drn,dcn] = alpha * op(m0[drn,m0cn_m1rn]) * op(m1[m0cn_m1rn,dcn]) + beta * d[drn,dcn] +/// See enum { kTranpsoseM0Fl=0x01, kTransposeM1Fl=0x02 } in cmVectOps for flags. +T_t* cmVOT_MultMMM1(T_t* dbp, unsigned drn, unsigned dcn, T_t alpha, const T_t* m0, const T_t* m1, unsigned m0cn_m1rn, T_t beta, unsigned flags ); + +// Same a cmVOT_MultMMM1 except allows the operation on a sub-matrix by providing the physical (memory) row count rather than the logical (matrix) row count. +T_t* cmVOT_MultMMM2(T_t* dbp, unsigned drn, unsigned dcn, T_t alpha, const T_t* m0, const T_t* m1, unsigned m0cn_m1rn, T_t beta, unsigned flags, unsigned dprn, unsigned m0prn, unsigned m1prn ); + +// d[drn,dcn] = m0[drn,m0cn] * m1[m1rn,dcn] +T_t* cmVOT_MultMMM( T_t* dbp, unsigned drn, unsigned dcn, const T_t* m0, const T_t* m1, unsigned m0cn_m1rn ); + +// same as MultMMM() except second source matrix is transposed prior to the multiply +T_t* cmVOT_MultMMMt(T_t* dbp, unsigned drn, unsigned dcn, const T_t* m0, const T_t* m1, unsigned m0cn_m1rn ); + +//====================================================================================================================== +//) + +//( { label:"Linear algebra" desc:"Miscellaneous linear algebra operations. Determinant, Inversion, Cholesky decompostion. Linear system solver." kw:[vop] } + +// Initialize dbp[dn,dn] as a square symetric positive definite matrix using values +// from a random uniform distribution. This is useful for initializing random +// covariance matrices as used by multivariate Gaussian distributions +// If t is non-NULL it must point to a block of scratch memory of t[dn,dn]. +// If t is NULL then scratch memory is internally allocated and deallocated. +T_t* cmVOT_RandSymPosDef( T_t* dbp, unsigned dn, T_t* t ); + + +// Compute the determinant of any square matrix. +T_t cmVOT_DetM( const T_t* sp, unsigned srn ); + +// Compute the determinant of a diagonal matrix. +T_t cmVOT_DetDiagM( const T_t* sp, unsigned srn); + +// Compute the log determinant of any square matrix. +T_t cmVOT_LogDetM( const T_t* sp, unsigned srn ); + +// Compute the log determinant of a diagonal matrix. +T_t cmVOT_LogDetDiagM( const T_t* sp, unsigned srn); + + +// Compute the inverse of a square matrix. Returns NULL if the matrix is not invertable. +// 'drn' is the dimensionality of the data. +T_t* cmVOT_InvM( T_t* dp, unsigned drn ); + +// Compute the inverse of a diagonal matrix. Returns NULL if the matrix is not invertable. +T_t* cmVOT_InvDiagM( T_t* dp, unsigned drn ); + +// Solve a linear system of the form AX=B where A[an,an] is square. +// Since A is square B must have 'an' rows. +// Result is returned in B. +// Returns a pointer to B on success or NULL on fail. +// NOTE: Both A and B are overwritten by this operation. +T_t* cmVOT_SolveLS( T_t* A, unsigned an, T_t* B, unsigned bcn ); + +// Perform a Cholesky decomposition of the square symetric matrix U[un,un]. +// The factorization has the form: A=U'TU. +// If the factorization is successful A is set to U and a pointer to A is returned. +// Note that the lower triangle of A is not overwritten. See CholZ(). +// If the factorization fails NULL is returned. +T_t* cmVOT_Chol(T_t* A, unsigned an ); + +// Same as Chol() but sets the lower triangle of U to zero. +// This is equivalent ot the Matlab version. +T_t* cmVOT_CholZ(T_t* U, unsigned un ); + +// Calculate the best fit line: b0 + b1*x_i through the points x_i,y_i. +// Set x to NULL if it uses sequential integers [0,1,2,3...] +void cmVOT_Lsq1(const T_t* x, const T_t* y, unsigned n, T_t* b0, T_t* b1 ); + + +//====================================================================================================================== +//) + +//( { label:"Stretch/Shrink" desc:"Stretch or shrink a vector by resampling." kw:[vop] } + +// Return the average value of the contents of sbp[] between two fractional indexes +T_t cmVOT_FracAvg( double bi, double ei, const T_t* sbp, unsigned sn ); + +// Shrinking function - Decrease the size of sbp[] by averaging blocks of values into single values in dbp[] +T_t* cmVOT_DownSampleAvg( T_t* dbp, unsigned dn, const T_t* sbp, unsigned sn ); + +// Stretching function - linear interpolate between points in sbp[] to fill dbp[] ... where dn > sn +T_t* cmVOT_UpSampleInterp( T_t* dbp, unsigned dn, const T_t* sbp, unsigned sn ); + +// Stretch or shrink the sbp[] to fit into dbp[] +T_t* cmVOT_FitToSize( T_t* dbp, unsigned dn, const T_t* sbp, unsigned sn ); + +// Stretch or shrink sV[] to fit into dV[] using a simple linear mapping. +// When stretching (sndn) each dest value is formed by the average of sequential segments +// of sn/dn source elements. Fractional values are used at the beginning +// and end of each segment. +T_t* cmVOT_LinearMap(T_t* dV, unsigned dn, T_t* sV, unsigned sn ); + +//====================================================================================================================== +//) + +//( { label:"Random number generation" desc:"Generate random numbers." kw:[vop] } + +// Generate a vector of uniformly distributed random numbers in the range minVal to maxVal. +T_t* cmVOT_Random( T_t* dbp, unsigned dn, T_t minVal, T_t maxVal ); + +// Generate dn random numbers integers between 0 and wn-1 based on a the relative +// weights in wp[wn]. Note thtat the weights do not have to sum to 1.0. +unsigned* cmVOT_WeightedRandInt( unsigned* dbp, unsigned dn, const T_t* wp, unsigned wn ); + +// Generate a vector of normally distributed univariate random numbers +T_t* cmVOT_RandomGauss( T_t* dbp, unsigned dn, T_t mean, T_t var ); + +// Generate a vector of normally distributed univariate random numbers where each value has been drawn from a +// seperately parameterized Gaussian distribution. meanV[] and varV[] must both contain dn velues. +T_t* cmVOT_RandomGaussV( T_t* dbp, unsigned dn, const T_t* meanV, const T_t* varV ); + +// Generate a matrix of multi-dimensional random values. Each column represents a single vector value and each row contains a dimension. +// meanV[] and varV[] must both contain drn elements where each meanV[i],varV[i] pair parameterize one dimensions Gaussian distribution. +T_t* cmVOT_RandomGaussM( T_t* dbp, unsigned drn, unsigned dcn, const T_t* meanV, const T_t* varV ); +T_t* cmVOT_RandomGaussDiagM( T_t* dbp, unsigned drn, unsigned dcn, const T_t* meanV, const T_t* diagCovarM ); + +// Generate a matrix of multivariate random values drawn from a normal distribution. +// The dimensionality of the values are 'drn'. +// The count of returned values is 'dcn'. +// meanV[drn] and covarM[drn,drn] parameterize the normal distribution. +// The covariance matrix must be symetric and positive definite. +// t[(drn*drn) ] points to scratch memory or is set to NULL if the function should +// allocate the memory internally. +// Based on octave function mvrnd.m. +T_t* cmVOT_RandomGaussNonDiagM( T_t* dbp, unsigned drn, unsigned dcn, const T_t* meanV, const T_t* covarM, T_t* t ); + +// Same as RandomGaussNonDiagM() except requires the upper trianglular +// Cholesky factor of the covar matrix in 'uM'. +T_t* cmVOT_RandomGaussNonDiagM2( T_t* dbp, unsigned drn, unsigned dcn, const T_t* meanV, const T_t* uM ); + + +// Generate a matrix of N*K multi-dimensional data points. +// Where D is the dimensionality of the data. (D == drn). +// K is the number of multi-dimensional PDF's (clusters). +// N is the number of data points to generate per cluster. +// dbp[ D, N*K ] contains the returned data point. +// The first N columns is associated with the cluster 0, +// the next N columns is associated with cluster 1, ... +// meanM[ D, K ] and varM[D,K] parameterize the generating PDF.s for each cluster +T_t* cmVOT_RandomGaussMM( T_t* dbp, unsigned drn, unsigned dcn, const T_t* meanM, const T_t* varM, unsigned K ); + + +// Evaluate the univariate normal distribution defined by 'mean' and 'stdDev'. +T_t* cmVOT_GaussPDF( T_t* dbp, unsigned dn, const T_t* sbp, T_t mean, T_t stdDev ); + +// Evaluate a multivariate normal distribution defined by meanV[D] and covarM[D,D] +// at the data points held in the columns of xM[D,N]. Return the evaluation +// results in the vector yV[N]. D is the dimensionality of the data. N is the number of +// data points to evaluate and values to return in yV[N]. +// Set diagFl to true if covarM is diagonal. +// The function fails and returns false if the covariance matrix is singular. +bool cmVOT_MultVarGaussPDF( T_t* yV, const T_t* xM, const T_t* meanV, const T_t* covarM, unsigned D, unsigned N, bool diagFl ); + +// Same as multVarGaussPDF[] except takes the inverse covar mtx invCovarM[D,D] +// and log determinant of covar mtx. +// Always returns yV[]. +T_t* cmVOT_MultVarGaussPDF2( T_t* yV, const T_t* xM, const T_t* meanV, const T_t* invCovarM, T_t logDet, unsigned D, unsigned N, bool diagFl ); + +// Same as multVarGaussPDF[] except uses a function to obtain the data vectors. +// srcFunc() can filter the data points by returning NULL if the data vector at frmIdx should +// not be evaluated against the PDF. In this case yV[frmIdx] will be set to 0. +T_t* cmVOT_MultVarGaussPDF3( + T_t* yV, + const T_t* (*srcFunc)(void* funcDataPtr, unsigned frmIdx ), + void* funcDataPtr, + const T_t* meanV, + const T_t* invCovarM, + T_t logDet, + unsigned D, + unsigned N, + bool diagFl ); + + +//====================================================================================================================== +//) + + +//( { label:"Signal generators" desc:"Generate periodic signals." kw:[vop] } + +// The following functions all return the phase of the next value. +unsigned cmVOT_SynthSine( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz ); +unsigned cmVOT_SynthCosine( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz ); +unsigned cmVOT_SynthSquare( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz, unsigned otCnt ); +unsigned cmVOT_SynthTriangle( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz, unsigned otCnt ); +unsigned cmVOT_SynthSawtooth( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz, unsigned otCnt ); +unsigned cmVOT_SynthPulseCos( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz, unsigned otCnt ); +unsigned cmVOT_SynthImpulse( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz ); +unsigned cmVOT_SynthPhasor( T_t* dbp, unsigned dn, unsigned phase, double srate, double hz ); + + +// Return value should be passed back via delaySmp on the next call. +T_t cmVOT_SynthPinkNoise( T_t* dbp, unsigned dn, T_t delaySmp ); + +//====================================================================================================================== +//) + +//( { label:"Exponential conversion" desc:"pow() and log() functions." kw:[vop] } + +// Raise dbp[] to the power 'expon' +T_t* cmVOT_PowVS( T_t* dbp, unsigned dn, T_t expon ); +T_t* cmVOT_PowVVS( T_t* dbp, unsigned dn, const T_t* sp, T_t expon ); + +// Take the natural log of all values in sbp[dn]. It is allowable for sbp point to the same array as dbp=. +T_t* cmVOT_LogV( T_t* dbp, unsigned dn, const T_t* sbp ); + +//====================================================================================================================== +//) + +//( { label:"dB Conversions" desc:"Convert vectors between dB,linear and power representations." kw:[vop] } + +// Convert a magnitude (amplitude) spectrum to/from decibels. +// It is allowable for dbp==sbp. +T_t* cmVOT_AmplToDbVV( T_t* dbp, unsigned dn, const T_t* sbp, T_t minDb ); +T_t* cmVOT_DbToAmplVV( T_t* dbp, unsigned dn, const T_t* sbp); + +T_t* cmVOT_PowToDbVV( T_t* dbp, unsigned dn, const T_t* sbp, T_t minDb ); +T_t* cmVOT_DbToPowVV( T_t* dbp, unsigned dn, const T_t* sbp); + +T_t* cmVOT_LinearToDb( T_t* dbp, unsigned dn, const T_t* sp, T_t mult ); +T_t* cmVOT_dBToLinear( T_t* dbp, unsigned dn, const T_t* sp, T_t mult ); +T_t* cmVOT_AmplitudeToDb( T_t* dbp, unsigned dn, const T_t* sp ); +T_t* cmVOT_PowerToDb( T_t* dbp, unsigned dn, const T_t* sp ); +T_t* cmVOT_dBToAmplitude( T_t* dbp, unsigned dn, const T_t* sp ); +T_t* cmVOT_dBToPower( T_t* dbp, unsigned dn, const T_t* sp ); +//====================================================================================================================== +//) + +//( { label:"DSP Windows" desc:"DSP windowing functions." kw:[vop] } + +T_t cmVOT_KaiserBetaFromSidelobeReject( double sidelobeRejectDb ); +T_t cmVOT_KaiserFreqResolutionFactor( double sidelobeRejectDb ); +T_t* cmVOT_Kaiser( T_t* dbp, unsigned dn, double beta ); +T_t* cmVOT_Gaussian(T_t* dbp, unsigned dn, double mean, double variance ); +T_t* cmVOT_Hamming( T_t* dbp, unsigned dn ); +T_t* cmVOT_Hann( T_t* dbp, unsigned dn ); +T_t* cmVOT_Triangle(T_t* dbp, unsigned dn ); + +// The MATLAB equivalent Hamming and Hann windows. +//T_t* cmVOT_HammingMatlab(T_t* dbp, unsigned dn ); +T_t* cmVOT_HannMatlab( T_t* dbp, unsigned dn ); + +// Simulates the MATLAB GaussWin function. Set arg to 2.5 to simulate the default arg +// as used by MATLAB. +T_t* cmVOT_GaussWin( T_t* dbp, unsigned dn, double arg ); +//====================================================================================================================== +//) + +//( { label:"DSP Filters" desc:"DSP filtering functions." kw:[vop] } + +// Direct form II algorithm based on the MATLAB implmentation +// http://www.mathworks.com/access/helpdesk/help/techdoc/ref/filter.html#f83-1015962 +// The only difference between this function and the equivalent MATLAB filter() function +// is that the first feedforward coeff is given as a seperate value. The first b coefficient +// in this function is therefore the same as the second coefficient in the MATLAB function. +// and the first a[] coefficient (which is generally set to 1.0) is skipped. +// Example: +// Matlab: b=[.5 .4 .3] a=[1 .2 .1] +// Equiv: b0 = .5 b=[ .4 .3] a=[ .2 .1]; +// +// y[yn] - output vector +// x[xn] - input vector. xn must be <= yn. if xn < yn then the end of y[] is set to zero. +// b0 - signal scale. This can also be seen as b[0] (which is not included in b[]) +// b[dn] - feedforward coeff's b[1..dn-1] +// a[dn] - feedback coeff's a[1..dn-1] +// d[dn+1] - delay registers - note that this array must be one element longer than the coeff arrays. +// +T_t* cmVOT_Filter( T_t* y, unsigned yn, const T_t* x, unsigned xn, cmReal_t b0, const cmReal_t* b, const cmReal_t* a, cmReal_t* d, unsigned dn ); + +struct cmFilter_str; +//typedef cmRC_t (*cmVOT_FiltExecFunc_t)( struct acFilter_str* f, const T_t* x, unsigned xn, T_t* y, unsigned yn ); +T_t* cmVOT_FilterFilter(struct cmFilter_str* f, cmRC_t (*func)( struct cmFilter_str* f, const T_t* x, unsigned xn, T_t* y, unsigned yn ), const cmReal_t bb[], unsigned bn, const cmReal_t aa[], unsigned an, const T_t* x, unsigned xn, T_t* y, unsigned yn ); + +// Compute the coefficients of a low/high pass FIR filter +// wndV[dn] gives the window function used to truncate the ideal low-pass impulse response. +// Set wndV to NULL to use a unity window. +// See enum { kHighPass_LPSincFl=0x01, kNormalize_LPSincFl=0x02 } in cmVectOps.h +T_t* cmVOT_LP_Sinc(T_t* dp, unsigned dn, const T_t* wndV, double srate, double fcHz, unsigned flags ); + + + +//====================================================================================================================== +//) + +//( { label:"Spectral Masking" desc:"A collection of spectral masking functions." kw:[vop] } + +// Compute a set of filterCnt mel filter masks for wieghting magnitude spectra consisting of binCnt bins. +// The spectrum is divided into bandCnt equal bands in the mel domain +// Each row of the matrix contains the mask for a single filter band consisting of binCnt elements. +// See enum{ kShiftMelFl=0x01, kNormalizeMelFl=0x02 } in cmVectOps.h +// Set kShiftMelFl to shift the mel bands onto the nearest FFT bin. +// Set kNormalizeMelFl to normalize the combined filters for unity gain. +T_t* cmVOT_MelMask( T_t* maskMtx, unsigned bandCnt, unsigned binCnt, double srate, unsigned flags ); + +// Fill binIdxV[bandCnt] and cntV[bandCnt] with a bin to band map. +// binIdx[] contains the first (minimum) bin index for a given band. +// cntV[] contains the count of bins for each band. +// bandCnt is the number of bark bands to return +// The function returns the actual number of bands mapped which will always be <= 23. +unsigned cmVOT_BarkMap(unsigned* binIdxV, unsigned* cntV, unsigned bandCnt, unsigned binCnt, double srate ); + +// Calc a set of triangle fitler masks into each row of maskMtx. +// maskMtx[ bandCnt, binCnt ] - result matrix +// binHz - freq resolution of the output filters. +// stSpread - Semi-tone spread above and below each center frequency (stSpread*2) is the total bandwidth. +// (Only used if lowHzV or uprHzV are NULL) +// lowHz[ bandCnt ] - set of upper frequency limits for each band. +// ctrHz[ bandCnt ] set to the center value in Hz for each band +// uprHz[ bandCnt ] - set of lower frequency limits for each band. +// Note if lowHz[] and uprHz[] are set to NULL then stSpread is used to set the bandwidth of each band. +T_t* cmVOT_TriangleMask(T_t* maskMtx, unsigned bandCnt, unsigned binCnt, const T_t* ctrHzV, T_t binHz, T_t stSpread, const T_t* lowHzV, const T_t* uprHzV ); + +// Calculate a set of Bark band triangle filters into maskMtx. +// Each row of maskMtx contains the filter for one band. +// maskMtx[ bandCnt, binCnt ] +// bandCnt - the number of triangle bankds. If bandCnt is > 24 it will be reduced to 24. +// binCnt - the number of bins in the filters. +// binHz - the width of each bin in Hz. +T_t* cmVOT_BarkMask(T_t* maskMtx, unsigned bandCnt, unsigned binCnt, double binHz ); + +// Terhardt 1979 (Calculating virtual pitch, Hearing Research #1, pp 155-182) +// See enum { kNoTtmFlags=0, kModifiedTtmFl=0x01 } in cmVectOps.h +T_t* cmVOT_TerhardtThresholdMask(T_t* maskV, unsigned binCnt, double srate, unsigned flags); + +//Schroeder et al., 1979, JASA, Optimizing digital speech coders by exploiting masking properties of the human ear +T_t* cmVOT_ShroederSpreadingFunc(T_t* m, unsigned bandCnt, double srate); + +//====================================================================================================================== +//) + +//( { label:"Machine learning" desc:"K-means clustering and Viterbi algorithms." kw:[vop] } + +// Assign each data point to one of k clusters using an expectation-maximization algorithm. +// k gives the number of clusters to identify +// Each column of sp[ srn, scn ] contains a multidimensional data point. +// srn therefore defines the dimensionality of the data. +// Each column of centroidV[ srn, k ] is set to the centroid of each of k clusters. +// classIdxV[ scn ] assigns the index (0 to k-1) of a cluster to each soure data point +// The function returns the number of iterations required for the EM process to converge. +// selIdxV[ scn ] is optional and contains a list of id's assoc'd with each column of sM. +// selKey is a integer value. +// If selIdxV is non-NULL then only columns of sM[] where selIdxV[] == selKey will be clustered. +// All columns of sM[] where the associated column in selIdxV[] do not match will be ignored. +// Set 'initFromCentroidFl' to true if the initial centroids should be taken from centroidM[]. +// otherwise the initial centroids are selected from 'k' random data points in sp[]. +// The distance function distFunc(cV,dV,dN) is called to determine the distance from a +// centroid the centroid 'cV[dN]' to a data point 'dV[dN]'. 'dN' is the dimensionality of the +// feature vector and is therefore equal to 'srn'. +unsigned cmVOT_Kmeans( + unsigned* classIdxV, + T_t* centroidM, + unsigned k, + const T_t* sp, + unsigned srn, + unsigned scn, + const unsigned* selIdxV, + unsigned selKey, + bool initFromCentroidFl, + T_t (*distFunc)( void* userPtr, const T_t* cV, const T_t* dV, unsigned dN ), + void* userDistPtr ); + +// 'srcFunc() should return NULL if the data point located at 'frmIdx' should not be included in the clustering. +// Clustering is considered to be complete after 'maxIterCnt' iterations or when +// 'deltaStopCnt' or fewer data points change class on a single iteration +unsigned cmVOT_Kmeans2( + unsigned* classIdxV, // classIdxV[scn] - data point class assignments + T_t* centroidM, // centroidM[srn,K] - cluster centroids + unsigned K, // count of clusters + const T_t* (*srcFunc)(void* userPtr, unsigned frmIdx ), + unsigned srn, // dimensionality of each data point + unsigned scn, // count of data points + void* userSrcPtr, // callback data for srcFunc + T_t (*distFunc)( void* userPtr, const T_t* cV, const T_t* dV, unsigned dN ), + void* userDistPtr, // arg. to distFunc() + int iterCnt, // max. number of iterations (-1 to ignore) + int deltaStopCnt); // if less than deltaStopCnt data points change classes on a given iteration then convergence occurs. + +// Determine the most likely state sequece stateV[timeN] given a +// transition matrix a[stateN,stateN], +// observation probability matrix b[stateN,timeN] and +// initial state probability vector phi[stateN]. +// a[i,j] is the probability of transitioning from state i to state j. +// b[i,t] is the probability of state i emitting the obj t. +void cmVOT_DiscreteViterbi(unsigned* stateV, unsigned timeN, unsigned stateN, const T_t* phi, const T_t* a, const T_t* b ); + + +//====================================================================================================================== +//) + +//( { label:"Graphics" desc:"Graphics related algorithms." kw:[vop] } + +// Generate the set of coordinates which describe a circle with a center at x,y. +// dbp[dn,2] must contain 2*dn elements. The first column holds the x coord and and the second holds the y coord. +T_t* cmVOT_CircleCoords( T_t* dbp, unsigned dn, T_t x, T_t y, T_t varX, T_t varY ); + +// Clip the line defined by x0,y0 to x1,y1 into the rect defined by xMin,yMin xMax,yMax. +bool cmVOT_ClipLine( T_t* x0, T_t* y0, T_t* x1, T_t* y1, T_t xMin, T_t yMin, T_t xMax, T_t yMax ); + +// Return true if the line defined by x0,y0 to x1,y1 intersects with +// the rectangle formed by xMin,yMin - xMax,yMax +bool cmVOT_IsLineInRect( T_t x0, T_t y0, T_t x1, T_t y1, T_t xMin, T_t yMin, T_t xMax, T_t yMax ); + + +// Return the perpendicular distance from the line formed by x0,y0 and x1,y1 +// and the point px,py +T_t cmVOT_PtToLineDistance( T_t x0, T_t y0, T_t x1, T_t y1, T_t px, T_t py); + +//====================================================================================================================== +//) + +//( { label:"Miscellaneous DSP" desc:"Common DSP algorithms." kw:[vop] } + +// Compute the complex transient detection function from successive spectral frames. +// The spectral magntidue mag0V precedes mag1V and the phase (radians) spectrum phs0V precedes the phs1V which precedes phs2V. +// binCnt gives the length of each of the spectral vectors. +T_t cmVOT_ComplexDetect(const T_t* mag0V, const T_t* mag1V, const T_t* phs0V, const T_t* phs1V, const T_t* phs2V, unsigned binCnt ); + +// Compute a set of DCT-II coefficients. Result dp[ coeffCnt, filtCnt ] +T_t* cmVOT_DctMatrix( T_t* dp, unsigned coeffCnt, unsigned filtCnt ); + + +// Set the indexes of local peaks greater than threshold in dbp[]. +// Returns the number of peaks in dbp[] +// The maximum number of peaks from n source values is max(0,floor((n-1)/2)). +// Note that peaks will never be found at index 0 or index sn-1. +unsigned cmVOT_PeakIndexes( unsigned* dbp, unsigned dn, const T_t* sbp, unsigned sn, T_t threshold ); + +// Return the index of the bin containing v otherwise return kInvalidIdx if v is below sbp[0] or above sbp[ n-1 ] +// The bin limits are contained in sbp[]. +// The value in spb[] are therefore expected to be in increasing order. +// The value returned will be in the range 0:sn-1. +unsigned cmVOT_BinIndex( const T_t* sbp, unsigned sn, T_t v ); + + +// Given the points x0[xy0N],y0[xy0N] fill y1[i] with the interpolated value of y0[] at +// x1[i]. Note that x0[] and x1[] must be increasing monotonic. +// This function is similar to the octave interp1() function. +void cmVOT_Interp1(T_t* y1, const T_t* x1, unsigned xy1N, const T_t* x0, const T_t* y0, unsigned xy0N ); + +//====================================================================================================================== +//) + + +//( { label:"Matrix ops" desc:"Common 2D matrix operations and accessors." kw:[vop] } + +// 2D matrix accessors +T_t* cmVOT_Col( T_t* m, unsigned ci, unsigned rn, unsigned cn ); +T_t* cmVOT_Row( T_t* m, unsigned ri, unsigned rn, unsigned cn ); +T_t* cmVOT_ElePtr( T_t* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn ); +T_t cmVOT_Ele( T_t* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn ); +void cmVOT_Set( T_t* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn, T_t v ); + +const T_t* cmVOT_CCol( const T_t* m, unsigned ci, unsigned rn, unsigned cn ); +const T_t* cmVOT_CRow( const T_t* m, unsigned ri, unsigned rn, unsigned cn ); +const T_t* cmVOT_CElePtr( const T_t* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn ); +T_t cmVOT_CEle( const T_t* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn ); + + +// Set only the diagonal of a square mtx to sbp. +T_t* cmVOT_Diag( T_t* dbp, unsigned n, const T_t* sbp ); + +// Set the diagonal of a square mtx to db to sbp and set all other values to zero. +T_t* cmVOT_DiagZ( T_t* dbp, unsigned n, const T_t* sbp ); + +// Create an identity matrix (only sets 1's not zeros). +T_t* cmVOT_Identity( T_t* dbp, unsigned rn, unsigned cn ); + +// Zero the matrix and then fill it as an identity matrix. +T_t* cmVOT_IdentityZ( T_t* dbp, unsigned rn, unsigned cn ); + +// Transpose the matrix sbp[srn,scn] into dbp[scn,srn] +T_t* cmVOT_Transpose( T_t* dbp, const T_t* sbp, unsigned srn, unsigned scn ); + +//====================================================================================================================== +//) + + +//( { label:"Fill,move,copy" desc:"Basic data movement and initialization." kw:[vop] } + +// Fill a vector with a value. If value is 0 then the function is accellerated via memset(). +T_t* cmVOT_Fill( T_t* dbp, unsigned dn, T_t value ); + +// Fill a vector with zeros +T_t* cmVOT_Zero( T_t* dbp, unsigned dn ); + +// Analogous to memmove() +T_t* cmVOT_Move( T_t* dbp, unsigned dn, const T_t* sp ); + +// Fill the vector from various sources +T_t* cmVOT_Copy( T_t* dbp, unsigned dn, const T_t* sp ); +T_t* cmVOT_CopyN( T_t* dbp, unsigned dn, unsigned d_stride, const T_t* sp, unsigned s_stride ); +T_t* cmVOT_CopyU( T_t* dbp, unsigned dn, const unsigned* sp ); +T_t* cmVOT_CopyI( T_t* dbp, unsigned dn, const int* sp ); +T_t* cmVOT_CopyF( T_t* dbp, unsigned dn, const float* sp ); +T_t* cmVOT_CopyD( T_t* dbp, unsigned dn, const double* sp ); +T_t* cmVOT_CopyS( T_t* dbp, unsigned dn, const cmSample_t* sp ); +T_t* cmVOT_CopyR( T_t* dbp, unsigned dn, const cmReal_t* sp ); + +// Fill the the destination vector from a source vector where the source vector contains +// srcStride interleaved elements to be ignored. +T_t* cmVOT_CopyStride( T_t* dbp, unsigned dn, const T_t* sp, unsigned srcStride ); + + +//====================================================================================================================== +//) + +//( { label:"Shrink/Expand/Replace" desc:"Change the size of a vector." kw:[vop] } + + +// Shrink the elemetns of dbp[dn] by copying all elements past t+tn to t. +// This operation results in overwriting the elements in the range t[tn]. +// t[tn] must be entirely inside dbp[dn]. +T_t* cmVOT_Shrink( T_t* dbp, unsigned dn, const T_t* t, unsigned tn ); + +// Expand dbp[[dn] by shifting all elements past t to t+tn. +// This produces a set of empty elements in t[tn]. +// t must be inside or at the end of dbp[dn]. +// This results in a reallocation of dbp[]. Be sure to call cmMemFree(dbp) +// to release the returned pointer. +T_t* cmVOT_Expand( T_t* dbp, unsigned dn, const T_t* t, unsigned tn ); + +// Replace the elements t[tn] with the elements in u[un]. +// t must be inside or at the end of dbp[dn]. +// This operation may result in a reallocation of dbp[]. Be sure to call cmMemFree(dbp) +// to release the returned pointer. +// IF dbp==NULL and tn==0 then the dbp[un] is allocated and returned +// with the contents of u[un]. +T_t* cmVOT_Replace(T_t* dbp, unsigned* dn, const T_t* t, unsigned tn, const T_t* u, unsigned un ); + +//====================================================================================================================== +//) + + + +//( { label:"Rotate/Shift/Flip/Sequence" desc:"Modify/generate the vector sequence." kw:[vop] } + +// Assuming a row vector positive shiftCnt rotates right, negative shiftCnt rotates left. +T_t* cmVOT_Rotate( T_t* dbp, unsigned dn, int shiftCnt ); + +// Equivalent to Matlab circshift(). +T_t* cmVOT_RotateM( T_t* dbp, unsigned drn, unsigned dcn, const T_t* sbp, int rShift, int cShift ); + +// Assuming a row vector positive shiftCnt shifts right, negative shiftCnt shifts left. +T_t* cmVOT_Shift( T_t* dbp, unsigned dn, int shiftCnt, T_t fill ); + +// Reverse the contents of the vector. +T_t* cmVOT_Flip( T_t* dbp, unsigned dn); + +// Fill dbp[] with a sequence of values. Returns next value. +T_t cmVOT_Seq( T_t* dbp, unsigned dn, T_t beg, T_t incr ); + + + + +//====================================================================================================================== +//) + +//( { label:"Arithmetic" desc:"Add,Sub,Mult,Divde" kw:[vop] } + +T_t* cmVOT_SubVS( T_t* dp, unsigned dn, T_t v ); +T_t* cmVOT_SubVV( T_t* dp, unsigned dn, const T_t* v ); +T_t* cmVOT_SubVVS( T_t* dp, unsigned dn, const T_t* v, T_t s ); +T_t* cmVOT_SubVVNN(T_t* dp, unsigned dn, unsigned dnn, const T_t* sp, unsigned snn ); +T_t* cmVOT_SubVVV( T_t* dp, unsigned dn, const T_t* sb0p, const T_t* sb1p ); +T_t* cmVOT_SubVSV( T_t* dp, unsigned dn, const T_t s0, const T_t* sb1p ); + +T_t* cmVOT_AddVS( T_t* dp, unsigned dn, T_t v ); +T_t* cmVOT_AddVV( T_t* dp, unsigned dn, const T_t* v ); +T_t* cmVOT_AddVVS( T_t* dp, unsigned dn, const T_t* v, T_t s ); +T_t* cmVOT_AddVVNN(T_t* dp, unsigned dn, unsigned dnn, const T_t* sp, unsigned snn ); +T_t* cmVOT_AddVVV( T_t* dp, unsigned dn, const T_t* sb0p, const T_t* sb1p ); + +T_t* cmVOT_MultVVV( T_t* dbp, unsigned dn, const T_t* sb0p, const T_t* sb1p ); +T_t* cmVOT_MultVV( T_t* dbp, unsigned dn, const T_t* sbp ); +T_t* cmVOT_MultVVNN(T_t* dp, unsigned dn, unsigned dnn, const T_t* sp, unsigned snn ); +T_t* cmVOT_MultVS( T_t* dbp, unsigned dn, T_t s ); +T_t* cmVOT_MultVVS( T_t* dbp, unsigned dn, const T_t* sbp, T_t s ); +T_t* cmVOT_MultVaVS( T_t* dbp, unsigned dn, const T_t* sbp, T_t s ); +T_t* cmVOT_MultSumVVS(T_t* dbp, unsigned dn, const T_t* sbp, T_t s ); + +T_t* cmVOT_DivVVS( T_t* dbp, unsigned dn, const T_t* sb0p, T_t sb1 ); +T_t* cmVOT_DivVVV( T_t* dbp, unsigned dn, const T_t* sb0p, const T_t* sb1p ); +T_t* cmVOT_DivVV( T_t* dbp, unsigned dn, const T_t* sb0p ); +T_t* cmVOT_DivVVNN(T_t* dp, unsigned dn, unsigned dnn, const T_t* sp, unsigned snn ); +T_t* cmVOT_DivVS( T_t* dbp, unsigned dn, T_t s ); +T_t* cmVOT_DivVSV( T_t* dp, unsigned dn, const T_t s0, const T_t* sb1p ); + +// Set dest to 0 if denominator is 0. +T_t* cmVOT_DivVVVZ( T_t* dbp, unsigned dn, const T_t* sb0p, const T_t* sb1p ); +T_t* cmVOT_DivVVZ( T_t* dbp, unsigned dn, const T_t* sb0p ); + +// Divide columns of dp[:,i] by each value in the source vector sp[i]. +T_t* cmVOT_DivMS( T_t* dp, unsigned drn, unsigned dcn, const T_t* sp ); + +//====================================================================================================================== +//) + +//( { label:"Sum vectors" desc:"Operations which take sum vector elements." kw:[vop] } + +T_t cmVOT_Sum( const T_t* sp, unsigned sn ); +T_t cmVOT_SumN( const T_t* sp, unsigned sn, unsigned stride ); + +// Sum the columns of sp[srn,scn] into dp[scn]. +// dp[] is zeroed prior to computing the sum. +T_t* cmVOT_SumM( const T_t* sp, unsigned srn, unsigned scn, T_t* dp ); + +// Sum the rows of sp[srn,scn] into dp[srn] +// dp[] is zeroed prior to computing the sum. +T_t* cmVOT_SumMN( const T_t* sp, unsigned srn, unsigned scn, T_t* dp ); + +//====================================================================================================================== +//) + + +//( { label:"Min/max/median/mode" desc:"Simple descriptive statistics." kw:[vop] } + +T_t cmVOT_Median( const T_t* sp, unsigned sn ); +unsigned cmVOT_MinIndex( const T_t* sp, unsigned sn, unsigned stride ); +unsigned cmVOT_MaxIndex( const T_t* sp, unsigned sn, unsigned stride ); +T_t cmVOT_Min( const T_t* sp, unsigned sn, unsigned stride ); +T_t cmVOT_Max( const T_t* sp, unsigned sn, unsigned stride ); + +T_t* cmVOT_MinVV( T_t* dp, unsigned dn, const T_t* sp ); +T_t* cmVOT_MaxVV( T_t* dp, unsigned dn, const T_t* sp ); + + +// Return index of max/min value into dp[scn] of each column of sp[srn,scn] +unsigned* cmVOT_MinIndexM( unsigned* dp, const T_t* sp, unsigned srn, unsigned scn ); +unsigned* cmVOT_MaxIndexM( unsigned* dp, const T_t* sp, unsigned srn, unsigned scn ); + +// Return the most frequently occuring element in sp. +T_t cmVOT_Mode( const T_t* sp, unsigned sn ); + +//====================================================================================================================== +//) + +//( { label:"Compare/Find" desc:"Compare, find, replace and count elements in a vector." kw:[vop] } + +// Return true if s0p[sn] is equal to s1p[sn] +bool cmVOT_IsEqual( const T_t* s0p, const T_t* s1p, unsigned sn ); + +// Return true if all elements of s0p[sn] are within 'eps' of s1p[sn]. +// This function is based on cmMath.h:cmIsCloseX() +bool cmVOT_IsClose( const T_t* s0p, const T_t* s1p, unsigned sn, double eps ); + +// Replace all values <= lteKeyVal with replaceVal. sp==dp is legal. +T_t* cmVOT_ReplaceLte( T_t* dp, unsigned dn, const T_t* sp, T_t lteKeyVal, T_t replaceVal ); + +// Return the index of 'key' in sp[sn] or cmInvalidIdx if 'key' does not exist. +unsigned cmVOT_Find( const T_t* sp, unsigned sn, T_t key ); + +// Count the number of times 'key' occurs in sp[sn]. +unsigned cmVOT_Count(const T_t* sp, unsigned sn, T_t key ); + +//====================================================================================================================== +//) + + + +//( { label:"Absolute value" desc:"Absolute value and signal rectification." kw:[vop] } + +T_t* cmVOT_Abs( T_t* dbp, unsigned dn ); + +// Half wave rectify the source vector. +// dbp[] = sbp<0 .* sbp +// Overlapping the source and dest is allowable as long as dbp <= sbp. +T_t* cmVOT_HalfWaveRectify(T_t* dbp, unsigned dn, const T_t* sp ); + +//====================================================================================================================== +//) + + +//( { label:"Filter" desc:"Apply filtering to a vector taking into account vector begin/end conditions." kw:[vop] } + +// Apply a median or other filter of order wndN to xV[xN] and store the result in yV[xN]. +// When the window goes off either side of the vector the window is shortened. +// This algorithm produces the same result as the fn_thresh function in MATLAB fv codebase. +void cmVOT_FnThresh( const T_t* xV, unsigned xN, unsigned wndN, T_t* yV, unsigned yStride, T_t (*fnPtr)(const T_t*, unsigned) ); + + +// Apply a median filter of order wndN to xV[xN] and store the result in yV[xN]. +// When the window goes off either side of the vector the missing elements are considered +// to be 0. +// This algorithm produces the same result as the MATLAB medfilt1() function. +void cmVOT_MedianFilt( const T_t* xV, unsigned xN, unsigned wndN, T_t* yV, unsigned yStride ); +//====================================================================================================================== +//) + + +//( { label:"Edit distance" desc:"Calculate the Levenshtein edit distance between vectors." kw:[vop] } + +// Allocate and initialize a matrix for use by LevEditDist(). +// This matrix can be released with a call to cmMemFree(). +unsigned* cmVOT_LevEditDistAllocMtx(unsigned mtxMaxN); + +// Return the Levenshtein edit distance between two vectors. +// m must point to a matrix pre-allocated by cmVOT_InitiLevEditDistMtx(maxN). +double cmVOT_LevEditDist(unsigned mtxMaxN, unsigned* m, const T_t* s0, int n0, const T_t* s1, int n1, unsigned maxN ); + +// Return the Levenshtein edit distance between two vectors. +// Edit distance with a max cost threshold. This version of the algorithm +// will run faster than LevEditDist() because it will stop execution as soon +// as the distance exceeds 'maxCost'. +// 'maxCost' must be between 0.0 and 1.0 or it is forced into this range. +// The maximum distance returned will be 'maxCost'. +// m must point to a matrix pre-allocated by cmVOT_InitiLevEditDistMtx(maxN). +double cmVOT_LevEditDistWithCostThresh( int mtxMaxN, unsigned* m, const T_t* s0, int n0, const T_t* s1, int n1, double maxCost, unsigned maxN ); + +//====================================================================================================================== +//) + + diff --git a/src/cmXml.h b/src/cmXml.h index 1aeffdd..08e7836 100644 --- a/src/cmXml.h +++ b/src/cmXml.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"XML file reader." kw[file] } + enum { kOkXmlRC = cmOkRC, @@ -101,6 +103,8 @@ extern "C" { cmXmlRC_t cmXmlTest( cmCtx_t* ctx, const cmChar_t* fn ); + + //) #ifdef __cpluspus } diff --git a/src/dsp/cmDspBuiltIn.h b/src/dsp/cmDspBuiltIn.h index 0e96869..dabb6c0 100644 --- a/src/dsp/cmDspBuiltIn.h +++ b/src/dsp/cmDspBuiltIn.h @@ -6,9 +6,13 @@ extern "C" { #endif + + //( { file_desc:"Dataflow built-in process interface." kw:[snap] } + // Returns NULL if index is outside of valid range. cmDspClassConsFunc_t cmDspClassGetBuiltIn( unsigned index ); + //) #ifdef __cplusplus diff --git a/src/dsp/cmDspCtx.h b/src/dsp/cmDspCtx.h index 45e618c..5992cfa 100644 --- a/src/dsp/cmDspCtx.h +++ b/src/dsp/cmDspCtx.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Dataflow global context interface." kw:[snap] } + typedef cmHandle_t cmDspSysH_t; typedef cmHandle_t cmDspStoreH_t; @@ -34,6 +36,8 @@ extern "C" { unsigned execDurUsecs; } cmDspCtx_t; + //) + #ifdef __cplusplus } #endif diff --git a/src/dsp/cmDspFx.h b/src/dsp/cmDspFx.h index c5af6bb..08edbbf 100644 --- a/src/dsp/cmDspFx.h +++ b/src/dsp/cmDspFx.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Large collection of real-time audio processing dataflow class descriptions originally developed for 'fluxo'." kw:[snap fluxo] } + struct cmDspClass_str* cmDelayClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmPShiftClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmLoopRecdClassCons( cmDspCtx_t* ctx ); @@ -43,6 +45,8 @@ extern "C" { struct cmDspClass_str* cmBcastSymClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmSegLineClassCons( cmDspCtx_t* ctx ); + //) + #ifdef __cplusplus } #endif diff --git a/src/dsp/cmDspPgm.h b/src/dsp/cmDspPgm.h index 5d52a17..5e0ed70 100644 --- a/src/dsp/cmDspPgm.h +++ b/src/dsp/cmDspPgm.h @@ -5,6 +5,8 @@ extern "C" { #endif + //( { file_desc:"Dataflow program instance interface." kw:[snap] } + typedef cmDspRC_t (*cmDspPgmFunc_t)( cmDspSysH_t h, void** userPtrPtr ); typedef struct @@ -20,7 +22,7 @@ extern "C" { _cmDspSysPgm_t* _cmDspSysPgmArrayBase(); - + //) #ifdef __cplusplus } diff --git a/src/dsp/cmDspPgmKr.h b/src/dsp/cmDspPgmKr.h index b0cc52e..f19643b 100644 --- a/src/dsp/cmDspPgmKr.h +++ b/src/dsp/cmDspPgmKr.h @@ -5,11 +5,15 @@ extern "C" { #endif + //( { file_desc:"Dataflow pgm interfaces for 'GUTIM'." kw:[gutim snap] } + cmDspRC_t _cmDspSysPgm_TimeLine( cmDspSysH_t h, void** userPtrPtr ); cmDspRC_t _cmDspSysPgm_TimeLineLite( cmDspSysH_t h, void** userPtrPtr ); cmDspRC_t _cmDspSysPgm_TimeLineLiteAf( cmDspSysH_t h, void** userPtrPtr ); cmDspRC_t _cmDspSysPgm_Tksb(cmDspSysH_t h, void** userPtrPtr ); cmDspRC_t _cmDspSysPgm_TksbLite(cmDspSysH_t h, void** userPtrPtr ); + + //) #ifdef __cplusplus } diff --git a/src/dsp/cmDspPgmKrChain.h b/src/dsp/cmDspPgmKrChain.h index a0bb54c..36257bf 100644 --- a/src/dsp/cmDspPgmKrChain.h +++ b/src/dsp/cmDspPgmKrChain.h @@ -6,6 +6,8 @@ extern "C" { #endif + //( { file_desc:"Signal processing chain implementation for 'GUTIM'." kw:[snap gutim] } + typedef struct { const cmChar_t* tlFn; @@ -44,6 +46,7 @@ void _cmDspSys_TlXformChain( unsigned ach, unsigned mch ); + //) #ifdef __cplusplus } diff --git a/src/dsp/cmDspPgmPPMain.h b/src/dsp/cmDspPgmPPMain.h index 39896d1..87e33e7 100644 --- a/src/dsp/cmDspPgmPPMain.h +++ b/src/dsp/cmDspPgmPPMain.h @@ -1,6 +1,7 @@ #ifndef cmDspPgmPPMain_h #define cmDspPgmPPMain_h +//( { file_desc:"'fluxo' implementation header." kw:[fluxo] } cmDspInst_t* _cmDspSys_PresetMgmt( cmDspSysH_t h, const cmChar_t* preLbl, unsigned presetGroupSymId ); @@ -44,6 +45,8 @@ const _cmDspPP_CircDesc_t* _cmDspPP_CircuitDesc( unsigned idx ); cmDspRC_t _cmDspPP_CircuitSwitchAlloc( cmDspSysH_t h, _cmDspPP_Ctx_t* ctx, cmDspPP_CircuitSwitch_t* p, cmDspInst_t* reset, cmDspInst_t** csel, cmDspInst_t** ain, cmDspInst_t** ef ); cmDspRC_t _cmDspPP_CircuitSwitchFree( cmDspSysH_t h, cmDspPP_CircuitSwitch_t* p); +//) + #ifdef __cplusplus extern "C" { #endif diff --git a/src/dsp/cmDspUi.h b/src/dsp/cmDspUi.h index 76fc5ca..8caff49 100644 --- a/src/dsp/cmDspUi.h +++ b/src/dsp/cmDspUi.h @@ -8,7 +8,9 @@ extern "C" { #endif + //( { file_desc:"Dataflow UI interfaces." kw:[snap] } + //) #ifdef __cplusplus diff --git a/src/vop/cmVectOpsDoc.h b/src/vop/cmVectOpsDoc.h index 7c0c9a7..6e4b109 100644 --- a/src/vop/cmVectOpsDoc.h +++ b/src/vop/cmVectOpsDoc.h @@ -5,8 +5,9 @@ // is generated using the gcc preprocessor. // switches: -E : Stop after preprocess // -C : Do not strip comments. -// -P : Do not generate line markers -// gcc -E -C -P -o cmVectOpsDocOut.h cmVectOpsDoc.h +// -P : Do not generate line markers +// -traditional-cpp : preserve white space +// gcc -E -C -P -traditional-cpp -o cmVectOpsDocOut.h cmVectOpsDoc.h #include "cmVectOpsTemplateUndef.h" @@ -17,11 +18,9 @@ #define VECT_OP_MIN FLT_MIN #define VECT_OP_LAP_FUNC(F) s##F #define VECT_OP_BLAS_FUNC(F) cblas_s##F - -//{ -//[ +//end_cut +//( { file_desc:"Math vector operations." kw:[vop math] } +//) #include "cmVectOpsTemplateHdr.h" #include "cmVectOpsRIHdr.h" -//] -//} diff --git a/src/vop/cmVectOpsRICode.h b/src/vop/cmVectOpsRICode.h index 0f1d438..1bf7b55 100644 --- a/src/vop/cmVectOpsRICode.h +++ b/src/vop/cmVectOpsRICode.h @@ -46,6 +46,57 @@ VECT_OP_TYPE VECT_OP_FUNC(CEle)( const VECT_OP_TYPE* m, unsigned ri, unsigned ci { return *VECT_OP_FUNC(CElePtr)(m,ri,ci,rn,cn); } +VECT_OP_TYPE* VECT_OP_FUNC(Diag)( VECT_OP_TYPE* dbp, unsigned n, const VECT_OP_TYPE* sbp ) +{ + unsigned i,j; + for(i=0,j=0; imx ) + { + mi = i; + mx = cmAbs(dp[i]); + } + + VECT_OP_FUNC(MultVS)(dp,dn,fact/mx); + + return mi; + +} + + + VECT_OP_TYPE VECT_OP_FUNC(Mean)( const VECT_OP_TYPE* bp, unsigned n ) { return VECT_OP_FUNC(Sum)(bp,n)/n; } @@ -312,52 +357,6 @@ VECT_OP_TYPE* VECT_OP_FUNC(VarianceM)(VECT_OP_TYPE* dp, const VECT_OP_TYPE* sp return dp; } -unsigned VECT_OP_FUNC(NormToMax)( VECT_OP_TYPE* dp, unsigned dn ) -{ - unsigned i = VECT_OP_FUNC(MaxIndex)(dp,dn,1); - - if( i != cmInvalidIdx ) - { - VECT_OP_TYPE v = dp[i]; - VECT_OP_FUNC(DivVS)(dp,dn,v); - } - - return i; -} - -unsigned VECT_OP_FUNC(NormToAbsMax)( VECT_OP_TYPE* dp, unsigned dn, VECT_OP_TYPE fact ) -{ - if( dn == 0 ) - return cmInvalidIdx; - - unsigned i = 0; - unsigned mi = 0; - VECT_OP_TYPE mx = cmAbs(dp[0]); - - for(i=1; imx ) - { - mi = i; - mx = cmAbs(dp[i]); - } - - VECT_OP_FUNC(MultVS)(dp,dn,fact/mx); - - return mi; - -} - - -VECT_OP_TYPE VECT_OP_FUNC(AlphaNorm)(const VECT_OP_TYPE* sp, unsigned sn, VECT_OP_TYPE alpha ) -{ - double sum = 0; - const VECT_OP_TYPE* bp = sp; - const VECT_OP_TYPE* ep = sp + sn; - while( bp < ep ) - sum += pow(fabs(*bp++),alpha); - - return (VECT_OP_TYPE)pow(sum/sn,1.0/alpha); -} void VECT_OP_FUNC(GaussCovariance)(VECT_OP_TYPE* yM, unsigned D, const VECT_OP_TYPE* xM, unsigned xN, const VECT_OP_TYPE* uV, const unsigned* selIdxV, unsigned selKey ) { @@ -468,14 +467,6 @@ void VECT_OP_FUNC(GaussCovariance2)(VECT_OP_TYPE* yM, unsigned D, const VECT_OP } -bool VECT_OP_FUNC(Equal)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn ) -{ - const VECT_OP_TYPE* ep = s0p + sn; - while( s0p < ep ) - if( *s0p++ != *s1p++ ) - return false; - return true; -} bool VECT_OP_FUNC(IsNormal)( const VECT_OP_TYPE* sp, unsigned sn ) { @@ -584,6 +575,19 @@ VECT_OP_TYPE* VECT_OP_FUNC(RmsV)( VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_T VECT_OP_TYPE VECT_OP_FUNC(EuclidNorm)( const VECT_OP_TYPE* sp, unsigned sn ) { return (VECT_OP_TYPE)sqrt( VECT_OP_FUNC(MultSumVV)(sp,sp,sn)); } + +VECT_OP_TYPE VECT_OP_FUNC(AlphaNorm)(const VECT_OP_TYPE* sp, unsigned sn, VECT_OP_TYPE alpha ) +{ + double sum = 0; + const VECT_OP_TYPE* bp = sp; + const VECT_OP_TYPE* ep = sp + sn; + while( bp < ep ) + sum += pow(fabs(*bp++),alpha); + + return (VECT_OP_TYPE)pow(sum/sn,1.0/alpha); +} + + /* From:http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/doc/voicebox/distitpf.html [nf1,p2]=size(pf1); @@ -1150,47 +1154,6 @@ VECT_OP_TYPE* VECT_OP_FUNC(LogV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_ return dbp; } -VECT_OP_TYPE* VECT_OP_FUNC(AmplToDbVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE minDb ) -{ - VECT_OP_TYPE minVal = pow(10.0,minDb/20.0); - VECT_OP_TYPE* dp = dbp; - VECT_OP_TYPE* ep = dp + dn; - - for(; dp M_PI) - dev_rads -= 2*M_PI; - - while( dev_rads < -M_PI) - dev_rads += 2*M_PI; - - // convert into rect coord's - double m1r = *mag1V++; - double m0r = *mag0V * cos(dev_rads); - double m0i = *mag0V++ * sin(dev_rads); - - // calc the combined amplitude and phase deviation - // sum += hypot( m1 - (m0 * e^(-1*dev_rads))); - - sum += hypot( m1r-m0r, -m0i ); - - } - - return (VECT_OP_TYPE)sum; -} VECT_OP_TYPE* VECT_OP_FUNC(MelMask)( VECT_OP_TYPE* maskMtx, unsigned filterCnt, unsigned binCnt, double srate, unsigned flags ) { @@ -2614,68 +2728,6 @@ VECT_OP_TYPE* VECT_OP_FUNC(ShroederSpreadingFunc)(VECT_OP_TYPE* m, unsigned band return m; } - -VECT_OP_TYPE* VECT_OP_FUNC(DctMatrix)( VECT_OP_TYPE* dp, unsigned coeffCnt, unsigned filtCnt ) -{ - VECT_OP_TYPE* dbp = dp; - - double c0 = 1.0/sqrt(filtCnt/2); // row 1-coeffCnt factor - double c1 = c0 * sqrt(2)/2; // row 0 factor - - unsigned i,j; - - // for each column - for(i=0; i *s2p) && (*s1p >= threshold) ) - { - *dbp++ = s1p - sbp; - s0p = s2p++; - s1p = s2p++; - ++pkCnt; - } - else - { - s0p = s1p; - s1p = s2p++; - } - } - - return pkCnt; -} - -unsigned VECT_OP_FUNC(BinIndex)( const VECT_OP_TYPE* sbp, unsigned sn, VECT_OP_TYPE v ) -{ - const VECT_OP_TYPE* sep = sbp + sn; - const VECT_OP_TYPE* bp = sbp; - sep--; - for(; sbp < sep; ++sbp ) - if( *sbp <= v && v < *(sbp+1) ) - return sbp - bp; - - return cmInvalidIdx; -} - - - unsigned VECT_OP_FUNC(Kmeans)( unsigned* classIdxV, // classIdxV[scn] - data point class assignments VECT_OP_TYPE* centroidM, // centroidM[srn,K] - cluster centroids @@ -2913,136 +2965,6 @@ unsigned VECT_OP_FUNC(Kmeans2)( return iterCnt; } - -VECT_OP_TYPE* VECT_OP_FUNC(GaussPDF)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE mean, VECT_OP_TYPE stdDev ) -{ - VECT_OP_TYPE* rp = dbp; - const VECT_OP_TYPE* dep = dbp + dn; - VECT_OP_TYPE var = stdDev * stdDev; - VECT_OP_TYPE fact0 = 1.0/sqrt(2*M_PI*var); - VECT_OP_TYPE fact1 = 2.0 * var; - - for(; dbp < dep; ++sbp ) - *dbp++ = fact0 * exp( -((*sbp-mean)*(*sbp-mean))/ fact1 ); - - return rp; -} - -/// Evaluate a multivariate normal distribution defined by meanV[D] and covarM[D,D] -/// at the data points held in the columns of xM[D,N]. Return the evaluation -/// results in the vector yV[N]. -bool VECT_OP_FUNC(MultVarGaussPDF)( VECT_OP_TYPE* yV, const VECT_OP_TYPE* xM, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* covarM, unsigned D, unsigned N, bool diagFl ) -{ - VECT_OP_TYPE det0; - - // calc the determinant of the covariance matrix - if( diagFl ) - // kpl 1/16/11 det0 = VECT_OP_FUNC(LogDetDiagM)(covarM,D); - det0 = VECT_OP_FUNC(DetDiagM)(covarM,D); - else - // kpl 1/16/11 det0 = VECT_OP_FUNC(LogDetM)(covarM,D); - det0 = VECT_OP_FUNC(DetM)(covarM,D); - - assert(det0 != 0 ); - - if( det0 == 0 ) - return false; - - // calc the inverse of the covariance matrix - VECT_OP_TYPE icM[D*D]; - VECT_OP_FUNC(Copy)(icM,D*D,covarM); - - VECT_OP_TYPE* r; - if( diagFl ) - r = VECT_OP_FUNC(InvDiagM)(icM,D); - else - r = VECT_OP_FUNC(InvM)(icM,D); - - if( r == NULL ) - return false; - - VECT_OP_FUNC(MultVarGaussPDF2)( yV, xM, meanV, icM, det0, D, N, diagFl ); - - return true; -} - -VECT_OP_TYPE* VECT_OP_FUNC(MultVarGaussPDF2)( VECT_OP_TYPE* yV, const VECT_OP_TYPE* xM, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* icM, VECT_OP_TYPE logDet, unsigned D, unsigned N, bool diagFl ) -{ - unsigned i; - - double fact = (-(cmReal_t)D/2) * log(2.0*M_PI) - 0.5*logDet; - - for(i=0; i M_PI) + dev_rads -= 2*M_PI; + + while( dev_rads < -M_PI) + dev_rads += 2*M_PI; + + // convert into rect coord's + double m1r = *mag1V++; + double m0r = *mag0V * cos(dev_rads); + double m0i = *mag0V++ * sin(dev_rads); + + // calc the combined amplitude and phase deviation + // sum += hypot( m1 - (m0 * e^(-1*dev_rads))); + + sum += hypot( m1r-m0r, -m0i ); + } - *b1 = (sxy * n - sx * sy) / (sx_2 * n - sx*sx); - *b0 = (sy - (*b1) * sx) / n; - + return (VECT_OP_TYPE)sum; } +VECT_OP_TYPE* VECT_OP_FUNC(DctMatrix)( VECT_OP_TYPE* dp, unsigned coeffCnt, unsigned filtCnt ) +{ + VECT_OP_TYPE* dbp = dp; + + double c0 = 1.0/sqrt(filtCnt/2); // row 1-coeffCnt factor + double c1 = c0 * sqrt(2)/2; // row 0 factor + + unsigned i,j; + + // for each column + for(i=0; i *s2p) && (*s1p >= threshold) ) + { + *dbp++ = s1p - sbp; + s0p = s2p++; + s1p = s2p++; + ++pkCnt; + } + else + { + s0p = s1p; + s1p = s2p++; + } + } + + return pkCnt; +} + +unsigned VECT_OP_FUNC(BinIndex)( const VECT_OP_TYPE* sbp, unsigned sn, VECT_OP_TYPE v ) +{ + const VECT_OP_TYPE* sep = sbp + sn; + const VECT_OP_TYPE* bp = sbp; + sep--; + for(; sbp < sep; ++sbp ) + if( *sbp <= v && v < *(sbp+1) ) + return sbp - bp; + + return cmInvalidIdx; +} + + void VECT_OP_FUNC(Interp1)(VECT_OP_TYPE* y1, const VECT_OP_TYPE* x1, unsigned xy1N, const VECT_OP_TYPE* x0, const VECT_OP_TYPE* y0, unsigned xy0N ) diff --git a/src/vop/cmVectOpsTemplateHdr.h b/src/vop/cmVectOpsTemplateHdr.h index c74159d..cb5da55 100644 --- a/src/vop/cmVectOpsTemplateHdr.h +++ b/src/vop/cmVectOpsTemplateHdr.h @@ -1,7 +1,21 @@ -// \file cmVectOpsTemplateHdr.h -/// Vector operations interface. +//( { label:misc desc:"Miscellaneous vector operations." kw:[vop] } -/// Setting fieldWidth or decPltCnt to to negative values result in fieldWidth == 10 or decPlCnt == 4 +// Compute the cummulative sum of sbp[dn]. Equivalent to Matlab cumsum(). +VECT_OP_TYPE* VECT_OP_FUNC(CumSum)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp ); + +// Returns true if all values in each vector are equal. +bool VECT_OP_FUNC(Equal)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn ); + +// Same as Matlab linspace() v[i] = i * (limit-1)/n +VECT_OP_TYPE* VECT_OP_FUNC(LinSpace)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE base, VECT_OP_TYPE limit ); + +//====================================================================================================================== +//) + + +//( { label:Print desc:"Vector printing functions." kw:[vop] } +// Setting fieldWidth or decPltCnt to to negative values result in fieldWidth == 10 or decPlCnt == 4 +// void VECT_OP_FUNC(Printf)( cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp, int fieldWidth, int decPlCnt, const char* fmt, unsigned flags ); void VECT_OP_FUNC(Print)( cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp ); void VECT_OP_FUNC(PrintE)( cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp ); @@ -9,64 +23,68 @@ void VECT_OP_FUNC(PrintE)( cmRpt_t* rpt, unsigned rn, unsigned cn, cons void VECT_OP_FUNC(PrintLf)( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp, unsigned fieldWidth, unsigned decPlCnt, const char* fmt ); void VECT_OP_FUNC(PrintL)( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp ); void VECT_OP_FUNC(PrintLE)( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp ); +//====================================================================================================================== +//) +//( { label:Normalization desc:"Normalization and standardization functions." kw:[vop] } -/// Normalize the vector of proabilities by dividing through by the sum. -/// This leaves the relative proportions of each value unchanged while producing a total probability of 1.0. +// Normalize the vector of proabilities by dividing through by the sum. +// This leaves the relative proportions of each value unchanged while producing a total probability of 1.0. +// VECT_OP_TYPE* VECT_OP_FUNC(NormalizeProbabilityVV)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp); VECT_OP_TYPE* VECT_OP_FUNC(NormalizeProbability)(VECT_OP_TYPE* dbp, unsigned dn); VECT_OP_TYPE* VECT_OP_FUNC(NormalizeProbabilityN)(VECT_OP_TYPE* dbp, unsigned dn, unsigned stride); - -/// Standardize the columns of the matrix by subtracting the mean and dividing by the standard deviation. -/// uV[dcn] returns the mean of the data and is optional. -/// sdV[dcn] return the standard deviation of the data and is optional. +// +// Standardize the columns of the matrix by subtracting the mean and dividing by the standard deviation. +// uV[dcn] returns the mean of the data and is optional. +// sdV[dcn] return the standard deviation of the data and is optional. VECT_OP_TYPE* VECT_OP_FUNC(StandardizeRows)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, VECT_OP_TYPE* uV, VECT_OP_TYPE* sdV ); VECT_OP_TYPE* VECT_OP_FUNC(StandardizeCols)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, VECT_OP_TYPE* uV, VECT_OP_TYPE* sdV ); +// +// Normalize by dividing through by the max. value. +// dp[] ./= max(dp). Returns the index of the max value. +unsigned VECT_OP_FUNC(NormToMax)( VECT_OP_TYPE* dp, unsigned dn ); +// +// Normalize by dividing through by the max. absolute value. +// db[] .*= fact / abs(max(dp)); +unsigned VECT_OP_FUNC(NormToAbsMax)( VECT_OP_TYPE* dp, unsigned dn, VECT_OP_TYPE fact ); +//====================================================================================================================== +//) -/// dbp[] = sbp<0 .* sbp -/// Overlapping the source and dest is allowable as long as dbp <= sbp. -VECT_OP_TYPE* VECT_OP_FUNC(HalfWaveRectify)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp ); -/// Compute the cummulative sum of sbp[dn]. Equivalent to Matlab cumsum(). -VECT_OP_TYPE* VECT_OP_FUNC(CumSum)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp ); +//( { label:"Mean and variance" desc:"Compute mean and variance." kw:[vop] } VECT_OP_TYPE VECT_OP_FUNC(Mean)( const VECT_OP_TYPE* sp, unsigned sn ); VECT_OP_TYPE VECT_OP_FUNC(MeanN)( const VECT_OP_TYPE* sp, unsigned sn, unsigned stride ); - +// // Take the mean of each column/row of a matrix. // Set 'dim' to 0 to return mean of columns else return mean of rows. VECT_OP_TYPE* VECT_OP_FUNC(MeanM)( VECT_OP_TYPE* dp, const VECT_OP_TYPE* sp, unsigned srn, unsigned scn, unsigned dim ); - +// // Take the mean of the first 'cnt' element of each column/row of a matrix. // Set 'dim' to 0 to return mean of columns else return mean of rows. // If 'cnt' is greater than the number of elements in the column/row then 'cnt' is // reduced to the number of elements in the column/row. VECT_OP_TYPE* VECT_OP_FUNC(MeanM2)( VECT_OP_TYPE* dp, const VECT_OP_TYPE* sp, unsigned srn, unsigned scn, unsigned dim, unsigned cnt ); - +// // Find the mean of the data points returned by srcFuncPtr(argPtr,i) and return it in dp[dim]. // 'dim' is both the size of dp[] and the length of each data point returned by srcFuncPtr(). // srcFuncPtr() will be called 'cnt' times but it may return NULL on some calls if the associated // data point should not be included in the mean calculation. VECT_OP_TYPE* VECT_OP_FUNC(Mean2)( VECT_OP_TYPE* dp, const VECT_OP_TYPE* (*srcFuncPtr)(void* arg, unsigned idx ), unsigned dim, unsigned cnt, void* argPtr ); - - +// // avgPtr is optional - set to NULL to compute the average VECT_OP_TYPE VECT_OP_FUNC(Variance)( const VECT_OP_TYPE* sp, unsigned sn, const VECT_OP_TYPE* avgPtr ); VECT_OP_TYPE VECT_OP_FUNC(VarianceN)(const VECT_OP_TYPE* sp, unsigned sn, unsigned stride, const VECT_OP_TYPE* avgPtr ); - +// // Set dim=0 to return variance of columns otherwise return variance or rows. VECT_OP_TYPE* VECT_OP_FUNC(VarianceM)(VECT_OP_TYPE* dp, const VECT_OP_TYPE* sp, unsigned srn, unsigned scn, const VECT_OP_TYPE* avgPtr, unsigned dim ); - -// dp[] ./= max(dp). Returns the index of the max value. -unsigned VECT_OP_FUNC(NormToMax)( VECT_OP_TYPE* dp, unsigned dn ); - -// db[] .*= fact / abs(max(dp)); -unsigned VECT_OP_FUNC(NormToAbsMax)( VECT_OP_TYPE* dp, unsigned dn, VECT_OP_TYPE fact ); +//====================================================================================================================== +//) -VECT_OP_TYPE VECT_OP_FUNC(AlphaNorm)(const VECT_OP_TYPE* sp, unsigned sn, VECT_OP_TYPE alpha ); - +//( { label:"Covariance" desc:"Matrix covariance" kw:[vop] } // Calculate the sample covariance matrix from a set of Gaussian distributed multidimensional data. // sp[dn,scn] is the data set. @@ -92,8 +110,10 @@ void VECT_OP_FUNC(GaussCovariance)(VECT_OP_TYPE* dp, unsigned dn, const VECT_OP // through the 'sn' data points. // The result of this function are identical to the octave cov() function. void VECT_OP_FUNC(GaussCovariance2)(VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* (*srcFuncPtr)(void* userPtr, unsigned idx), unsigned sn, void* userPtr, const VECT_OP_TYPE* uV, const unsigned* selIdxV, unsigned selKey ); +//====================================================================================================================== +//) -bool VECT_OP_FUNC(Equal)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn ); +//( { label:"Float point normal" desc:"Evaluate the 'normalness of floating point values." kw:[vop] } // Returns true if all values are 'normal' according the the C macro 'isnormal'. // This function will return false if any of the values are zero. @@ -107,80 +127,90 @@ bool VECT_OP_FUNC(IsNormalZ)(const VECT_OP_TYPE* sp, unsigned sn ); // Returns the count of indexes stored in dp[]. unsigned VECT_OP_FUNC(FindNonNormal)( unsigned* dp, unsigned dn, const VECT_OP_TYPE* sp ); unsigned VECT_OP_FUNC(FindNonNormalZ)( unsigned* dp, unsigned dn, const VECT_OP_TYPE* sp ); +//====================================================================================================================== +//) -/// Successive call to to ZeroCrossCount should preserve the value pointed to by delaySmpPtr. +//( { label:"Measure" desc:"Measure features of a vector." kw:[vop] } + +// Successive call to to ZeroCrossCount should preserve the value pointed to by delaySmpPtr. unsigned VECT_OP_FUNC(ZeroCrossCount)( const VECT_OP_TYPE* sp, unsigned n, VECT_OP_TYPE* delaySmpPtr); // Calculuate the sum of the squares of all elements in bp[bn]. VECT_OP_TYPE VECT_OP_FUNC(SquaredSum)( const VECT_OP_TYPE* bp, unsigned bn ); -/// sn must be <= wndSmpCnt. If sn < wndSmpCnt then sp[sn] is treated as a -/// a partially filled buffer padded with wndSmpCnt-sn zeros. -/// rms = sqrt( sum(sp[1:sn] .* sp[1:sn]) / wndSmpCnt ) +// sn must be <= wndSmpCnt. If sn < wndSmpCnt then sp[sn] is treated as a +// a partially filled buffer padded with wndSmpCnt-sn zeros. +// rms = sqrt( sum(sp[1:sn] .* sp[1:sn]) / wndSmpCnt ) VECT_OP_TYPE VECT_OP_FUNC(RMS)( const VECT_OP_TYPE* sp, unsigned sn, unsigned wndSmpCnt ); -/// This function handles the case were sn is not an integer multiple of -/// wndSmpCnt or hopSmpCnt. In this case the function computes zero -/// padded RMS values for windows which go past the end of sp[sn]. +// This function handles the case were sn is not an integer multiple of +// wndSmpCnt or hopSmpCnt. In this case the function computes zero +// padded RMS values for windows which go past the end of sp[sn]. VECT_OP_TYPE* VECT_OP_FUNC(RmsV)( VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* sp, unsigned sn, unsigned wndSmpCnt, unsigned hopSmpCnt ); - -/// Return the magnitude (Euclidean Norm) of a vector. +// Return the magnitude (Euclidean Norm) of a vector. VECT_OP_TYPE VECT_OP_FUNC(EuclidNorm)( const VECT_OP_TYPE* sp, unsigned sn ); +VECT_OP_TYPE VECT_OP_FUNC(AlphaNorm)(const VECT_OP_TYPE* sp, unsigned sn, VECT_OP_TYPE alpha ); + +//====================================================================================================================== +//) + + + +//( { label:"Distance" desc:"Calculate various vector distances." kw:[vop] } + // Return the Itakura-Saito distance between a modelled power spectrum (up) and another power spectrum (sp). VECT_OP_TYPE VECT_OP_FUNC(ItakuraDistance)( const VECT_OP_TYPE* up, const VECT_OP_TYPE* sp, unsigned sn ); -/// Return the cosine distance between two vectors. +// Return the cosine distance between two vectors. VECT_OP_TYPE VECT_OP_FUNC(CosineDistance)( const VECT_OP_TYPE* s0P, const VECT_OP_TYPE* s1p, unsigned sn ); -/// Return the Euclidean distance between two vectors +// Return the Euclidean distance between two vectors VECT_OP_TYPE VECT_OP_FUNC(EuclidDistance)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn ); -/// Return the Manhattan distance between two vectors +// Return the Manhattan distance between two vectors VECT_OP_TYPE VECT_OP_FUNC(L1Distance)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn ); -/// Return the Mahalanobis distance between a vector and the mean of the distribution. -/// The mean vector could be replaced with another vector drawn from the same distribution in which -/// case the returned value would reflect the distance between the two vectors. -/// 'sn' is the dimensionality of the data. -/// up[D] and invCovM[sn,sn] are the mean and inverse of the covariance matrix of the distribution from -/// which sp[D] is drawn. +// Return the Mahalanobis distance between a vector and the mean of the distribution. +// The mean vector could be replaced with another vector drawn from the same distribution in which +// case the returned value would reflect the distance between the two vectors. +// 'sn' is the dimensionality of the data. +// up[D] and invCovM[sn,sn] are the mean and inverse of the covariance matrix of the distribution from +// which sp[D] is drawn. VECT_OP_TYPE VECT_OP_FUNC(MahalanobisDistance)( const VECT_OP_TYPE* sp, unsigned sn, const VECT_OP_TYPE* up, const VECT_OP_TYPE* invCovM ); -/// Return the KL distance between two probability distributions up[sn] and sp[sn]. -/// Since up[] and sp[] are probability distributions they must sum to 1.0. +// Return the KL distance between two probability distributions up[sn] and sp[sn]. +// Since up[] and sp[] are probability distributions they must sum to 1.0. VECT_OP_TYPE VECT_OP_FUNC(KL_Distance)( const VECT_OP_TYPE* up, const VECT_OP_TYPE* sp, unsigned sn ); -/// Return the KL distance between a prototype vector up[sn] and another vector sp[sn]. -/// This function first normalizes the two vectors to sum to 1.0 before calling +// Return the KL distance between a prototype vector up[sn] and another vector sp[sn]. +// This function first normalizes the two vectors to sum to 1.0 before calling // VECT_OP_FUNC(KL_Distance)(up,sp,sn); VECT_OP_TYPE VECT_OP_FUNC(KL_Distance2)( const VECT_OP_TYPE* up, const VECT_OP_TYPE* sp, unsigned sn ); -/// Measure the Euclidean distance between a vector and all the columns in a matrix. -/// If dv[scn] is no NULL then return the Euclidean distance from sv[scn] to each column of sm[srn,scn]. -/// The function returns the index of the closest data point (column) in sm[]. +// Measure the Euclidean distance between a vector and all the columns in a matrix. +// If dv[scn] is no NULL then return the Euclidean distance from sv[scn] to each column of sm[srn,scn]. +// The function returns the index of the closest data point (column) in sm[]. unsigned VECT_OP_FUNC(EuclidDistanceVM)( VECT_OP_TYPE* dv, const VECT_OP_TYPE* sv, const VECT_OP_TYPE* sm, unsigned srn, unsigned scn ); - - -/// Measure the distance between each column in s0M[ rn, s0cn ] and -/// each column in s1M[rn, s1cn ]. If dM is non-NULL store the -/// result in dM[s1cn, s0cn]. The difference between s0M[:,0] and s1M[:,0] -/// is stored in dM[0,0], the diff. between s0M[:,1] and s1M[:,1] is stored -/// in dM[1,0], etc. If mvV[s0cn] is non-NULL then minV[i] is set with -/// the distance from s0M[:,i] to the nearest column in s1M[]. If miV[s0cn] -/// is non-NULL then it is set with the column index of s1M[] which is -/// closest to s0M[:,i]. In other words mvV[i] gives the distance to column -/// miV[i] from column s0M[:,i]. -/// In those cases where the distane from a prototype (centroid) to the data point -/// is not the same as from the data point to the centroid then s1M[] is considered -/// to hold the prototypes and s0M[] is considered to hold the data points. -/// The distance function returns the distance from a prototype 'cV[dimN]' to -/// an datapoint dV[dimN]. 'dimN' is the dimensionality of the data vector -/// and is threfore equal to 'rn'. +// Measure the distance between each column in s0M[ rn, s0cn ] and +// each column in s1M[rn, s1cn ]. If dM is non-NULL store the +// result in dM[s1cn, s0cn]. The difference between s0M[:,0] and s1M[:,0] +// is stored in dM[0,0], the diff. between s0M[:,1] and s1M[:,1] is stored +// in dM[1,0], etc. If mvV[s0cn] is non-NULL then minV[i] is set with +// the distance from s0M[:,i] to the nearest column in s1M[]. If miV[s0cn] +// is non-NULL then it is set with the column index of s1M[] which is +// closest to s0M[:,i]. In other words mvV[i] gives the distance to column +// miV[i] from column s0M[:,i]. +// In those cases where the distane from a prototype (centroid) to the data point +// is not the same as from the data point to the centroid then s1M[] is considered +// to hold the prototypes and s0M[] is considered to hold the data points. +// The distance function returns the distance from a prototype 'cV[dimN]' to +// an datapoint dV[dimN]. 'dimN' is the dimensionality of the data vector +// and is threfore equal to 'rn'. void VECT_OP_FUNC(DistVMM)( VECT_OP_TYPE* dM, // dM[s1cn,s0cn] return distance mtx (optional) VECT_OP_TYPE* mvV, // mvV[s0cn] distance to closest data point in s0M[]. (optional) @@ -193,192 +223,238 @@ void VECT_OP_FUNC(DistVMM)( VECT_OP_TYPE (*distFunc)( void* userPtr, const VECT_OP_TYPE* cV, const VECT_OP_TYPE* dV, unsigned dimN ), void* userPtr ); -/// Select 'selIdxN' columns from sM[srn,scn]. -/// dM[srn,selIdxN] receives copies of the selected columns. -/// selIdxV[selIdxN] receives the column indexes of the selected columns. -/// Both dM[] and selIdxV[] are optional. -/// In each case the first selected point is chosen at random. -/// SelectRandom() then selects the following selIdxN-1 points at random. -/// SelectMaxDist() selects the next selIdxN-1 points by selecting -/// the point whose combined distance to the previously selected points -/// is greatest. SelectMaxAvgDist() selectes the points whose combined -/// average distance is greatest relative the the previously selected -/// points. +//====================================================================================================================== +//) + +//( { label:"Select columns" desc:"Select columns based on distance." kw:[vop] } + +// Select 'selIdxN' columns from sM[srn,scn]. +// dM[srn,selIdxN] receives copies of the selected columns. +// selIdxV[selIdxN] receives the column indexes of the selected columns. +// Both dM[] and selIdxV[] are optional. +// In each case the first selected point is chosen at random. +// SelectRandom() then selects the following selIdxN-1 points at random. +// SelectMaxDist() selects the next selIdxN-1 points by selecting +// the point whose combined distance to the previously selected points +// is greatest. SelectMaxAvgDist() selectes the points whose combined +// average distance is greatest relative the the previously selected +// points. void VECT_OP_FUNC(SelectRandom)( VECT_OP_TYPE* dM, unsigned* selIdxV, unsigned selIdxN, const VECT_OP_TYPE* sM, unsigned srn, unsigned scn ); void VECT_OP_FUNC(SelectMaxDist)( VECT_OP_TYPE* dM, unsigned* selIdxV, unsigned selIdxN, const VECT_OP_TYPE* sM, unsigned srn, unsigned scn, VECT_OP_TYPE (*distFunc)( void* userPtr, const VECT_OP_TYPE* s0V, const VECT_OP_TYPE* s1V, unsigned sn ), void* distUserPtr ); void VECT_OP_FUNC(SelectMaxAvgDist)( VECT_OP_TYPE* dM, unsigned* selIdxV, unsigned selIdxN, const VECT_OP_TYPE* sM, unsigned srn, unsigned scn, VECT_OP_TYPE (*distFunc)( void* userPtr, const VECT_OP_TYPE* s0V, const VECT_OP_TYPE* s1V, unsigned sn ), void* distUserPtr ); -/// Return the sum of the products (dot product) +//====================================================================================================================== +//) + +//( { label:"Matrix multiplication" desc:"Various matrix multiplication operations." kw:[vop] } + +// Return the sum of the products (dot product) VECT_OP_TYPE VECT_OP_FUNC(MultSumVV)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn ); VECT_OP_TYPE VECT_OP_FUNC(MultSumVS)( const VECT_OP_TYPE* s0p, unsigned sn, VECT_OP_TYPE s ); -/// Number of elements in the dest vector is expected to be the same -/// as the number of source matrix rows. -/// mcn gives the number of columns in the source matrix which is +// Number of elements in the dest vector is expected to be the same +// as the number of source matrix rows. +// mcn gives the number of columns in the source matrix which is // expected to match the number of elements in the source vector. -/// dbp[dn,1] = mp[dn,mcn] * vp[mcn,1] +// dbp[dn,1] = mp[dn,mcn] * vp[mcn,1] VECT_OP_TYPE* VECT_OP_FUNC(MultVMV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* mp, unsigned mcn, const VECT_OP_TYPE* vp ); -/// Multiply a row vector with a matrix to produce a row vector. -/// dbp[1,dn] = v[1,vn] * m[vn,dn] +// Multiply a row vector with a matrix to produce a row vector. +// dbp[1,dn] = v[1,vn] * m[vn,dn] VECT_OP_TYPE* VECT_OP_FUNC(MultVVM)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* vp, unsigned vn, const VECT_OP_TYPE* mp ); -/// Same as MultVMtV() except M is transposed as part of the multiply. -/// mrn gives the number of rows in m[] and number of elements in vp[] -/// dpb[dn] = mp[mrn,dn] * vp[mrn] +// Same as MultVMtV() except M is transposed as part of the multiply. +// mrn gives the number of rows in m[] and number of elements in vp[] +// dpb[dn] = mp[mrn,dn] * vp[mrn] VECT_OP_TYPE* VECT_OP_FUNC(MultVMtV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* mp, unsigned mrn, const VECT_OP_TYPE* vp ); -/// Same as MultVMV() but where the matrix is diagonal. +// Same as MultVMV() but where the matrix is diagonal. VECT_OP_TYPE* VECT_OP_FUNC(MultDiagVMV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* mp, unsigned mcn, const VECT_OP_TYPE* vp ); -/// Generalized matrix multiply. -/// If transposition is selected for M0 or M1 then the given dimension represent the size of the matrix 'after' the transposion. -/// d[drn,dcn] = alpha * op(m0[drn,m0cn_m1rn]) * op(m1[m0cn_m1rn,dcn]) + beta * d[drn,dcn] -//// See enum { kTranpsoseM0Fl=0x01, kTransposeM1Fl=0x02 } in cmVectOps for flags. +// Generalized matrix multiply. +// If transposition is selected for M0 or M1 then the given dimension represent the size of the matrix 'after' the transposion. +// d[drn,dcn] = alpha * op(m0[drn,m0cn_m1rn]) * op(m1[m0cn_m1rn,dcn]) + beta * d[drn,dcn] +/// See enum { kTranpsoseM0Fl=0x01, kTransposeM1Fl=0x02 } in cmVectOps for flags. VECT_OP_TYPE* VECT_OP_FUNC(MultMMM1)(VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, VECT_OP_TYPE alpha, const VECT_OP_TYPE* m0, const VECT_OP_TYPE* m1, unsigned m0cn_m1rn, VECT_OP_TYPE beta, unsigned flags ); -/// Same a VECT_OP_FUNC(MultMMM1) except allows the operation on a sub-matrix by providing the physical (memory) row count rather than the logical (matrix) row count. +// Same a VECT_OP_FUNC(MultMMM1) except allows the operation on a sub-matrix by providing the physical (memory) row count rather than the logical (matrix) row count. VECT_OP_TYPE* VECT_OP_FUNC(MultMMM2)(VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, VECT_OP_TYPE alpha, const VECT_OP_TYPE* m0, const VECT_OP_TYPE* m1, unsigned m0cn_m1rn, VECT_OP_TYPE beta, unsigned flags, unsigned dprn, unsigned m0prn, unsigned m1prn ); -/// d[drn,dcn] = m0[drn,m0cn] * m1[m1rn,dcn] +// d[drn,dcn] = m0[drn,m0cn] * m1[m1rn,dcn] VECT_OP_TYPE* VECT_OP_FUNC(MultMMM)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* m0, const VECT_OP_TYPE* m1, unsigned m0cn_m1rn ); -/// same as MultMMM() except second source matrix is transposed prior to the multiply +// same as MultMMM() except second source matrix is transposed prior to the multiply VECT_OP_TYPE* VECT_OP_FUNC(MultMMMt)(VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* m0, const VECT_OP_TYPE* m1, unsigned m0cn_m1rn ); - -// Raise dbp[] to the power 'expon' -VECT_OP_TYPE* VECT_OP_FUNC(PowVS)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE expon ); -VECT_OP_TYPE* VECT_OP_FUNC(PowVVS)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp, VECT_OP_TYPE expon ); +//====================================================================================================================== +//) -// Take the natural log of all values in sbp[dn]. It is allowable for sbp point to the same array as dbp=. -VECT_OP_TYPE* VECT_OP_FUNC(LogV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp ); +//( { label:"Linear algebra" desc:"Miscellaneous linear algebra operations. Determinant, Inversion, Cholesky decompostion. Linear system solver." kw:[vop] } -// Convert a magnitude (amplitude) spectrum to/from decibels. -// It is allowable for dbp==sbp. -VECT_OP_TYPE* VECT_OP_FUNC(AmplToDbVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE minDb ); -VECT_OP_TYPE* VECT_OP_FUNC(DbToAmplVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp); - -VECT_OP_TYPE* VECT_OP_FUNC(PowToDbVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE minDb ); -VECT_OP_TYPE* VECT_OP_FUNC(DbToPowVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp); - -/// Initialize dbp[dn,dn] as a square symetric positive definite matrix using values -/// from a random uniform distribution. This is useful for initializing random -/// covariance matrices as used by multivariate Gaussian distributions -/// If t is non-NULL it must point to a block of scratch memory of t[dn,dn]. -/// If t is NULL then scratch memory is internally allocated and deallocated. +// Initialize dbp[dn,dn] as a square symetric positive definite matrix using values +// from a random uniform distribution. This is useful for initializing random +// covariance matrices as used by multivariate Gaussian distributions +// If t is non-NULL it must point to a block of scratch memory of t[dn,dn]. +// If t is NULL then scratch memory is internally allocated and deallocated. VECT_OP_TYPE* VECT_OP_FUNC(RandSymPosDef)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE* t ); - -/// Compute the determinant of any square matrix. +// Compute the determinant of any square matrix. VECT_OP_TYPE VECT_OP_FUNC(DetM)( const VECT_OP_TYPE* sp, unsigned srn ); -/// Compute the determinant of a diagonal matrix. +// Compute the determinant of a diagonal matrix. VECT_OP_TYPE VECT_OP_FUNC(DetDiagM)( const VECT_OP_TYPE* sp, unsigned srn); -/// Compute the log determinant of any square matrix. +// Compute the log determinant of any square matrix. VECT_OP_TYPE VECT_OP_FUNC(LogDetM)( const VECT_OP_TYPE* sp, unsigned srn ); -/// Compute the log determinant of a diagonal matrix. +// Compute the log determinant of a diagonal matrix. VECT_OP_TYPE VECT_OP_FUNC(LogDetDiagM)( const VECT_OP_TYPE* sp, unsigned srn); -/// Compute the inverse of a square matrix. Returns NULL if the matrix is not invertable. -/// 'drn' is the dimensionality of the data. +// Compute the inverse of a square matrix. Returns NULL if the matrix is not invertable. +// 'drn' is the dimensionality of the data. VECT_OP_TYPE* VECT_OP_FUNC(InvM)( VECT_OP_TYPE* dp, unsigned drn ); -/// Compute the inverse of a diagonal matrix. Returns NULL if the matrix is not invertable. +// Compute the inverse of a diagonal matrix. Returns NULL if the matrix is not invertable. VECT_OP_TYPE* VECT_OP_FUNC(InvDiagM)( VECT_OP_TYPE* dp, unsigned drn ); -/// Solve a linear system of the form AX=B where A[an,an] is square. -/// Since A is square B must have 'an' rows. -/// Result is returned in B. -/// Returns a pointer to B on success or NULL on fail. -/// NOTE: Both A and B are overwritten by this operation. +// Solve a linear system of the form AX=B where A[an,an] is square. +// Since A is square B must have 'an' rows. +// Result is returned in B. +// Returns a pointer to B on success or NULL on fail. +// NOTE: Both A and B are overwritten by this operation. VECT_OP_TYPE* VECT_OP_FUNC(SolveLS)( VECT_OP_TYPE* A, unsigned an, VECT_OP_TYPE* B, unsigned bcn ); -/// Perform a Cholesky decomposition of the square symetric matrix U[un,un]. -/// The factorization has the form: A=U'TU. -/// If the factorization is successful A is set to U and a pointer to A is returned. -/// Note that the lower triangle of A is not overwritten. See CholZ(). -/// If the factorization fails NULL is returned. +// Perform a Cholesky decomposition of the square symetric matrix U[un,un]. +// The factorization has the form: A=U'TU. +// If the factorization is successful A is set to U and a pointer to A is returned. +// Note that the lower triangle of A is not overwritten. See CholZ(). +// If the factorization fails NULL is returned. VECT_OP_TYPE* VECT_OP_FUNC(Chol)(VECT_OP_TYPE* A, unsigned an ); -/// Same as Chol() but sets the lower triangle of U to zero. -/// This is equivalent ot the Matlab version. +// Same as Chol() but sets the lower triangle of U to zero. +// This is equivalent ot the Matlab version. VECT_OP_TYPE* VECT_OP_FUNC(CholZ)(VECT_OP_TYPE* U, unsigned un ); +// Calculate the best fit line: b0 + b1*x_i through the points x_i,y_i. +// Set x to NULL if it uses sequential integers [0,1,2,3...] +void VECT_OP_FUNC(Lsq1)(const VECT_OP_TYPE* x, const VECT_OP_TYPE* y, unsigned n, VECT_OP_TYPE* b0, VECT_OP_TYPE* b1 ); -/// Return the average value of the contents of sbp[] between two fractional indexes + +//====================================================================================================================== +//) + +//( { label:"Stretch/Shrink" desc:"Stretch or shrink a vector by resampling." kw:[vop] } + +// Return the average value of the contents of sbp[] between two fractional indexes VECT_OP_TYPE VECT_OP_FUNC(FracAvg)( double bi, double ei, const VECT_OP_TYPE* sbp, unsigned sn ); -/// Shrinking function - Decrease the size of sbp[] by averaging blocks of values into single values in dbp[] +// Shrinking function - Decrease the size of sbp[] by averaging blocks of values into single values in dbp[] VECT_OP_TYPE* VECT_OP_FUNC(DownSampleAvg)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn ); -/// Stretching function - linear interpolate between points in sbp[] to fill dbp[] ... where dn > sn +// Stretching function - linear interpolate between points in sbp[] to fill dbp[] ... where dn > sn VECT_OP_TYPE* VECT_OP_FUNC(UpSampleInterp)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn ); -/// Stretch or shrink the sbp[] to fit into dbp[] +// Stretch or shrink the sbp[] to fit into dbp[] VECT_OP_TYPE* VECT_OP_FUNC(FitToSize)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn ); -/// Stretch or shrink sV[] to fit into dV[] using a simple linear mapping. -/// When stretching (sndn) each dest value is formed by the average of sequential segments -/// of sn/dn source elements. Fractional values are used at the beginning -/// and end of each segment. +// Stretch or shrink sV[] to fit into dV[] using a simple linear mapping. +// When stretching (sndn) each dest value is formed by the average of sequential segments +// of sn/dn source elements. Fractional values are used at the beginning +// and end of each segment. VECT_OP_TYPE* VECT_OP_FUNC(LinearMap)(VECT_OP_TYPE* dV, unsigned dn, VECT_OP_TYPE* sV, unsigned sn ); -/// Generate a vector of uniformly distributed random numbers in the range minVal to maxVal. +//====================================================================================================================== +//) + +//( { label:"Random number generation" desc:"Generate random numbers." kw:[vop] } + +// Generate a vector of uniformly distributed random numbers in the range minVal to maxVal. VECT_OP_TYPE* VECT_OP_FUNC(Random)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE minVal, VECT_OP_TYPE maxVal ); -/// Generate dn random numbers integers between 0 and wn-1 based on a the relative -/// weights in wp[wn]. Note thtat the weights do not have to sum to 1.0. +// Generate dn random numbers integers between 0 and wn-1 based on a the relative +// weights in wp[wn]. Note thtat the weights do not have to sum to 1.0. unsigned* VECT_OP_FUNC(WeightedRandInt)( unsigned* dbp, unsigned dn, const VECT_OP_TYPE* wp, unsigned wn ); -/// Generate a vector of normally distributed univariate random numbers +// Generate a vector of normally distributed univariate random numbers VECT_OP_TYPE* VECT_OP_FUNC(RandomGauss)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE mean, VECT_OP_TYPE var ); -/// Generate a vector of normally distributed univariate random numbers where each value has been drawn from a -/// seperately parameterized Gaussian distribution. meanV[] and varV[] must both contain dn velues. +// Generate a vector of normally distributed univariate random numbers where each value has been drawn from a +// seperately parameterized Gaussian distribution. meanV[] and varV[] must both contain dn velues. VECT_OP_TYPE* VECT_OP_FUNC(RandomGaussV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* varV ); -/// Generate a matrix of multi-dimensional random values. Each column represents a single vector value and each row contains a dimension. -/// meanV[] and varV[] must both contain drn elements where each meanV[i],varV[i] pair parameterize one dimensions Gaussian distribution. +// Generate a matrix of multi-dimensional random values. Each column represents a single vector value and each row contains a dimension. +// meanV[] and varV[] must both contain drn elements where each meanV[i],varV[i] pair parameterize one dimensions Gaussian distribution. VECT_OP_TYPE* VECT_OP_FUNC(RandomGaussM)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* varV ); VECT_OP_TYPE* VECT_OP_FUNC(RandomGaussDiagM)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* diagCovarM ); -/// Generate a matrix of multivariate random values drawn from a normal distribution. -/// The dimensionality of the values are 'drn'. -/// The count of returned values is 'dcn'. -/// meanV[drn] and covarM[drn,drn] parameterize the normal distribution. -/// The covariance matrix must be symetric and positive definite. -/// t[(drn*drn) ] points to scratch memory or is set to NULL if the function should -/// allocate the memory internally. -/// Based on octave function mvrnd.m. +// Generate a matrix of multivariate random values drawn from a normal distribution. +// The dimensionality of the values are 'drn'. +// The count of returned values is 'dcn'. +// meanV[drn] and covarM[drn,drn] parameterize the normal distribution. +// The covariance matrix must be symetric and positive definite. +// t[(drn*drn) ] points to scratch memory or is set to NULL if the function should +// allocate the memory internally. +// Based on octave function mvrnd.m. VECT_OP_TYPE* VECT_OP_FUNC(RandomGaussNonDiagM)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* covarM, VECT_OP_TYPE* t ); -/// Same as RandomGaussNonDiagM() except requires the upper trianglular -/// Cholesky factor of the covar matrix in 'uM'. +// Same as RandomGaussNonDiagM() except requires the upper trianglular +// Cholesky factor of the covar matrix in 'uM'. VECT_OP_TYPE* VECT_OP_FUNC(RandomGaussNonDiagM2)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* uM ); -/// Generate a matrix of N*K multi-dimensional data points. -/// Where D is the dimensionality of the data. (D == drn). -/// K is the number of multi-dimensional PDF's (clusters). -/// N is the number of data points to generate per cluster. -/// dbp[ D, N*K ] contains the returned data point. -/// The first N columns is associated with the cluster 0, -/// the next N columns is associated with cluster 1, ... -/// meanM[ D, K ] and varM[D,K] parameterize the generating PDF.s for each cluster +// Generate a matrix of N*K multi-dimensional data points. +// Where D is the dimensionality of the data. (D == drn). +// K is the number of multi-dimensional PDF's (clusters). +// N is the number of data points to generate per cluster. +// dbp[ D, N*K ] contains the returned data point. +// The first N columns is associated with the cluster 0, +// the next N columns is associated with cluster 1, ... +// meanM[ D, K ] and varM[D,K] parameterize the generating PDF.s for each cluster VECT_OP_TYPE* VECT_OP_FUNC(RandomGaussMM)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* meanM, const VECT_OP_TYPE* varM, unsigned K ); -/// Generate the set of coordinates which describe a circle with a center at x,y. -/// dbp[dn,2] must contain 2*dn elements. The first column holds the x coord and and the second holds the y coord. -VECT_OP_TYPE* VECT_OP_FUNC(CircleCoords)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE x, VECT_OP_TYPE y, VECT_OP_TYPE varX, VECT_OP_TYPE varY ); -/// The following functions all return the phase of the next value. +// Evaluate the univariate normal distribution defined by 'mean' and 'stdDev'. +VECT_OP_TYPE* VECT_OP_FUNC(GaussPDF)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE mean, VECT_OP_TYPE stdDev ); + +// Evaluate a multivariate normal distribution defined by meanV[D] and covarM[D,D] +// at the data points held in the columns of xM[D,N]. Return the evaluation +// results in the vector yV[N]. D is the dimensionality of the data. N is the number of +// data points to evaluate and values to return in yV[N]. +// Set diagFl to true if covarM is diagonal. +// The function fails and returns false if the covariance matrix is singular. +bool VECT_OP_FUNC(MultVarGaussPDF)( VECT_OP_TYPE* yV, const VECT_OP_TYPE* xM, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* covarM, unsigned D, unsigned N, bool diagFl ); + +// Same as multVarGaussPDF[] except takes the inverse covar mtx invCovarM[D,D] +// and log determinant of covar mtx. +// Always returns yV[]. +VECT_OP_TYPE* VECT_OP_FUNC(MultVarGaussPDF2)( VECT_OP_TYPE* yV, const VECT_OP_TYPE* xM, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* invCovarM, VECT_OP_TYPE logDet, unsigned D, unsigned N, bool diagFl ); + +// Same as multVarGaussPDF[] except uses a function to obtain the data vectors. +// srcFunc() can filter the data points by returning NULL if the data vector at frmIdx should +// not be evaluated against the PDF. In this case yV[frmIdx] will be set to 0. +VECT_OP_TYPE* VECT_OP_FUNC(MultVarGaussPDF3)( + VECT_OP_TYPE* yV, + const VECT_OP_TYPE* (*srcFunc)(void* funcDataPtr, unsigned frmIdx ), + void* funcDataPtr, + const VECT_OP_TYPE* meanV, + const VECT_OP_TYPE* invCovarM, + VECT_OP_TYPE logDet, + unsigned D, + unsigned N, + bool diagFl ); + + +//====================================================================================================================== +//) + + +//( { label:"Signal generators" desc:"Generate periodic signals." kw:[vop] } + +// The following functions all return the phase of the next value. unsigned VECT_OP_FUNC(SynthSine)( VECT_OP_TYPE* dbp, unsigned dn, unsigned phase, double srate, double hz ); unsigned VECT_OP_FUNC(SynthCosine)( VECT_OP_TYPE* dbp, unsigned dn, unsigned phase, double srate, double hz ); unsigned VECT_OP_FUNC(SynthSquare)( VECT_OP_TYPE* dbp, unsigned dn, unsigned phase, double srate, double hz, unsigned otCnt ); @@ -389,11 +465,33 @@ unsigned VECT_OP_FUNC(SynthImpulse)( VECT_OP_TYPE* dbp, unsigned dn, unsi unsigned VECT_OP_FUNC(SynthPhasor)( VECT_OP_TYPE* dbp, unsigned dn, unsigned phase, double srate, double hz ); -/// Return value should be passed back via delaySmp on the next call. +// Return value should be passed back via delaySmp on the next call. VECT_OP_TYPE VECT_OP_FUNC(SynthPinkNoise)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE delaySmp ); -/// Same as Matlab linspace() v[i] = i * (limit-1)/n -VECT_OP_TYPE* VECT_OP_FUNC(LinSpace)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE base, VECT_OP_TYPE limit ); +//====================================================================================================================== +//) + +//( { label:"Exponential conversion" desc:"pow() and log() functions." kw:[vop] } + +// Raise dbp[] to the power 'expon' +VECT_OP_TYPE* VECT_OP_FUNC(PowVS)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE expon ); +VECT_OP_TYPE* VECT_OP_FUNC(PowVVS)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp, VECT_OP_TYPE expon ); + +// Take the natural log of all values in sbp[dn]. It is allowable for sbp point to the same array as dbp=. +VECT_OP_TYPE* VECT_OP_FUNC(LogV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp ); + +//====================================================================================================================== +//) + +//( { label:"dB Conversions" desc:"Convert vectors between dB,linear and power representations." kw:[vop] } + +// Convert a magnitude (amplitude) spectrum to/from decibels. +// It is allowable for dbp==sbp. +VECT_OP_TYPE* VECT_OP_FUNC(AmplToDbVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE minDb ); +VECT_OP_TYPE* VECT_OP_FUNC(DbToAmplVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp); + +VECT_OP_TYPE* VECT_OP_FUNC(PowToDbVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE minDb ); +VECT_OP_TYPE* VECT_OP_FUNC(DbToPowVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp); VECT_OP_TYPE* VECT_OP_FUNC(LinearToDb)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp, VECT_OP_TYPE mult ); VECT_OP_TYPE* VECT_OP_FUNC(dBToLinear)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp, VECT_OP_TYPE mult ); @@ -401,6 +499,10 @@ VECT_OP_TYPE* VECT_OP_FUNC(AmplitudeToDb)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* VECT_OP_FUNC(PowerToDb)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp ); VECT_OP_TYPE* VECT_OP_FUNC(dBToAmplitude)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp ); VECT_OP_TYPE* VECT_OP_FUNC(dBToPower)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp ); +//====================================================================================================================== +//) + +//( { label:"DSP Windows" desc:"DSP windowing functions." kw:[vop] } VECT_OP_TYPE VECT_OP_FUNC(KaiserBetaFromSidelobeReject)( double sidelobeRejectDb ); VECT_OP_TYPE VECT_OP_FUNC(KaiserFreqResolutionFactor)( double sidelobeRejectDb ); @@ -410,84 +512,86 @@ VECT_OP_TYPE* VECT_OP_FUNC(Hamming)( VECT_OP_TYPE* dbp, unsigned dn ); VECT_OP_TYPE* VECT_OP_FUNC(Hann)( VECT_OP_TYPE* dbp, unsigned dn ); VECT_OP_TYPE* VECT_OP_FUNC(Triangle)(VECT_OP_TYPE* dbp, unsigned dn ); -/// The MATLAB equivalent Hamming and Hann windows. +// The MATLAB equivalent Hamming and Hann windows. //VECT_OP_TYPE* VECT_OP_FUNC(HammingMatlab)(VECT_OP_TYPE* dbp, unsigned dn ); VECT_OP_TYPE* VECT_OP_FUNC(HannMatlab)( VECT_OP_TYPE* dbp, unsigned dn ); -/// Simulates the MATLAB GaussWin function. Set arg to 2.5 to simulate the default arg -/// as used by MATLAB. +// Simulates the MATLAB GaussWin function. Set arg to 2.5 to simulate the default arg +// as used by MATLAB. VECT_OP_TYPE* VECT_OP_FUNC(GaussWin)( VECT_OP_TYPE* dbp, unsigned dn, double arg ); +//====================================================================================================================== +//) +//( { label:"DSP Filters" desc:"DSP filtering functions." kw:[vop] } -/// Direct form II algorithm based on the MATLAB implmentation -/// http://www.mathworks.com/access/helpdesk/help/techdoc/ref/filter.html#f83-1015962 -/// The only difference between this function and the equivalent MATLAB filter() function -/// is that the first feedforward coeff is given as a seperate value. The first b coefficient -/// in this function is therefore the same as the second coefficient in the MATLAB function. -/// and the first a[] coefficient (which is generally set to 1.0) is skipped. -/// Example: -/// Matlab: b=[.5 .4 .3] a=[1 .2 .1] -/// Equiv: b0 = .5 b=[ .4 .3] a=[ .2 .1]; -/// -/// y[yn] - output vector -/// x[xn] - input vector. xn must be <= yn. if xn < yn then the end of y[] is set to zero. -/// b0 - signal scale. This can also be seen as b[0] (which is not included in b[]) -/// b[dn] - feedforward coeff's b[1..dn-1] -/// a[dn] - feedback coeff's a[1..dn-1] -/// d[dn+1] - delay registers - note that this array must be one element longer than the coeff arrays. -/// +// Direct form II algorithm based on the MATLAB implmentation +// http://www.mathworks.com/access/helpdesk/help/techdoc/ref/filter.html#f83-1015962 +// The only difference between this function and the equivalent MATLAB filter() function +// is that the first feedforward coeff is given as a seperate value. The first b coefficient +// in this function is therefore the same as the second coefficient in the MATLAB function. +// and the first a[] coefficient (which is generally set to 1.0) is skipped. +// Example: +// Matlab: b=[.5 .4 .3] a=[1 .2 .1] +// Equiv: b0 = .5 b=[ .4 .3] a=[ .2 .1]; +// +// y[yn] - output vector +// x[xn] - input vector. xn must be <= yn. if xn < yn then the end of y[] is set to zero. +// b0 - signal scale. This can also be seen as b[0] (which is not included in b[]) +// b[dn] - feedforward coeff's b[1..dn-1] +// a[dn] - feedback coeff's a[1..dn-1] +// d[dn+1] - delay registers - note that this array must be one element longer than the coeff arrays. +// VECT_OP_TYPE* VECT_OP_FUNC(Filter)( VECT_OP_TYPE* y, unsigned yn, const VECT_OP_TYPE* x, unsigned xn, cmReal_t b0, const cmReal_t* b, const cmReal_t* a, cmReal_t* d, unsigned dn ); struct cmFilter_str; //typedef cmRC_t (*VECT_OP_FUNC(FiltExecFunc_t))( struct acFilter_str* f, const VECT_OP_TYPE* x, unsigned xn, VECT_OP_TYPE* y, unsigned yn ); VECT_OP_TYPE* VECT_OP_FUNC(FilterFilter)(struct cmFilter_str* f, cmRC_t (*func)( struct cmFilter_str* f, const VECT_OP_TYPE* x, unsigned xn, VECT_OP_TYPE* y, unsigned yn ), const cmReal_t bb[], unsigned bn, const cmReal_t aa[], unsigned an, const VECT_OP_TYPE* x, unsigned xn, VECT_OP_TYPE* y, unsigned yn ); -/// Compute the coefficients of a low/high pass FIR filter -/// wndV[dn] gives the window function used to truncate the ideal low-pass impulse response. -/// Set wndV to NULL to use a unity window. -/// See enum { kHighPass_LPSincFl=0x01, kNormalize_LPSincFl=0x02 } in cmVectOps.h +// Compute the coefficients of a low/high pass FIR filter +// wndV[dn] gives the window function used to truncate the ideal low-pass impulse response. +// Set wndV to NULL to use a unity window. +// See enum { kHighPass_LPSincFl=0x01, kNormalize_LPSincFl=0x02 } in cmVectOps.h VECT_OP_TYPE* VECT_OP_FUNC(LP_Sinc)(VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* wndV, double srate, double fcHz, unsigned flags ); -/// Compute the complex transient detection function from successive spectral frames. -/// The spectral magntidue mag0V precedes mag1V and the phase (radians) spectrum phs0V precedes the phs1V which precedes phs2V. -/// binCnt gives the length of each of the spectral vectors. -VECT_OP_TYPE VECT_OP_FUNC(ComplexDetect)(const VECT_OP_TYPE* mag0V, const VECT_OP_TYPE* mag1V, const VECT_OP_TYPE* phs0V, const VECT_OP_TYPE* phs1V, const VECT_OP_TYPE* phs2V, unsigned binCnt ); -/// Compute a set of filterCnt mel filter masks for wieghting magnitude spectra consisting of binCnt bins. -/// The spectrum is divided into bandCnt equal bands in the mel domain -/// Each row of the matrix contains the mask for a single filter band consisting of binCnt elements. -/// See enum{ kShiftMelFl=0x01, kNormalizeMelFl=0x02 } in cmVectOps.h -/// Set kShiftMelFl to shift the mel bands onto the nearest FFT bin. -/// Set kNormalizeMelFl to normalize the combined filters for unity gain. +//====================================================================================================================== +//) + +//( { label:"Spectral Masking" desc:"A collection of spectral masking functions." kw:[vop] } + +// Compute a set of filterCnt mel filter masks for wieghting magnitude spectra consisting of binCnt bins. +// The spectrum is divided into bandCnt equal bands in the mel domain +// Each row of the matrix contains the mask for a single filter band consisting of binCnt elements. +// See enum{ kShiftMelFl=0x01, kNormalizeMelFl=0x02 } in cmVectOps.h +// Set kShiftMelFl to shift the mel bands onto the nearest FFT bin. +// Set kNormalizeMelFl to normalize the combined filters for unity gain. VECT_OP_TYPE* VECT_OP_FUNC(MelMask)( VECT_OP_TYPE* maskMtx, unsigned bandCnt, unsigned binCnt, double srate, unsigned flags ); - - -/// Fill binIdxV[bandCnt] and cntV[bandCnt] with a bin to band map. -/// binIdx[] contains the first (minimum) bin index for a given band. -/// cntV[] contains the count of bins for each band. -/// bandCnt is the number of bark bands to return -/// The function returns the actual number of bands mapped which will always be <= 23. +// Fill binIdxV[bandCnt] and cntV[bandCnt] with a bin to band map. +// binIdx[] contains the first (minimum) bin index for a given band. +// cntV[] contains the count of bins for each band. +// bandCnt is the number of bark bands to return +// The function returns the actual number of bands mapped which will always be <= 23. unsigned VECT_OP_FUNC(BarkMap)(unsigned* binIdxV, unsigned* cntV, unsigned bandCnt, unsigned binCnt, double srate ); -/// Calc a set of triangle fitler masks into each row of maskMtx. -/// maskMtx[ bandCnt, binCnt ] - result matrix -/// binHz - freq resolution of the output filters. -/// stSpread - Semi-tone spread above and below each center frequency (stSpread*2) is the total bandwidth. -/// (Only used if lowHzV or uprHzV are NULL) -/// lowHz[ bandCnt ] - set of upper frequency limits for each band. -/// ctrHz[ bandCnt ] set to the center value in Hz for each band -/// uprHz[ bandCnt ] - set of lower frequency limits for each band. -/// Note if lowHz[] and uprHz[] are set to NULL then stSpread is used to set the bandwidth of each band. +// Calc a set of triangle fitler masks into each row of maskMtx. +// maskMtx[ bandCnt, binCnt ] - result matrix +// binHz - freq resolution of the output filters. +// stSpread - Semi-tone spread above and below each center frequency (stSpread*2) is the total bandwidth. +// (Only used if lowHzV or uprHzV are NULL) +// lowHz[ bandCnt ] - set of upper frequency limits for each band. +// ctrHz[ bandCnt ] set to the center value in Hz for each band +// uprHz[ bandCnt ] - set of lower frequency limits for each band. +// Note if lowHz[] and uprHz[] are set to NULL then stSpread is used to set the bandwidth of each band. VECT_OP_TYPE* VECT_OP_FUNC(TriangleMask)(VECT_OP_TYPE* maskMtx, unsigned bandCnt, unsigned binCnt, const VECT_OP_TYPE* ctrHzV, VECT_OP_TYPE binHz, VECT_OP_TYPE stSpread, const VECT_OP_TYPE* lowHzV, const VECT_OP_TYPE* uprHzV ); -/// Calculate a set of Bark band triangle filters into maskMtx. -/// Each row of maskMtx contains the filter for one band. -/// maskMtx[ bandCnt, binCnt ] -/// bandCnt - the number of triangle bankds. If bandCnt is > 24 it will be reduced to 24. -/// binCnt - the number of bins in the filters. -/// binHz - the width of each bin in Hz. +// Calculate a set of Bark band triangle filters into maskMtx. +// Each row of maskMtx contains the filter for one band. +// maskMtx[ bandCnt, binCnt ] +// bandCnt - the number of triangle bankds. If bandCnt is > 24 it will be reduced to 24. +// binCnt - the number of bins in the filters. +// binHz - the width of each bin in Hz. VECT_OP_TYPE* VECT_OP_FUNC(BarkMask)(VECT_OP_TYPE* maskMtx, unsigned bandCnt, unsigned binCnt, double binHz ); // Terhardt 1979 (Calculating virtual pitch, Hearing Research #1, pp 155-182) @@ -497,39 +601,27 @@ VECT_OP_TYPE* VECT_OP_FUNC(TerhardtThresholdMask)(VECT_OP_TYPE* maskV, unsigned //Schroeder et al., 1979, JASA, Optimizing digital speech coders by exploiting masking properties of the human ear VECT_OP_TYPE* VECT_OP_FUNC(ShroederSpreadingFunc)(VECT_OP_TYPE* m, unsigned bandCnt, double srate); -/// Compute a set of DCT-II coefficients. Result dp[ coeffCnt, filtCnt ] -VECT_OP_TYPE* VECT_OP_FUNC(DctMatrix)( VECT_OP_TYPE* dp, unsigned coeffCnt, unsigned filtCnt ); +//====================================================================================================================== +//) +//( { label:"Machine learning" desc:"K-means clustering and Viterbi algorithms." kw:[vop] } -/// Set the indexes of local peaks greater than threshold in dbp[]. -/// Returns the number of peaks in dbp[] -/// The maximum number of peaks from n source values is max(0,floor((n-1)/2)). -/// Note that peaks will never be found at index 0 or index sn-1. -unsigned VECT_OP_FUNC(PeakIndexes)( unsigned* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn, VECT_OP_TYPE threshold ); - -/// Return the index of the bin containing v or acInvalidIdx if v is below sbp[0] or above sbp[ n-1 ] -/// The bin limits are contained in sbp[]. -/// The value in spb[] are therefore expected to be in increasing order. -/// The value returned will be in the range 0:sn-1. -unsigned VECT_OP_FUNC(BinIndex)( const VECT_OP_TYPE* sbp, unsigned sn, VECT_OP_TYPE v ); - - -/// Assign each data point to one of k clusters using an expectation-maximization algorithm. -/// k gives the number of clusters to identify -/// Each column of sp[ srn, scn ] contains a multidimensional data point. -/// srn therefore defines the dimensionality of the data. -/// Each column of centroidV[ srn, k ] is set to the centroid of each of k clusters. -/// classIdxV[ scn ] assigns the index (0 to k-1) of a cluster to each soure data point -/// The function returns the number of iterations required for the EM process to converge. -/// selIdxV[ scn ] is optional and contains a list of id's assoc'd with each column of sM. -/// selKey is a integer value. -/// If selIdxV is non-NULL then only columns of sM[] where selIdxV[] == selKey will be clustered. -/// All columns of sM[] where the associated column in selIdxV[] do not match will be ignored. -/// Set 'initFromCentroidFl' to true if the initial centroids should be taken from centroidM[]. -/// otherwise the initial centroids are selected from 'k' random data points in sp[]. -/// The distance function distFunc(cV,dV,dN) is called to determine the distance from a -/// centroid the centroid 'cV[dN]' to a data point 'dV[dN]'. 'dN' is the dimensionality of the -/// feature vector and is therefore equal to 'srn'. +// Assign each data point to one of k clusters using an expectation-maximization algorithm. +// k gives the number of clusters to identify +// Each column of sp[ srn, scn ] contains a multidimensional data point. +// srn therefore defines the dimensionality of the data. +// Each column of centroidV[ srn, k ] is set to the centroid of each of k clusters. +// classIdxV[ scn ] assigns the index (0 to k-1) of a cluster to each soure data point +// The function returns the number of iterations required for the EM process to converge. +// selIdxV[ scn ] is optional and contains a list of id's assoc'd with each column of sM. +// selKey is a integer value. +// If selIdxV is non-NULL then only columns of sM[] where selIdxV[] == selKey will be clustered. +// All columns of sM[] where the associated column in selIdxV[] do not match will be ignored. +// Set 'initFromCentroidFl' to true if the initial centroids should be taken from centroidM[]. +// otherwise the initial centroids are selected from 'k' random data points in sp[]. +// The distance function distFunc(cV,dV,dN) is called to determine the distance from a +// centroid the centroid 'cV[dN]' to a data point 'dV[dN]'. 'dN' is the dimensionality of the +// feature vector and is therefore equal to 'srn'. unsigned VECT_OP_FUNC(Kmeans)( unsigned* classIdxV, VECT_OP_TYPE* centroidM, @@ -543,9 +635,9 @@ unsigned VECT_OP_FUNC(Kmeans)( VECT_OP_TYPE (*distFunc)( void* userPtr, const VECT_OP_TYPE* cV, const VECT_OP_TYPE* dV, unsigned dN ), void* userDistPtr ); -/// 'srcFunc() should return NULL if the data point located at 'frmIdx' should not be included in the clustering. -/// Clustering is considered to be complete after 'maxIterCnt' iterations or when -/// 'deltaStopCnt' or fewer data points change class on a single iteration +// 'srcFunc() should return NULL if the data point located at 'frmIdx' should not be included in the clustering. +// Clustering is considered to be complete after 'maxIterCnt' iterations or when +// 'deltaStopCnt' or fewer data points change class on a single iteration unsigned VECT_OP_FUNC(Kmeans2)( unsigned* classIdxV, // classIdxV[scn] - data point class assignments VECT_OP_TYPE* centroidM, // centroidM[srn,K] - cluster centroids @@ -559,64 +651,67 @@ unsigned VECT_OP_FUNC(Kmeans2)( int iterCnt, // max. number of iterations (-1 to ignore) int deltaStopCnt); // if less than deltaStopCnt data points change classes on a given iteration then convergence occurs. -/// Evaluate the univariate normal distribution defined by 'mean' and 'stdDev'. -VECT_OP_TYPE* VECT_OP_FUNC(GaussPDF)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE mean, VECT_OP_TYPE stdDev ); - -/// Evaluate a multivariate normal distribution defined by meanV[D] and covarM[D,D] -/// at the data points held in the columns of xM[D,N]. Return the evaluation -/// results in the vector yV[N]. D is the dimensionality of the data. N is the number of -/// data points to evaluate and values to return in yV[N]. -/// Set diagFl to true if covarM is diagonal. -/// The function fails and returns false if the covariance matrix is singular. -bool VECT_OP_FUNC(MultVarGaussPDF)( VECT_OP_TYPE* yV, const VECT_OP_TYPE* xM, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* covarM, unsigned D, unsigned N, bool diagFl ); - -/// Same as multVarGaussPDF[] except takes the inverse covar mtx invCovarM[D,D] -/// and log determinant of covar mtx. -/// Always returns yV[]. -VECT_OP_TYPE* VECT_OP_FUNC(MultVarGaussPDF2)( VECT_OP_TYPE* yV, const VECT_OP_TYPE* xM, const VECT_OP_TYPE* meanV, const VECT_OP_TYPE* invCovarM, VECT_OP_TYPE logDet, unsigned D, unsigned N, bool diagFl ); - -/// Same as multVarGaussPDF[] except uses a function to obtain the data vectors. -/// srcFunc() can filter the data points by returning NULL if the data vector at frmIdx should -/// not be evaluated against the PDF. In this case yV[frmIdx] will be set to 0. -VECT_OP_TYPE* VECT_OP_FUNC(MultVarGaussPDF3)( - VECT_OP_TYPE* yV, - const VECT_OP_TYPE* (*srcFunc)(void* funcDataPtr, unsigned frmIdx ), - void* funcDataPtr, - const VECT_OP_TYPE* meanV, - const VECT_OP_TYPE* invCovarM, - VECT_OP_TYPE logDet, - unsigned D, - unsigned N, - bool diagFl ); - -/// Determine the most likely state sequece stateV[timeN] given a -/// transition matrix a[stateN,stateN], -/// observation probability matrix b[stateN,timeN] and -/// initial state probability vector phi[stateN]. -/// a[i,j] is the probability of transitioning from state i to state j. -/// b[i,t] is the probability of state i emitting the obj t. +// Determine the most likely state sequece stateV[timeN] given a +// transition matrix a[stateN,stateN], +// observation probability matrix b[stateN,timeN] and +// initial state probability vector phi[stateN]. +// a[i,j] is the probability of transitioning from state i to state j. +// b[i,t] is the probability of state i emitting the obj t. void VECT_OP_FUNC(DiscreteViterbi)(unsigned* stateV, unsigned timeN, unsigned stateN, const VECT_OP_TYPE* phi, const VECT_OP_TYPE* a, const VECT_OP_TYPE* b ); -/// Clip the line defined by x0,y0 to x1,y1 into the rect defined by xMin,yMin xMax,yMax. +//====================================================================================================================== +//) + +//( { label:"Graphics" desc:"Graphics related algorithms." kw:[vop] } + +// Generate the set of coordinates which describe a circle with a center at x,y. +// dbp[dn,2] must contain 2*dn elements. The first column holds the x coord and and the second holds the y coord. +VECT_OP_TYPE* VECT_OP_FUNC(CircleCoords)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE x, VECT_OP_TYPE y, VECT_OP_TYPE varX, VECT_OP_TYPE varY ); + +// Clip the line defined by x0,y0 to x1,y1 into the rect defined by xMin,yMin xMax,yMax. bool VECT_OP_FUNC(ClipLine)( VECT_OP_TYPE* x0, VECT_OP_TYPE* y0, VECT_OP_TYPE* x1, VECT_OP_TYPE* y1, VECT_OP_TYPE xMin, VECT_OP_TYPE yMin, VECT_OP_TYPE xMax, VECT_OP_TYPE yMax ); -/// Return true if the line defined by x0,y0 to x1,y1 intersects with -/// the rectangle formed by xMin,yMin - xMax,yMax +// Return true if the line defined by x0,y0 to x1,y1 intersects with +// the rectangle formed by xMin,yMin - xMax,yMax bool VECT_OP_FUNC(IsLineInRect)( VECT_OP_TYPE x0, VECT_OP_TYPE y0, VECT_OP_TYPE x1, VECT_OP_TYPE y1, VECT_OP_TYPE xMin, VECT_OP_TYPE yMin, VECT_OP_TYPE xMax, VECT_OP_TYPE yMax ); -/// Return the perpendicular distance from the line formed by x0,y0 and x1,y1 -/// and the point px,py +// Return the perpendicular distance from the line formed by x0,y0 and x1,y1 +// and the point px,py VECT_OP_TYPE VECT_OP_FUNC(PtToLineDistance)( VECT_OP_TYPE x0, VECT_OP_TYPE y0, VECT_OP_TYPE x1, VECT_OP_TYPE y1, VECT_OP_TYPE px, VECT_OP_TYPE py); -/// Calculate the best fit line: b0 + b1*x_i through the points x_i,y_i. -/// Set x to NULL if it uses sequential integers [0,1,2,3...] -void VECT_OP_FUNC(Lsq1)(const VECT_OP_TYPE* x, const VECT_OP_TYPE* y, unsigned n, VECT_OP_TYPE* b0, VECT_OP_TYPE* b1 ); +//====================================================================================================================== +//) + +//( { label:"Miscellaneous DSP" desc:"Common DSP algorithms." kw:[vop] } + +// Compute the complex transient detection function from successive spectral frames. +// The spectral magntidue mag0V precedes mag1V and the phase (radians) spectrum phs0V precedes the phs1V which precedes phs2V. +// binCnt gives the length of each of the spectral vectors. +VECT_OP_TYPE VECT_OP_FUNC(ComplexDetect)(const VECT_OP_TYPE* mag0V, const VECT_OP_TYPE* mag1V, const VECT_OP_TYPE* phs0V, const VECT_OP_TYPE* phs1V, const VECT_OP_TYPE* phs2V, unsigned binCnt ); + +// Compute a set of DCT-II coefficients. Result dp[ coeffCnt, filtCnt ] +VECT_OP_TYPE* VECT_OP_FUNC(DctMatrix)( VECT_OP_TYPE* dp, unsigned coeffCnt, unsigned filtCnt ); -/// Given the points x0[xy0N],y0[xy0N] fill y1[i] with the interpolated value of y0[] at -/// x1[i]. Note that x0[] and x1[] must be increasing monotonic. -/// This function is similar to the octave interp1() function. +// Set the indexes of local peaks greater than threshold in dbp[]. +// Returns the number of peaks in dbp[] +// The maximum number of peaks from n source values is max(0,floor((n-1)/2)). +// Note that peaks will never be found at index 0 or index sn-1. +unsigned VECT_OP_FUNC(PeakIndexes)( unsigned* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn, VECT_OP_TYPE threshold ); + +// Return the index of the bin containing v otherwise return kInvalidIdx if v is below sbp[0] or above sbp[ n-1 ] +// The bin limits are contained in sbp[]. +// The value in spb[] are therefore expected to be in increasing order. +// The value returned will be in the range 0:sn-1. +unsigned VECT_OP_FUNC(BinIndex)( const VECT_OP_TYPE* sbp, unsigned sn, VECT_OP_TYPE v ); + + +// Given the points x0[xy0N],y0[xy0N] fill y1[i] with the interpolated value of y0[] at +// x1[i]. Note that x0[] and x1[] must be increasing monotonic. +// This function is similar to the octave interp1() function. void VECT_OP_FUNC(Interp1)(VECT_OP_TYPE* y1, const VECT_OP_TYPE* x1, unsigned xy1N, const VECT_OP_TYPE* x0, const VECT_OP_TYPE* y0, unsigned xy0N ); +//====================================================================================================================== +//)