libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmProc5.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #ifndef cmProc5_h
  4. #define cmProc5_h
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. //( { file_desc:"Process Library 5", kw:[proclib]}
  9. //)
  10. //( { label:cmGoertzel file_desc:"Goertzel tone detection filter." kw:[proc]}
  11. typedef struct
  12. {
  13. double s0;
  14. double s1;
  15. double s2;
  16. double coeff;
  17. double hz;
  18. } cmGoertzelCh;
  19. struct cmShiftBuf_str;
  20. typedef struct cmGoertzel_str
  21. {
  22. cmObj obj;
  23. cmGoertzelCh* ch;
  24. unsigned chCnt;
  25. double srate;
  26. struct cmShiftBuf_str* shb;
  27. cmSample_t* wnd;
  28. } cmGoertzel;
  29. cmGoertzel* cmGoertzelAlloc( cmCtx* c, cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt, unsigned procSmpCnt, unsigned hopSmpCnt, unsigned wndSmpCnt );
  30. cmRC_t cmGoertzelFree( cmGoertzel** pp );
  31. cmRC_t cmGoertzelInit( cmGoertzel* p, double srate, const double* fcHzV, unsigned chCnt, unsigned procSmpCnt, unsigned hopSmpCnt, unsigned wndSmpCnt );
  32. cmRC_t cmGoertzelFinal( cmGoertzel* p );
  33. cmRC_t cmGoertzelSetFcHz( cmGoertzel* p, unsigned chIdx, double hz );
  34. cmRC_t cmGoertzelExec( cmGoertzel* p, const cmSample_t* in, unsigned procSmpCnt, double* outV, unsigned chCnt );
  35. //------------------------------------------------------------------------------------------------------------
  36. //)
  37. //( { label:cmGoldCode file_desc:"Gold code random generator." kw:[proc]}
  38. typedef struct
  39. {
  40. unsigned chN; // count of channels (each channel has a unique id)
  41. double srate; // system sample rate (samples/second)
  42. unsigned lfsrN; // linear feedback shift register (LFSR) length used to form Gold codes
  43. unsigned mlsCoeff0; // LFSR coeff. 0
  44. unsigned mlsCoeff1; // LFSR coeff. 1
  45. unsigned samplesPerChip; // samples per spreading code bit
  46. double rcosBeta; // raised cosine impulse response beta coeff.
  47. unsigned rcosOSFact; // raised cosine impulse response oversample factor
  48. double carrierHz; // carrier frequency
  49. double envMs; // attack/decay envelope duration
  50. } cmGoldSigArg_t;
  51. typedef struct
  52. {
  53. int* pnV; // pnV[ mlsN ] spread code (aliased from pnM[:,i])
  54. cmSample_t* bbV; // bbV[ sigN ] baseband signal at audio rate
  55. cmSample_t* mdV; // mdV[ sigN ] modulated signal at audio rate
  56. } cmGoldSigCh_t;
  57. typedef struct
  58. {
  59. cmObj obj; //
  60. cmGoldSigArg_t a; // argument record
  61. cmGoldSigCh_t* ch; // ch[ chN ] channel array
  62. int* pnM; // pnM[mlsN,chN] (aliased to ch[].pnV)
  63. cmSample_t* rcosV; // rcosV[rcosN] raised cosine impulse response
  64. unsigned rcosN; // length of raised cosine impulse response
  65. unsigned mlsN; // length of Gold codes (Maximum length sequence length)
  66. unsigned sigN; // length of channel signals bbV[] and mdV[]
  67. cmFIR* fir;
  68. } cmGoldSig_t;
  69. cmGoldSig_t* cmGoldSigAlloc( cmCtx* ctx, cmGoldSig_t* p, const cmGoldSigArg_t* a );
  70. cmRC_t cmGoldSigFree( cmGoldSig_t** pp );
  71. cmRC_t cmGoldSigInit( cmGoldSig_t* p, const cmGoldSigArg_t* a );
  72. cmRC_t cmGoldSigFinal( cmGoldSig_t* p );
  73. cmRC_t cmGoldSigWrite( cmCtx* ctx, cmGoldSig_t* p, const char* fn );
  74. // Generate a signal consisting of underlying white noise with
  75. // bsiN repeated copies of the id signal associated with
  76. // channel 'chIdx'. Each discrete id signal copy is separated by 'dsN' samples.
  77. // The signal will be prefixed with 'prefixN' samples of silence (noise).
  78. // On return sets 'yVRef' to point to the generated signal and 'yNRef'
  79. // to the count of samples in 'yVRef'.
  80. // On error sets yVRef to NULL and yNRef to zero.
  81. // The vector returned in 'yVRef' should be freed via atMemFree().
  82. // On return sets bsiV[bsiN] to the onset sample index of each id signal copy.
  83. // The background noise signal is limited to the range -noiseGain to noiseGain.
  84. cmRC_t cmGoldSigGen(
  85. cmGoldSig_t* p,
  86. unsigned chIdx,
  87. unsigned prefixN,
  88. unsigned dsN,
  89. unsigned *bsiV,
  90. unsigned bsiN,
  91. double noiseGain,
  92. cmSample_t** yVRef,
  93. unsigned* yNRef );
  94. cmRC_t cmGoldSigTest( cmCtx* ctx );
  95. //------------------------------------------------------------------------------------------------------------
  96. //)
  97. //( { label:cmPhat file_desc:"Phase-aligned transform for generalized cross correlator." kw:[proc]}
  98. // Flags for use with the 'flags' argument to cmPhatAlloc()
  99. enum
  100. {
  101. kNoFlagsAtPhatFl= 0x00,
  102. kDebugAtPhatFl = 0x01, // generate debugging file
  103. kHannAtPhatFl = 0x02 // apply a hann window function to the id/audio signals prior to correlation.
  104. };
  105. typedef struct
  106. {
  107. cmObj obj;
  108. cmFftSR fft;
  109. cmIFftRS ifft;
  110. float alpha;
  111. unsigned flags;
  112. cmComplexR_t* fhM; // fhM[fhN,chN] FT of each id signal stored in complex form
  113. float* mhM; // mhM[binN,chN] magnitude of each fhM column
  114. unsigned chN; // count of id signals
  115. unsigned fhN; // length of each FT id signal (fft->xN)
  116. unsigned binN; // length of each mhM column (fft->xN/2);
  117. unsigned hN; // length of each time domain id signal (hN<=fhN/2)
  118. unsigned absIdx; // abs. sample index of p->di
  119. cmSample_t* dV; // dV[fhN] delay line
  120. unsigned di; // next input into delay line
  121. cmSample_t* xV; // xV[fhN] linear delay buffer
  122. cmComplexR_t* t0V; // t0V[fhN]
  123. cmComplexR_t* t1V; // t1V[fhN]
  124. cmSample_t* wndV;
  125. cmVectArray_t* ftVa;
  126. } cmPhat_t;
  127. // Allocate a PHAT based multi-channel correlator.
  128. // 'chN' is the maximum count of id signals to be set via cmPhatSetId().
  129. // 'hN' is the the length of the id signal in samples.
  130. // 'alpha' weight used to emphasize the frequencies where the id signal contains energy.
  131. // 'mult' * 'hN' is the correlation length (fhN)
  132. // 'flags' See kDebugAtPhatFl and kWndAtPhatFl.
  133. cmPhat_t* cmPhatAlloc( cmCtx* ctx, cmPhat_t* p, unsigned chN, unsigned hN, float alpha, unsigned mult, unsigned flags );
  134. cmRC_t cmPhatFree( cmPhat_t** pp );
  135. cmRC_t cmPhatInit( cmPhat_t* p, unsigned chN, unsigned hN, float alpha, unsigned mult, unsigned flags );
  136. cmRC_t cmPhatFinal( cmPhat_t* p );
  137. // Zero the audio delay line and reset the current input sample (di)
  138. // and absolute time index (absIdx) to 0.
  139. cmRC_t cmPhatReset( cmPhat_t* p );
  140. // Register an id signal with the correlator.
  141. cmRC_t cmPhatSetId( cmPhat_t* p, unsigned chIdx, const cmSample_t* hV, unsigned hN );
  142. // Update the correlators internal delay buffer.
  143. cmRC_t cmPhatExec( cmPhat_t* p, const cmSample_t* xV, unsigned xN );
  144. // Set p->xV[0:fhN-1] to the correlation function based on
  145. // correlation between the current audio delay line d[] and
  146. // the id signal in fhM[:,chIdx].
  147. // 'sessionId' and 'roleId' are only used to label the
  148. // data stored in the debug file and may be set to any
  149. // arbitrary value if the debug files are not being generated.
  150. void cmPhatChExec(
  151. cmPhat_t* p,
  152. unsigned chIdx,
  153. unsigned sessionId,
  154. unsigned roleId);
  155. cmRC_t cmPhatWrite( cmPhat_t* p, const char* dirStr );
  156. //------------------------------------------------------------------------------------------------------------
  157. //)
  158. //( { label:cmReflectCal file_desc:"Calculate the time of flight of Gold code acoustic reflections." kw:[proc]}
  159. typedef struct
  160. {
  161. cmObj obj;
  162. cmGoldSig_t* gs;
  163. cmPhat_t* phat;
  164. unsigned xi; // index into xV[] of the next sample to output
  165. unsigned t;
  166. unsigned* t0V; // t0V[tN] - last tN signal start times
  167. unsigned* t1V; // t1V[tN] - last tN signal detection times
  168. unsigned tN;
  169. unsigned ti;
  170. cmVectArray_t* phVa;
  171. cmVectArray_t* xVa;
  172. cmVectArray_t* yVa;
  173. } cmReflectCalc_t;
  174. cmReflectCalc_t* cmReflectCalcAlloc( cmCtx* ctx, cmReflectCalc_t* p, const cmGoldSigArg_t* gsa, float phat_alpha, unsigned phat_mult );
  175. cmRC_t cmReflectCalcFree( cmReflectCalc_t** pp );
  176. cmRC_t cmReflectCalcInit( cmReflectCalc_t* p, const cmGoldSigArg_t* gsa, float phat_alpha, unsigned phat_mult );
  177. cmRC_t cmReflectCalcFinal( cmReflectCalc_t* p );
  178. cmRC_t cmReflectCalcExec( cmReflectCalc_t* p, const cmSample_t* xV, cmSample_t* yV, unsigned xyN );
  179. cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr );
  180. //------------------------------------------------------------------------------------------------------------
  181. //)
  182. //( { label:cmNlms file_desc:"Normalized least mean squares echo canceller." kw:[proc]}
  183. typedef struct
  184. {
  185. cmObj obj;
  186. float mu; // LMS step rate
  187. unsigned hN; // filter length
  188. unsigned delayN; // fixed delay to apply to align xV with fV.
  189. unsigned dN; // max length of the fixed delay
  190. cmSample_t* delayV; // delayV[ dN ] fixed delay buffer[]
  191. unsigned di; // delay index
  192. double* wV; // wV[hN] filter weights
  193. double* hV; // hV[hN] filter delay line
  194. unsigned w0i; // The index into hV[] of the start of the delay line.
  195. cmVectArray_t* uVa;
  196. cmVectArray_t* fVa;
  197. cmVectArray_t* eVa;
  198. } cmNlmsEc_t;
  199. cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* p, double srate, float mu, unsigned hN, unsigned delayN );
  200. cmRC_t cmNlmsEcFree( cmNlmsEc_t** pp );
  201. cmRC_t cmNlmsEcInit( cmNlmsEc_t* p, double srate, float mu, unsigned hN, unsigned delayN );
  202. cmRC_t cmNlmsEcFinal( cmNlmsEc_t* p );
  203. // xV[] unfiltered reference signal (direct from xform output)
  204. // fV[] filtered reference signal (from mic)
  205. // yV[] echo-canelled signal
  206. cmRC_t cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN );
  207. cmRC_t cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dir );
  208. void cmNlmsEcSetMu( cmNlmsEc_t* p, float mu );
  209. void cmNlmsEcSetDelayN( cmNlmsEc_t* p, unsigned delayN );
  210. void cmNlmsEcSetIrN( cmNlmsEc_t* p, unsigned irN );
  211. //------------------------------------------------------------------------------------------------------------
  212. //)
  213. //( { label:cmSeqAlign file_desc:"Align two sequences where each sequence is composed of records with varying numbers of features." kw:[proc]}
  214. typedef struct cmSeqAlignLoc_str
  215. {
  216. unsigned id; // location id
  217. unsigned vN; //
  218. unsigned* vV; // vV[vN]
  219. struct cmSeqAlignLoc_str* link;
  220. } cmSeqAlignLoc_t;
  221. typedef struct cmSeqAlignSeq_str
  222. {
  223. unsigned id;
  224. cmSeqAlignLoc_t* locL;
  225. struct cmSeqAlignSeq_str* link;
  226. } cmSeqAlignSeq_t;
  227. typedef struct
  228. {
  229. cmObj obj;
  230. cmSeqAlignSeq_t* seqL;
  231. } cmSeqAlign_t;
  232. cmSeqAlign_t* cmSeqAlignAlloc( cmCtx* ctx, cmSeqAlign_t* p );
  233. cmRC_t cmSeqAlignFree( cmSeqAlign_t** p );
  234. cmRC_t cmSeqAlignInit( cmSeqAlign_t* p );
  235. cmRC_t cmSeqAlignFinal( cmSeqAlign_t* p );
  236. cmRC_t cmSeqAlignInsert( cmSeqAlign_t* p, unsigned seqId, unsigned locId, unsigned value );
  237. cmRC_t cmSeqAlignExec( cmSeqAlign_t* p );
  238. void cmSeqAlignReport( cmSeqAlign_t* p, cmRpt_t* rpt );
  239. //------------------------------------------------------------------------------------------------------------
  240. //)
  241. #ifdef __cplusplus
  242. }
  243. #endif
  244. #endif