libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cmProc4.h 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. #ifndef cmProc4_h
  2. #define cmProc4_h
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. typedef struct
  7. {
  8. unsigned smpIdx; // time tag sample index for val
  9. cmMidiByte_t val; //
  10. bool validFl; //
  11. } cmScFolBufEle_t;
  12. typedef struct
  13. {
  14. unsigned pitch;
  15. unsigned scEvtIdx;
  16. } cmScFolEvt_t;
  17. typedef struct
  18. {
  19. unsigned evtCnt; //
  20. cmScFolEvt_t* evtV; // pitchV[pitchCnt]
  21. unsigned scIdx; // index of the score loc (into cmScoreEvt[]) at this location
  22. int barNumb; // bar number of this location
  23. } cmScFolLoc_t;
  24. typedef struct
  25. {
  26. cmObj obj;
  27. cmReal_t srate; //
  28. cmScH_t scH; // score handle
  29. unsigned bufN; // event buffer count
  30. cmScFolBufEle_t* bufV; // event buffer bufV[bufN] - bufV[bufN-1] newest event, bufV[boi] oldest event
  31. int locN; // count of score locations
  32. cmScFolLoc_t* loc; // score loc[locN]
  33. unsigned sbi; // oldest score window index
  34. unsigned sei; // newest score window index
  35. unsigned msln; // minimum score look ahead count
  36. unsigned mswn; // maximum score window length
  37. unsigned forwardCnt; // count of score loc's to look ahead for a match to the current pitch when the optimal edit-dist alignment does not produce a match for the current pitch
  38. unsigned maxDist; // max. dist allowed to still consider matching
  39. unsigned minVel; // notes < minVel are ignored
  40. bool printFl; // true if pitch tracker reporting should be included
  41. bool noBackFl; // prevent the tracker from going backwards in time
  42. unsigned* edWndMtx;
  43. unsigned missCnt; // current consecutive unmatched notes
  44. unsigned matchCnt; // current consecutive matched notes
  45. unsigned eventIdx; // events since reset
  46. unsigned skipCnt; // notes skipped due to velocity
  47. unsigned ret_idx; // last tracked location
  48. } cmScFol;
  49. cmScFol* cmScFolAlloc( cmCtx* ctx, cmScFol* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
  50. cmRC_t cmScFolFree( cmScFol** pp );
  51. cmRC_t cmScFolInit( cmScFol* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
  52. cmRC_t cmScFolFinal( cmScFol* p );
  53. // Jump to a score location and reset the internal state of the follower.
  54. cmRC_t cmScFolReset( cmScFol* p, unsigned scoreIndex );
  55. // Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
  56. // all others are ignored.
  57. unsigned cmScFolExec( cmScFol* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
  58. //=======================================================================================================================
  59. typedef struct
  60. {
  61. unsigned pitch;
  62. unsigned scEvtIdx;
  63. bool matchFl;
  64. } cmScTrkEvt_t;
  65. typedef struct
  66. {
  67. unsigned evtCnt; //
  68. cmScTrkEvt_t* evtV; // evtV[evtCnt]
  69. unsigned scIdx; // index of the score event (into cmScoreEvt[]) at this location
  70. int barNumb; // bar number of this location
  71. } cmScTrkLoc_t;
  72. typedef struct
  73. {
  74. cmObj obj;
  75. cmScFol* sfp;
  76. double srate;
  77. cmScH_t scH;
  78. unsigned locN;
  79. cmScTrkLoc_t* loc;
  80. unsigned minVel;
  81. unsigned maxWndCnt;
  82. unsigned minWndLookAhead;
  83. bool printFl;
  84. int curLocIdx;
  85. unsigned evtIndex;
  86. } cmScTrk;
  87. cmScTrk* cmScTrkAlloc( cmCtx* ctx, cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
  88. cmRC_t cmScTrkFree( cmScTrk** pp );
  89. cmRC_t cmScTrkInit( cmScTrk* p, cmReal_t srate, cmScH_t scH, unsigned bufN, unsigned minWndLookAhead, unsigned maxWndCnt, unsigned minVel );
  90. cmRC_t cmScTrkFinal( cmScTrk* p );
  91. // Jump to a score location and reset the internal state of the follower.
  92. cmRC_t cmScTrkReset( cmScTrk* p, unsigned scoreIndex );
  93. // Give the follower a MIDI performance event. Only MIDI note-on events are acted upon;
  94. // all others are ignored.
  95. unsigned cmScTrkExec( cmScTrk* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1 );
  96. //=======================================================================================================================
  97. //
  98. // Simplified string alignment function based on Levenshtein edit distance.
  99. //
  100. enum { kEdMinIdx, kEdSubIdx, kEdDelIdx, kEdInsIdx, kEdCnt };
  101. typedef struct
  102. {
  103. unsigned v[kEdCnt];
  104. bool matchFl;
  105. bool transFl;
  106. } ed_val;
  107. typedef struct ed_path_str
  108. {
  109. unsigned code;
  110. unsigned ri;
  111. unsigned ci;
  112. bool matchFl;
  113. bool transFl;
  114. struct ed_path_str* next;
  115. } ed_path;
  116. /*
  117. Backtracking:
  118. m[rn,cn] is organized to indicate the mutation operations
  119. on s0[0:rn-1] or s1[0:cn-1] during backtracking.
  120. Backtracking begins at cell m[rn-1,cn-1] and proceeds
  121. up and left toward m[0,0]. The action to perform during
  122. backtracking is determined by examinging which values
  123. int m[].v[1:3] match m[].v[0].
  124. Match Next Cell
  125. Index Operation Location
  126. ----- ------------------------ ------------------------
  127. 1 Substitute char s0[ri-1] move diagonally; up-left
  128. 2 Delete char s0[ri-1] move up.
  129. 3 Delete char s1[ci-1] move left.
  130. (same as inserting blank
  131. into after s[ri-1]
  132. Note that more than one value in m[].v[1:3] may match
  133. m[].v[0]. In this case the candidate solution branches
  134. at this point in the candidate selection processes.
  135. */
  136. typedef struct
  137. {
  138. const char* s0; // forms rows of m[] - mutate to match s1 - rn=strlen(s0)
  139. const char* s1; // forms columns of m[] - target string - cn=strlen(s1)
  140. unsigned rn; // length of s0 + 1
  141. unsigned cn; // length of s1 + 1
  142. ed_val* m; // m[rn,cn]
  143. unsigned pn; // rn+cn
  144. ed_path* p_mem; // pmem[ 2*pn ];
  145. ed_path* p_avl; // available path record linked list
  146. ed_path* p_cur; // current path linked list
  147. ed_path* p_opt; // p_opt[pn] current best alignment
  148. double s_opt; // score of the current best alignment
  149. } ed_r;
  150. // print the DP matrix ed_r.m[rn,cn].
  151. void ed_print_mtx( ed_r* r );
  152. // Initialize ed_r.
  153. void ed_init( ed_r* r, const char* s0, const char* s1 );
  154. // Fill in the DP matrix.
  155. void ed_calc_mtx( ed_r* r );
  156. // Traverse the possible alignments in the DP matrix and determine the optimal alignment.
  157. void ed_align( ed_r* r );
  158. // Print the optimal alignment p_opt[]
  159. void ed_print_opt( ed_r* r );
  160. // Free resource allocated by ed_init().
  161. void ed_free(ed_r* r);
  162. // Main test function.
  163. void ed_main();
  164. //=======================================================================================================================
  165. enum
  166. {
  167. kSmMinIdx, //
  168. kSmSubIdx, // 'substitute' - may or may not match
  169. kSmDelIdx, // 'delete' - delete a MIDI note
  170. kSmInsIdx, // 'insert' - insert a space in the score
  171. kSmCnt
  172. };
  173. enum
  174. {
  175. kSmMatchFl = 0x01,
  176. kSmTransFl = 0x02,
  177. kSmTruePosFl = 0x04,
  178. kSmFalsePosFl = 0x08,
  179. kSmBarFl = 0x10,
  180. kSmNoteFl = 0x20
  181. };
  182. // Dynamic Programming (DP) matrix element
  183. typedef struct
  184. {
  185. unsigned v[kSmCnt]; // cost for each operation
  186. unsigned flags; // cmSmMatchFl | cmSmTransFl
  187. unsigned scEvtIdx;
  188. } cmScMatchVal_t;
  189. // List record used to track a path through the DP matrix p->m[,]
  190. typedef struct cmScMatchPath_str
  191. {
  192. unsigned code; // kSmXXXIdx
  193. unsigned ri; // matrix row index
  194. unsigned ci; // matrix col index
  195. unsigned flags; // cmSmMatchFl | cmSmTransFl
  196. unsigned locIdx; // p->loc index or cmInvalidIdx
  197. unsigned scEvtIdx; // scScore event index
  198. struct cmScMatchPath_str* next; //
  199. } cmScMatchPath_t;
  200. typedef struct cmScMatchEvt_str
  201. {
  202. unsigned pitch; //
  203. unsigned scEvtIdx; // scScore event index
  204. } cmScMatchEvt_t;
  205. // Score location record.
  206. typedef struct
  207. {
  208. unsigned evtCnt; //
  209. cmScMatchEvt_t* evtV; // evtV[evtCnt]
  210. unsigned scLocIdx; // scH score location index
  211. int barNumb; // bar number of this location
  212. } cmScMatchLoc_t;
  213. typedef struct
  214. {
  215. unsigned mni; // unique identifier for this MIDI note - used to recognize when the cmScMatcher backtracks.
  216. unsigned smpIdx; // time stamp of this event
  217. unsigned pitch; // MIDI note pitch
  218. unsigned vel; // " " velocity
  219. unsigned locIdx; // location assoc'd with this MIDI evt (cmInvalidIdx if not a matching or non-matching 'substitute')
  220. unsigned scEvtIdx; // cmScore event index assoc'd with this event
  221. } cmScMatchMidi_t;
  222. typedef struct
  223. {
  224. cmObj obj; //
  225. cmScH_t scH; // cmScore handle
  226. unsigned locN; //
  227. cmScMatchLoc_t* loc; // loc[locN]
  228. unsigned mrn; // max m[] row count (midi)
  229. unsigned rn; // cur m[] row count
  230. unsigned mcn; // max m[] column count (score)
  231. unsigned cn; // cur m[] column count
  232. unsigned mmn; // max length of midiBuf[] (mrn-1)
  233. unsigned msn; // max length of score window (mcn-1)
  234. cmScMatchVal_t* m; // m[mrn,mcn] DP matrix
  235. unsigned pn; // mrn+mcn
  236. cmScMatchPath_t* p_mem; // pmem[ 2*pn ] - path memory
  237. cmScMatchPath_t* p_avl; // available path record linked list
  238. cmScMatchPath_t* p_cur; // current path linked list
  239. cmScMatchPath_t* p_opt; // p_opt[pn] - current best alignment as a linked list
  240. double opt_cost; // last p_opt cost set by cmScMatchExec()
  241. } cmScMatch;
  242. /*
  243. 1) This matcher cannot handle multiple instances of the same pitch occuring
  244. at the same 'location'.
  245. 2) Because each note of a chord is spread out over multiple locations, and
  246. there is no way to indicate that a note in the chord is already 'in-use'.
  247. If a MIDI note which is part of the chord is repeated, in error, it will
  248. apear to be correct (a positive match will be assigned to
  249. the second (and possible successive notes)).
  250. */
  251. cmScMatch* cmScMatchAlloc( cmCtx* c, cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
  252. cmRC_t cmScMatchFree( cmScMatch** pp );
  253. cmRC_t cmScMatchInit( cmScMatch* p, cmScH_t scH, unsigned maxScWndN, unsigned maxMidiWndN );
  254. cmRC_t cmScMatchFinal( cmScMatch* p );
  255. // Locate the position in p->loc[locIdx:locIdx+locN-1] which bests
  256. // matches midiV[midiN].
  257. // The result of this function is to update p_opt[]
  258. // The optimal path p_opt[] will only be updated if the edit_cost associated 'midiV[midiN]'.
  259. // with the best match is less than 'min_cost'.
  260. // Set 'min_cost' to DBL_MAX to force p_opt[] to be updated.
  261. // Returns cmEofRC if locIdx + locN > p->locN - note that this is not
  262. // necessarily an error.
  263. cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMatchMidi_t* midiV, unsigned midiN, double min_cost );
  264. //=======================================================================================================================
  265. typedef struct
  266. {
  267. unsigned locIdx;
  268. unsigned scEvtIdx;
  269. unsigned mni;
  270. unsigned smpIdx;
  271. unsigned pitch;
  272. unsigned vel;
  273. unsigned flags;
  274. } cmScMatcherResult_t;
  275. struct cmScMatcher_str;
  276. typedef void (*cmScMatcherCb_t)( struct cmScMatcher_str* p, void* arg, cmScMatcherResult_t* rp );
  277. typedef struct cmScMatcher_str
  278. {
  279. cmObj obj;
  280. cmScMatcherCb_t cbFunc;
  281. void* cbArg;
  282. cmScMatch* mp;
  283. unsigned mn;
  284. cmScMatchMidi_t* midiBuf; // midiBuf[mn]
  285. cmScMatcherResult_t* res; // res[rn]
  286. unsigned rn; // length of res[]
  287. unsigned ri; // next avail res[] recd.
  288. double s_opt; //
  289. unsigned missCnt; // current count of consecutive trailing non-matches
  290. unsigned ili; // index into loc[] to start scan following reset
  291. unsigned eli; // index into loc[] of the last positive match.
  292. unsigned mni; // current count of MIDI events since the last call to cmScMatcherReset()
  293. unsigned mbi; // index of oldest MIDI event in midiBuf[]; stays at 0 when the buffer is full.
  294. unsigned begSyncLocIdx; // start of score window, in mp->loc[], of best match in previous scan
  295. unsigned initHopCnt; // max window hops during the initial (when the MIDI buffer fills for first time) sync scan
  296. unsigned stepCnt; // count of forward/backward score loc's to examine for a match during cmScMatcherStep().
  297. unsigned maxMissCnt; // max. number of consecutive non-matches during step prior to executing a scan.
  298. unsigned scanCnt; // current count of times a resync-scan was executed during cmScMatcherStep()
  299. bool printFl;
  300. } cmScMatcher;
  301. cmScMatcher* cmScMatcherAlloc( cmCtx* c, cmScMatcher* p, double srate, cmScH_t scH, unsigned scWndN, unsigned midiWndN, cmScMatcherCb_t cbFunc, void* cbArg );
  302. cmRC_t cmScMatcherFree( cmScMatcher** pp );
  303. cmRC_t cmScMatcherInit( cmScMatcher* p, double srate, cmScH_t scH, unsigned scWndN, unsigned midiWndN, cmScMatcherCb_t cbFunc, void* cbArg );
  304. cmRC_t cmScMatcherFinal( cmScMatcher* p );
  305. // 'scLocIdx' is a score index as used by cmScoreLoc(scH) not into p->mp->loc[].
  306. cmRC_t cmScMatcherReset( cmScMatcher* p, unsigned scLocIdx );
  307. // Slide a score window hopCnt times, beginning at 'bli' (an
  308. // index int p->mp->loc[]) looking for the best match to p->midiBuf[].
  309. // The score window contain scWndN (p->mp->mcn-1) score locations.
  310. // Returns the index into p->mp->loc[] of the start of the best
  311. // match score window. The score associated
  312. // with this match is stored in s_opt.
  313. unsigned cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned hopCnt );
  314. // Step forward/back by p->stepCnt from p->eli.
  315. // p->eli must therefore be valid prior to calling this function.
  316. // If more than p->maxMissCnt consecutive MIDI events are
  317. // missed then automatically run cmScAlignScan().
  318. // Return cmEofRC if the end of the score is encountered.
  319. // Return cmSubSysFailRC if an internal scan resync. failed.
  320. cmRC_t cmScMatcherStep( cmScMatcher* p );
  321. // This function calls cmScMatcherScan() and cmScMatcherStep() internally.
  322. // If 'status' is not kNonMidiMdId then the function returns without changing the
  323. // state of the object.
  324. // If the MIDI note passed by the call results in a successful match then
  325. // p->eli will be updated to the location in p->mp->loc[] of the latest
  326. // match, the MIDI note in p->midiBuf[] associated with this match
  327. // will be assigned a valid locIdx and scLocIdx values, and *scLocIdxPtr
  328. // will be set with the matched scLocIdx of the match.
  329. // If this call does not result in a successful match *scLocIdxPtr is set
  330. // to cmInvalidIdx.
  331. // Return:
  332. // cmOkRC - Continue processing MIDI events.
  333. // cmEofRC - The end of the score was encountered.
  334. // cmInvalidArgRC - scan failed or the object was in an invalid state to attempt a match.
  335. // cmSubSysFailRC - a scan resync failed in cmScMatcherStep().
  336. cmRC_t cmScMatcherExec( cmScMatcher* p, unsigned smpIdx, unsigned status, cmMidiByte_t d0, cmMidiByte_t d1, unsigned* scLocIdxPtr );
  337. //=======================================================================================================================
  338. typedef struct
  339. {
  340. cmScoreSet_t* sp; // ptr to this set in the score
  341. unsigned bsei; // begin score event index
  342. unsigned esei; // end score event index
  343. unsigned bsli; // beg score loc index
  344. unsigned esli; // end score loc index
  345. unsigned bli; //
  346. unsigned eli; //
  347. double value; // DBL_MAX if the value has not yet been set
  348. double tempo; //
  349. double match_cost; // cost of the match to the performance divided by sp->eleCnt
  350. } cmScMeasSet_t;
  351. typedef struct
  352. {
  353. cmObj obj;
  354. double srate; //
  355. cmScMatch* mp; //
  356. unsigned mii; // next avail recd in midiBuf[]
  357. unsigned mn; // length of of midiBuf[]
  358. cmScMatchMidi_t* midiBuf; // midiBuf[mn]
  359. unsigned sn; // length of set[]
  360. cmScMeasSet_t* set; // set[sn]
  361. unsigned dn; // length of dynRef[]
  362. unsigned* dynRef; // dynRef[dn]
  363. unsigned nsi; // next set index
  364. unsigned nsli; // next score location index
  365. unsigned vsi; // set[vsi:nsi-1] indicates sets with new values following a call to cmScMeasExec()
  366. unsigned vsli; // vsli:nsli-1 indicates cmScore loc's to check for section triggers following a call to cmScMeasExec()
  367. } cmScMeas;
  368. //
  369. // Notes:
  370. //
  371. // 1) midiBuf[] stores all MIDI notes for the duration of the performance
  372. // it is initialized to 2*score_event_count.
  373. //
  374. // 2) dynRef][ is the gives the MIDI velocity range for each dynamics
  375. // category: pppp-fff
  376. //
  377. // 3) See a cmDspKr.c _cmScFolMatcherCb() for an example of how
  378. // cmScMeas.vsi and cmScMeas.vsli are used to act on the results of
  379. // a call to cmMeasExec().
  380. cmScMeas* cmScMeasAlloc( cmCtx* c, cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
  381. cmRC_t cmScMeasFree( cmScMeas** pp );
  382. cmRC_t cmScMeasInit( cmScMeas* p, cmScH_t scH, double srate, const unsigned* dynRefArray, unsigned dynRefCnt );
  383. cmRC_t cmScMeasFinal( cmScMeas* p );
  384. // Empty MIDI buffer and set the next set nsi and nsli to zero.
  385. cmRC_t cmScMeasReset( cmScMeas* p );
  386. // This function is called for each input MIDI note which is assigned a
  387. // score location by cmScMatcher.
  388. // 'mni' is the MIDI event index which uniquely identifies this MIDI event.
  389. // 'locIdx' is the location index into cmScMatcher.mp->loc[] associated with
  390. // this event.
  391. cmRC_t cmScMeasExec( cmScMeas* p, unsigned mni, unsigned locIdx, unsigned scEvtIdx, unsigned flags, unsigned smpIdx, unsigned pitch, unsigned vel );
  392. //=======================================================================================================================
  393. unsigned cmScAlignScanToTimeLineEvent( cmScMatcher* p, cmTlH_t tlH, cmTlObj_t* top, unsigned endSmpIdx );
  394. // Given a score, a time-line, and a marker on the time line scan the
  395. // entire score looking for the best match between the first 'midiN'
  396. // notes in each marker region and the score.
  397. void cmScAlignScanMarkers( cmRpt_t* rpt, cmTlH_t tlH, cmScH_t scH );
  398. //=======================================================================================================================
  399. enum
  400. {
  401. kInvalidModTId,
  402. kSetModTId, // set variable to parray[0] at scLocIdx
  403. kLineModTId, // linear ramp variable to parray[0] over parray[1] seconds
  404. kSetLineModTId, // set variable to parray[0] and ramp to parray[1] over parray[2] seconds
  405. };
  406. enum
  407. {
  408. kActiveModFl = 0x01, // this variable is on the 'active' list
  409. kCalcModFl = 0x02 // when this variable is used as a parameter it's value must be calculated rather than used directly.
  410. };
  411. struct cmScModEntry_str;
  412. typedef enum
  413. {
  414. kInvalidModPId,
  415. kLiteralModPId, // this is a literal value
  416. kSymbolModPId //
  417. } cmScModPId_t;
  418. typedef struct cmScModParam_str
  419. {
  420. cmScModPId_t pid; // parameter type: literal or symbol
  421. unsigned symId; // symbol of external and internal variables
  422. double val; // value of literals
  423. } cmScModParam_t;
  424. typedef struct cmScModVar_str
  425. {
  426. unsigned flags; // see kXXXModFl flags above.
  427. unsigned varSymId; // variable name
  428. unsigned outVarId; // output var id
  429. double value; // current value of this variable
  430. double v0; // reserved internal variable
  431. unsigned phase; // cycle phase since activation
  432. double min;
  433. double max;
  434. double rate; // output rate in milliseconds
  435. struct cmScModEntry_str* entry; // last entry assoc'd with this value
  436. struct cmScModVar_str* vlink; // p->vlist link
  437. struct cmScModVar_str* alink; // p->alist link
  438. } cmScModVar_t;
  439. // Each entry gives a time tagged location and some parameters
  440. // for an algorthm which is used to set/modulate a value.
  441. typedef struct cmScModEntry_str
  442. {
  443. unsigned scLocIdx; // entry start time
  444. unsigned typeId; // variable type
  445. cmScModParam_t beg; // parameter values
  446. cmScModParam_t end; //
  447. cmScModParam_t dur; //
  448. cmScModParam_t min; // min value for this variable
  449. cmScModParam_t max; // max value for this variable
  450. cmScModParam_t rate; // update rate in milliseconds (DBL_MAX to disable)
  451. cmScModVar_t* varPtr; // target variable
  452. } cmScModEntry_t;
  453. typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value );
  454. typedef struct
  455. {
  456. cmObj obj;
  457. cmChar_t* fn; // modulator score file
  458. unsigned modSymId; // modulator name
  459. cmSymTblH_t stH; // symbol table used by this modulator
  460. cmScModCb_t cbFunc; // active value callback function
  461. void* cbArg; // first arg to cbFunc()
  462. unsigned samplesPerCycle; // interval in samples between calls to cmScModulatorExec()
  463. double srate; // system sample rate
  464. cmScModEntry_t* earray; // earray[en] - entry array sorted on ascending cmScModEntry_t.scLocIdx
  465. unsigned en; // count
  466. cmScModVar_t* vlist; // variable list
  467. cmScModVar_t* alist; // active variable list
  468. cmScModVar_t* elist; // last element on the active list
  469. unsigned nei; // next entry index
  470. unsigned outVarCnt; // count of unique vars that are targets of entry recds
  471. } cmScModulator;
  472. cmScModulator* cmScModulatorAlloc( cmCtx* c, cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg );
  473. cmRC_t cmScModulatorFree( cmScModulator** pp );
  474. cmRC_t cmScModulatorInit( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg );
  475. cmRC_t cmScModulatorFinal( cmScModulator* p );
  476. // Return count of variables.
  477. unsigned cmScModulatorOutVarCount( cmScModulator* p );
  478. // Return a pointer to the variable at vlist[idx].
  479. cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx );
  480. cmRC_t cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max );
  481. cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx );
  482. cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx );
  483. cmRC_t cmScModulatorDump( cmScModulator* p );
  484. #ifdef __cplusplus
  485. }
  486. #endif
  487. #endif