libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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( cmCsvInsertQTextColAfter( 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. }