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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. #include "cmGlobal.h"
  2. #include "cmFloatTypes.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmCtx.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include "cmLinkedHeap.h"
  9. #include "cmSymTbl.h"
  10. #include "cmJson.h"
  11. #include "cmFile.h"
  12. #include "cmTime.h"
  13. #include "cmMidi.h"
  14. #include "cmMidiFile.h"
  15. #include "cmAudioFile.h"
  16. #include "cmScore.h"
  17. #include "cmTimeLine.h"
  18. #include "cmScoreProc.h"
  19. #include "cmProcObj.h"
  20. #include "cmProc4.h"
  21. enum
  22. {
  23. kOkSpRC,
  24. kJsonFailSpRC,
  25. kScoreFailSpRC,
  26. kTimeLineFailSpRC,
  27. kScoreMatchFailSpRC,
  28. kFileFailSpRC,
  29. kProcFailSpRC
  30. };
  31. typedef enum
  32. {
  33. kBeginSectionSpId,
  34. kEndSectionSpId
  35. } cmScoreProcSelId_t;
  36. struct cmSp_str;
  37. typedef cmSpRC_t (*cmScoreProcCb_t)( void* arg, struct cmSp_str* p, cmScoreProcSelId_t id, cmTlMarker_t* curMarkPtr );
  38. typedef struct cmSp_str
  39. {
  40. cmErr_t err; // score proc object error state
  41. cmCtx* ctx; // application context
  42. cmScH_t scH; // score object
  43. const cmChar_t* tlFn; // time-line filename
  44. cmTlH_t tlH; // time-line object
  45. cmJsonH_t jsH; //
  46. unsigned* dynArray; // dynArray[dynCnt] dynamics reference array
  47. unsigned dynCnt; //
  48. double srate; //
  49. cmScMatcher* match; // score follower
  50. cmScMatcherCb_t matchCb; // score follower callback
  51. cmScoreProcCb_t procCb; // score processor callback
  52. void* cbArg; // callback arg. for both matchCb and procCb.
  53. } cmSp_t;
  54. // read the dynamics reference array from the time-line project file.
  55. cmSpRC_t _cmJsonReadDynArray( cmJsonH_t jsH, unsigned** dynArray, unsigned* dynCnt )
  56. {
  57. cmJsonNode_t* np;
  58. int i;
  59. if( cmJsonPathToArray(jsH, NULL, NULL, "dynRef", &np ) != kOkJsRC )
  60. return kJsonFailSpRC;
  61. *dynCnt = cmJsonChildCount(np);
  62. *dynArray = cmMemAllocZ(unsigned,*dynCnt);
  63. for(i=0; i<*dynCnt; ++i)
  64. if( cmJsonUIntValue( cmJsonArrayElement(np,i), (*dynArray)+i ) != kOkJsRC )
  65. return kJsonFailSpRC;
  66. return kOkSpRC;
  67. }
  68. cmSpRC_t _cmScoreProcInit( cmCtx_t* ctx, cmSp_t* p, const cmChar_t* rsrcFn, cmScoreProcCb_t procCb, cmScMatcherCb_t matchCb, void* cbArg )
  69. {
  70. cmSpRC_t rc = kOkSpRC;
  71. const cmChar_t* scFn = NULL;
  72. const cmChar_t* tlFn = NULL;
  73. const cmChar_t* tlPrefixPath = NULL;
  74. cmErrSetup(&p->err,&ctx->rpt,"ScoreProc");
  75. // open the resource file
  76. if( cmJsonInitializeFromFile( &p->jsH, rsrcFn, ctx ) != kOkJsRC )
  77. {
  78. rc = cmErrMsg(&p->err,kJsonFailSpRC,"Unable to load the main resource file:%s.",cmStringNullGuard(rsrcFn));
  79. goto errLabel;
  80. }
  81. // get the time line fn
  82. if( cmJsonPathToString( p->jsH, NULL, NULL, "timeLineFn", &tlFn ) != kOkJsRC )
  83. {
  84. rc = cmErrMsg(&p->err,kJsonFailSpRC,"Unable to locate the time line file name in the main resource file:%s",cmStringNullGuard(rsrcFn));
  85. goto errLabel;
  86. }
  87. // get the score file name
  88. if( cmJsonPathToString( p->jsH, NULL, NULL, "scoreFn", &scFn ) != kOkJsRC )
  89. {
  90. rc = cmErrMsg(&p->err,kJsonFailSpRC,"Unable to locate the score file name in the main resource file:%s",cmStringNullGuard(rsrcFn));
  91. goto errLabel;
  92. }
  93. // get the time line data file prefix path
  94. if( cmJsonPathToString( p->jsH, NULL, NULL, "tlPrefixPath", &tlPrefixPath ) != kOkJsRC )
  95. {
  96. rc = cmErrMsg(&p->err,kJsonFailSpRC,"Unable to locate the time line data file prefix path in the main resource file:%s",cmStringNullGuard(rsrcFn));
  97. goto errLabel;
  98. }
  99. // read the dynamics reference array
  100. if((rc = _cmJsonReadDynArray( p->jsH, &p->dynArray, &p->dynCnt )) != kOkSpRC )
  101. {
  102. rc = cmErrMsg(&p->err,rc,"Unable to read dynamics reference array resource from the main resource file:%s",cmStringNullGuard(rsrcFn));
  103. goto errLabel;
  104. }
  105. // load the time-line file
  106. if( cmTimeLineInitializeFromFile(ctx, &p->tlH, NULL, NULL, tlFn, tlPrefixPath ) != kOkTlRC )
  107. {
  108. rc = cmErrMsg(&p->err,kTimeLineFailSpRC,"Time line load failed for time line file:%s.",cmStringNullGuard(tlFn));
  109. goto errLabel;
  110. }
  111. p->srate = cmTimeLineSampleRate(p->tlH);
  112. // load the score file
  113. if( cmScoreInitialize(ctx, &p->scH, scFn, p->srate, NULL, 0, NULL, NULL, cmSymTblNullHandle ) != kOkScRC )
  114. {
  115. rc = cmErrMsg(&p->err,kScoreFailSpRC,"Score load failed for score file:%s.",cmStringNullGuard(scFn));
  116. goto errLabel;
  117. }
  118. p->ctx = cmCtxAlloc(NULL, &ctx->rpt, cmLHeapNullHandle, cmSymTblNullHandle );
  119. p->matchCb = matchCb;
  120. p->procCb = procCb;
  121. p->cbArg = cbArg;
  122. errLabel:
  123. return rc;
  124. }
  125. cmSpRC_t _cmScoreProcProcess(cmCtx_t* ctx, cmSp_t* sp)
  126. {
  127. cmSpRC_t rc = kOkSpRC;
  128. unsigned midiN = 7;
  129. unsigned scWndN = 10;
  130. unsigned seqN = cmTimeLineSeqCount(sp->tlH);
  131. double srate = cmTimeLineSampleRate(sp->tlH);
  132. unsigned seqId;
  133. assert( sp->srate == srate);
  134. // allocate the score matcher
  135. sp->match = cmScMatcherAlloc(sp->ctx,NULL,sp->srate,sp->scH,scWndN,midiN,sp->matchCb,sp->cbArg);
  136. assert(sp->match != NULL );
  137. // for each time line sequence
  138. for(seqId=0; seqId<seqN; ++seqId)
  139. {
  140. cmTlObj_t* o0p = NULL;
  141. // for each 'marker' in this time line sequence
  142. while( (o0p = cmTimeLineNextTypeObj(sp->tlH, o0p, seqId, kMarkerTlId)) != NULL )
  143. {
  144. // get the 'marker' recd
  145. cmTlMarker_t* markPtr = cmTimeLineMarkerObjPtr(sp->tlH,o0p);
  146. assert( markPtr != NULL );
  147. // if the marker does not have a valid start bar location
  148. if( markPtr->bar == 0 )
  149. continue;
  150. // get the end-of-marker time as a sample index
  151. unsigned markEndSmpIdx = markPtr->obj.seqSmpIdx + markPtr->obj.durSmpCnt;
  152. // get the score event associated with the marker's bar number.
  153. const cmScoreEvt_t* evtPtr = cmScoreBarEvt(sp->scH,markPtr->bar);
  154. assert( evtPtr != NULL );
  155. // get the score location associated with the markers bar score event
  156. const cmScoreLoc_t* locPtr = cmScoreEvtLoc(sp->scH,evtPtr);
  157. assert( locPtr != NULL );
  158. cmRptPrintf(&ctx->rpt,"Processing loc:%i seq:%i %s %s\n",locPtr->index,seqId,cmStringNullGuard(markPtr->obj.name),cmStringNullGuard(markPtr->text));
  159. // inform the score processor that we are about to start a new section
  160. if( sp->procCb( sp->cbArg, sp, kBeginSectionSpId, markPtr ) != kOkSpRC )
  161. {
  162. cmErrMsg(&sp->err,kProcFailSpRC,"The score process object failed on reset.");
  163. continue;
  164. }
  165. // reset the score matcher to begin searching at the bar location
  166. if( cmScMatcherReset(sp->match, locPtr->index ) != cmOkRC )
  167. {
  168. cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher reset failed on location: %i.",locPtr->index);
  169. continue;
  170. }
  171. cmTlObj_t* o1p = o0p;
  172. // as long as more MIDI events are available get the next MIDI msg
  173. while( (rc == kOkSpRC) && (o1p = cmTimeLineNextTypeObj(sp->tlH, o1p, seqId, kMidiEvtTlId )) != NULL )
  174. {
  175. cmTlMidiEvt_t* mep = cmTimeLineMidiEvtObjPtr(sp->tlH,o1p);
  176. assert(mep != NULL );
  177. // if the msg falls after the end of the marker then we are done
  178. if( mep->obj.seqSmpIdx != cmInvalidIdx && mep->obj.seqSmpIdx > markEndSmpIdx )
  179. break;
  180. // if the time line MIDI msg a note-on
  181. if( mep->msg->status == kNoteOnMdId )
  182. {
  183. cmRC_t cmRC = cmScMatcherExec(sp->match, mep->obj.seqSmpIdx, mep->msg->status, mep->msg->u.chMsgPtr->d0, mep->msg->u.chMsgPtr->d1, NULL );
  184. switch( cmRC )
  185. {
  186. case cmOkRC: // continue processing MIDI events
  187. break;
  188. case cmEofRC: // end of the score was encountered
  189. break;
  190. case cmInvalidArgRC: // p->eli was not set correctly
  191. rc = cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher failed due to an invalid argument.");
  192. goto errLabel;
  193. break;
  194. case cmSubSysFailRC: // scan resync failed
  195. rc = cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher failed on resync.");
  196. cmScMatcherPrint(sp->match);
  197. //goto errLabel;
  198. break;
  199. default:
  200. { assert(0); }
  201. }
  202. }
  203. }
  204. // inform the score processor that we done processing a section
  205. if( sp->procCb( sp->cbArg, sp, kEndSectionSpId, NULL ) != kOkSpRC )
  206. cmErrMsg(&sp->err,kProcFailSpRC,"The score process object failed on reset.");
  207. rc = kOkSpRC;
  208. }
  209. }
  210. errLabel:
  211. if( cmScMatcherFree(&sp->match) != cmOkRC )
  212. cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher release failed.");
  213. return rc;
  214. }
  215. cmSpRC_t _cmScoreProcFinal( cmSp_t* p )
  216. {
  217. cmSpRC_t rc = kOkSpRC;
  218. cmCtxFree(&p->ctx);
  219. if( cmScoreFinalize(&p->scH) != kOkScRC )
  220. cmErrMsg(&p->err,kScoreFailSpRC,"Score finalize failed.");
  221. if( cmTimeLineFinalize(&p->tlH) != kOkTlRC )
  222. cmErrMsg(&p->err,kTimeLineFailSpRC,"Time line finalize failed.");
  223. if( cmJsonFinalize(&p->jsH) != kOkJsRC )
  224. cmErrMsg(&p->err,kJsonFailSpRC,"JSON finalize failed.");
  225. cmMemFree(p->dynArray);
  226. return rc;
  227. }
  228. //==================================================================================================
  229. typedef struct _cmSpMeas_t
  230. {
  231. cmTlMarker_t* markPtr; // time-line marker in which this 'set' exists
  232. cmScoreSet_t* setPtr; // score set on which this measurment is based
  233. double value; // the value of the measurement
  234. double cost; // the quality of the perf->score match
  235. struct _cmSpMeas_t* link;
  236. } _cmSpMeas_t;
  237. typedef struct
  238. {
  239. struct cmSp_str* sp;
  240. cmScMeas* meas; // performance analyzer
  241. cmTlMarker_t* curMarkPtr; //
  242. _cmSpMeas_t* list_beg; //
  243. _cmSpMeas_t* list_end; //
  244. _cmSpMeas_t* slist_beg; //
  245. } _cmSpMeasProc_t;
  246. typedef struct
  247. {
  248. unsigned srcSeqId;
  249. const cmChar_t* srcMarkNameStr;
  250. unsigned srcTypeId;
  251. const cmChar_t* srcTypeLabelStr;
  252. unsigned dstScLocIdx;
  253. unsigned dstEvtIdx;
  254. const cmChar_t* dstSectLabelStr;
  255. double value;
  256. double cost;
  257. } _cmSpMeasSect_t;
  258. unsigned _cmSpMeasSectCount( _cmSpMeasProc_t* m )
  259. {
  260. const _cmSpMeas_t* mp = m->list_beg;
  261. unsigned n = 0;
  262. for(; mp != NULL; mp=mp->link)
  263. n += mp->setPtr->sectCnt;
  264. return n;
  265. }
  266. int _cmSpMeasSectCompare( const void* p0, const void* p1 )
  267. {
  268. _cmSpMeasSect_t* m0 = (_cmSpMeasSect_t*)p0;
  269. _cmSpMeasSect_t* m1 = (_cmSpMeasSect_t*)p1;
  270. return (int)m0->dstScLocIdx - (int)m1->dstScLocIdx;
  271. }
  272. cmSpRC_t _cmScWriteMeasFile( cmCtx_t* ctx, cmSp_t* sp, _cmSpMeasProc_t* m, const cmChar_t* outFn )
  273. {
  274. cmFileH_t fH = cmFileNullHandle;
  275. cmSpRC_t rc = kOkSpRC;
  276. unsigned i,j,k;
  277. _cmSpMeas_t* mp = m->list_beg;
  278. unsigned scnt = _cmSpMeasSectCount(m);
  279. _cmSpMeasSect_t sarray[ scnt ];
  280. for(i=0,k=0; k<scnt && mp!=NULL; ++i,mp=mp->link)
  281. {
  282. const cmChar_t* typeLabel = NULL;
  283. switch(mp->setPtr->varId)
  284. {
  285. case kEvenVarScId: typeLabel="even"; break;
  286. case kDynVarScId: typeLabel="dyn"; break;
  287. case kTempoVarScId:typeLabel="tempo";break;
  288. default:
  289. { assert(0); }
  290. }
  291. for(j=0; j<mp->setPtr->sectCnt; ++j,++k)
  292. {
  293. _cmSpMeasSect_t* r = sarray + k;
  294. r->srcSeqId = mp->markPtr->obj.seqId,
  295. r->srcMarkNameStr = cmStringNullGuard(mp->markPtr->obj.name),
  296. r->srcTypeId = mp->setPtr->varId,
  297. r->srcTypeLabelStr = typeLabel,
  298. r->dstScLocIdx = mp->setPtr->sectArray[j]->locPtr->index,
  299. r->dstEvtIdx = mp->setPtr->sectArray[j]->begEvtIndex,
  300. r->dstSectLabelStr = cmStringNullGuard(mp->setPtr->sectArray[j]->label),
  301. r->value = mp->value,
  302. r->cost = mp->cost;
  303. }
  304. }
  305. assert(mp==NULL && k==scnt);
  306. qsort(sarray,scnt,sizeof(sarray[0]),_cmSpMeasSectCompare);
  307. if( cmFileOpen(&fH,outFn,kWriteFileFl,&ctx->rpt) != kOkFileRC )
  308. {
  309. rc = cmErrMsg(&sp->err,kFileFailSpRC,"Unable to create the output file '%s'.",cmStringNullGuard(outFn));
  310. goto errLabel;
  311. }
  312. cmFilePrintf(fH,"{\n meas : \n[\n[ \"sec\" \"typeLabel\" \"val\" \"cost\" \"loc\" \"evt\" \"seq\" \"mark\" \"typeId\" ]\n");
  313. for(i=0; i<scnt; ++i)
  314. {
  315. _cmSpMeasSect_t* r = sarray + i;
  316. cmFilePrintf(fH,"[ \"%s\" \"%s\" %f %f %i %i %i \"%s\" %i ]\n",
  317. r->dstSectLabelStr,
  318. r->srcTypeLabelStr,
  319. r->value,
  320. r->cost,
  321. r->dstScLocIdx,
  322. r->dstEvtIdx,
  323. r->srcSeqId,
  324. r->srcMarkNameStr,
  325. r->srcTypeId
  326. );
  327. }
  328. /*
  329. mp = sp->list_beg;
  330. for(; mp!=NULL; mp=mp->link)
  331. {
  332. for(i=0; i<mp->setPtr->sectCnt; ++i)
  333. {
  334. cmFilePrintf(fH,"[ %i \"%s\" %i \"%s\" %i %i \"%s\" %f %f ]\n",
  335. mp->markPtr->obj.seqId,
  336. cmStringNullGuard(mp->markPtr->obj.name),
  337. mp->setPtr->varId,
  338. typeLabel,
  339. mp->setPtr->sectArray[i]->locPtr->index,
  340. mp->setPtr->sectArray[i]->begEvtIndex,
  341. cmStringNullGuard(mp->setPtr->sectArray[i]->label),
  342. mp->value,
  343. mp->cost );
  344. }
  345. }
  346. */
  347. cmFilePrintf(fH,"\n]\n}\n");
  348. errLabel:
  349. if( cmFileClose(&fH) != kOkFileRC )
  350. cmErrMsg(&sp->err,kFileFailSpRC,"The output file close failed on '%s'.",cmStringNullGuard(outFn));
  351. return rc;
  352. }
  353. // score matcher callback
  354. void _cmSpMatchMeasCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp )
  355. {
  356. _cmSpMeasProc_t* m = (_cmSpMeasProc_t*)arg;
  357. cmScMeas* sm = m->meas;
  358. if( cmScMeasExec(sm, rp->mni, rp->locIdx, rp->scEvtIdx, rp->flags, rp->smpIdx, rp->pitch, rp->vel ) == cmOkRC )
  359. {
  360. unsigned i;
  361. for(i=sm->vsi; i<sm->nsi; ++i)
  362. // ignore set's which did not produce a valid value
  363. if(sm->set[i].value != DBL_MAX )
  364. {
  365. _cmSpMeas_t* r = cmMemAllocZ(_cmSpMeas_t,1);
  366. r->markPtr = m->curMarkPtr;
  367. r->setPtr = sm->set[i].sp;
  368. r->value = sm->set[i].value;
  369. r->cost = sm->set[i].match_cost;
  370. if( m->list_beg == NULL )
  371. {
  372. m->list_beg = r;
  373. m->list_end = r;
  374. }
  375. else
  376. {
  377. m->list_end->link = r;
  378. m->list_end = r;
  379. }
  380. }
  381. }
  382. }
  383. // measurement proc callback
  384. cmSpRC_t _cmSpProcMeasCb( void* arg, cmSp_t* sp, cmScoreProcSelId_t id, cmTlMarker_t* curMarkPtr )
  385. {
  386. cmSpRC_t rc = kOkSpRC;
  387. _cmSpMeasProc_t* m = (_cmSpMeasProc_t*)arg;
  388. switch( id )
  389. {
  390. case kBeginSectionSpId:
  391. // reset the performance evaluation object
  392. if( cmScMeasReset(m->meas) != cmOkRC )
  393. rc = cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score performance evaluation object failed on reset.");
  394. m->curMarkPtr = curMarkPtr;
  395. break;
  396. case kEndSectionSpId:
  397. break;
  398. }
  399. return rc;
  400. }
  401. cmSpRC_t _cmScoreProcGenAllMeasurementsMain(cmCtx_t* ctx)
  402. {
  403. const cmChar_t* rsrcFn = "/home/kevin/.kc/time_line.js";
  404. const cmChar_t* outFn = "/home/kevin/src/cmkc/src/kc/data/meas0.js";
  405. cmSpRC_t rc = kOkSpRC;
  406. _cmSpMeasProc_t* m = cmMemAllocZ(_cmSpMeasProc_t,1);
  407. cmSp_t s;
  408. cmSp_t* sp = &s;
  409. memset(sp,0,sizeof(s));
  410. cmRptPrintf(&ctx->rpt,"Score Performance Evaluation Start\n");
  411. // initialize the score processor
  412. if((rc = _cmScoreProcInit(ctx,sp,rsrcFn,_cmSpProcMeasCb,_cmSpMatchMeasCb,m)) != kOkSpRC )
  413. goto errLabel;
  414. // allocate the performance evaluation measurement object
  415. m->meas = cmScMeasAlloc( sp->ctx, NULL, sp->scH, sp->srate, sp->dynArray, sp->dynCnt );
  416. m->sp = sp;
  417. // run the score processor
  418. _cmScoreProcProcess(ctx,sp);
  419. // write the results of the performance evaluation
  420. if((rc = _cmScWriteMeasFile(ctx, sp, m, outFn )) != kOkSpRC )
  421. cmErrMsg(&sp->err,kFileFailSpRC,"The measurement output did not complete without errors.");
  422. // free the measurement linked list
  423. _cmSpMeas_t* mp = m->list_beg;
  424. while(mp!=NULL)
  425. {
  426. _cmSpMeas_t* np = mp->link;
  427. cmMemFree(mp);
  428. mp = np;
  429. }
  430. // free the performance evaluation object
  431. if( cmScMeasFree(&m->meas) != cmOkRC )
  432. cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The performance evaluation object failed.");
  433. //cmScorePrint(sp.scH,&ctx->rpt);
  434. //cmScorePrintLoc(sp.scH);
  435. errLabel:
  436. _cmScoreProcFinal(sp);
  437. cmMemFree(m);
  438. cmRptPrintf(&ctx->rpt,"Score Proc End\n");
  439. return rc;
  440. }
  441. //==================================================================================================
  442. typedef struct
  443. {
  444. cmSp_t* sp;
  445. } cmSpPerfProc_t;
  446. void _cmSpMatchPerfCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp )
  447. {
  448. cmSpPerfProc_t* m = (cmSpPerfProc_t*)arg;
  449. }
  450. cmSpRC_t _cmSpProcPerfCb( void* arg, cmSp_t* sp, cmScoreProcSelId_t id, cmTlMarker_t* curMarkPtr )
  451. {
  452. cmSpPerfProc_t* m = (cmSpPerfProc_t*)arg;
  453. }
  454. cmSpRC_t _cmScoreProcGenPerfMain(cmCtx_t* ctx)
  455. {
  456. const cmChar_t* rsrcFn = "/home/kevin/.kc/time_line.js";
  457. const cmChar_t* outFn = "/home/kevin/src/cmkc/src/kc/data/meas0.js";
  458. cmSpRC_t rc = kOkSpRC;
  459. cmSpPerfProc_t* m = cmMemAllocZ(cmSpPerfProc_t,1);
  460. cmSp_t s;
  461. cmSp_t* sp = &s;
  462. memset(sp,0,sizeof(s));
  463. cmRptPrintf(&ctx->rpt,"Score Performance Start\n");
  464. // initialize the score processor
  465. if((rc = _cmScoreProcInit(ctx,sp,rsrcFn,_cmSpProcPerfCb,_cmSpMatchPerfCb,m)) != kOkSpRC )
  466. goto errLabel;
  467. m->sp = sp;
  468. // run the score processor
  469. _cmScoreProcProcess(ctx,sp);
  470. // write the results of the performance evaluation
  471. if((rc = _cmScWriteMeasFile(ctx, sp, m, outFn )) != kOkSpRC )
  472. cmErrMsg(&sp->err,kFileFailSpRC,"The measurement output did not complete without errors.");
  473. //cmScorePrint(sp.scH,&ctx->rpt);
  474. //cmScorePrintLoc(sp.scH);
  475. errLabel:
  476. _cmScoreProcFinal(sp);
  477. cmMemFree(m);
  478. cmRptPrintf(&ctx->rpt,"Score Proc End\n");
  479. return rc;
  480. }
  481. //==================================================================================================
  482. cmSpRC_t cmScoreProc(cmCtx_t* ctx)
  483. {
  484. cmSpRC_t rc = kOkSpRC;
  485. _cmScoreProcGenAllMeasurementsMain(ctx);
  486. return rc;
  487. }