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

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