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.

cmTakeSeqBldr.c 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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. cmTakeTsb_t* takeV;
  40. unsigned takeN;
  41. } cmTsb_t;
  42. cmTakeSeqBldrH_t cmTakeSeqBldrNullHandle = cmSTATIC_NULL_HANDLE;
  43. cmTsb_t* _cmTsbHandleToPtr( cmTakeSeqBldrH_t h )
  44. {
  45. cmTsb_t* p = (cmTsb_t*)h.h;
  46. return p;
  47. }
  48. cmTsbRC_t _cmTsbFree( cmTsb_t* p )
  49. {
  50. cmTsbRC_t rc = kOkTsbRC;
  51. if( cmJsonFinalize(&p->jsH) != kOkJsRC )
  52. {
  53. rc = cmErrMsg(&p->err,kJsonFailTsbRC,"JSON object finalize failed.");
  54. goto errLabel;
  55. }
  56. cmMemFree(p);
  57. errLabel:
  58. return rc;
  59. }
  60. cmTsbRC_t cmTakeSeqBldrAlloc( cmCtx_t* ctx, cmTakeSeqBldrH_t* hp )
  61. {
  62. cmTsbRC_t rc;
  63. if((rc = cmTakeSeqBldrFree(hp)) != kOkTsbRC )
  64. return kOkTsbRC;
  65. cmTsb_t* p = cmMemAllocZ(cmTsb_t,1);
  66. cmErrSetup(&p->err,&ctx->rpt,"TakeSeqBldr");
  67. p->ctx = *ctx;
  68. hp->h = p;
  69. return rc;
  70. }
  71. cmTsbRC_t cmTakeSeqBldrAllocFn( cmCtx_t* ctx, cmTakeSeqBldrH_t* hp, const cmChar_t* tsbFn )
  72. {
  73. cmTsbRC_t rc;
  74. if((rc = cmTakeSeqBldrAlloc(ctx,hp)) != kOkTsbRC )
  75. return rc;
  76. if((rc = cmTakeSeqBldrInitialize(*hp,tsbFn)) != kOkTsbRC )
  77. return rc;
  78. return rc;
  79. }
  80. cmTsbRC_t cmTakeSeqBldrFree( cmTakeSeqBldrH_t* hp )
  81. {
  82. cmRC_t rc = kOkTsbRC;
  83. if( hp == NULL || cmTakeSeqBldrIsValid(*hp)==false )
  84. return kOkTsbRC;
  85. cmTsb_t* p = _cmTsbHandleToPtr(*hp);
  86. if((rc = _cmTsbFree(p)) != kOkTsbRC )
  87. return rc;
  88. hp->h = NULL;
  89. return rc;
  90. }
  91. bool cmTakeSeqBldrIsValid( cmTakeSeqBldrH_t h )
  92. { return h.h != NULL; }
  93. cmTsbRC_t cmTakeSeqBldrInitialize( cmTakeSeqBldrH_t h, const cmChar_t* tsbFn )
  94. {
  95. cmTsbRC_t rc = kOkTsbRC;
  96. cmTsb_t* p = _cmTsbHandleToPtr(h);
  97. cmJsonNode_t* tkArrObj = NULL;
  98. cmJsRC_t jsRC = kOkJsRC;
  99. const cmChar_t* errMsg = NULL;
  100. unsigned i;
  101. // initialize the TSB json object
  102. if(( rc = cmJsonInitializeFromFile(&p->jsH,tsbFn,&p->ctx)) != kOkJsRC )
  103. {
  104. rc = cmErrMsg(&p->err,kJsonFailTsbRC,"The Take Sequence Builder JSON file object could not be initialized from '%s'.",cmStringNullGuard(tsbFn));
  105. goto errLabel;
  106. }
  107. // parse the header
  108. if((jsRC = cmJsonMemberValues( cmJsonRoot(p->jsH), &errMsg,
  109. "tlFn",kStringTId,&p->tlFn,
  110. "scFn",kStringTId,&p->scFn,
  111. "takeArray",kArrayTId | kOptArgJsFl,&tkArrObj,
  112. 0 )) != kOkJsRC )
  113. {
  114. if( jsRC == kNodeNotFoundJsRC && errMsg != NULL )
  115. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file header parse failed missing required field:'%s'",errMsg);
  116. else
  117. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file header parse failed.");
  118. }
  119. // count of take records
  120. unsigned tkArrN = cmJsonChildCount(tkArrObj);
  121. // array of take records
  122. p->takeV = cmMemAllocZ(cmTakeTsb_t,tkArrN);
  123. // for each take record
  124. for(i=0; i<tkArrN; ++i)
  125. {
  126. cmJsonNode_t* takeObj = NULL;
  127. cmJsonNode_t* noteArrObj = NULL;
  128. unsigned j;
  129. // get a pointer to the take record JSON object
  130. if((takeObj = cmJsonArrayElement(tkArrObj,i)) == NULL )
  131. {
  132. rc = cmErrMsg(&p->err,kParseFailTsbRC,"Take record header at index %i access failed.",i);
  133. goto errLabel;
  134. }
  135. // parse the take record
  136. if((jsRC = cmJsonMemberValues( takeObj, &errMsg,
  137. "markerUid",kIntTId, &p->takeV[i].markerUid,
  138. "failFl", kIntTId, &p->takeV[i].failFl,
  139. "array", kArrayTId, &noteArrObj,
  140. 0)) != kOkJsRC )
  141. {
  142. if( jsRC == kNodeNotFoundJsRC && errMsg != NULL )
  143. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file take record parse failed missing required field:'%s'",errMsg);
  144. else
  145. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file take record parse failed.");
  146. }
  147. // get the count of note records
  148. p->takeV[i].noteN = cmJsonChildCount(noteArrObj);
  149. // allocate a note record array for this take
  150. p->takeV[i].noteV = cmMemAllocZ(cmNoteTsb_t, p->takeV[i].noteN);
  151. // for each note record
  152. for(j=0; j<p->takeV[i].noteN; ++j)
  153. {
  154. cmJsonNode_t* noteObj = NULL;
  155. // get the note record JSON object
  156. if((noteObj = cmJsonArrayElement(noteArrObj,j)) == NULL )
  157. {
  158. rc = cmErrMsg(&p->err,kParseFailTsbRC,"Access failed for note record at index %i at take index %i.",j,i);
  159. goto errLabel;
  160. }
  161. // parse the note record
  162. if((jsRC = cmJsonMemberValues( noteObj, &errMsg,
  163. "mni", kIntTId, &p->takeV[i].noteV[j].mni,
  164. "scEvtIdx", kIntTId, &p->takeV[i].noteV[j].scEvtIdx,
  165. "flags", kIntTId, &p->takeV[i].noteV[j].flags,
  166. 0)) != kOkJsRC )
  167. {
  168. if( jsRC == kNodeNotFoundJsRC && errMsg != NULL )
  169. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file note record parse failed missing required field:'%s'",errMsg);
  170. else
  171. rc = cmErrMsg(&p->err,kParseFailTsbRC,"JSON file note record parse failed.");
  172. }
  173. }
  174. }
  175. errLabel:
  176. return rc;
  177. }
  178. cmTsbRC_t cmTakeSeqBldrLoadSection( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool overwriteFL )
  179. {
  180. cmTsbRC_t rc = kOkTsbRC;
  181. return rc;
  182. }
  183. cmTsbRC_t cmTakeSeqBldrUnloadSection( cmTakeSeqBldrH_t h, unsigned tlMarkUid )
  184. {
  185. cmTsbRC_t rc = kOkTsbRC;
  186. return rc;
  187. }
  188. cmTsbRC_t cmTakeSeqBldrInsertScoreNotes( cmTakeSeqBldrH_t h, unsigned begScEvtIdx, unsigned endScEvtId )
  189. {
  190. cmTsbRC_t rc = kOkTsbRC;
  191. return rc;
  192. }
  193. cmTsbRC_t cmTakeSeqBldrRemoveScoreNotes( cmTakeSeqBldrH_t h, unsigned begScEvtIdx, unsigned endScEvtId )
  194. {
  195. cmTsbRC_t rc = kOkTsbRC;
  196. return rc;
  197. }
  198. cmTsbRC_t cmTakeSeqBldrSelectEnable( cmTakeSeqBldrH_t h, unsigned flags, unsigned id, bool selectFl )
  199. {
  200. cmTsbRC_t rc = kOkTsbRC;
  201. return rc;
  202. }
  203. cmTsbRC_t cmTakeSeqBldrEnableNote( cmTakeSeqBldrH_t h, unsigned ssqId, bool enableFl )
  204. {
  205. cmTsbRC_t rc = kOkTsbRC;
  206. return rc;
  207. }
  208. cmTsbRC_t cmTakeSeqBldrMoveNote( cmTakeSeqBldrH_t h, unsigned ssqId, int deltaSmpIdx )
  209. {
  210. cmTsbRC_t rc = kOkTsbRC;
  211. return rc;
  212. }
  213. cmTsbRC_t cmTakeSeqBldrWriteMidiFile( cmTakeSeqBldrH_t h, const char* fn )
  214. {
  215. cmTsbRC_t rc = kOkTsbRC;
  216. return rc;
  217. }
  218. cmTsbRC_t cmTakeSeqBldrTest( cmCtx_t* ctx )
  219. {
  220. const cmChar_t* tsbFn = "/home/kevin/src/cmkc/src/kc/data/assoc0.js";
  221. cmTakeSeqBldrH_t tsbH = cmTakeSeqBldrNullHandle;
  222. cmTsbRC_t tsbRC = kOkTsbRC;
  223. if((tsbRC = cmTakeSeqBldrAllocFn(ctx, &tsbH, tsbFn )) != kOkTsbRC )
  224. return cmErrMsg(&ctx->err,tsbRC,"TSB Allocate and parse '%s' failed.",tsbFn);
  225. if((tsbRC = cmTakeSeqBldrFree(&tsbH)) != kOkTsbRC )
  226. return cmErrMsg(&ctx->err,tsbRC,"TSB Free failed.");
  227. return tsbRC;
  228. }