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.

cmDspPreset.c 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  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 "cmLinkedHeap.h"
  8. #include "cmSymTbl.h"
  9. #include "cmJson.h"
  10. #include "cmFileSys.h"
  11. #include "cmDspValue.h"
  12. #include "cmDspCtx.h"
  13. #include "cmDspClass.h"
  14. #include "cmDspPreset.h"
  15. #include "cmLex.h"
  16. #include "cmCsv.h"
  17. const cmChar_t* _cmDspPresetGroupLabelStr(cmDspPresetMgr_t* p, _cmDspPresetGrp_t* gp )
  18. { return cmStringNullGuard(cmSymTblLabel(p->stH,gp->symId)); }
  19. const cmChar_t* _cmDspPresetLabelStr(cmDspPresetMgr_t* p, _cmDspPresetPre_t* pp )
  20. { return cmStringNullGuard(cmSymTblLabel(p->stH,pp->symId)); }
  21. const cmChar_t* _cmDspPresetInstLabelStr(cmDspPresetMgr_t* p, _cmDspPresetInst_t* ip )
  22. { return cmStringNullGuard(cmSymTblLabel(p->stH,ip->symId)); }
  23. const cmChar_t* _cmDspPresetVarLabelStr(cmDspPresetMgr_t* p, _cmDspPresetVar_t* vp )
  24. { return cmStringNullGuard(cmSymTblLabel(p->stH,vp->symId)); }
  25. void _cmDspPresetAlloc( cmDspPresetMgr_t* p )
  26. {
  27. p->err = NULL;
  28. p->lhH = cmLHeapNullHandle;
  29. p->stH = cmSymTblNullHandle;
  30. p->list = NULL;
  31. p->gp = NULL;
  32. p->dfltPathJsFn = NULL;
  33. p->dfltPathCsvFn = NULL;
  34. }
  35. cmDspRC_t _cmDspPresetLoad( cmDspPresetMgr_t* p, cmCtx_t* ctx, cmErr_t* err, cmLHeapH_t lhH, cmSymTblH_t stH, const cmChar_t* fnPrefixStr )
  36. {
  37. cmDspRC_t rc = kOkDspRC;
  38. p->err = err;
  39. p->lhH = lhH;
  40. p->stH = stH;
  41. p->list = NULL;
  42. p->gp = NULL;
  43. p->dfltPathJsFn = NULL;
  44. p->dfltPathCsvFn = NULL;
  45. const cmChar_t* path;
  46. const cmChar_t fnSuffixStr[] = "_preset";
  47. unsigned fnN = strlen(fnPrefixStr) + strlen(fnSuffixStr) + 1;
  48. cmChar_t fn[ fnN ];
  49. strcpy(fn,fnPrefixStr);
  50. strcat(fn,fnSuffixStr);
  51. assert( strlen(fn) == fnN - 1 );
  52. // form JSON preset file name
  53. if((path = cmFsMakeFn(cmFsPrefsDir(),fn,"js",NULL)) == NULL )
  54. return cmErrMsg(p->err,kFileSysFailDspRC,"Default preset JSON file name formation failed.");
  55. p->dfltPathJsFn = cmLhAllocStr(p->lhH,path);
  56. cmFsFreeFn(path);
  57. // form CSV preset file name
  58. if((path = cmFsMakeFn(cmFsPrefsDir(),fn,"csv",NULL)) == NULL )
  59. return cmErrMsg(p->err,kFileSysFailDspRC,"Default preset CSV file name formation failed.");
  60. p->dfltPathCsvFn = cmLhAllocStr(p->lhH,path);
  61. cmFsFreeFn(path);
  62. // read JSON preset file
  63. if( cmFsIsFile(p->dfltPathJsFn) )
  64. if((rc = _cmDspPresetRead(p,ctx,p->dfltPathJsFn)) != kOkDspRC )
  65. return rc;
  66. return kOkDspRC;
  67. }
  68. bool _cmDspPresetIsInitialized( cmDspPresetMgr_t* p )
  69. {
  70. return p->err != NULL && cmLHeapIsValid(p->lhH) && cmSymTblIsValid(p->stH);
  71. }
  72. cmDspRC_t _cmDspPresetUnload( cmDspPresetMgr_t* p, cmCtx_t* ctx )
  73. {
  74. cmDspRC_t rc;
  75. if( _cmDspPresetIsInitialized(p) )
  76. {
  77. if((rc = _cmDspPresetWrite(p,ctx,p->dfltPathJsFn)) != kOkDspRC )
  78. cmErrMsg(p->err,rc,"DSP Preset JSON write on unload failed.");
  79. if((rc = _cmDspPresetWriteCsv(p,ctx,p->dfltPathCsvFn)) != kOkDspRC )
  80. cmErrMsg(p->err,rc,"DSP Preset CSV write on unload failed.");
  81. }
  82. _cmDspPresetAlloc(p);
  83. return kOkDspRC;
  84. }
  85. /*
  86. {
  87. presetGroupArray:
  88. [
  89. {
  90. group: "myGroup"
  91. presetArray:
  92. [
  93. {
  94. preset:"myPreset"
  95. instArray:
  96. [
  97. {
  98. inst:"myInst"
  99. varArray:
  100. [
  101. {
  102. var:"myVar"
  103. value:<value>
  104. }
  105. ]
  106. }
  107. ]
  108. }
  109. ]
  110. }
  111. ]
  112. }
  113. */
  114. cmDspRC_t _cmDspPresetRdErr( cmDspPresetMgr_t* p, cmJsRC_t jsRC, const cmChar_t* errLabel, const cmChar_t* msg )
  115. {
  116. if( jsRC == kNodeNotFoundJsRC )
  117. return cmErrMsg(p->err,kJsonFailDspRC,"The JSON node '%s' could not be found while reading the preset %s.",cmStringNullGuard(errLabel),cmStringNullGuard(msg));
  118. return cmErrMsg(p->err,kJsonFailDspRC,"JSON preset read failed on '%s'.",cmStringNullGuard(msg));
  119. }
  120. cmDspRC_t _cmDspPresetRead( cmDspPresetMgr_t* p, cmCtx_t* ctx, const cmChar_t* fn )
  121. {
  122. cmDspRC_t rc = kOkDspRC;
  123. cmJsonH_t jsH = cmJsonNullHandle;
  124. cmJsonNode_t* pga, *pa, *ia, *va;
  125. unsigned gi,pi,ii,vi;
  126. cmJsRC_t jsRC;
  127. const cmChar_t* errLabelPtr = NULL;
  128. if( cmJsonInitializeFromFile(&jsH,fn,ctx) != kOkJsRC )
  129. return cmErrMsg(p->err,kJsonFailDspRC,"The JSON preset file '%s' could not be opened.",cmStringNullGuard(fn));
  130. if((pga = cmJsonFindValue(jsH,"presetGroupArray",NULL,kArrayTId)) == NULL )
  131. {
  132. rc = cmErrMsg(p->err,kJsonFailDspRC,"JSON preset read failed. The 'presetGroupArray' could not be found.");
  133. goto errLabel;
  134. }
  135. // for each group
  136. for(gi=0; gi<cmJsonChildCount(pga); ++gi)
  137. {
  138. cmChar_t* groupLabel = NULL;
  139. // read the group header
  140. if(( jsRC = cmJsonMemberValues(cmJsonArrayElementC(pga,gi), &errLabelPtr,
  141. "group", kStringTId,&groupLabel,
  142. "presetArray", kArrayTId, &pa,
  143. NULL )) != kOkJsRC )
  144. {
  145. rc = _cmDspPresetRdErr(p,jsRC,errLabelPtr,"group object");
  146. goto errLabel;
  147. }
  148. // for each preset in this group
  149. for(pi=0; pi<cmJsonChildCount(pa); ++pi)
  150. {
  151. cmChar_t* presetLabel = NULL;
  152. // read the preset header
  153. if(( jsRC = cmJsonMemberValues(cmJsonArrayElementC(pa,pi), &errLabelPtr,
  154. "preset", kStringTId, &presetLabel,
  155. "instArray", kArrayTId, &ia,
  156. NULL )) != kOkJsRC )
  157. {
  158. rc = _cmDspPresetRdErr(p,jsRC,errLabelPtr,"preset object");
  159. goto errLabel;
  160. }
  161. // create the preset record
  162. if((rc = _cmDspPresetCreatePreset(p,groupLabel,presetLabel)) != kOkDspRC )
  163. goto errLabel;
  164. // for each instance in this preset
  165. for(ii=0; ii<cmJsonChildCount(ia); ++ii)
  166. {
  167. cmChar_t* instLabel = NULL;
  168. // read the instance header
  169. if(( jsRC = cmJsonMemberValues(cmJsonArrayElementC(ia,ii), &errLabelPtr,
  170. "inst", kStringTId,&instLabel,
  171. "varArray", kArrayTId, &va,
  172. NULL )) != kOkJsRC )
  173. {
  174. rc = _cmDspPresetRdErr(p,jsRC,errLabelPtr,"instance object");
  175. goto errLabel;
  176. }
  177. // create the preset instance record
  178. if(( rc = _cmDspPresetCreateInstance(p, cmSymTblRegisterSymbol(p->stH,instLabel) )) != kOkDspRC )
  179. goto errLabel;
  180. // for each var
  181. for(vi=0; vi<cmJsonChildCount(va); ++vi)
  182. {
  183. const cmChar_t* varLabel = NULL;
  184. const cmJsonNode_t* vnp;
  185. cmDspValue_t value;
  186. // get the var obj
  187. const cmJsonNode_t* obp = cmJsonArrayElementC(va,vi);
  188. assert( obp->typeId == kObjectTId );
  189. // get the var label
  190. if( cmJsonStringMember(obp,"var",&varLabel) != kOkJsRC || varLabel==NULL )
  191. rc = cmErrMsg(p->err,kJsonFailDspRC,"A preset var label could not be read in group:%s preset:%s inst:%s var index:%i.",_cmDspPresetGroupLabelStr(p,p->gp),_cmDspPresetLabelStr(p,p->gp->pp),_cmDspPresetInstLabelStr(p,p->gp->pp->ip),vi);
  192. // fine the value node
  193. if(( vnp = cmJsonFindValue(jsH,"value",obp,kInvalidTId)) == NULL )
  194. rc = cmErrMsg(p->err,kJsonFailDspRC,"A preset value label could not be read in group:%s preset:%s inst:%s var index:%i.",_cmDspPresetGroupLabelStr(p,p->gp),_cmDspPresetLabelStr(p,p->gp->pp),_cmDspPresetInstLabelStr(p,p->gp->pp->ip),vi);
  195. switch( vnp->typeId )
  196. {
  197. case kTrueTId:
  198. cmDsvSetBool(&value,true);
  199. break;
  200. case kFalseTId:
  201. cmDsvSetBool(&value,false);
  202. break;
  203. case kRealTId:
  204. cmDsvSetDouble(&value,vnp->u.realVal);
  205. break;
  206. case kIntTId:
  207. cmDsvSetInt(&value,vnp->u.intVal);
  208. break;
  209. case kStringTId:
  210. cmDsvSetStrz(&value,cmLhAllocStr(p->lhH,cmStringNullGuard(vnp->u.stringVal)));
  211. break;
  212. default:
  213. {
  214. rc = cmErrMsg(p->err,kJsonFailDspRC,"An invalid JSON type (%i) was encountered while reading preset group:%s preset:%s inst:%s var index:%i.",_cmDspPresetGroupLabelStr(p,p->gp),_cmDspPresetLabelStr(p,p->gp->pp),_cmDspPresetInstLabelStr(p,p->gp->pp->ip),vi);
  215. goto errLabel;
  216. }
  217. }
  218. // create the var preset recd
  219. if((rc = _cmDspPresetCreateVar(p,cmSymTblRegisterSymbol(p->stH,varLabel),&value)) != kOkDspRC )
  220. goto errLabel;
  221. }
  222. }
  223. }
  224. }
  225. errLabel:
  226. if( cmJsonFinalize(&jsH) != kOkJsRC )
  227. rc = cmErrMsg(p->err,kJsonFailDspRC,"The JSON preset tree finalization failed.");
  228. return rc;
  229. }
  230. // return ptr to array node
  231. cmJsonNode_t* _cmDspPresetWriteArrObj(
  232. cmDspPresetMgr_t* p,
  233. cmJsonH_t jsH,
  234. cmJsonNode_t* parentPtr,
  235. const cmChar_t* label,
  236. const cmChar_t* labelValue,
  237. const cmChar_t* arrLabel )
  238. {
  239. cmJsonNode_t* obp = NULL;
  240. cmJsonNode_t* anp = NULL;
  241. if( (obp = cmJsonCreateObject(jsH,parentPtr)) == NULL )
  242. {
  243. cmErrMsg(p->err,kJsonFailDspRC,"JSON object created failed during preset write of %s:%s.",cmStringNullGuard(label),cmStringNullGuard(labelValue));
  244. goto errLabel;
  245. }
  246. if( cmJsonInsertPairString(jsH,obp,label,labelValue) != kOkJsRC )
  247. {
  248. cmErrMsg(p->err,kJsonFailDspRC,"JSON pair w/ string create failed during preset write of %s:%s.",cmStringNullGuard(label),cmStringNullGuard(labelValue));
  249. goto errLabel;
  250. }
  251. if( (anp = cmJsonInsertPairArray(jsH,obp,arrLabel)) == NULL )
  252. {
  253. cmErrMsg(p->err,kJsonFailDspRC,"JSON pair w/ array create failed during preset write of %s:%s.",cmStringNullGuard(label),cmStringNullGuard(labelValue));
  254. goto errLabel;
  255. }
  256. errLabel:
  257. return anp;
  258. }
  259. cmDspRC_t _cmDspPresetWrite( cmDspPresetMgr_t* p, cmCtx_t* ctx, const cmChar_t* fn )
  260. {
  261. cmDspRC_t rc = kOkDspRC;
  262. cmJsonH_t jsH = cmJsonNullHandle;
  263. cmJsonNode_t* pga, *pa, *ia, *va;
  264. _cmDspPresetGrp_t* gp;
  265. _cmDspPresetPre_t* pp;
  266. _cmDspPresetInst_t* ip;
  267. _cmDspPresetVar_t* vp;
  268. if( cmJsonInitialize(&jsH,ctx) != kOkJsRC )
  269. return cmErrMsg(p->err,kJsonFailDspRC,"JSON tree initialization failed during preset writing.");
  270. // create the root object in the blank tree
  271. if( cmJsonCreateObject(jsH,NULL) == NULL )
  272. {
  273. rc = cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed while creating the root object.");
  274. goto errLabel;
  275. }
  276. // create the root presetGroupArray
  277. if((pga = cmJsonInsertPairArray(jsH, cmJsonRoot(jsH), "presetGroupArray" )) == NULL )
  278. {
  279. rc = cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed on 'presetGroupArray'.");
  280. goto errLabel;
  281. }
  282. rc = kJsonFailDspRC;
  283. // for each group
  284. for(gp=p->list; gp!=NULL; gp=gp->link)
  285. {
  286. // create the group object and presetArray
  287. if((pa = _cmDspPresetWriteArrObj(p,jsH,pga,"group",_cmDspPresetGroupLabelStr(p,gp),"presetArray")) == NULL )
  288. goto errLabel;
  289. // for each preset
  290. for(pp=gp->list; pp!=NULL; pp=pp->link)
  291. {
  292. // create the preset object and instArray
  293. if((ia = _cmDspPresetWriteArrObj(p,jsH,pa,"preset",_cmDspPresetLabelStr(p,pp),"instArray")) == NULL )
  294. goto errLabel;
  295. // for each inst
  296. for(ip=pp->list; ip!=NULL; ip=ip->link)
  297. {
  298. // create the inst object and varArray
  299. if((va = _cmDspPresetWriteArrObj(p,jsH,ia,"inst",_cmDspPresetInstLabelStr(p,ip),"varArray")) == NULL )
  300. goto errLabel;
  301. // for each var
  302. for(vp=ip->list; vp!=NULL; vp=vp->link)
  303. {
  304. // create the var object
  305. cmJsonNode_t* obp;
  306. if((obp = cmJsonCreateObject(jsH,va)) == NULL )
  307. {
  308. cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed during var object create.");
  309. goto errLabel;
  310. }
  311. // insert the var label
  312. if( cmJsonInsertPairString(jsH,obp,"var",_cmDspPresetVarLabelStr(p,vp)) != kOkJsRC )
  313. {
  314. cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed during var label create.");
  315. goto errLabel;
  316. }
  317. assert( cmDsvIsMtx(&vp->value) == false && cmDsvIsJson(&vp->value) == false );
  318. // determine the var value type - and write the var value
  319. unsigned tid = cmDsvBasicType(&vp->value);
  320. switch(tid)
  321. {
  322. case kBoolDsvFl:
  323. if( cmJsonInsertPairBool(jsH,obp,"value",cmDsvGetBool(&vp->value)) != kOkJsRC )
  324. {
  325. cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed on 'bool' value.");
  326. goto errLabel;
  327. }
  328. break;
  329. case kStrzDsvFl:
  330. if( cmJsonInsertPairString(jsH,obp,"value",cmDsvGetStrcz(&vp->value)) != kOkJsRC )
  331. {
  332. cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed on 'string' value.");
  333. goto errLabel;
  334. }
  335. break;
  336. case kFloatDsvFl:
  337. case kDoubleDsvFl:
  338. case kRealDsvFl:
  339. case kSampleDsvFl:
  340. if( cmJsonInsertPairReal(jsH,obp,"value",cmDsvGetDouble(&vp->value)) != kOkJsRC )
  341. {
  342. cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed on 'double' value.");
  343. goto errLabel;
  344. }
  345. break;
  346. default:
  347. {
  348. if( cmDsvCanConvertFlags(kIntDsvFl,tid) )
  349. {
  350. if( cmJsonInsertPairInt(jsH,obp,"value",cmDsvGetInt(&vp->value)) != kOkJsRC )
  351. {
  352. cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed on 'int' value.");
  353. goto errLabel;
  354. }
  355. }
  356. else
  357. {
  358. rc = cmErrMsg(p->err,kJsonFailDspRC,"Unable to convert DSV type 0x%x to JSON type.",tid);
  359. goto errLabel;
  360. }
  361. }
  362. break;
  363. } // switch
  364. }
  365. }
  366. }
  367. }
  368. // write the JSON tree
  369. if( cmJsonWrite(jsH, cmJsonRoot(jsH), fn ) != kOkJsRC )
  370. {
  371. rc = cmErrMsg(p->err,kJsonFailDspRC,"JSON preset write failed.");
  372. goto errLabel;
  373. }
  374. rc = kOkDspRC;
  375. errLabel:
  376. if( cmJsonFinalize(&jsH) != kOkJsRC )
  377. rc = cmErrMsg(p->err,kJsonFailDspRC,"JSON tree finalization failed during preset writing.");
  378. return rc;
  379. }
  380. cmDspRC_t _cmDspPresetWriteCsv( cmDspPresetMgr_t* p, cmCtx_t* ctx, const cmChar_t* fn )
  381. {
  382. cmDspRC_t rc = kOkDspRC;
  383. cmCsvH_t csvH = cmCsvNullHandle;
  384. _cmDspPresetGrp_t* gp;
  385. _cmDspPresetPre_t* pp;
  386. _cmDspPresetInst_t* ip;
  387. _cmDspPresetVar_t* vp;
  388. if( cmCsvInitialize(&csvH,ctx) != kOkCsvRC )
  389. return cmErrMsg(p->err,kCsvFailDspRC,"CSV initialization failed during preset writing.");
  390. // for each group
  391. for(gp=p->list; gp!=NULL; gp=gp->link)
  392. {
  393. // for each preset
  394. for(pp=gp->list; pp!=NULL; pp=pp->link)
  395. {
  396. // for each inst
  397. for(ip=pp->list; ip!=NULL; ip=ip->link)
  398. {
  399. // for each var
  400. for(vp=ip->list; vp!=NULL; vp=vp->link)
  401. {
  402. assert( cmDsvIsMtx(&vp->value) == false && cmDsvIsJson(&vp->value) == false );
  403. cmCsvCell_t* cellPtr = NULL;
  404. unsigned lexTId = 0;
  405. if( cmCsvAppendRow(csvH, &cellPtr, cmCsvInsertSymText(csvH,_cmDspPresetGroupLabelStr(p,gp)), kStrCsvTFl, lexTId ) != kOkCsvRC )
  406. {
  407. rc = cmErrMsg(p->err,kCsvFailDspRC,"CSV create failed during 'group' name insertion.");
  408. goto errLabel;
  409. }
  410. if( cmCsvInsertColAfter(csvH, cellPtr, &cellPtr, cmCsvInsertSymText(csvH,_cmDspPresetLabelStr(p,pp)), kStrCsvTFl, lexTId ) != kOkCsvRC )
  411. {
  412. rc = cmErrMsg(p->err,kCsvFailDspRC,"CSV create failed during 'Preset' name insertion.");
  413. goto errLabel;
  414. }
  415. if( cmCsvInsertColAfter(csvH, cellPtr, &cellPtr, cmCsvInsertSymText(csvH,_cmDspPresetInstLabelStr(p,ip)), kStrCsvTFl, lexTId ) != kOkCsvRC )
  416. {
  417. rc = cmErrMsg(p->err,kCsvFailDspRC,"CSV create failed during 'inst' name insertion.");
  418. goto errLabel;
  419. }
  420. if( cmCsvInsertColAfter(csvH, cellPtr, &cellPtr, cmCsvInsertSymText(csvH,_cmDspPresetVarLabelStr(p,vp)), kStrCsvTFl, lexTId ) != kOkCsvRC )
  421. {
  422. rc = cmErrMsg(p->err,kCsvFailDspRC,"CSV create failed during 'inst' name insertion.");
  423. goto errLabel;
  424. }
  425. // determine the var value type - and write the var value
  426. unsigned tid = cmDsvBasicType(&vp->value);
  427. switch(tid)
  428. {
  429. case kBoolDsvFl:
  430. if( cmCsvInsertIntColAfter( csvH, cellPtr, &cellPtr, cmDsvGetInt(&vp->value), lexTId ) != kOkCsvRC )
  431. {
  432. cmErrMsg(p->err,kCsvFailDspRC,"CSV preset write failed on 'bool' value.");
  433. goto errLabel;
  434. }
  435. break;
  436. case kStrzDsvFl:
  437. if( cmCsvInsertTextColAfter( csvH, cellPtr, &cellPtr, cmDsvGetStrcz(&vp->value), lexTId ) != kOkCsvRC )
  438. {
  439. cmErrMsg(p->err,kCsvFailDspRC,"CSV preset write failed on 'string' value.");
  440. goto errLabel;
  441. }
  442. break;
  443. case kFloatDsvFl:
  444. case kDoubleDsvFl:
  445. case kRealDsvFl:
  446. case kSampleDsvFl:
  447. if( cmCsvInsertDoubleColAfter( csvH, cellPtr, &cellPtr, cmDsvGetDouble(&vp->value), lexTId ) != kOkCsvRC )
  448. {
  449. cmErrMsg(p->err,kCsvFailDspRC,"CSV preset write failed on 'double' value.");
  450. goto errLabel;
  451. }
  452. break;
  453. default:
  454. {
  455. if( cmDsvCanConvertFlags(kIntDsvFl,tid) )
  456. {
  457. if( cmCsvInsertIntColAfter( csvH, cellPtr, &cellPtr, cmDsvGetInt(&vp->value), lexTId ) != kOkCsvRC )
  458. {
  459. cmErrMsg(p->err,kCsvFailDspRC,"CSV preset write failed on 'int' value.");
  460. goto errLabel;
  461. }
  462. }
  463. else
  464. {
  465. rc = cmErrMsg(p->err,kCsvFailDspRC,"Unable to convert DSV type 0x%x to CSV type.",tid);
  466. goto errLabel;
  467. }
  468. }
  469. break;
  470. } // switch
  471. }
  472. }
  473. }
  474. }
  475. // write the JSON tree
  476. if( cmCsvWrite(csvH, fn ) != kOkCsvRC )
  477. {
  478. rc = cmErrMsg(p->err,kCsvFailDspRC,"CSV preset write failed.");
  479. goto errLabel;
  480. }
  481. rc = kOkDspRC;
  482. errLabel:
  483. if( cmCsvFinalize(&csvH) != kOkJsRC )
  484. rc = cmErrMsg(p->err,kCsvFailDspRC,"CSV finalization failed during preset writing.");
  485. return rc;
  486. }
  487. _cmDspPresetVar_t* _cmDspPresetFindVar( _cmDspPresetInst_t* ip, unsigned varSymId )
  488. {
  489. _cmDspPresetVar_t* vp = ip->list;
  490. for(; vp!=NULL; vp=vp->link)
  491. if( vp->symId == varSymId )
  492. return vp;
  493. return NULL;
  494. }
  495. _cmDspPresetInst_t* _cmDspPresetFindInst( _cmDspPresetPre_t* pp, unsigned instSymId )
  496. {
  497. _cmDspPresetInst_t* ip = pp->list;
  498. for(; ip!=NULL; ip=ip->link)
  499. if( ip->symId == instSymId )
  500. return ip;
  501. return NULL;
  502. }
  503. _cmDspPresetPre_t* _cmDspPresetFindPreset( _cmDspPresetGrp_t* gp, unsigned preSymId )
  504. {
  505. _cmDspPresetPre_t* pp = gp->list;
  506. for(; pp!=NULL; pp=pp->link)
  507. if( pp->symId == preSymId )
  508. return pp;
  509. return NULL;
  510. }
  511. _cmDspPresetGrp_t* _cmDspPresetFindGroup( cmDspPresetMgr_t* p, unsigned grpSymId )
  512. {
  513. _cmDspPresetGrp_t* gp = p->list;
  514. for(; gp != NULL; gp = gp->link)
  515. if( gp->symId == grpSymId )
  516. return gp;
  517. return NULL;
  518. }
  519. unsigned _cmDspPresetGroupCount( cmDspPresetMgr_t* p )
  520. {
  521. unsigned cnt = 0;
  522. _cmDspPresetGrp_t* gp = p->list;
  523. for(; gp!=NULL; gp=gp->link)
  524. ++cnt;
  525. return cnt;
  526. }
  527. _cmDspPresetGrp_t* _cmDspPresetGroupFromIndex( cmDspPresetMgr_t* p, unsigned idx )
  528. {
  529. unsigned i = 0;
  530. _cmDspPresetGrp_t* gp = p->list;
  531. for(; gp!=NULL; gp=gp->link,++idx)
  532. if( i == idx )
  533. break;
  534. return gp;
  535. }
  536. unsigned _cmDspPresetGroupSymId( cmDspPresetMgr_t* p, unsigned groupIdx )
  537. {
  538. _cmDspPresetGrp_t* gp;
  539. if((gp = _cmDspPresetGroupFromIndex(p,groupIdx)) == NULL )
  540. return cmInvalidIdx;
  541. return gp->symId;
  542. }
  543. const cmChar_t* _cmDspPresetGroupLabel( cmDspPresetMgr_t* p, unsigned groupIdx )
  544. {
  545. unsigned symId;
  546. if((symId = _cmDspPresetGroupSymId(p,groupIdx)) == cmInvalidId )
  547. return NULL;
  548. return cmSymTblLabel(p->stH,symId);
  549. }
  550. cmJsonNode_t* _cmDspPresetCreateJsonListHdr( cmDspPresetMgr_t* p, cmJsonH_t jsH, const cmChar_t* label )
  551. {
  552. cmJsonNode_t* anp, *tnp;
  553. cmDspRC_t rc = kJsonFailDspRC;
  554. // create the container array
  555. if((anp = cmJsonInsertPairArray(jsH, cmJsonRoot(jsH), label )) == NULL)
  556. goto errLabel;
  557. // create the title array
  558. if((tnp = cmJsonCreateArray(jsH, anp )) == NULL )
  559. goto errLabel;
  560. if( cmJsonCreateString(jsH,tnp, "label" ) != kOkJsRC )
  561. goto errLabel;
  562. if( cmJsonCreateString(jsH,tnp, "sym" ) != kOkJsRC )
  563. goto errLabel;
  564. rc = kOkDspRC;
  565. errLabel:
  566. return rc == kOkDspRC ? anp : NULL;
  567. }
  568. cmDspRC_t _cmDspPresetGroupJsonList( cmDspPresetMgr_t* p, cmJsonH_t* jsHPtr )
  569. {
  570. cmJsonNode_t* anp;
  571. cmDspRC_t rc = kJsonFailDspRC;
  572. unsigned i,n;
  573. // create the container array and title elements in the first row
  574. if((anp = _cmDspPresetCreateJsonListHdr(p,*jsHPtr,"groupArray")) == NULL )
  575. goto errLabel;
  576. // get the count of groups
  577. n = _cmDspPresetGroupCount(p);
  578. // for each group
  579. for(i=0; i<n; ++i)
  580. {
  581. // create the row array
  582. cmJsonNode_t* tnp;
  583. if((tnp = cmJsonCreateArray(*jsHPtr,anp)) == NULL )
  584. goto errLabel;
  585. // insert the group label
  586. if( cmJsonCreateString(*jsHPtr, tnp, cmStringNullGuard( _cmDspPresetGroupLabel(p,i))) != kOkJsRC )
  587. goto errLabel;
  588. // insert the group symbol id
  589. if( cmJsonCreateInt(*jsHPtr, tnp, _cmDspPresetGroupSymId(p,i)) != kOkJsRC )
  590. goto errLabel;
  591. }
  592. rc = kOkDspRC;
  593. errLabel:
  594. if( rc != kOkDspRC )
  595. rc = cmErrMsg(p->err,rc,"Preset group array JSON object create failed.");
  596. return rc;
  597. }
  598. unsigned _cmDspPresetPresetCount( cmDspPresetMgr_t* p, unsigned groupIdx )
  599. {
  600. unsigned cnt = 0;
  601. _cmDspPresetGrp_t* gp;
  602. _cmDspPresetPre_t* pp;
  603. if((gp = _cmDspPresetGroupFromIndex(p,groupIdx)) == NULL )
  604. return 0;
  605. pp = gp->list;
  606. for(; pp!=NULL; pp=pp->link)
  607. ++cnt;
  608. return cnt;
  609. }
  610. _cmDspPresetPre_t* _cmDspPresetPreFromIndex( cmDspPresetMgr_t* p, unsigned gi, unsigned pi )
  611. {
  612. _cmDspPresetGrp_t* gp;
  613. _cmDspPresetPre_t* pp;
  614. if((gp = _cmDspPresetGroupFromIndex(p,gi)) == NULL )
  615. return NULL;
  616. unsigned i = 0;
  617. pp = gp->list;
  618. for(; pp!=NULL; pp=pp->link,++i)
  619. if( i == pi )
  620. break;
  621. return pp;
  622. }
  623. unsigned _cmDspPresetPresetSymId( cmDspPresetMgr_t* p, unsigned groupIdx, unsigned presetIdx )
  624. {
  625. _cmDspPresetPre_t* pp;
  626. if((pp = _cmDspPresetPreFromIndex(p,groupIdx,presetIdx)) == NULL )
  627. return cmInvalidId;
  628. return pp->symId;
  629. }
  630. const cmChar_t* _cmDspPresetPresetLabel( cmDspPresetMgr_t* p, unsigned groupIdx, unsigned presetIdx )
  631. {
  632. unsigned symId;
  633. if((symId = _cmDspPresetPresetSymId(p,groupIdx,presetIdx)) == cmInvalidId )
  634. return NULL;
  635. return cmSymTblLabel(p->stH, symId);
  636. }
  637. cmDspRC_t _cmDspPresetPresetJsonList( cmDspPresetMgr_t* p, cmJsonH_t* jsHPtr, unsigned groupSymId )
  638. {
  639. cmJsonNode_t* anp;
  640. cmDspRC_t rc = kJsonFailDspRC;
  641. _cmDspPresetGrp_t* gp;
  642. _cmDspPresetPre_t* pp;
  643. // find the group containing the preset list
  644. if((gp = _cmDspPresetFindGroup(p, groupSymId )) == NULL )
  645. return cmErrMsg(p->err,kPresetGrpNotFoundDspRC,"The preset JSON list could not be created because the group '%s', was not found.",cmStringNullGuard(cmSymTblLabel(p->stH,groupSymId)));
  646. // create the JSON container array and title element in the first row
  647. if((anp = _cmDspPresetCreateJsonListHdr(p,*jsHPtr,"presetArray")) == NULL )
  648. goto errLabel;
  649. // for each preset in this group
  650. for(pp=gp->list; pp!=NULL; pp=pp->link)
  651. {
  652. cmJsonNode_t* tnp;
  653. // create the row array
  654. if((tnp = cmJsonCreateArray(*jsHPtr,anp)) == NULL )
  655. goto errLabel;
  656. // write the preset label
  657. if( cmJsonCreateString(*jsHPtr, tnp, cmStringNullGuard( _cmDspPresetLabelStr(p,pp))) != kOkJsRC )
  658. goto errLabel;
  659. // write the preset symbol id
  660. if( cmJsonCreateInt(*jsHPtr, tnp, pp->symId ) != kOkJsRC )
  661. goto errLabel;
  662. }
  663. rc = kOkDspRC;
  664. errLabel:
  665. if( rc != kOkDspRC )
  666. rc = cmErrMsg(p->err,rc,"Preset array JSON object create failed.");
  667. return rc;
  668. }
  669. cmDspRC_t _cmDspPresetCreatePreset( cmDspPresetMgr_t* p, const cmChar_t* groupLabel, const cmChar_t* presetLabel )
  670. {
  671. cmDspRC_t rc = kOkDspRC;
  672. unsigned groupSymId = cmSymTblRegisterSymbol(p->stH,groupLabel);
  673. unsigned preSymId = cmSymTblRegisterSymbol(p->stH,presetLabel);
  674. _cmDspPresetGrp_t* gp = NULL;
  675. _cmDspPresetPre_t* pp = NULL;
  676. // if the group does not already exist ...
  677. if((gp = _cmDspPresetFindGroup(p,groupSymId)) != NULL )
  678. p->gp = gp;
  679. else
  680. { // ... then create it
  681. gp = cmLhAllocZ(p->lhH,_cmDspPresetGrp_t,1);
  682. gp->symId = groupSymId;
  683. gp->link = p->list;
  684. p->list = gp;
  685. p->gp = gp;
  686. }
  687. // if the preset does not already exist ...
  688. if((pp = _cmDspPresetFindPreset(gp,preSymId)) != NULL )
  689. cmErrMsg(p->err,kOkDspRC,"The preset label %s is already in use in the group:'%s'.",cmStringNullGuard(presetLabel),cmStringNullGuard(groupLabel));
  690. else
  691. {
  692. // ... then create it
  693. pp = cmLhAllocZ(p->lhH,_cmDspPresetPre_t,1);
  694. pp->symId = preSymId;
  695. pp->link = gp->list;
  696. gp->list = pp;
  697. gp->pp = pp;
  698. }
  699. return rc;
  700. }
  701. cmDspRC_t _cmDspPresetCreateInstance( cmDspPresetMgr_t* p, unsigned instSymId )
  702. {
  703. // a current group and preset must exist
  704. assert( p->gp != NULL && p->gp->pp != NULL);
  705. cmDspRC_t rc = kOkDspRC;
  706. _cmDspPresetInst_t* ip;
  707. _cmDspPresetPre_t* pp = p->gp->pp;
  708. // an instance with the same name should not already exist in this preset
  709. if((ip = _cmDspPresetFindInst(pp,instSymId)) != NULL )
  710. return cmErrMsg(p->err,kDuplPresetInstDspRC,"A duplicate preset instance named '%s' was encounted in group:'%s' preset:'%s'.",cmStringNullGuard(cmSymTblLabel(p->stH,instSymId)),_cmDspPresetGroupLabelStr(p,p->gp),_cmDspPresetLabelStr(p,pp));
  711. ip = cmLhAllocZ(p->lhH,_cmDspPresetInst_t,1);
  712. ip->symId = instSymId;
  713. ip->link = pp->list;
  714. pp->list = ip;
  715. pp->ip = ip;
  716. return rc;
  717. }
  718. cmDspRC_t _cmDspPresetCreateVar( cmDspPresetMgr_t* p, unsigned varSymId, const cmDspValue_t* valPtr )
  719. {
  720. assert( p->gp != NULL && p->gp->pp != NULL && p->gp->pp->ip != NULL );
  721. cmDspRC_t rc = kOkDspRC;
  722. _cmDspPresetInst_t* ip = p->gp->pp->ip;
  723. _cmDspPresetVar_t* vp = NULL;
  724. if((vp = _cmDspPresetFindVar(ip,varSymId)) != NULL)
  725. return cmErrMsg(p->err,kDuplPresetVarDspRC,"A duplicate preset var named '%s' was encounted in group:'%s' preset:'%s' inst:'%s'.",cmStringNullGuard(cmSymTblLabel(p->stH,varSymId)),_cmDspPresetGroupLabelStr(p,p->gp),_cmDspPresetLabelStr(p,p->gp->pp),_cmDspPresetInstLabelStr(p,ip));
  726. vp = cmLhAllocZ(p->lhH,_cmDspPresetVar_t,1);
  727. vp->symId = varSymId;
  728. vp->link = ip->list;
  729. ip->list = vp;
  730. // we aren't handling matrices yet
  731. assert( cmDsvIsMtx(valPtr) == false && cmDsvIsJson(valPtr)==false );
  732. if( cmDsvIsStrz(valPtr) )
  733. {
  734. cmChar_t* str = cmLhAllocStr(p->lhH,cmDsvStrz(valPtr));
  735. cmDsvSetStrz(&vp->value,str);
  736. }
  737. else
  738. {
  739. cmDsvCopy(&vp->value,valPtr);
  740. }
  741. return rc;
  742. }
  743. cmDspRC_t _cmDspPresetRecallPreset( cmDspPresetMgr_t* p, const cmChar_t* groupLabel, const cmChar_t* presetLabel )
  744. {
  745. cmDspRC_t rc = kOkDspRC;
  746. unsigned groupSymId = cmSymTblRegisterSymbol(p->stH,groupLabel);
  747. unsigned preSymId = cmSymTblRegisterSymbol(p->stH,presetLabel);
  748. _cmDspPresetGrp_t* gp = NULL;
  749. _cmDspPresetPre_t* pp = NULL;
  750. p->gp = NULL;
  751. if((gp = _cmDspPresetFindGroup(p,groupSymId)) == NULL )
  752. return cmErrMsg(p->err,kPresetGrpNotFoundDspRC,"The preset group '%s' was not found.",cmStringNullGuard(groupLabel));
  753. if((pp = _cmDspPresetFindPreset(gp,preSymId)) == NULL )
  754. return cmErrMsg(p->err,kPresetPreNotFoundDspRC,"The preset '%s' in group '%s' was not found.",cmStringNullGuard(presetLabel),cmStringNullGuard(presetLabel));
  755. p->gp = gp;
  756. p->gp->pp = pp;
  757. return rc;
  758. }
  759. cmDspRC_t _cmDspPresetRecallInstance( cmDspPresetMgr_t* p, unsigned instSymId )
  760. {
  761. // a current group and preset must exist
  762. assert( p->gp != NULL && p->gp->pp != NULL);
  763. cmDspRC_t rc = kOkDspRC;
  764. _cmDspPresetInst_t* ip;
  765. _cmDspPresetPre_t* pp = p->gp->pp;
  766. // an instance with the same name should not already exist in this preset
  767. if((ip = _cmDspPresetFindInst(pp,instSymId)) == NULL )
  768. return cmErrMsg(p->err,kPresetInstNotFoundDspRC,"A preset instance named '%s' was not found in group:'%s' preset:'%s'.",cmStringNullGuard(cmSymTblLabel(p->stH,instSymId)),_cmDspPresetGroupLabelStr(p,p->gp),_cmDspPresetLabelStr(p,pp));
  769. p->gp->pp->ip = ip;
  770. return rc;
  771. }
  772. cmDspRC_t _cmDspPresetRecallVar( cmDspPresetMgr_t* p, unsigned varSymId, cmDspValue_t* valPtr )
  773. {
  774. assert( p->gp != NULL && p->gp->pp != NULL && p->gp->pp->ip != NULL );
  775. cmDspRC_t rc = kOkDspRC;
  776. _cmDspPresetInst_t* ip = p->gp->pp->ip;
  777. _cmDspPresetVar_t* vp = NULL;
  778. if((vp = _cmDspPresetFindVar(ip,varSymId)) == NULL)
  779. return cmErrMsg(p->err,kPresetVarNotFoundDspRC,"A preset var named '%s' was not found in the group:'%s' preset:'%s' inst:'%s'.",cmStringNullGuard(cmSymTblLabel(p->stH,varSymId)),_cmDspPresetGroupLabelStr(p,p->gp),_cmDspPresetLabelStr(p,p->gp->pp),_cmDspPresetInstLabelStr(p,ip));
  780. cmDsvCopy(valPtr,&vp->value);
  781. return rc;
  782. }