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

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