libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmTakeSeqBldr.c 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmFloatTypes.h"
  4. #include "cmRpt.h"
  5. #include "cmErr.h"
  6. #include "cmCtx.h"
  7. #include "cmMem.h"
  8. #include "cmMallocDebug.h"
  9. #include "cmLinkedHeap.h"
  10. #include "cmJson.h"
  11. #include "cmTime.h"
  12. #include "cmMidi.h"
  13. #include "cmMidiFile.h"
  14. #include "cmAudioFile.h"
  15. #include "cmTimeLine.h"
  16. #include "cmSymTbl.h"
  17. #include "cmScore.h"
  18. #include "cmTakeSeqBldr.h"
  19. typedef struct cmNoteTsb_str
  20. {
  21. unsigned mni; // midi note index as an offset from the take marker
  22. unsigned scEvtIdx; // score event index this not is assoc'd with or -1 if it did not match
  23. unsigned flags; // flags from cmScMatcherResult_t
  24. } cmNoteTsb_t;
  25. typedef struct cmTakeTsb_str
  26. {
  27. unsigned markerUid; // marker time line uid assoc'd with this take
  28. cmNoteTsb_t* noteV; // noteV[noteN] score to midi file map recd. array.
  29. unsigned noteN;
  30. bool failFl;
  31. } cmTakeTsb_t;
  32. typedef struct
  33. {
  34. cmCtx_t ctx;
  35. cmErr_t err;
  36. cmJsonH_t jsH;
  37. const cmChar_t* tlFn;
  38. const cmChar_t* scFn;
  39. const cmChar_t* tlPrefixPath;
  40. cmTakeTsb_t* takeV; // takeV[ takeN ]
  41. unsigned takeN;
  42. cmTlH_t tlH;
  43. cmScH_t scH;
  44. } cmTsb_t;
  45. cmTakeSeqBldrH_t cmTakeSeqBldrNullHandle = cmSTATIC_NULL_HANDLE;
  46. cmTsb_t* _cmTsbHandleToPtr( cmTakeSeqBldrH_t h )
  47. {
  48. cmTsb_t* p = (cmTsb_t*)h.h;
  49. return p;
  50. }
  51. cmTsbRC_t _cmTsbScoreTrkFree( cmTsb_t* p )
  52. {
  53. cmTsbRC_t rc = kOkTsbRC;
  54. unsigned i;
  55. if( cmJsonFinalize(&p->jsH) != kOkJsRC )
  56. {
  57. rc = cmErrMsg(&p->err,kJsonFailTsbRC,"JSON object finalize failed.");
  58. goto errLabel;
  59. }
  60. for(i=0; i<p->takeN; ++i)
  61. cmMemPtrFree(&p->takeV[i].noteV);
  62. cmMemPtrFree(&p->takeV);
  63. if( cmTimeLineFinalize(&p->tlH) != kOkTlRC )
  64. rc = cmErrMsg(&p->err,kTimeLineFailTsbRC,"Time line object finalize failed.");
  65. if( cmScoreFinalize(&p->scH) != kOkScRC )
  66. rc = cmErrMsg(&p->err,kScoreFailTsbRC,"Score finalize failed.");
  67. errLabel:
  68. return rc;
  69. }
  70. cmTsbRC_t _cmTsbFree( cmTsb_t* p )
  71. {
  72. cmTsbRC_t rc = kOkTsbRC;
  73. if((rc = _cmTsbScoreTrkFree(p)) != kOkTsbRC )
  74. goto errLabel;
  75. cmMemFree(p);
  76. errLabel:
  77. return rc;
  78. }
  79. cmTsbRC_t _cmTsbLoadScoreTrkFile( cmTsb_t* p, const cmChar_t* scoreTrkFn )
  80. {
  81. cmTsbRC_t rc = kOkTsbRC;
  82. cmJsonNode_t* tkArrObj = NULL;
  83. cmJsRC_t jsRC = kOkJsRC;
  84. const cmChar_t* errMsg = NULL;
  85. unsigned i;
  86. // initialize the TSB json object
  87. if(( rc = cmJsonInitializeFromFile(&p->jsH,scoreTrkFn,&p->ctx)) != kOkJsRC )
  88. {
  89. rc = cmErrMsg(&p->err,kJsonFailTsbRC,"The Take Sequence Builder JSON file object could not be initialized from '%s'.",cmStringNullGuard(scoreTrkFn));
  90. goto errLabel;
  91. }
  92. // parse the header
  93. if((jsRC = cmJsonMemberValues( cmJsonRoot(p->jsH), &errMsg,
  94. "timeLineFn", kStringTId, &p->tlFn,
  95. "scoreFn", kStringTId, &p->scFn,
  96. "tlPrefixPath", kStringTId, &p->tlPrefixPath,
  97. "takeArray", kArrayTId | kOptArgJsFl, &tkArrObj,
  98. 0 )) != kOkJsRC )
  99. {
  100. if( jsRC == kNodeNotFoundJsRC && errMsg != NULL )
  101. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file header parse failed missing required field:'%s'",errMsg);
  102. else
  103. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file header parse failed.");
  104. goto errLabel;
  105. }
  106. // count of take records
  107. p->takeN = cmJsonChildCount(tkArrObj);
  108. // array of take records
  109. p->takeV = cmMemAllocZ(cmTakeTsb_t,p->takeN);
  110. // for each take record
  111. for(i=0; i<p->takeN; ++i)
  112. {
  113. cmJsonNode_t* takeObj = NULL;
  114. cmJsonNode_t* noteArrObj = NULL;
  115. unsigned j;
  116. // get a pointer to the take record JSON object
  117. if((takeObj = cmJsonArrayElement(tkArrObj,i)) == NULL )
  118. {
  119. rc = cmErrMsg(&p->err,kParseFailTsbRC,"Take record header at index %i access failed.",i);
  120. goto errLabel;
  121. }
  122. // parse the take record
  123. if((jsRC = cmJsonMemberValues( takeObj, &errMsg,
  124. "markerUid",kIntTId, &p->takeV[i].markerUid,
  125. "failFl", kIntTId, &p->takeV[i].failFl,
  126. "array", kArrayTId, &noteArrObj,
  127. 0)) != kOkJsRC )
  128. {
  129. if( jsRC == kNodeNotFoundJsRC && errMsg != NULL )
  130. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file take record parse failed missing required field:'%s'",errMsg);
  131. else
  132. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file take record parse failed.");
  133. goto errLabel;
  134. }
  135. // get the count of note records
  136. p->takeV[i].noteN = cmJsonChildCount(noteArrObj);
  137. // allocate a note record array for this take
  138. p->takeV[i].noteV = cmMemAllocZ(cmNoteTsb_t, p->takeV[i].noteN);
  139. // for each note record
  140. for(j=0; j<p->takeV[i].noteN; ++j)
  141. {
  142. cmJsonNode_t* noteObj = NULL;
  143. // get the note record JSON object
  144. if((noteObj = cmJsonArrayElement(noteArrObj,j)) == NULL )
  145. {
  146. rc = cmErrMsg(&p->err,kParseFailTsbRC,"Access failed for note record at index %i at take index %i.",j,i);
  147. goto errLabel;
  148. }
  149. // parse the note record
  150. if((jsRC = cmJsonMemberValues( noteObj, &errMsg,
  151. "mni", kIntTId, &p->takeV[i].noteV[j].mni,
  152. "scEvtIdx", kIntTId, &p->takeV[i].noteV[j].scEvtIdx,
  153. "flags", kIntTId, &p->takeV[i].noteV[j].flags,
  154. 0)) != kOkJsRC )
  155. {
  156. if( jsRC == kNodeNotFoundJsRC && errMsg != NULL )
  157. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file note record parse failed missing required field:'%s'",errMsg);
  158. else
  159. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file note record parse failed.");
  160. goto errLabel;
  161. }
  162. }
  163. }
  164. errLabel:
  165. if( rc != kOkTsbRC )
  166. rc = _cmTsbScoreTrkFree(p);
  167. return rc;
  168. }
  169. cmTsbRC_t cmTakeSeqBldrAlloc( cmCtx_t* ctx, cmTakeSeqBldrH_t* hp )
  170. {
  171. cmTsbRC_t rc;
  172. if((rc = cmTakeSeqBldrFree(hp)) != kOkTsbRC )
  173. return kOkTsbRC;
  174. cmTsb_t* p = cmMemAllocZ(cmTsb_t,1);
  175. cmErrSetup(&p->err,&ctx->rpt,"TakeSeqBldr");
  176. p->ctx = *ctx;
  177. hp->h = p;
  178. return rc;
  179. }
  180. cmTsbRC_t cmTakeSeqBldrAllocFn( cmCtx_t* ctx, cmTakeSeqBldrH_t* hp, const cmChar_t* scoreTrkFn )
  181. {
  182. cmTsbRC_t rc;
  183. if((rc = cmTakeSeqBldrAlloc(ctx,hp)) != kOkTsbRC )
  184. return rc;
  185. if((rc = cmTakeSeqBldrInitialize(*hp,scoreTrkFn)) != kOkTsbRC )
  186. return rc;
  187. return rc;
  188. }
  189. cmTsbRC_t cmTakeSeqBldrFree( cmTakeSeqBldrH_t* hp )
  190. {
  191. cmRC_t rc = kOkTsbRC;
  192. if( hp == NULL || cmTakeSeqBldrIsValid(*hp)==false )
  193. return kOkTsbRC;
  194. cmTsb_t* p = _cmTsbHandleToPtr(*hp);
  195. if((rc = _cmTsbFree(p)) != kOkTsbRC )
  196. return rc;
  197. hp->h = NULL;
  198. return rc;
  199. }
  200. bool cmTakeSeqBldrIsValid( cmTakeSeqBldrH_t h )
  201. { return h.h != NULL; }
  202. cmTsbRC_t cmTakeSeqBldrInitialize( cmTakeSeqBldrH_t h, const cmChar_t* scoreTrkFn )
  203. {
  204. cmTsbRC_t rc = kOkTsbRC;
  205. cmTsb_t* p = _cmTsbHandleToPtr(h);
  206. if(( rc = _cmTsbLoadScoreTrkFile( p, scoreTrkFn )) != kOkTsbRC )
  207. return rc;
  208. if( cmTimeLineInitializeFromFile(&p->ctx, &p->tlH, NULL, NULL, p->tlFn, p->tlPrefixPath ) != kOkTlRC )
  209. {
  210. rc = cmErrMsg(&p->err,kTimeLineFailTsbRC,"The time-line file '%s' could not be loaded.",p->tlFn);
  211. goto errLabel;
  212. }
  213. if( cmScoreInitialize(&p->ctx, &p->scH, p->scFn, 0, NULL, 0, NULL, NULL, cmSymTblNullHandle ) != kOkScRC )
  214. {
  215. rc = cmErrMsg(&p->err,kScoreFailTsbRC,"The score file '%s' could not be loaded.",p->scFn);
  216. goto errLabel;
  217. }
  218. errLabel:
  219. if( rc != kOkTsbRC )
  220. _cmTsbScoreTrkFree(p);
  221. return rc;
  222. }
  223. cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool overwriteFL )
  224. {
  225. cmTsbRC_t rc = kOkTsbRC;
  226. return rc;
  227. }
  228. cmTsbRC_t cmTakeSeqBldrUnloadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid )
  229. {
  230. cmTsbRC_t rc = kOkTsbRC;
  231. return rc;
  232. }
  233. cmTsbRC_t cmTakeSeqBldrInsertScoreNotes( cmTakeSeqBldrH_t h, unsigned begScEvtIdx, unsigned endScEvtId )
  234. {
  235. cmTsbRC_t rc = kOkTsbRC;
  236. return rc;
  237. }
  238. cmTsbRC_t cmTakeSeqBldrRemoveScoreNotes( cmTakeSeqBldrH_t h, unsigned begScEvtIdx, unsigned endScEvtId )
  239. {
  240. cmTsbRC_t rc = kOkTsbRC;
  241. return rc;
  242. }
  243. cmTsbRC_t cmTakeSeqBldrSelectEnable( cmTakeSeqBldrH_t h, unsigned flags, unsigned id, bool selectFl )
  244. {
  245. cmTsbRC_t rc = kOkTsbRC;
  246. return rc;
  247. }
  248. cmTsbRC_t cmTakeSeqBldrEnableNote( cmTakeSeqBldrH_t h, unsigned ssqId, bool enableFl )
  249. {
  250. cmTsbRC_t rc = kOkTsbRC;
  251. return rc;
  252. }
  253. cmTsbRC_t cmTakeSeqBldrMoveNote( cmTakeSeqBldrH_t h, unsigned ssqId, int deltaSmpIdx )
  254. {
  255. cmTsbRC_t rc = kOkTsbRC;
  256. return rc;
  257. }
  258. cmTsbRC_t cmTakeSeqBldrWriteMidiFile( cmTakeSeqBldrH_t h, const char* fn )
  259. {
  260. cmTsbRC_t rc = kOkTsbRC;
  261. return rc;
  262. }
  263. cmTsbRC_t cmTakeSeqBldrTest( cmCtx_t* ctx )
  264. {
  265. const cmChar_t* scoreTrkFn = "/home/kevin/src/cmkc/src/kc/data/assoc0.js";
  266. cmTakeSeqBldrH_t tsbH = cmTakeSeqBldrNullHandle;
  267. cmTsbRC_t tsbRC = kOkTsbRC;
  268. if((tsbRC = cmTakeSeqBldrAllocFn(ctx, &tsbH, scoreTrkFn )) != kOkTsbRC )
  269. return cmErrMsg(&ctx->err,tsbRC,"TSB Allocate and parse '%s' failed.",scoreTrkFn);
  270. if((tsbRC = cmTakeSeqBldrFree(&tsbH)) != kOkTsbRC )
  271. return cmErrMsg(&ctx->err,tsbRC,"TSB Free failed.");
  272. return tsbRC;
  273. }