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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmFloatTypes.h"
  4. #include "cmRpt.h"
  5. #include "cmErr.h"
  6. #include "cmCtx.h"
  7. #include "cmMem.h"
  8. #include "cmMallocDebug.h"
  9. #include "cmLinkedHeap.h"
  10. #include "cmText.h"
  11. #include "cmFileSys.h"
  12. #include "cmSymTbl.h"
  13. #include "cmJson.h"
  14. #include "cmPrefs.h"
  15. #include "cmDspValue.h"
  16. #include "cmMsgProtocol.h"
  17. #include "cmThread.h"
  18. #include "cmUdpPort.h"
  19. #include "cmUdpNet.h"
  20. #include "cmAudioSys.h"
  21. #include "cmProcObj.h"
  22. #include "cmDspCtx.h"
  23. #include "cmDspClass.h"
  24. #include "cmDspSys.h"
  25. #include "cmDspBuiltIn.h"
  26. #include "cmDspPgm.h"
  27. #include "cmDspPreset.h"
  28. #include "cmDspNet.h"
  29. #include "cmTime.h"
  30. cmDspSysH_t cmDspNullHandle = cmSTATIC_NULL_HANDLE;
  31. #define kDspSysLabelCharCnt (127)
  32. cmChar_t _cmDspSysLabel0[ kDspSysLabelCharCnt + 1 ];
  33. cmChar_t _cmDspSysLabel1[ kDspSysLabelCharCnt + 1 ];
  34. const cmChar_t* cmDspSysPrintLabel( const cmChar_t* label, unsigned i )
  35. {
  36. snprintf(_cmDspSysLabel0,kDspSysLabelCharCnt,"%s-%i",label,i);
  37. assert( strlen(_cmDspSysLabel0 ) <= kDspSysLabelCharCnt );
  38. return _cmDspSysLabel0;
  39. }
  40. const cmChar_t* cmDspSysPrintLabel2( const cmChar_t* label, unsigned i )
  41. {
  42. snprintf(_cmDspSysLabel1,kDspSysLabelCharCnt,"%s-%i",label,i);
  43. assert( strlen(_cmDspSysLabel1 ) <= kDspSysLabelCharCnt );
  44. return _cmDspSysLabel1;
  45. }
  46. ///============================================================================================
  47. cmDsp_t* _cmDspHandleToPtr( cmDspSysH_t h )
  48. {
  49. assert(h.h != NULL);
  50. return (cmDsp_t*)h.h;
  51. }
  52. cmDspInst_t* _cmDspSysInstSymIdToPtr( cmDsp_t* p, unsigned instSymId )
  53. {
  54. _cmDspInst_t* ip = p->instList;
  55. for(; ip!=NULL; ip = ip->linkPtr )
  56. if( ip->instPtr->symId == instSymId )
  57. return ip->instPtr;
  58. return NULL;
  59. }
  60. // free a single instance
  61. cmDspRC_t _cmDspInstFree( cmDspCtx_t* ctx, cmDspInst_t* inst )
  62. {
  63. cmDspRC_t rc = kOkDspRC;
  64. if( inst->freeFunc != NULL )
  65. if((rc = inst->freeFunc( ctx, inst, NULL )) != kOkDspRC )
  66. return rc;
  67. cmLHeapFree(ctx->lhH,inst);
  68. return kOkDspRC;
  69. }
  70. cmDspRC_t _cmDspSysFreeInst( cmDsp_t* p, unsigned instId )
  71. {
  72. cmDspRC_t rc = kOkDspRC;
  73. _cmDspInst_t* ip = p->instList;
  74. _cmDspInst_t* pp = NULL;
  75. // locate the requested instance
  76. for(; ip!=NULL; ip=ip->linkPtr)
  77. {
  78. if( ip->instPtr->id == instId )
  79. break;
  80. pp = ip;
  81. }
  82. // verify the instance was located
  83. if( ip == NULL )
  84. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The DSP instance %i could not be found.",instId);
  85. // instruct the instance to release its resources
  86. if( _cmDspInstFree(&p->ctx,ip->instPtr ) != kOkDspRC )
  87. return cmErrMsg(&p->err,kInstFinalFailDspRC,"An attempt to free DSP instance '%s' id:%i failed.",ip->instPtr->classPtr->labelStr,ip->instPtr->id);
  88. // remove the instance from the linked list
  89. if( pp == NULL )
  90. p->instList = NULL;
  91. else
  92. pp->linkPtr = ip->linkPtr;
  93. return rc;
  94. }
  95. cmDspRC_t _cmDspSysFinalize( cmDsp_t* p )
  96. {
  97. cmDspRC_t rc = kOkDspRC;
  98. _cmDspClass_t* cp = p->classList;
  99. _cmDspSysNetFree(p);
  100. // finalize the classes - no need to free the class ctl
  101. // recd's because they were allocated in the linked heap
  102. for(; cp!=NULL; cp=cp->linkPtr)
  103. {
  104. if( cp->classPtr->finalClassFunc != NULL )
  105. if( cp->classPtr->finalClassFunc(&p->ctx,cp->classPtr) != kOkDspRC )
  106. rc = cmErrMsg(&p->err,kClassFinalFailDspRC,"Class finalization failed on class '%s'.",cp->classPtr->labelStr);
  107. }
  108. if( p->ctx.cmProcCtx != NULL )
  109. if( cmCtxFree(&p->ctx.cmProcCtx) != cmOkRC )
  110. rc = cmErrMsg(&p->err,kProcFailDspRC,"The proc context finalizatoin failed.");
  111. if( cmSymTblIsValid(p->stH) )
  112. cmSymTblDestroy(&p->stH);
  113. if( cmJsonIsValid(p->jsH) )
  114. if( cmJsonFinalize(&p->jsH) != kOkJsRC )
  115. rc = cmErrMsg(&p->err,kJsonFailDspRC,"JSON finalization failed.");
  116. if( cmLHeapIsValid(p->lhH) )
  117. cmLHeapDestroy(&p->lhH);
  118. if( rc == kOkJsRC )
  119. {
  120. cmMemFree(p);
  121. // clear the cmAudioSysCtx_t
  122. memset(&p->ctx.ctx,0,sizeof(p->ctx.ctx));
  123. }
  124. return rc;
  125. }
  126. cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH )
  127. {
  128. unsigned i;
  129. cmDspRC_t rc = kOkDspRC;
  130. if((rc = cmDspSysFinalize(hp )) != kOkDspRC )
  131. return rc;
  132. cmDsp_t* p = cmMemAllocZ( cmDsp_t, 1 );
  133. cmErrSetup(&p->err,&ctx->rpt,"DSP System");
  134. //p->ctx.ctx = asCtx;
  135. p->cmCtx = *ctx;
  136. p->netH = netH;
  137. p->pgmIdx = cmInvalidIdx;
  138. // create the DSP class linked heap
  139. if(cmLHeapIsValid( p->lhH = cmLHeapCreate(1024,ctx)) == false)
  140. return cmErrMsg(&p->err,kLHeapFailDspRC,"Linked heap intiialization failed.");
  141. // initialize the DSP class JSON object
  142. if( cmJsonInitialize(&p->jsH,ctx) != kOkJsRC )
  143. {
  144. rc = cmErrMsg(&p->err,kJsonFailDspRC,"JSON initialization failed.");
  145. goto errLabel;
  146. }
  147. // intialize the DSP class symbol table
  148. if( cmSymTblIsValid( p->stH = cmSymTblCreate(cmSymTblNullHandle,1,ctx)) == false )
  149. {
  150. rc = cmErrMsg(&p->err,kSymTblFailDspRC,"Symbol table initialization failed.");
  151. goto errLabel;
  152. }
  153. // initialize the proc context
  154. if( (p->ctx.cmProcCtx = cmCtxAlloc(NULL,&ctx->rpt,p->lhH,p->stH)) == NULL )
  155. {
  156. rc = cmErrMsg(&p->err,kProcFailDspRC,"cmProc context initialization failed.");
  157. goto errLabel;
  158. }
  159. // allocate the the preset mgr
  160. _cmDspPresetAlloc(&p->pm);
  161. // initialize the networking compenents
  162. if((rc = _cmDspSysNetAlloc(p)) != kOkDspRC )
  163. goto errLabel;
  164. // set the DSP ctx to use the system lHeap and sym. tbl so that the
  165. // DSP class instantions use them
  166. p->ctx.lhH = p->lhH;
  167. p->ctx.jsH = p->jsH;
  168. p->ctx.stH = p->stH;
  169. p->ctx.rsrcJsH = cmJsonNullHandle;
  170. p->ctx.rpt = &ctx->rpt;
  171. p->ctx.cmCtx = &p->cmCtx;
  172. p->ctx.dspH.h = p;
  173. _cmDspClass_t* pp = NULL;
  174. cmDspClassConsFunc_t classConsFunc = NULL;
  175. // Get each DSP class construction function
  176. for(i=0; (classConsFunc = cmDspClassGetBuiltIn(i))!=NULL; ++i)
  177. {
  178. // allocate the class ctl recd
  179. _cmDspClass_t* cp = cmLhAllocZ(p->ctx.lhH,_cmDspClass_t,1);
  180. // call the class constructor func
  181. cp->classPtr = classConsFunc(&p->ctx);
  182. // set the class symbol id
  183. cp->symId = cmSymTblRegister(p->ctx.stH,cp->classPtr->labelStr,true);
  184. // link in the class ctl recd
  185. if( pp == NULL )
  186. p->classList = cp;
  187. else
  188. pp->linkPtr = cp;
  189. pp = cp;
  190. }
  191. hp->h = p;
  192. p->ctx.lhH = cmLHeapNullHandle;
  193. p->ctx.jsH = cmJsonNullHandle;
  194. p->ctx.stH = cmSymTblNullHandle;
  195. errLabel:
  196. if( rc != kOkDspRC )
  197. _cmDspSysFinalize(p);
  198. return rc;
  199. }
  200. cmDspRC_t cmDspSysFinalize( cmDspSysH_t* hp )
  201. {
  202. cmDspRC_t rc = kOkDspRC;
  203. if( hp==NULL || cmDspSysIsValid(*hp)==false )
  204. return kOkDspRC;
  205. if((rc = cmDspSysUnload(*hp)) != kOkDspRC )
  206. return rc;
  207. cmDsp_t* p = _cmDspHandleToPtr(*hp);
  208. if((rc = _cmDspSysFinalize(p)) == kOkDspRC )
  209. hp->h = NULL;
  210. return rc;
  211. }
  212. unsigned cmDspSysPgmCount( cmDspSysH_t h )
  213. {
  214. _cmDspSysPgm_t* arr = _cmDspSysPgmArrayBase();
  215. unsigned i = 0;
  216. while( arr != NULL && arr[i].label != NULL )
  217. ++i;
  218. return i;
  219. }
  220. const cmChar_t* cmDspPgmLabel( cmDspSysH_t h, unsigned idx )
  221. {
  222. if( idx < cmDspSysPgmCount(h) )
  223. {
  224. _cmDspSysPgm_t* arr = _cmDspSysPgmArrayBase();
  225. return arr[idx].label;
  226. }
  227. return NULL;
  228. }
  229. bool cmDspSysIsValid( cmDspSysH_t h )
  230. { return h.h != NULL; }
  231. cmDspRC_t cmDspSysLastRC( cmDspSysH_t h )
  232. {
  233. cmDsp_t* p = _cmDspHandleToPtr(h);
  234. return cmErrLastRC(&p->err);
  235. }
  236. cmDspRC_t cmDspSysLoad( cmDspSysH_t h, cmAudioSysCtx_t* asCtx, unsigned pgmIdx )
  237. {
  238. cmDspRC_t rc;
  239. cmDsp_t* p = _cmDspHandleToPtr(h);
  240. p->pgmIdx = cmInvalidIdx;
  241. if( pgmIdx >= cmDspSysPgmCount(h) )
  242. return cmErrMsg(&p->err,kInvalidPgmIdxDspRC,"%i is not a valid program index.",pgmIdx);
  243. // unload the previously loaded DSP program
  244. if((rc = cmDspSysUnload(h)) != kOkDspRC )
  245. return rc;
  246. // assign the cmAudioSysCtx_t context recd
  247. p->ctx.ctx = asCtx;
  248. _cmDspSysPgm_t* arr = _cmDspSysPgmArrayBase();
  249. // form the resource file name
  250. if((p->rsrcFn = cmFsMakeFn(cmFsPrefsDir(),arr[pgmIdx].label,"js",NULL)) == NULL )
  251. {
  252. rc = cmErrMsg(&p->err,kFileSysFailDspRC,"Resource file name formation failed.");
  253. goto errLabel;
  254. }
  255. // if the pgm specific resource file already exists
  256. if( cmFsIsFile(p->rsrcFn) )
  257. {
  258. // open and parse the resource file
  259. if( cmJsonInitializeFromFile(&p->ctx.rsrcJsH,p->rsrcFn,&p->cmCtx) != kOkJsRC )
  260. {
  261. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Resource file open failed.");
  262. goto errLabel;
  263. }
  264. }
  265. else // ... the resource file does not currently exists - create it
  266. {
  267. cmJsonNode_t* rootPtr;
  268. if( cmJsonInitialize(&p->ctx.rsrcJsH,&p->cmCtx) != kOkJsRC )
  269. {
  270. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Resource object allocate failed.");
  271. goto errLabel;
  272. }
  273. if((rootPtr = cmJsonCreateObject(p->ctx.rsrcJsH, NULL )) == NULL )
  274. {
  275. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Resource object root allocate failed.");
  276. goto errLabel;
  277. }
  278. }
  279. // create a linked heap for use by the DSP instances
  280. if(cmLHeapIsValid( p->ctx.lhH = cmLHeapCreate(1024,&p->cmCtx)) == false)
  281. return cmErrMsg(&p->err,kLHeapFailDspRC,"DSP instance linked heap intiialization failed.");
  282. // initialize a JSON object for use by the DSP instances
  283. if( cmJsonInitialize(&p->ctx.jsH,&p->cmCtx) != kOkJsRC )
  284. {
  285. rc = cmErrMsg(&p->err,kJsonFailDspRC,"JSON initialization failed.");
  286. goto errLabel;
  287. }
  288. // create a symbol table for use by the DSP instance (note that it uses the system sym. tbl. as it's parent)
  289. if( cmSymTblIsValid( p->ctx.stH = cmSymTblCreate(p->stH, cmDspSys_PARENT_SYM_TBL_BASE_ID, &p->cmCtx)) == false )
  290. {
  291. rc = cmErrMsg(&p->err,kSymTblFailDspRC,"DSP instance symbol table initialization failed.");
  292. goto errLabel;
  293. }
  294. // load the preset mgr
  295. if((rc = _cmDspPresetLoad(&p->pm,&p->cmCtx,&p->err,p->ctx.lhH,p->ctx.stH,arr[pgmIdx].label)) != kOkDspRC )
  296. {
  297. rc = cmErrMsg(&p->err,rc,"Preset manager load failed.");
  298. goto errLabel;
  299. }
  300. // setup the DSP network components
  301. if((rc = _cmDspSysNetPreLoad(p)) != kOkDspRC )
  302. goto errLabel;
  303. p->ctx.cycleCnt = 0;
  304. p->ctx._disableSymId = cmSymTblRegisterStaticSymbol(p->ctx.stH,"_disable");
  305. p->ctx._enableSymId = cmSymTblRegisterStaticSymbol(p->ctx.stH,"_enable");
  306. void** vpp = &arr[ pgmIdx ].userPtr;
  307. cmDspPgmFunc_t pgm = arr[ pgmIdx ].loadFunc;
  308. // allocate and connect user defined signal processing network
  309. if((rc = pgm(h,vpp)) == kOkDspRC )
  310. if((rc = cmErrLastRC(&p->err)) != kOkDspRC )
  311. {
  312. cmErrMsg(&p->err,rc,"User DSP system load failed.");
  313. goto errLabel;
  314. }
  315. p->pgmIdx = pgmIdx;
  316. // enter sync mode
  317. if((rc = _cmDspSysNetSync(p)) != kOkDspRC )
  318. {
  319. cmErrMsg(&p->err,rc,"DSP system sync failed.");
  320. goto errLabel;
  321. }
  322. errLabel:
  323. if( rc != kOkDspRC )
  324. cmDspSysUnload(h);
  325. return rc;
  326. }
  327. cmDspRC_t cmDspSysUnload( cmDspSysH_t h )
  328. {
  329. if( cmDspSysIsValid(h) == false )
  330. return kOkDspRC;
  331. cmDspRC_t rc = kOkDspRC;
  332. cmDsp_t* p = _cmDspHandleToPtr(h);
  333. _cmDspInst_t* ip = p->instList;
  334. // call the DSP network unload function - this function is provided
  335. // by the client network to release any resources obtained when
  336. // the network was created
  337. if( p->pgmIdx != cmInvalidIdx )
  338. {
  339. _cmDspSysPgm_t* arr = _cmDspSysPgmArrayBase();
  340. void** vpp = &arr[ p->pgmIdx ].userPtr;
  341. cmDspPgmFunc_t pgm = arr[ p->pgmIdx ].unloadFunc;
  342. if( pgm != NULL )
  343. if((rc = pgm(h,vpp)) == kOkDspRC )
  344. if((rc = cmErrLastRC(&p->err)) != kOkDspRC )
  345. cmErrMsg(&p->err,rc,"User DSP system unload failed.");
  346. }
  347. p->pgmIdx = cmInvalidIdx;
  348. // unload the networking components
  349. _cmDspSysNetUnload(p);
  350. // free the DSP instances
  351. for(; ip!=NULL; ip=ip->linkPtr)
  352. if((rc = _cmDspInstFree(&p->ctx,ip->instPtr)) != kOkDspRC )
  353. rc = cmErrMsg(&p->err,kInstFinalFailDspRC,"An attempt to free DSP instance '%s' id:%i failed.",ip->instPtr->classPtr->labelStr,ip->instPtr->id);
  354. p->instList = NULL;
  355. // unload the preset manager
  356. if((rc = _cmDspPresetUnload(&p->pm,&p->cmCtx)) != kOkDspRC)
  357. rc = cmErrMsg(&p->err,rc,"Preset manager 'unload' failed.");
  358. // finalize the pgm specific JSON tree
  359. if( cmJsonIsValid(p->ctx.rsrcJsH))
  360. {
  361. //if( cmJsonWrite(p->ctx.rsrcJsH, cmJsonRoot(p->ctx.rsrcJsH), p->rsrcFn ) != kOkJsRC )
  362. // rc = cmErrMsg(&p->err,kJsonFailDspRC,"JSON file write failed on '%s'.",cmStringNullGuard(p->rsrcFn));
  363. //else
  364. //{
  365. if( cmJsonFinalize(&p->ctx.rsrcJsH) != kOkJsRC )
  366. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Resource JSON finalization failed.");
  367. //}
  368. }
  369. // release the JSON file name
  370. if( p->rsrcFn != NULL )
  371. {
  372. cmFsFreeFn(p->rsrcFn); // free the resource file name
  373. p->rsrcFn = NULL;
  374. }
  375. // tell the DSP net system that the pgm has been unloaded
  376. _cmDspSysNetUnload(p);
  377. // elimnate the linked heap, system table, and json object used by the DSP instance objects
  378. if( cmLHeapIsValid(p->ctx.lhH) )
  379. cmLHeapDestroy(&p->ctx.lhH);
  380. if( cmJsonIsValid(p->ctx.jsH) )
  381. if( cmJsonFinalize(&p->ctx.jsH) != kOkJsRC )
  382. rc = cmErrMsg(&p->err,kJsonFailDspRC,"DSP instance JSON object finalization failed.");
  383. if( cmSymTblIsValid(p->ctx.stH) )
  384. cmSymTblDestroy(&p->ctx.stH);
  385. return rc;
  386. }
  387. cmDspRC_t cmDspSysReset( cmDspSysH_t h )
  388. {
  389. cmDsp_t* p = _cmDspHandleToPtr(h);
  390. cmDspRC_t rc = kOkDspRC;
  391. // call reset on each of the instances
  392. _cmDspInst_t* ip = p->instList;
  393. for(; ip != NULL; ip = ip->linkPtr )
  394. if( ip->instPtr->resetFunc != NULL )
  395. {
  396. if( ip->instPtr->resetFunc(&p->ctx,ip->instPtr,NULL) != kOkDspRC )
  397. rc = cmErrMsg(&p->err,kInstResetFailDspRC,"Reset failed on DSP instance '%s' id:%i.",ip->instPtr->classPtr->labelStr,ip->instPtr->id);
  398. ip->instPtr->flags = 0;
  399. }
  400. // send the _reset symbol to every instance which has the _reset attribute symbol
  401. if( rc == kOkDspRC )
  402. {
  403. cmDspValue_t v;
  404. unsigned resetSymId = cmDspSysRegisterStaticSymbol(h,"_reset");
  405. cmDsvSetSymbol(&v,resetSymId);
  406. rc = cmDspSysBroadcastValue(h, resetSymId, &v);
  407. }
  408. return rc;
  409. }
  410. // Handle msg's arriving from the UI
  411. cmDspRC_t _cmDspSysHandleUiMsg(cmDsp_t* p, _cmDspInst_t* ip, const void* msgPtr, unsigned msgByteCnt)
  412. {
  413. cmDspRC_t rc = kOkDspRC;
  414. cmDspUiHdr_t* h = (cmDspUiHdr_t*)msgPtr;
  415. cmDspEvt_t e;
  416. assert( h->uiId == kUiSelAsId );
  417. // the only source of msg's (at the time of this writing) is the UI so:
  418. // Mark the msg as a UI event and set the kUiEchoDspFl if the UI has requested duplex operation.
  419. e.flags = kUiDspFl | (cmIsFlag(h->flags,kDuplexDuiFl) ? kUiEchoDspFl : 0);
  420. e.srcInstPtr = NULL; // the UI has no source instance
  421. e.srcVarId = h->selId; // set the event srcVarId to the UI selId
  422. e.dstVarId = h->instVarId; // identify the dst inst variable
  423. e.dstDataPtr = NULL; // UI msg's don't have custom data (yet)
  424. e.valuePtr = &h->value; //
  425. // if the value associated with this msg is a mtx then set
  426. // its mtx data area pointer to just after the msg header.
  427. if( cmDsvIsMtx(&h->value) )
  428. h->value.u.m.u.vp = ((char*)msgPtr) + sizeof(cmDspUiHdr_t);
  429. else
  430. rc = cmDsvDeserializeInPlace(&h->value,msgByteCnt-sizeof(cmDspUiHdr_t));
  431. if( rc != kOkDsvRC )
  432. cmErrMsg(&p->err,kSerializeUiMsgFailDspRC,"DSP system receive Deserialize failed.");
  433. // find the dest. DSP instance for this msg
  434. for(; ip != NULL; ip = ip->linkPtr )
  435. if( ip->instPtr->id == h->instId )
  436. {
  437. // send the msg to the DSP dst. instance
  438. if( ip->instPtr->recvFunc != NULL )
  439. if( ip->instPtr->recvFunc(&p->ctx,ip->instPtr,&e) != kOkDspRC )
  440. rc = cmErrMsg(&p->err,kInstMsgRcvFailDspRC,"Message recv failed on DSP instance '%s' id:%i.",ip->instPtr->classPtr->labelStr,ip->instPtr->id);
  441. break;
  442. }
  443. if( ip == NULL )
  444. rc = cmErrMsg(&p->err,kInstNotFoundDspRC,"No DSP instance with id %i was found during message delivery.",h->instId);
  445. return rc;
  446. }
  447. // Recv msg's arriving from the audio engine.
  448. cmDspRC_t cmDspSysRcvMsg( cmDspSysH_t h, cmAudioSysCtx_t* asCtx, const void* msgPtr, unsigned msgByteCnt, unsigned srcNetNodeId )
  449. {
  450. cmDsp_t* p = _cmDspHandleToPtr(h);
  451. _cmDspInst_t* ip = p->instList;
  452. if( msgByteCnt == 0 && asCtx->audioRateFl==true)
  453. {
  454. cmTimeSpec_t t0,t1;
  455. cmTimeGet(&t0);
  456. for(; ip != NULL; ip = ip->linkPtr )
  457. if( ip->instPtr->execFunc != NULL && cmIsFlag(ip->instPtr->flags,kDisableExecInstFl)==false )
  458. {
  459. if( ip->instPtr->execFunc(&p->ctx,ip->instPtr,NULL) != kOkDspRC )
  460. cmErrMsg(&p->err,kInstExecFailDspRC,"Execution failed on DSP instance '%s' id:%i.",ip->instPtr->classPtr->labelStr,ip->instPtr->id);
  461. //printf("%i %s\n",p->ctx.cycleCnt,ip->instPtr->classPtr->labelStr);
  462. }
  463. cmTimeGet(&t1);
  464. p->ctx.execDurUsecs = cmTimeElapsedMicros(&t0,&t1);
  465. ++p->ctx.cycleCnt;
  466. }
  467. else
  468. {
  469. // the msg selector is the second field in the data packet (following the audio system sub-system id)
  470. const unsigned msgTypeSelId = ((const unsigned*)msgPtr)[1];
  471. switch( msgTypeSelId )
  472. {
  473. case kUiSelAsId:
  474. _cmDspSysHandleUiMsg(p,ip,msgPtr,msgByteCnt);
  475. break;
  476. case kNetSyncSelAsId:
  477. _cmDspSysNetRecv(p, (const cmDspNetMsg_t*)msgPtr, msgByteCnt, srcNetNodeId );
  478. break;
  479. case kMidiMsgArraySelAsId:
  480. /*
  481. // data format for MIDI messages
  482. { kMidiMsgArraytSelAsId, devIdx, portIdx, msgCnt, msgArray[msgCnt] }
  483. where each msgArray[] record is a cmMidiMsg record.
  484. */
  485. break;
  486. }
  487. }
  488. // report any error - this should stop further calls to the DSP process
  489. return cmErrLastRC(&p->err);
  490. }
  491. unsigned cmDspSysSyncState( cmDspSysH_t h )
  492. {
  493. cmDsp_t* p = _cmDspHandleToPtr(h);
  494. return p->syncState;
  495. }
  496. unsigned cmDspSysPresetGroupCount( cmDspSysH_t h )
  497. {
  498. cmDsp_t* p = _cmDspHandleToPtr(h);
  499. return _cmDspPresetGroupCount(&p->pm);
  500. }
  501. unsigned cmDspSysPresetGroupSymId( cmDspSysH_t h, unsigned groupIdx )
  502. {
  503. cmDsp_t* p = _cmDspHandleToPtr(h);
  504. return _cmDspPresetGroupSymId(&p->pm,groupIdx);
  505. }
  506. const cmChar_t* cmDspSysPresetGroupLabel( cmDspSysH_t h, unsigned groupIdx )
  507. {
  508. cmDsp_t* p = _cmDspHandleToPtr(h);
  509. return _cmDspPresetGroupLabel(&p->pm,groupIdx);
  510. }
  511. cmDspRC_t cmDspSysPresetGroupJsonList( cmDspSysH_t h, cmJsonH_t* jsHPtr )
  512. {
  513. cmDsp_t* p = _cmDspHandleToPtr(h);
  514. return _cmDspPresetGroupJsonList(&p->pm,jsHPtr);
  515. }
  516. unsigned cmDspSysPresetPresetCount( cmDspSysH_t h, unsigned groupIdx )
  517. {
  518. cmDsp_t* p = _cmDspHandleToPtr(h);
  519. return _cmDspPresetPresetCount(&p->pm,groupIdx);
  520. }
  521. unsigned cmDspSysPresetPresetSymId( cmDspSysH_t h, unsigned groupIdx, unsigned presetIdx )
  522. {
  523. cmDsp_t* p = _cmDspHandleToPtr(h);
  524. return _cmDspPresetPresetSymId(&p->pm,groupIdx,presetIdx);
  525. }
  526. const cmChar_t* cmDspSysPresetPresetLabel( cmDspSysH_t h, unsigned groupIdx, unsigned presetIdx )
  527. {
  528. cmDsp_t* p = _cmDspHandleToPtr(h);
  529. return _cmDspPresetPresetLabel(&p->pm,groupIdx,presetIdx);
  530. }
  531. cmDspRC_t cmDspSysPresetPresetJsonList( cmDspSysH_t h, unsigned groupSymId, cmJsonH_t* jsHPtr )
  532. {
  533. cmDsp_t* p = _cmDspHandleToPtr(h);
  534. return _cmDspPresetPresetJsonList(&p->pm,jsHPtr,groupSymId);
  535. }
  536. unsigned cmDspSysPresetRegisterGroup( cmDspSysH_t h, const cmChar_t* groupLabel )
  537. {
  538. cmDsp_t* p = _cmDspHandleToPtr(h);
  539. assert( groupLabel != NULL );
  540. unsigned grpSymId;
  541. if((grpSymId = cmSymTblRegisterSymbol(p->ctx.stH,groupLabel)) == cmInvalidIdx )
  542. cmErrMsg(&p->err,kSymTblFailDspRC,"Registration of the group label:'%s' failed.",cmStringNullGuard(groupLabel));
  543. return grpSymId;
  544. }
  545. cmDspRC_t cmDspSysPresetCreate( cmDspSysH_t h, const cmChar_t* groupLabel, const cmChar_t* presetLabel )
  546. {
  547. cmDspRC_t rc;
  548. cmDsp_t* p = _cmDspHandleToPtr(h);
  549. // create a new preset and make it active
  550. if((rc = _cmDspPresetCreatePreset(&p->pm, groupLabel, presetLabel )) != kOkDspRC )
  551. return rc;
  552. assert( p->pm.gp != NULL );
  553. // call store on each of the instances
  554. _cmDspInst_t* ip = p->instList;
  555. for(; ip != NULL; ip = ip->linkPtr )
  556. if( ip->instPtr->symId != cmInvalidId && ip->instPtr->presetGroupSymId == p->pm.gp->symId && ip->instPtr->storeFunc != NULL )
  557. {
  558. // create an instance preset and make it active
  559. if((rc = _cmDspPresetCreateInstance(&p->pm, ip->instPtr->symId )) != kOkDspRC )
  560. return rc;
  561. // call the store function on each instance
  562. if( ip->instPtr->storeFunc(&p->ctx,ip->instPtr,true) != kOkDspRC )
  563. rc = cmErrMsg(&p->err,kInstStoreFailDspRC,"Save failed on DSP instance '%s' id:%i.",ip->instPtr->classPtr->labelStr,ip->instPtr->id);
  564. }
  565. return rc;
  566. }
  567. cmDspRC_t cmDspSysPresetRecall( cmDspSysH_t h, const cmChar_t* groupLabel, const cmChar_t* presetLabel )
  568. {
  569. cmDspRC_t rc;
  570. cmDsp_t* p = _cmDspHandleToPtr(h);
  571. // make the given group/preset active
  572. if((rc = _cmDspPresetRecallPreset(&p->pm, groupLabel, presetLabel )) != kOkDspRC )
  573. return rc;
  574. assert( p->pm.gp != NULL );
  575. // call store on each of the instances
  576. _cmDspInst_t* ip = p->instList;
  577. for(; ip != NULL; ip = ip->linkPtr )
  578. if( ip->instPtr->symId != cmInvalidId && ip->instPtr->storeFunc != NULL && ip->instPtr->presetGroupSymId == p->pm.gp->symId )
  579. {
  580. // make the instance active
  581. if((rc = _cmDspPresetRecallInstance(&p->pm, ip->instPtr->symId )) != kOkDspRC )
  582. {
  583. if( rc == kPresetInstNotFoundDspRC )
  584. {
  585. cmErrWarnMsg(&p->err,kOkDspRC,"Assuming a new instance was added to the preset - continuing with preset load.");
  586. continue;
  587. }
  588. }
  589. // call the store function on each instance
  590. if( ip->instPtr->storeFunc(&p->ctx,ip->instPtr,false) != kOkDspRC )
  591. rc = cmErrMsg(&p->err,kInstStoreFailDspRC,"Restore failed on DSP instance '%s' id:%i.",ip->instPtr->classPtr->labelStr,ip->instPtr->id);
  592. }
  593. return rc;
  594. }
  595. cmDspRC_t cmDspSysPresetWriteValue( cmDspSysH_t h, unsigned varSymId, const cmDspValue_t* valPtr )
  596. {
  597. cmDsp_t* p = _cmDspHandleToPtr(h);
  598. return _cmDspPresetCreateVar(&p->pm,varSymId,valPtr);
  599. }
  600. cmDspRC_t cmDspSysPresetReadValue( cmDspSysH_t h, unsigned varSymId, cmDspValue_t* valPtr )
  601. {
  602. cmDsp_t* p = _cmDspHandleToPtr(h);
  603. return _cmDspPresetRecallVar(&p->pm,varSymId,valPtr);
  604. }
  605. // allocate an instance given the class symbol id
  606. cmDspInst_t* _cmDspSysAllocateInst( cmDsp_t* p, unsigned classSymId, unsigned storeSymId, unsigned instSymId, unsigned va_cnt, va_list vl )
  607. {
  608. _cmDspClass_t* cp = p->classList;
  609. cmDspInst_t* instPtr = NULL;
  610. // locate the DSP class
  611. for(; cp != NULL; cp=cp->linkPtr )
  612. if( cp->symId == classSymId )
  613. break;
  614. // if the DSP class was not found
  615. if( cp == NULL )
  616. {
  617. cmErrMsg(&p->err,kClassNotFoundDspRC,"The DSP class '%s' could not be found.",cmSymTblLabel(p->ctx.stH,classSymId));
  618. return NULL;
  619. }
  620. // allocate the instance
  621. if((instPtr = cp->classPtr->allocFunc( &p->ctx, cp->classPtr, storeSymId, instSymId, p->nextInstId, va_cnt, vl )) == NULL )
  622. {
  623. cmErrMsg(&p->err,kAllocInstFailDspRC,"DSP instance allocation failed for class '%s'.",cp->classPtr->labelStr);
  624. return NULL;
  625. }
  626. // assign the symbol attributes
  627. cmDspInstSymId_t* ip = p->symIdList;
  628. for(; ip!=NULL; ip=ip->link)
  629. if( ip->symId != cmInvalidId )
  630. if( cmDspInstRegisterAttrSym(&p->ctx, instPtr, ip->symId ) != kOkDspRC )
  631. {
  632. cmErrMsg(&p->err,kAllocInstFailDspRC,"The DSP instance failed due to attribute symbol registration failure.");
  633. return NULL;
  634. }
  635. // allocate the instance ctl recd
  636. _cmDspInst_t* instCtlPtr = cmLhAllocZ( p->ctx.lhH, _cmDspInst_t, 1 );
  637. assert( instCtlPtr != NULL );
  638. // setup the inst ctl recd
  639. instCtlPtr->instPtr = instPtr;
  640. instCtlPtr->linkPtr = NULL;
  641. // link the inst ctl recd onto the end of the instance list
  642. if( p->instList == NULL )
  643. p->instList = instCtlPtr;
  644. else
  645. {
  646. _cmDspInst_t* ip = p->instList;
  647. while( ip->linkPtr != NULL )
  648. ip = ip->linkPtr;
  649. ip->linkPtr = instCtlPtr;
  650. }
  651. ++p->nextInstId;
  652. return instPtr;
  653. }
  654. // allocate a an instance from the class label - this function calls _cmDspSysAllocateInst()
  655. cmDspInst_t* cmDspSysAllocInstSV( cmDspSysH_t h, const cmChar_t* classLabelStr, unsigned storeSymId, const cmChar_t* instLabelStr, unsigned va_cnt, va_list vl)
  656. {
  657. cmDsp_t* p = _cmDspHandleToPtr(h);
  658. unsigned instSymId = cmInvalidId;
  659. cmDspInst_t* newInstPtr;
  660. unsigned classSymId;
  661. // get the class symbold
  662. if((classSymId = cmSymTblId(p->ctx.stH,classLabelStr)) == cmInvalidId )
  663. {
  664. cmErrMsg(&p->err,kSymNotFoundDspRC,"The symbol id associated with the class '%s' could not be found.",classLabelStr);
  665. return NULL;
  666. }
  667. if( instLabelStr != NULL )
  668. {
  669. // get the symbold id assoc'd with the instance label
  670. if((instSymId = cmSymTblRegisterSymbol(p->ctx.stH,instLabelStr)) == cmInvalidId )
  671. {
  672. cmErrMsg(&p->err,kSymTblFailDspRC,"The DSP instance symbol '%s' failed to register with the symbol table.",instLabelStr);
  673. return NULL;
  674. }
  675. // do not allow instance labels to be re-used
  676. if( _cmDspSysInstSymIdToPtr(p,instSymId) != NULL )
  677. {
  678. cmErrMsg(&p->err,kDuplInstSymIdDspRC,"The DSP instance label '%s' was reused (class:'%s').",cmStringNullGuard(instLabelStr),cmStringNullGuard(classLabelStr));
  679. return NULL;
  680. }
  681. }
  682. // allocate the instance
  683. newInstPtr = _cmDspSysAllocateInst(p, classSymId, storeSymId, instSymId, va_cnt, vl );
  684. return newInstPtr;
  685. }
  686. cmDspInst_t* cmDspSysAllocInstS( cmDspSysH_t h, const cmChar_t* classLabelStr, unsigned storeSymId, const cmChar_t* instLabelStr, unsigned va_cnt, ... )
  687. {
  688. cmDspInst_t* p;
  689. va_list vl;
  690. va_start(vl,va_cnt);
  691. p = cmDspSysAllocInstSV(h, classLabelStr, storeSymId, instLabelStr, va_cnt, vl);
  692. va_end(vl);
  693. return p;
  694. }
  695. cmDspInst_t* cmDspSysAllocInst( cmDspSysH_t h, const cmChar_t* classLabelStr, const cmChar_t* instLabelStr, unsigned va_cnt, ... )
  696. {
  697. cmDspInst_t* p;
  698. va_list vl;
  699. va_start(vl,va_cnt);
  700. p = cmDspSysAllocInstSV(h, classLabelStr, cmInvalidId, instLabelStr, va_cnt, vl);
  701. va_end(vl);
  702. return p;
  703. }
  704. cmDspInst_t** cmDspSysAllocInstArraySV( cmDspSysH_t h, unsigned cnt, unsigned presetGroupSymId, const cmChar_t* classLabelStr, const cmChar_t* instLabelStr, cmDspSysLabelFunc_t labelFunc, unsigned va_cnt, va_list vl )
  705. {
  706. cmDsp_t* p = _cmDspHandleToPtr(h);
  707. cmDspInst_t** a = cmLhAllocZ( p->lhH, cmDspInst_t*, cnt );
  708. unsigned i;
  709. for(i=0; i<cnt; ++i)
  710. {
  711. const cmChar_t* label = instLabelStr;
  712. va_list vl1;
  713. va_copy(vl1,vl);
  714. if( labelFunc != NULL )
  715. label = labelFunc(h,i);
  716. else
  717. if( instLabelStr != NULL )
  718. label = cmDspSysPrintLabel(instLabelStr,i);
  719. a[i] = cmDspSysAllocInstSV(h,classLabelStr,presetGroupSymId,label,va_cnt,vl1);
  720. }
  721. return a;
  722. }
  723. cmDspInst_t** cmDspSysAllocInstArrayS( cmDspSysH_t h, unsigned cnt, unsigned presetGroupSymId, const cmChar_t* classLabelStr, const cmChar_t* instLabelStr, cmDspSysLabelFunc_t labelFunc, unsigned va_cnt, ... )
  724. {
  725. va_list vl;
  726. va_start(vl,va_cnt);
  727. cmDspInst_t** a = cmDspSysAllocInstArraySV(h,cnt,presetGroupSymId,classLabelStr,instLabelStr,labelFunc,va_cnt,vl);
  728. va_end(vl);
  729. return a;
  730. }
  731. cmDspInst_t** cmDspSysAllocInstArray( cmDspSysH_t h, unsigned cnt, const cmChar_t* classLabelStr, const cmChar_t* instLabelStr, cmDspSysLabelFunc_t labelFunc, unsigned va_cnt, ... )
  732. {
  733. va_list vl;
  734. va_start(vl,va_cnt);
  735. cmDspInst_t** a = cmDspSysAllocInstArraySV(h,cnt,cmInvalidId,classLabelStr,instLabelStr,labelFunc,va_cnt,vl);
  736. va_end(vl);
  737. return a;
  738. }
  739. cmDspRC_t cmDspSysNewColumn( cmDspSysH_t h, unsigned colW )
  740. { return cmDspUiNewColumn(&_cmDspHandleToPtr(h)->ctx,colW); }
  741. cmDspRC_t cmDspSysInsertHorzBorder( cmDspSysH_t h )
  742. { return cmDspUiInsertHorzBorder(&_cmDspHandleToPtr(h)->ctx); }
  743. cmDspRC_t cmDspSysNewPage( cmDspSysH_t h, const cmChar_t* title )
  744. { return cmDspUiNewPage(&_cmDspHandleToPtr(h)->ctx,title); }
  745. cmDspRC_t _cmDspSysConnAudio( cmDsp_t* p, cmDspInst_t* srcInstPtr, unsigned srcVarSymId, cmDspInst_t* dstInstPtr, unsigned dstVarSymId )
  746. {
  747. cmDspVar_t* srcVarPtr;
  748. cmDspVar_t* dstVarPtr;
  749. //cmSample_t* srcDataPtr;
  750. if( srcInstPtr == NULL )
  751. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The audio connection process was passed a NULL source processor instance pointer for connection to '%s'.",cmStringNullGuard(dstInstPtr->classPtr->labelStr));
  752. if( dstInstPtr == NULL )
  753. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The audio connection process was passed a NULL destination processor instance pointer for connection from '%s'.",cmStringNullGuard(srcInstPtr->classPtr->labelStr));
  754. // locate the src audio variable
  755. if((srcVarPtr = cmDspVarSymbolToPtr( &p->ctx, srcInstPtr, srcVarSymId, kOutDsvFl )) == NULL )
  756. return cmErrMsg(&p->err,kVarNotFoundDspRC,"Audio connection failed. The source variable '%s' could not be found in DSP instance '%s' id=%i.", cmStringNullGuard(cmSymTblLabel(p->ctx.stH,srcVarSymId)), cmStringNullGuard(srcInstPtr->classPtr->labelStr),srcInstPtr->id);
  757. // validate the src variable type
  758. if( cmIsFlag(srcVarPtr->flags,kAudioBufDsvFl) == false )
  759. return cmErrMsg(&p->err,kVarTypeErrDspRC,"Audio connection failed. The source variable '%s' in '%s' id=%i was not an audio variable.", cmStringNullGuard(cmSymTblLabel(p->ctx.stH,srcVarSymId)), cmStringNullGuard(srcInstPtr->classPtr->labelStr),srcInstPtr->id);
  760. // locate the dst audio variable
  761. if((dstVarPtr = cmDspVarSymbolToPtr( &p->ctx, dstInstPtr, dstVarSymId, kInDsvFl )) == NULL )
  762. return cmErrMsg(&p->err,kVarNotFoundDspRC,"Audio connection failed. The destination variable '%s' could not be found in DSP instance '%s' id=%i.", cmStringNullGuard(cmSymTblLabel(p->ctx.stH,dstVarSymId)), cmStringNullGuard(dstInstPtr->classPtr->labelStr),dstInstPtr->id);
  763. // validate the dst variable type
  764. if( cmIsFlag(dstVarPtr->flags,kAudioBufDsvFl) == false )
  765. return cmErrMsg(&p->err,kVarTypeErrDspRC,"Audio connection failed. The destination variable '%s' in '%s' id=%i was not an audio variable.", cmStringNullGuard(cmSymTblLabel(p->ctx.stH,dstVarSymId)), cmStringNullGuard(dstInstPtr->classPtr->labelStr),dstInstPtr->id);
  766. // get a pointer to the source sample buffer
  767. //if( (srcDataPtr = cmDsvSampleMtx( &srcVarPtr->value )) == NULL )
  768. // return cmErrMsg(&p->err,kVarNotValidDspRC,"Audio connection failed. The audio source variable '%s' in '%s' id=%i has not been allocated.",cmSymTblLabel(p->ctx.stH,srcVarSymId), srcInstPtr->classPtr->labelStr,srcInstPtr->id);
  769. // set the destination sample buffer to point to the source sample buffer.
  770. //cmDsvSetSampleMtx( &dstVarPtr->value, srcDataPtr, cmDsvRows(&srcVarPtr->value), cmDsvCols(&srcVarPtr->value));
  771. cmDsvSetProxy( &dstVarPtr->value, &srcVarPtr->value );
  772. return kOkDspRC;
  773. }
  774. cmDspRC_t cmDspSysConnectAudio( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLbl, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarLbl )
  775. {
  776. cmDsp_t* p = _cmDspHandleToPtr(h);
  777. unsigned srcSymId, dstSymId;
  778. if( srcInstPtr == NULL && dstInstPtr == NULL )
  779. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The audio connection process was passed a NULL source and destination processor instance.");
  780. if( srcInstPtr == NULL )
  781. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The audio connection process was passed a NULL source processor instance pointer for connection to '%s'.",cmStringNullGuard(dstInstPtr->classPtr->labelStr));
  782. if( dstInstPtr == NULL )
  783. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The audio connection process was passed a NULL destination processor instance pointer for connection from '%s'.",cmStringNullGuard(srcInstPtr->classPtr->labelStr));
  784. if((srcSymId = cmSymTblId(p->ctx.stH,srcVarLbl)) == cmInvalidId )
  785. return cmErrMsg(&p->err,kSymNotFoundDspRC,"Audio connection failed. The source variable symbol '%s' for source DSP instance '%s' id=%i could not be found.",cmStringNullGuard(srcVarLbl),cmStringNullGuard(srcInstPtr->classPtr->labelStr),srcInstPtr->id);
  786. if((dstSymId = cmSymTblId(p->ctx.stH,dstVarLbl)) == cmInvalidId )
  787. return cmErrMsg(&p->err,kSymNotFoundDspRC,"Audio connection failed. The destination variable symbol '%s' for source DSP instance '%s' id=%i could not be found.",cmStringNullGuard(dstVarLbl),cmStringNullGuard(dstInstPtr->classPtr->labelStr),dstInstPtr->id);
  788. return _cmDspSysConnAudio(p,srcInstPtr,srcSymId,dstInstPtr,dstSymId);
  789. }
  790. cmDspRC_t cmDspSysConnectAudioN11N( cmDspSysH_t h, cmDspInst_t* srcInstArray[], const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarPrefixStr, unsigned n )
  791. {
  792. cmDspRC_t rc = kOkDspRC;
  793. unsigned i;
  794. for(i=0; i<n; ++i)
  795. {
  796. const cmChar_t* dstVarStr = dstVarPrefixStr;
  797. if( n >= 2 )
  798. dstVarStr = cmDspSysPrintLabel(dstVarPrefixStr,i);
  799. if((rc = cmDspSysConnectAudio( h, srcInstArray[i], srcVarLabel, dstInstPtr, dstVarStr )) != kOkDspRC )
  800. break;
  801. }
  802. return rc;
  803. }
  804. cmDspRC_t cmDspSysConnectAudio1NN1( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, cmDspInst_t* dstInstArray[], const cmChar_t* dstVarLabel, unsigned n )
  805. {
  806. cmDspRC_t rc = kOkDspRC;
  807. unsigned i;
  808. for(i=0; i<n; ++i)
  809. {
  810. const cmChar_t* label = srcVarPrefixStr;
  811. if( n >= 2 )
  812. label = cmDspSysPrintLabel(srcVarPrefixStr,i);
  813. if((rc = cmDspSysConnectAudio( h, srcInstPtr, label, dstInstArray[i], dstVarLabel )) != kOkDspRC )
  814. break;
  815. }
  816. return rc;
  817. }
  818. cmDspRC_t cmDspSysConnectAudio1N1N( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarPrefixStr, unsigned n )
  819. {
  820. cmDspRC_t rc = kOkDspRC;
  821. unsigned i;
  822. for(i=0; i<n; ++i)
  823. {
  824. const cmChar_t* label0 = cmDspSysPrintLabel(srcVarPrefixStr,i);
  825. const cmChar_t* label1 = cmDspSysPrintLabel2(dstVarPrefixStr,i);
  826. if((rc = cmDspSysConnectAudio( h, srcInstPtr, label0, dstInstPtr, label1 )) != kOkDspRC )
  827. break;
  828. }
  829. return rc;
  830. }
  831. cmDspRC_t cmDspSysConnectAudioN1N1( cmDspSysH_t h, cmDspInst_t* srcInstArray[], const cmChar_t* srcVarLabel, cmDspInst_t* dstInstArray[], const cmChar_t* dstVarLabel, unsigned n )
  832. {
  833. cmDspRC_t rc = kOkDspRC;
  834. unsigned i;
  835. for(i=0; i<n; ++i)
  836. {
  837. if((rc = cmDspSysConnectAudio( h, srcInstArray[i], srcVarLabel, dstInstArray[i], dstVarLabel )) != kOkDspRC )
  838. break;
  839. }
  840. return rc;
  841. }
  842. cmDspRC_t cmDspSysConnectAudio11N1( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, cmDspInst_t* dstInstArray[],const cmChar_t* dstVarLabel, unsigned n )
  843. {
  844. cmDspRC_t rc = kOkDspRC;
  845. unsigned i;
  846. for(i=0; i<n; ++i)
  847. {
  848. if((rc = cmDspSysConnectAudio( h, srcInstPtr, srcVarLabel, dstInstArray[i], dstVarLabel )) != kOkDspRC )
  849. break;
  850. }
  851. return rc;
  852. }
  853. cmDspRC_t cmDspSysConnectAudio111N( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarLabel, unsigned n )
  854. {
  855. cmDspRC_t rc = kOkDspRC;
  856. unsigned i;
  857. for(i=0; i<n; ++i)
  858. {
  859. const cmChar_t* label1 = cmDspSysPrintLabel(dstVarLabel,i);
  860. const cmChar_t* label = n>1 ? label1 : dstVarLabel;
  861. if((rc = cmDspSysConnectAudio( h, srcInstPtr, srcVarLabel, dstInstPtr, label )) != kOkDspRC )
  862. break;
  863. }
  864. return rc;
  865. }
  866. cmDspRC_t cmDspSysConnectAudioN11NM( cmDspSysH_t h, cmDspInst_t* srcInstArray[], const cmChar_t* srcVarLabel, unsigned srcCnt, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarPrefixStr, unsigned dstCnt, const unsigned* map )
  867. {
  868. cmDsp_t* p = _cmDspHandleToPtr(h);
  869. cmDspRC_t rc = kOkDspRC;
  870. unsigned i;
  871. for(i=0; i<dstCnt; ++i)
  872. {
  873. const cmChar_t* dstVarStr = dstVarPrefixStr;
  874. if( dstCnt >= 2 )
  875. dstVarStr = cmDspSysPrintLabel(dstVarPrefixStr,i);
  876. if( map[i] >= srcCnt )
  877. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The source instance map connection index %i is of range %i.",i,srcCnt);
  878. if((rc = cmDspSysConnectAudio( h, srcInstArray[ map[i] ], srcVarLabel, dstInstPtr, dstVarStr )) != kOkDspRC )
  879. break;
  880. }
  881. return rc;
  882. }
  883. cmDspRC_t cmDspSysInstallCb( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarLabel, void* dstCbDataPtr)
  884. {
  885. cmDsp_t* p = _cmDspHandleToPtr(h);
  886. return cmDspInstallCb(&p->ctx,srcInstPtr,srcVarLabel,dstInstPtr,dstVarLabel,dstCbDataPtr);
  887. }
  888. cmDspRC_t cmDspSysInstallCbN11N( cmDspSysH_t h, cmDspInst_t* srcInstArray[], const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarPrefixStr, unsigned n )
  889. {
  890. cmDspRC_t rc = kOkDspRC;
  891. unsigned i;
  892. for(i=0; i<n; ++i)
  893. {
  894. const cmChar_t* dstVarStr = dstVarPrefixStr;
  895. if( n >= 2 )
  896. dstVarStr = cmDspSysPrintLabel(dstVarPrefixStr,i);
  897. if((rc = cmDspSysInstallCb( h, srcInstArray[i], srcVarLabel, dstInstPtr, dstVarStr, NULL )) != kOkDspRC )
  898. break;
  899. }
  900. return rc;
  901. }
  902. cmDspRC_t cmDspSysInstallCb1NN1( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, cmDspInst_t* dstInstArray[], const cmChar_t* dstVarLabel, unsigned n )
  903. {
  904. cmDspRC_t rc = kOkDspRC;
  905. unsigned i;
  906. for(i=0; i<n; ++i)
  907. {
  908. const cmChar_t* srcVarStr = srcVarPrefixStr;
  909. if( n >= 2 )
  910. srcVarStr = cmDspSysPrintLabel(srcVarPrefixStr,i);
  911. if((rc = cmDspSysInstallCb( h, srcInstPtr, srcVarStr, dstInstArray[i], dstVarLabel, NULL )) != kOkDspRC )
  912. break;
  913. }
  914. return rc;
  915. }
  916. cmDspRC_t cmDspSysInstallCb1N1N( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarPrefixStr, unsigned n )
  917. {
  918. cmDspRC_t rc = kOkDspRC;
  919. unsigned i;
  920. for(i=0; i<n; ++i)
  921. {
  922. const cmChar_t* label0 = srcVarPrefixStr;
  923. const cmChar_t* label1 = dstVarPrefixStr;
  924. if( n >= 2 )
  925. {
  926. label0 = cmDspSysPrintLabel(srcVarPrefixStr,i);
  927. label1 = cmDspSysPrintLabel2(dstVarPrefixStr,i);
  928. }
  929. if((rc = cmDspSysInstallCb( h, srcInstPtr, label0, dstInstPtr, label1, NULL )) != kOkDspRC )
  930. break;
  931. }
  932. return rc;
  933. }
  934. cmDspRC_t cmDspSysInstallCbN1N1( cmDspSysH_t h, cmDspInst_t* srcInstArray[], const cmChar_t* srcVarLabel, cmDspInst_t* dstInstArray[], const cmChar_t* dstVarLabel, unsigned n )
  935. {
  936. cmDspRC_t rc = kOkDspRC;
  937. unsigned i;
  938. for(i=0; i<n; ++i)
  939. {
  940. if((rc = cmDspSysInstallCb( h, srcInstArray[i], srcVarLabel, dstInstArray[i], dstVarLabel, NULL )) != kOkDspRC )
  941. break;
  942. }
  943. return rc;
  944. }
  945. cmDspRC_t cmDspSysInstallCb11N1( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, cmDspInst_t* dstInstArray[], const cmChar_t* dstVarLabel, unsigned n )
  946. {
  947. cmDspRC_t rc = kOkDspRC;
  948. unsigned i;
  949. for(i=0; i<n; ++i)
  950. {
  951. if((rc = cmDspSysInstallCb( h, srcInstPtr, srcVarLabel, dstInstArray[i], dstVarLabel, NULL )) != kOkDspRC )
  952. break;
  953. }
  954. return rc;
  955. }
  956. cmDspRC_t cmDspSysInstallCb111N( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarPrefixLabel, unsigned n )
  957. {
  958. cmDspRC_t rc = kOkDspRC;
  959. unsigned i;
  960. for(i=0; i<n; ++i)
  961. {
  962. const cmChar_t* dstVarStr = dstVarPrefixLabel;
  963. if( n >= 2 )
  964. dstVarStr = cmDspSysPrintLabel(dstVarPrefixLabel,i);
  965. if((rc = cmDspSysInstallCb( h, srcInstPtr, srcVarLabel, dstInstPtr, dstVarStr, NULL )) != kOkDspRC )
  966. break;
  967. }
  968. return rc;
  969. }
  970. cmDspRC_t cmDspSysInstallCbN111( cmDspSysH_t h, cmDspInst_t* srcInstArray[], const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarLabel, unsigned n )
  971. {
  972. cmDspRC_t rc = kOkDspRC;
  973. unsigned i;
  974. for(i=0; i<n; ++i)
  975. {
  976. if((rc = cmDspSysInstallCb( h, srcInstArray[i], srcVarLabel, dstInstPtr, dstVarLabel, NULL )) != kOkDspRC )
  977. break;
  978. }
  979. return rc;
  980. }
  981. cmDspRC_t cmDspSysInstallCb1N11( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarLabel, unsigned n )
  982. {
  983. cmDspRC_t rc = kOkDspRC;
  984. unsigned i;
  985. for(i=0; i<n; ++i)
  986. {
  987. const cmChar_t* srcVarStr = srcVarPrefixLabel;
  988. if( n >= 2 )
  989. srcVarStr = cmDspSysPrintLabel(srcVarPrefixLabel,i);
  990. if((rc = cmDspSysInstallCb( h, srcInstPtr, srcVarStr, dstInstPtr, dstVarLabel, NULL )) != kOkDspRC )
  991. break;
  992. }
  993. return rc;
  994. }
  995. cmDspRC_t cmDspSysInstallCb1N1NM( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, unsigned srcCnt, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarPrefixStr, unsigned dstCnt, const unsigned* map )
  996. {
  997. cmDsp_t* p = _cmDspHandleToPtr(h);
  998. cmDspRC_t rc = kOkDspRC;
  999. unsigned i;
  1000. for(i=0; i<dstCnt; ++i)
  1001. {
  1002. const cmChar_t* label0 = srcVarPrefixStr;
  1003. const cmChar_t* label1 = dstVarPrefixStr;
  1004. if( map[i] >= srcCnt )
  1005. {
  1006. if( map[i] >= srcCnt )
  1007. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The source instance map connection index %i is of range %i.",i,srcCnt);
  1008. }
  1009. if( srcCnt >= 2 )
  1010. label0 = cmDspSysPrintLabel(srcVarPrefixStr,map[i]);
  1011. if( dstCnt >= 2 )
  1012. label1 = cmDspSysPrintLabel2(dstVarPrefixStr,i);
  1013. if((rc = cmDspSysInstallCb( h, srcInstPtr, label0, dstInstPtr, label1, NULL )) != kOkDspRC )
  1014. break;
  1015. }
  1016. return rc;
  1017. }
  1018. cmDspRC_t cmDspSysInstallCb1NN1M( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, unsigned srcCnt, cmDspInst_t* dstInstArray[], const cmChar_t* dstVarLabel, unsigned dstCnt, const unsigned* map )
  1019. {
  1020. cmDsp_t* p = _cmDspHandleToPtr(h);
  1021. cmDspRC_t rc = kOkDspRC;
  1022. unsigned i;
  1023. for(i=0; i<dstCnt; ++i)
  1024. {
  1025. if( map[i] >= srcCnt )
  1026. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The source instance map connection index %i is of range %i.",i,srcCnt);
  1027. const cmChar_t* srcVarStr = srcVarPrefixStr;
  1028. if( srcCnt >= 2 )
  1029. srcVarStr = cmDspSysPrintLabel(srcVarPrefixStr,map[i]);
  1030. if((rc = cmDspSysInstallCb( h, srcInstPtr, srcVarStr, dstInstArray[i], dstVarLabel, NULL )) != kOkDspRC )
  1031. break;
  1032. }
  1033. return rc;
  1034. }
  1035. cmDspRC_t cmDspSysInstallCb1NN1M2( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, unsigned srcCnt, const unsigned* map, cmDspInst_t* dstInstArray[], const cmChar_t* dstVarLabel, unsigned dstCnt )
  1036. {
  1037. cmDsp_t* p = _cmDspHandleToPtr(h);
  1038. cmDspRC_t rc = kOkDspRC;
  1039. unsigned i;
  1040. for(i=0; i<srcCnt; ++i)
  1041. {
  1042. if( map[i] >= dstCnt )
  1043. return cmErrMsg(&p->err,kInstNotFoundDspRC,"The dest. instance map connection index %i is of range %i.",map[i],dstCnt);
  1044. const cmChar_t* srcVarStr = srcVarPrefixStr;
  1045. if( srcCnt >= 2 )
  1046. srcVarStr = cmDspSysPrintLabel(srcVarPrefixStr,i);
  1047. if((rc = cmDspSysInstallCb( h, srcInstPtr, srcVarStr, dstInstArray[ map[i] ], dstVarLabel, NULL )) != kOkDspRC )
  1048. break;
  1049. }
  1050. return rc;
  1051. }
  1052. double cmDspSysSampleRate( cmDspSysH_t h )
  1053. {
  1054. cmDsp_t* p = _cmDspHandleToPtr(h);
  1055. return p->ctx.ctx->ss->args.srate;
  1056. }
  1057. cmJsonH_t cmDspSysPgmRsrcHandle( cmDspSysH_t h )
  1058. {
  1059. cmDsp_t* p = _cmDspHandleToPtr(h);
  1060. return p->ctx.rsrcJsH;
  1061. }
  1062. cmSymTblH_t cmDspSysSymbolTable( cmDspSysH_t h )
  1063. {
  1064. cmDsp_t* p = _cmDspHandleToPtr(h);
  1065. return p->ctx.stH;
  1066. }
  1067. unsigned cmDspSysRegisterStaticSymbol( cmDspSysH_t h, const cmChar_t* symLabel )
  1068. { return cmSymTblRegisterStaticSymbol( cmDspSysSymbolTable(h), symLabel ); }
  1069. unsigned cmDspSysRegisterSymbol( cmDspSysH_t h, const cmChar_t* symLabel )
  1070. { return cmSymTblRegisterSymbol( cmDspSysSymbolTable(h), symLabel); }
  1071. cmCtx_t* cmDspSysPgmCtx( cmDspSysH_t h )
  1072. {
  1073. cmDsp_t* p = _cmDspHandleToPtr(h);
  1074. return &p->cmCtx;
  1075. }
  1076. cmLHeapH_t cmDspSysLHeap( cmDspSysH_t h )
  1077. {
  1078. cmDsp_t* p = _cmDspHandleToPtr(h);
  1079. return p->lhH;
  1080. }
  1081. unsigned cmDspSysNetNodeId( cmDspSysH_t h )
  1082. {
  1083. cmDsp_t* p = _cmDspHandleToPtr(h);
  1084. return cmUdpNetLocalNodeId(p->netH);
  1085. }
  1086. const cmChar_t* cmDspSysNetNodeLabel( cmDspSysH_t h )
  1087. {
  1088. cmDsp_t* p = _cmDspHandleToPtr(h);
  1089. return cmUdpNetLocalNodeLabel(p->netH);
  1090. }
  1091. const cmChar_t* cmDspSysNetNodeIdToLabel( cmDspSysH_t h, unsigned netNodeId )
  1092. {
  1093. cmDsp_t* p = _cmDspHandleToPtr(h);
  1094. return cmUdpNetNodeIdToLabel(p->netH,netNodeId);
  1095. }
  1096. unsigned cmDspSysNetNodeLabelToId( cmDspSysH_t h, const cmChar_t* netNodeLabel )
  1097. {
  1098. cmDsp_t* p = _cmDspHandleToPtr(h);
  1099. return cmUdpNetNodeLabelToId(p->netH,netNodeLabel);
  1100. }
  1101. cmDspInstSymId_t* _cmDspSysFindInstSymId( cmDsp_t* p, unsigned symId )
  1102. {
  1103. cmDspInstSymId_t* ip = p->symIdList;
  1104. for(; ip != NULL; ip=ip->link)
  1105. if( ip->symId == symId )
  1106. return ip;
  1107. return NULL;
  1108. }
  1109. unsigned cmDspSysRegisterInstAttrSymbol( cmDspSysH_t h, unsigned symId )
  1110. {
  1111. cmDsp_t* p = _cmDspHandleToPtr(h);
  1112. cmDspInstSymId_t* ip;
  1113. // if this symbol is already registered
  1114. if((ip = _cmDspSysFindInstSymId(p,symId)) != NULL )
  1115. return ip->symId;
  1116. // try to find an unused symbol
  1117. ip = p->symIdList;
  1118. for(; ip != NULL; ip=ip->link)
  1119. if( ip->symId == cmInvalidId )
  1120. break;
  1121. // if no unused symbols were found then allocate a new one
  1122. if( ip == NULL )
  1123. {
  1124. ip = cmLhAllocZ(p->ctx.lhH, cmDspInstSymId_t, 1 );
  1125. ip->link = p->symIdList;
  1126. p->symIdList = ip;
  1127. }
  1128. ip->symId = symId;
  1129. return ip->symId;
  1130. }
  1131. unsigned cmDspSysRegisterInstAttrSymbolStr( cmDspSysH_t h, const cmChar_t* symLabel )
  1132. {
  1133. cmDsp_t* p = _cmDspHandleToPtr(h);
  1134. unsigned symId;
  1135. if((symId = cmSymTblRegisterSymbol(p->ctx.stH,symLabel)) == cmInvalidId )
  1136. return cmErrMsg(&p->err,kSymTblFailDspRC,"The instance attribute symbol '%s' could not be registered.",cmStringNullGuard(symLabel));
  1137. return cmDspSysRegisterInstAttrSymbol(h,symId);
  1138. }
  1139. cmDspRC_t cmDspSysAssignInstAttrSymbol( cmDspSysH_t h, cmDspInst_t* inst, unsigned symId )
  1140. {
  1141. cmDsp_t* p = _cmDspHandleToPtr(h);
  1142. return cmDspInstRegisterAttrSym(&p->ctx, inst, symId) != kOkDspRC;
  1143. }
  1144. unsigned cmDspSysAssignInstAttrSymbolStr( cmDspSysH_t h, cmDspInst_t* inst, const cmChar_t* symLabel )
  1145. {
  1146. unsigned symId = cmDspSysRegisterSymbol(h,symLabel);
  1147. if( cmDspSysAssignInstAttrSymbol( h, inst, symId) != kOkDspRC )
  1148. return cmInvalidId;
  1149. return symId;
  1150. }
  1151. cmDspRC_t cmDspSysRemoveInstAttrSymbol( cmDspSysH_t h, unsigned symId )
  1152. {
  1153. cmDsp_t* p = _cmDspHandleToPtr(h);
  1154. cmDspInstSymId_t* ip;
  1155. // if this symbol is already registered
  1156. if((ip = _cmDspSysFindInstSymId(p,symId)) == NULL )
  1157. return cmErrMsg(&p->err,kOkDspRC,"The instance attribute symbol '%s' is could not be found to be removed.",cmStringNullGuard(cmSymTblLabel(p->ctx.stH,symId)));
  1158. // mark a symbol recd as inactive by setting the symbol id to cmInalidId
  1159. ip->symId = cmInvalidId;
  1160. return kOkDspRC;
  1161. }
  1162. cmDspRC_t cmDspSysRemoveInstAttrSymbolStr( cmDspSysH_t h, const cmChar_t* symLabel )
  1163. {
  1164. cmDsp_t* p = _cmDspHandleToPtr(h);
  1165. unsigned symId;
  1166. if( (symId = cmSymTblId(p->ctx.stH, symLabel )) == cmInvalidId )
  1167. return cmErrMsg(&p->err,kSymNotFoundDspRC,"The instance attribute symbol '%s' does not exist and therefore cannot be removed.",cmStringNullGuard(symLabel));
  1168. return cmDspSysRemoveInstAttrSymbol(h, symId );
  1169. }
  1170. cmDspRC_t cmDspSysBroadcastValue( cmDspSysH_t h, unsigned instAttrSymId, const cmDspValue_t* valuePtr )
  1171. {
  1172. cmDsp_t* p = _cmDspHandleToPtr(h);
  1173. _cmDspInst_t* ip = p->instList;
  1174. for(; ip != NULL; ip = ip->linkPtr )
  1175. if( (instAttrSymId==cmInvalidId) || cmDspInstHasAttrSym(ip->instPtr,instAttrSymId))
  1176. ip->instPtr->sysRecvFunc(&p->ctx,ip->instPtr,instAttrSymId,valuePtr);
  1177. return kOkDspRC;
  1178. }
  1179. cmDspInst_t* cmDspSysAllocLabel( cmDspSysH_t h, const cmChar_t* label, unsigned alignId )
  1180. {
  1181. return cmDspSysAllocInst(h,"Label", NULL, 2, label, alignId);
  1182. }
  1183. cmDspRC_t _cmDspGetRsrcReal( cmDspSysH_t h, const cmChar_t* label, const cmChar_t* rsrcPath, cmReal_t* valPtr )
  1184. {
  1185. const cmChar_t* errLabelPtr = NULL;
  1186. if( cmJsonPathValues( cmDspSysPgmRsrcHandle(h),NULL,NULL,&errLabelPtr, rsrcPath, kRealTId, valPtr, NULL ) != kOkJsRC )
  1187. {
  1188. cmDsp_t* p = _cmDspHandleToPtr(h);
  1189. return cmErrMsg(&p->err,kRsrcNotFoundDspRC,"DSP instance allocation failed for '%s' and the initial value resource path '%s'.", cmStringNullGuard(label),cmStringNullGuard(rsrcPath));
  1190. }
  1191. return kOkDspRC;
  1192. }
  1193. cmDspInst_t* _cmDspSysAllocScalar( cmDspSysH_t h, unsigned presetGrpSymId, const cmChar_t* instLabel, cmReal_t min, cmReal_t max, cmReal_t step, cmReal_t val, const cmChar_t* label )
  1194. {
  1195. cmDspInst_t* inst;
  1196. if((inst = cmDspSysAllocInstS(h,"Scalar", presetGrpSymId, instLabel, 6, kNumberDuiId, min, max, step, val, label )) == NULL)
  1197. {
  1198. cmDsp_t* p = _cmDspHandleToPtr(h);
  1199. cmErrMsg(&p->err,kAllocInstFailDspRC,"Scalar UI control allocation failed for '%s'.", cmStringNullGuard(instLabel));
  1200. }
  1201. return inst;
  1202. }
  1203. cmDspInst_t* cmDspSysAllocScalar( cmDspSysH_t h, const cmChar_t* label, cmReal_t min, cmReal_t max, cmReal_t step, cmReal_t val )
  1204. { return _cmDspSysAllocScalar(h,cmInvalidId,label,min,max,step,val,label); }
  1205. cmChar_t* _cmDspSysFormLabel( cmDspSysH_t h, const cmChar_t* prefixLabel, const cmChar_t* label )
  1206. { return cmTsPrintfH(cmDspSysLHeap(h),"%s-%s",prefixLabel,label); }
  1207. cmDspInst_t* cmDspSysAllocScalarP( cmDspSysH_t h, unsigned presetGrpSymId, const cmChar_t* prefixLabel, const cmChar_t* label, cmReal_t min, cmReal_t max, cmReal_t step, cmReal_t val )
  1208. {
  1209. return _cmDspSysAllocScalar(h,presetGrpSymId,_cmDspSysFormLabel(h,prefixLabel,label),min,max,step,val,label);
  1210. }
  1211. cmDspInst_t* cmDspSysAllocScalarRsrc( cmDspSysH_t h, const cmChar_t* label, cmReal_t min, cmReal_t max, cmReal_t step, const cmChar_t* rsrcPath )
  1212. {
  1213. cmReal_t val;
  1214. if(_cmDspGetRsrcReal(h,label,rsrcPath,&val ) != kOkDspRC )
  1215. return NULL;
  1216. return cmDspSysAllocScalar(h,label,min,max,step,val);
  1217. }
  1218. cmDspInst_t** cmDspSysAllocScalarA( cmDspSysH_t h, unsigned cnt, unsigned presetGroupSymId, const cmChar_t* prefixLabel, const cmChar_t* label, cmReal_t min, cmReal_t max, cmReal_t step, cmReal_t val )
  1219. {
  1220. cmChar_t* lbl = cmTsPrintfH( cmDspSysLHeap(h), "%s-%s",prefixLabel,label);
  1221. return cmDspSysAllocInstArrayS( h, cnt, presetGroupSymId, "Scalar", lbl, NULL, 5, kNumberDuiId, min, max, step, val);
  1222. }
  1223. cmDspInst_t* _cmDspSysAllocButton( cmDspSysH_t h, unsigned btnTypeId, unsigned presetGroupSymId, const cmChar_t* instLabel, const cmChar_t* label, cmReal_t val, unsigned valSymId )
  1224. {
  1225. cmDspInst_t* inst;
  1226. if((inst = cmDspSysAllocInstS( h, "Button", presetGroupSymId, instLabel, 4, btnTypeId, val, valSymId, label)) == NULL )
  1227. {
  1228. cmDsp_t* p = _cmDspHandleToPtr(h);
  1229. cmErrMsg(&p->err,kAllocInstFailDspRC,"Button UI control allocation failed for '%s'.", cmStringNullGuard(label));
  1230. }
  1231. return inst;
  1232. }
  1233. cmDspInst_t* cmDspSysAllocButtonP( cmDspSysH_t h, const cmChar_t* prefixLabel, const cmChar_t* label, cmReal_t val )
  1234. {
  1235. return cmDspSysAllocButton(h,_cmDspSysFormLabel(h,prefixLabel,label),val);
  1236. }
  1237. cmDspInst_t* _cmDspSysAllocButtonRsrc( cmDspSysH_t h, unsigned typeId, unsigned presetGroupSymId, const cmChar_t* label, const cmChar_t* rsrcPath )
  1238. {
  1239. cmReal_t val;
  1240. if(_cmDspGetRsrcReal(h,label,rsrcPath,&val) != kOkDspRC )
  1241. return NULL;
  1242. return _cmDspSysAllocButton(h,typeId,presetGroupSymId,label,label,val,cmInvalidId);
  1243. }
  1244. cmDspInst_t* cmDspSysAllocButton( cmDspSysH_t h, const cmChar_t* label, cmReal_t val )
  1245. { return _cmDspSysAllocButton(h,kButtonDuiId,cmInvalidId,label,label,val,cmInvalidId); }
  1246. cmDspInst_t* cmDspSysAllocButtonRsrc( cmDspSysH_t h, const cmChar_t* label, const cmChar_t* rsrcPath )
  1247. { return _cmDspSysAllocButtonRsrc( h,kButtonDuiId,cmInvalidId,label,rsrcPath); }
  1248. cmDspInst_t* _cmDspSysAllocCheck( cmDspSysH_t h, unsigned presetGroupSymId, const cmChar_t* instLabel, const cmChar_t* label, cmReal_t val )
  1249. { return _cmDspSysAllocButton(h,kCheckDuiId,presetGroupSymId,instLabel,label,val,cmInvalidId); }
  1250. cmDspInst_t* cmDspSysAllocCheck( cmDspSysH_t h, const cmChar_t* label, cmReal_t val )
  1251. { return _cmDspSysAllocCheck(h,cmInvalidId,label,label,val); }
  1252. cmDspInst_t* cmDspSysAllocCheckP( cmDspSysH_t h, unsigned presetGroupSymId, const cmChar_t* prefixLabel, const cmChar_t* label, cmReal_t val )
  1253. { return _cmDspSysAllocCheck(h,presetGroupSymId,_cmDspSysFormLabel(h,prefixLabel,label),label,val); }
  1254. cmDspInst_t* cmDspSysAllocCheckRsrc( cmDspSysH_t h, const cmChar_t* label, const cmChar_t* rsrcPath )
  1255. { return _cmDspSysAllocButtonRsrc( h,kCheckDuiId, cmInvalidId, label,rsrcPath); }
  1256. cmDspInst_t* cmDspSysAllocMsgList( cmDspSysH_t h, const cmChar_t* fn, const cmChar_t* rsrcLabel, unsigned initSelIdx )
  1257. { return cmDspSysAllocInst( h, "MsgList", NULL, 3, rsrcLabel, fn, initSelIdx); }
  1258. cmDspInst_t* cmDspSysAllocMsgListP( cmDspSysH_t h, unsigned presetGroupSymId, const cmChar_t* preLabel, const cmChar_t* label, const cmChar_t* fn, const cmChar_t* rsrcLabel, unsigned initSelIdx )
  1259. {
  1260. cmDspInst_t* inst;
  1261. cmChar_t* lbl;
  1262. if((inst = cmDspSysAllocInstS( h, "MsgList", presetGroupSymId, lbl = _cmDspSysFormLabel(h,preLabel,label), 3, rsrcLabel, fn, initSelIdx)) == NULL )
  1263. {
  1264. cmDsp_t* p = _cmDspHandleToPtr(h);
  1265. cmErrMsg(&p->err,kAllocInstFailDspRC,"Msg List UI control allocation failed for '%s'.", cmStringNullGuard(lbl));
  1266. }
  1267. return inst;
  1268. }
  1269. cmDspInst_t* cmDspSysAllocAudioIn( cmDspSysH_t h, unsigned chIdx, cmReal_t gain )
  1270. { return cmDspSysAllocInst( h, "AudioIn", NULL, 2, chIdx, gain ); }
  1271. const cmJsonNode_t* _cmDspSysFindAudioChMap( cmDspSysH_t h, const cmChar_t* rsrcLabel )
  1272. {
  1273. cmDsp_t* p = _cmDspHandleToPtr(h);
  1274. cmJsonH_t jsH = cmDspSysPgmRsrcHandle(h);
  1275. assert( cmJsonIsValid(jsH) );
  1276. const cmJsonNode_t* np = NULL;
  1277. if(( np = cmJsonFindValue( jsH, rsrcLabel, cmJsonRoot(jsH), kArrayTId )) == NULL )
  1278. {
  1279. cmErrMsg(&p->err,kRsrcNotFoundDspRC,"The audio channel map resource '%s' was not found.", cmStringNullGuard(rsrcLabel));
  1280. return NULL;
  1281. }
  1282. unsigned chCnt = cmJsonChildCount(np);
  1283. if( chCnt == 0 )
  1284. {
  1285. cmErrMsg(&p->err,kInvalidArgDspRC,"The audio channel map resource '%s' is empty.",cmStringNullGuard(rsrcLabel));
  1286. return NULL;
  1287. }
  1288. return np;
  1289. }
  1290. cmDspRC_t _cmDspSysReadAudioChMap( cmDspSysH_t h, const cmChar_t* rsrcLabel, const cmJsonNode_t* mapNodePtr, unsigned* map, unsigned mapCnt )
  1291. {
  1292. cmDsp_t* p = _cmDspHandleToPtr(h);
  1293. unsigned i;
  1294. for(i=0; i<mapCnt; ++i)
  1295. {
  1296. const cmJsonNode_t* np;
  1297. if((np = cmJsonArrayElementC(mapNodePtr,i)) == NULL )
  1298. return cmErrMsg(&p->err,kInvalidArgDspRC,"The audio map element at index %i could not be accessed in the audio map:'%s'.",i,cmStringNullGuard(rsrcLabel));
  1299. if( cmJsonUIntValue(np,map + i ) != kOkJsRC )
  1300. return cmErrMsg(&p->err,kInvalidArgDspRC,"The audio map element at index %i could not be read as an integer in the audio map:'%s'..",i,cmStringNullGuard(rsrcLabel));
  1301. }
  1302. return kOkDspRC;
  1303. }
  1304. cmDspInst_t** _cmDspSysAllocAudioRsrc( cmDspSysH_t h, const cmChar_t* classLabel, const cmChar_t* rsrcLabel, cmReal_t gain, unsigned* retChCntPtr )
  1305. {
  1306. cmDsp_t* p = _cmDspHandleToPtr(h);
  1307. const cmJsonNode_t* np;
  1308. if( retChCntPtr != NULL )
  1309. *retChCntPtr = 0;
  1310. //
  1311. if( rsrcLabel==NULL )
  1312. rsrcLabel = "audioInMap";
  1313. // find the map resource
  1314. if((np = _cmDspSysFindAudioChMap(h,rsrcLabel)) == NULL )
  1315. return NULL;
  1316. unsigned chCnt = cmJsonChildCount(np);
  1317. cmDspInst_t** a = cmLhAllocZ( p->lhH, cmDspInst_t*, chCnt );
  1318. unsigned chMap[ chCnt ];
  1319. // fill in the channel map - maps virtual channels to physical channels
  1320. if( _cmDspSysReadAudioChMap(h,rsrcLabel,np,chMap,chCnt) != kOkDspRC )
  1321. return NULL;
  1322. unsigned i;
  1323. for(i=0; i<chCnt; ++i)
  1324. if((a[i] = cmDspSysAllocInst( h, classLabel, NULL, 2, chMap[i], gain )) == NULL )
  1325. break;
  1326. if( i==chCnt )
  1327. {
  1328. if( retChCntPtr != NULL )
  1329. *retChCntPtr = chCnt;
  1330. return a;
  1331. }
  1332. return NULL;
  1333. }
  1334. cmDspInst_t** cmDspSysAllocAudioInAR( cmDspSysH_t h, const cmChar_t* rsrcLabel, cmReal_t gain, unsigned* retChCntPtr )
  1335. { return _cmDspSysAllocAudioRsrc(h,"AudioIn",rsrcLabel,gain,retChCntPtr); }
  1336. cmDspInst_t* cmDspSysAllocAudioOut(cmDspSysH_t h, unsigned chIdx, cmReal_t gain )
  1337. { return cmDspSysAllocInst( h, "AudioOut", NULL, 2, chIdx, gain ); }
  1338. cmDspInst_t** cmDspSysAllocAudioOutAR( cmDspSysH_t h, const cmChar_t* rsrcLabel, cmReal_t gain, unsigned* retChCntPtr )
  1339. { return _cmDspSysAllocAudioRsrc(h,"AudioOut",rsrcLabel,gain,retChCntPtr); }
  1340. cmDspRC_t cmDspSysInstallNetCb( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, const cmChar_t* dstNetNodeLabel, const cmChar_t* dstInstLabel, const cmChar_t* dstVarLabel )
  1341. {
  1342. cmDsp_t* p = _cmDspHandleToPtr(h);
  1343. cmDspRC_t rc = kOkDspRC;
  1344. cmDspInst_t* netSendInstPtr;
  1345. unsigned dstNetNodeId;
  1346. _cmDspSrcConn_t* srcConnPtr = NULL;
  1347. // get the dest. network node id
  1348. if( (dstNetNodeId = cmUdpNetNodeLabelToId(p->netH, dstNetNodeLabel )) == cmInvalidId )
  1349. return cmErrMsg(&p->err,kNetNodeNotFoundDspRC,"The destination network node label '%s' was not found.",cmStringNullGuard(dstNetNodeLabel));
  1350. if((srcConnPtr = _cmDspSysNetCreateSrcConn( p, dstNetNodeId, dstInstLabel, dstVarLabel)) == NULL )
  1351. return rc;
  1352. // allocate a network sender
  1353. if((netSendInstPtr = cmDspSysAllocInst(h, "NetSend", NULL, 1, srcConnPtr )) == NULL )
  1354. return cmErrMsg(&p->err,kNetSendAllocFailDspRC,"The network sender DSP instance allocation failed.");
  1355. return cmDspSysInstallCb(h, srcInstPtr, srcVarLabel, netSendInstPtr, "in", NULL );
  1356. }
  1357. cmDspRC_t cmDspSysInstallNetCb1N1N( cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, const cmChar_t* dstNetNodeLabel, const cmChar_t* dstInstLabel, const cmChar_t* dstVarPrefixStr, unsigned dstOffs, unsigned n )
  1358. {
  1359. cmDspRC_t rc = kOkDspRC;
  1360. unsigned i;
  1361. for(i=0; i<n; ++i)
  1362. {
  1363. const cmChar_t* label0 = srcVarPrefixStr;
  1364. const cmChar_t* label1 = dstVarPrefixStr;
  1365. if( n >= 2 )
  1366. {
  1367. label0 = cmDspSysPrintLabel( srcVarPrefixStr,i);
  1368. label1 = cmDspSysPrintLabel2(dstVarPrefixStr,dstOffs + i);
  1369. }
  1370. if((rc = cmDspSysInstallNetCb(h,srcInstPtr,label0,dstNetNodeLabel,dstInstLabel,label1)) != kOkDspRC )
  1371. break;
  1372. }
  1373. return rc;
  1374. }
  1375. cmDspRC_t cmDspSysInstallNetCb1N1NM(cmDspSysH_t h, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarPrefixStr, unsigned srcCnt, const cmChar_t* dstNetNodeLabel, const cmChar_t* dstInstLabel, const cmChar_t* dstVarPrefixStr, unsigned dstCnt, const unsigned* map )
  1376. {
  1377. cmDspRC_t rc = kOkDspRC;
  1378. unsigned i;
  1379. for(i=0; i<dstCnt; ++i)
  1380. {
  1381. assert( map[i] < srcCnt );
  1382. const cmChar_t* label0 = cmDspSysPrintLabel( srcVarPrefixStr, map[i] );
  1383. const cmChar_t* label1 = cmDspSysPrintLabel2(dstVarPrefixStr, i );
  1384. if((rc = cmDspSysInstallNetCb(h,srcInstPtr,label0,dstNetNodeLabel,dstInstLabel,label1)) != kOkDspRC )
  1385. break;
  1386. }
  1387. return rc;
  1388. }
  1389. cmDspRC_t _cmDspRsrcPath( cmDspSysH_t h, cmChar_t** pathPtr, va_list vl )
  1390. {
  1391. unsigned i;
  1392. cmDspRC_t rc = kOkDspRC;;
  1393. cmDsp_t* p = _cmDspHandleToPtr(h);
  1394. cmChar_t* path = NULL;
  1395. unsigned maxArgCnt = 10;
  1396. *pathPtr = NULL;
  1397. for(i=0; i<maxArgCnt; ++i )
  1398. {
  1399. cmChar_t* str;
  1400. if((str = va_arg(vl,cmChar_t* )) == NULL )
  1401. break;
  1402. if( path != NULL )
  1403. path = cmTextAppendSS(path,"/");
  1404. path = cmTextAppendSS(path,str);
  1405. }
  1406. if( i >= maxArgCnt )
  1407. {
  1408. rc = cmErrMsg(&p->err,kJsonFailDspRC,"A resource path, beginning with '%25s', does not contain a terminating NULL.", cmStringNullGuard(path) );
  1409. goto errLabel;
  1410. }
  1411. // duplicate the string onto the program linked heap
  1412. *pathPtr = cmLhAllocStr( cmDspSysLHeap(h), path);
  1413. errLabel:
  1414. cmMemFree(path);
  1415. return rc;
  1416. }
  1417. cmDspRC_t cmDspRsrcBoolV( cmDspSysH_t h, bool* vp, va_list vl )
  1418. {
  1419. assert(vp != NULL);
  1420. cmDsp_t* p = _cmDspHandleToPtr(h);
  1421. cmChar_t* path = NULL;
  1422. cmDspRC_t rc;
  1423. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1424. return rc;
  1425. if((rc = cmJsonPathToBool( cmDspSysPgmRsrcHandle(h), NULL, NULL, path, vp )) != kOkJsRC )
  1426. return cmErrMsg(&p->err,kJsonFailDspRC,"'bool' resource not found at path:'%s'.",cmStringNullGuard(path));
  1427. return rc;
  1428. }
  1429. cmDspRC_t cmDspRsrcIntV( cmDspSysH_t h, int* vp, va_list vl )
  1430. {
  1431. assert(vp != NULL);
  1432. cmDsp_t* p = _cmDspHandleToPtr(h);
  1433. cmChar_t* path = NULL;
  1434. cmDspRC_t rc;
  1435. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1436. return rc;
  1437. if((rc = cmJsonPathToInt( cmDspSysPgmRsrcHandle(h), NULL, NULL, path, vp )) != kOkJsRC )
  1438. return cmErrMsg(&p->err,kJsonFailDspRC,"'int' resource not found at path:'%s'.",cmStringNullGuard(path));
  1439. return rc;
  1440. }
  1441. cmDspRC_t cmDspRsrcUIntV( cmDspSysH_t h, unsigned* vp, va_list vl )
  1442. {
  1443. assert(vp != NULL);
  1444. cmDsp_t* p = _cmDspHandleToPtr(h);
  1445. cmChar_t* path = NULL;
  1446. cmDspRC_t rc;
  1447. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1448. return rc;
  1449. if((rc = cmJsonPathToUInt( cmDspSysPgmRsrcHandle(h), NULL, NULL, path, vp )) != kOkJsRC )
  1450. return cmErrMsg(&p->err,kJsonFailDspRC,"'uint' resource not found at path:'%s'.",cmStringNullGuard(path));
  1451. return rc;
  1452. }
  1453. cmDspRC_t cmDspRsrcDblV( cmDspSysH_t h, double* vp, va_list vl )
  1454. {
  1455. assert(vp != NULL);
  1456. cmDsp_t* p = _cmDspHandleToPtr(h);
  1457. cmChar_t* path = NULL;
  1458. cmDspRC_t rc;
  1459. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1460. return rc;
  1461. if((rc = cmJsonPathToReal( cmDspSysPgmRsrcHandle(h), NULL, NULL, path, vp )) != kOkJsRC )
  1462. return cmErrMsg(&p->err,kJsonFailDspRC,"'real' resource not found at path:'%s'.",cmStringNullGuard(path));
  1463. return rc;
  1464. }
  1465. cmDspRC_t cmDspRsrcRealV( cmDspSysH_t h, cmReal_t* vp, va_list vl )
  1466. {
  1467. assert(vp != NULL);
  1468. cmDsp_t* p = _cmDspHandleToPtr(h);
  1469. cmChar_t* path = NULL;
  1470. cmDspRC_t rc;
  1471. double dval;
  1472. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1473. return rc;
  1474. if((rc = cmJsonPathToReal( cmDspSysPgmRsrcHandle(h), NULL, NULL, path, &dval )) != kOkJsRC )
  1475. return cmErrMsg(&p->err,kJsonFailDspRC,"'real' resource not found at path:'%s'.",cmStringNullGuard(path));
  1476. *vp = dval;
  1477. return rc;
  1478. }
  1479. cmDspRC_t cmDspRsrcStringV( cmDspSysH_t h, const cmChar_t** vp, va_list vl )
  1480. {
  1481. assert(vp != NULL);
  1482. cmDsp_t* p = _cmDspHandleToPtr(h);
  1483. cmChar_t* path = NULL;
  1484. cmDspRC_t rc;
  1485. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1486. return rc;
  1487. if((rc = cmJsonPathToString( cmDspSysPgmRsrcHandle(h), NULL, NULL, path, vp )) != kOkJsRC )
  1488. return cmErrMsg(&p->err,kJsonFailDspRC,"'string' resource not found at path:'%s'.",cmStringNullGuard(path));
  1489. return rc;
  1490. }
  1491. cmDspRC_t cmDspRsrcArrayCountV( cmDspSysH_t h, unsigned *n, va_list vl )
  1492. {
  1493. assert(n != NULL );
  1494. cmDsp_t* p = _cmDspHandleToPtr(h);
  1495. cmChar_t* path = NULL;
  1496. cmJsonNode_t* np = NULL;
  1497. cmDspRC_t rc;
  1498. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1499. return rc;
  1500. if((rc = cmJsonPathToArray( cmDspSysPgmRsrcHandle(h), NULL, NULL, path, &np )) != kOkJsRC )
  1501. return cmErrMsg(&p->err,kJsonFailDspRC,"'array' resource not found at path:'%s'.",cmStringNullGuard(path));
  1502. *n = cmJsonChildCount(np);
  1503. return rc;
  1504. }
  1505. cmDspRC_t _cmDspRsrcArrayV( cmDspSysH_t h, unsigned* np, cmJsonNode_t** npp, cmChar_t** pathPtrPtr, va_list vl )
  1506. {
  1507. cmDsp_t* p = _cmDspHandleToPtr(h);
  1508. cmChar_t* path = NULL;
  1509. cmJsonH_t jsH = cmDspSysPgmRsrcHandle(h);
  1510. cmDspRC_t rc;
  1511. if((rc = _cmDspRsrcPath(h,&path,vl)) != kOkDspRC )
  1512. return rc;
  1513. if((rc = cmJsonPathToArray( jsH, NULL, NULL, path, npp )) != kOkJsRC )
  1514. return cmErrMsg(&p->err,kJsonFailDspRC,"'array' resource not found at path:'%s'.",cmStringNullGuard(path));
  1515. if((*np = cmJsonChildCount(*npp)) == 0 )
  1516. return rc;
  1517. *pathPtrPtr = path;
  1518. return rc;
  1519. }
  1520. cmDspRC_t cmDspRsrcBoolArrayV( cmDspSysH_t h, unsigned* np, bool** vpp, va_list vl )
  1521. {
  1522. assert(vpp!=NULL);
  1523. cmDsp_t* p = _cmDspHandleToPtr(h);
  1524. cmJsonNode_t* nodePtr = NULL;
  1525. unsigned n = 0;
  1526. cmChar_t* path = NULL;
  1527. unsigned i;
  1528. cmDspRC_t rc;
  1529. if(( rc = _cmDspRsrcArrayV(h,&n,&nodePtr,&path,vl)) != kOkDspRC )
  1530. return rc;
  1531. bool* vp = *vpp;
  1532. vp = cmLhResizeN(p->ctx.lhH,bool,vp,n);
  1533. for(i=0; i<n && rc == kOkDspRC; ++i)
  1534. if( cmJsonBoolValue( cmJsonArrayElementC(nodePtr,i), vp + i ) != kOkJsRC )
  1535. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Element at index '%i' in resource '%s' is invalid.",i,cmStringNullGuard(path));
  1536. *vpp = vp;
  1537. *np = n;
  1538. return rc;
  1539. }
  1540. cmDspRC_t cmDspRsrcIntArrayV( cmDspSysH_t h, unsigned* np, int** vpp, va_list vl )
  1541. {
  1542. assert(vpp!=NULL);
  1543. cmDsp_t* p = _cmDspHandleToPtr(h);
  1544. cmJsonNode_t* nodePtr = NULL;
  1545. unsigned n = 0;
  1546. cmChar_t* path = NULL;
  1547. unsigned i;
  1548. cmDspRC_t rc;
  1549. if(( rc = _cmDspRsrcArrayV(h,&n,&nodePtr,&path,vl)) != kOkDspRC )
  1550. return rc;
  1551. int* vp = *vpp;
  1552. vp = cmLhResizeN(p->ctx.lhH,int,vp,n);
  1553. for(i=0; i<n && rc == kOkDspRC; ++i)
  1554. if( cmJsonIntValue( cmJsonArrayElementC(nodePtr,i), vp + i ) != kOkJsRC )
  1555. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Element at index '%i' in resource '%s' is invalid.",i,cmStringNullGuard(path));
  1556. *vpp = vp;
  1557. *np = n;
  1558. return rc;
  1559. }
  1560. cmDspRC_t cmDspRsrcUIntArrayV( cmDspSysH_t h, unsigned* np, unsigned** vpp, va_list vl )
  1561. {
  1562. assert(vpp!=NULL);
  1563. cmDsp_t* p = _cmDspHandleToPtr(h);
  1564. cmJsonNode_t* nodePtr = NULL;
  1565. unsigned n = 0;
  1566. cmChar_t* path = NULL;
  1567. unsigned i;
  1568. cmDspRC_t rc;
  1569. if(( rc = _cmDspRsrcArrayV(h,&n,&nodePtr,&path,vl)) != kOkDspRC )
  1570. return rc;
  1571. unsigned* vp = *vpp;
  1572. vp = cmLhResizeN(p->ctx.lhH,unsigned,vp,n);
  1573. for(i=0; i<n && rc == kOkDspRC; ++i)
  1574. if( cmJsonUIntValue( cmJsonArrayElementC(nodePtr,i), vp + i ) != kOkJsRC )
  1575. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Element at index '%i' in resource '%s' is invalid.",i,cmStringNullGuard(path));
  1576. *vpp = vp;
  1577. *np = n;
  1578. return rc;
  1579. }
  1580. cmDspRC_t cmDspRsrcDblArrayV( cmDspSysH_t h, unsigned* np, double** vpp, va_list vl )
  1581. {
  1582. assert(vpp!=NULL);
  1583. cmDsp_t* p = _cmDspHandleToPtr(h);
  1584. cmJsonNode_t* nodePtr = NULL;
  1585. unsigned n = 0;
  1586. cmChar_t* path = NULL;
  1587. unsigned i;
  1588. cmDspRC_t rc;
  1589. if(( rc = _cmDspRsrcArrayV(h,&n,&nodePtr,&path,vl)) != kOkDspRC )
  1590. return rc;
  1591. double* vp = *vpp;
  1592. vp = cmLhResizeN(p->ctx.lhH,double,vp,n);
  1593. for(i=0; i<n && rc == kOkDspRC; ++i)
  1594. if( cmJsonRealValue( cmJsonArrayElementC(nodePtr,i), vp + i ) != kOkJsRC )
  1595. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Element at index '%i' in resource '%s' is invalid.",i,cmStringNullGuard(path));
  1596. *vpp = vp;
  1597. *np = n;
  1598. return rc;
  1599. }
  1600. cmDspRC_t cmDspRsrcRealArrayV( cmDspSysH_t h, unsigned* np, cmReal_t** vpp, va_list vl )
  1601. {
  1602. assert(vpp!=NULL);
  1603. cmDsp_t* p = _cmDspHandleToPtr(h);
  1604. cmJsonNode_t* nodePtr = NULL;
  1605. unsigned n = 0;
  1606. cmChar_t* path = NULL;
  1607. unsigned i;
  1608. cmDspRC_t rc;
  1609. if(( rc = _cmDspRsrcArrayV(h,&n,&nodePtr,&path,vl)) != kOkDspRC )
  1610. return rc;
  1611. cmReal_t* vp = *vpp;
  1612. vp = cmLhResizeN(p->ctx.lhH,cmReal_t,vp,n);
  1613. for(i=0; i<n && rc == kOkDspRC; ++i)
  1614. {
  1615. double v;
  1616. if( cmJsonRealValue( cmJsonArrayElementC(nodePtr,i), &v ) != kOkJsRC )
  1617. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Element at index '%i' in resource '%s' is invalid.",i,cmStringNullGuard(path));
  1618. vp[i] = v;
  1619. }
  1620. *vpp = vp;
  1621. *np = n;
  1622. return rc;
  1623. }
  1624. cmDspRC_t cmDspRsrcStringArrayV(cmDspSysH_t h, unsigned* np, const cmChar_t*** vpp, va_list vl )
  1625. {
  1626. assert(vpp!=NULL);
  1627. cmDsp_t* p = _cmDspHandleToPtr(h);
  1628. cmJsonNode_t* nodePtr = NULL;
  1629. unsigned n = 0;
  1630. cmChar_t* path = NULL;
  1631. unsigned i;
  1632. cmDspRC_t rc;
  1633. if(( rc = _cmDspRsrcArrayV(h,&n,&nodePtr,&path,vl)) != kOkDspRC )
  1634. return rc;
  1635. const cmChar_t** vp = *vpp;
  1636. vp = cmLhResizeN(p->ctx.lhH,const cmChar_t*,vp,n);
  1637. for(i=0; i<n && rc == kOkDspRC; ++i)
  1638. if( cmJsonStringValue( cmJsonArrayElementC(nodePtr,i), vp + i ) != kOkJsRC )
  1639. rc = cmErrMsg(&p->err,kJsonFailDspRC,"Element at index '%i' in resource '%s' is invalid.",i,cmStringNullGuard(path));
  1640. *vpp = vp;
  1641. *np = n;
  1642. return rc;
  1643. }
  1644. cmDspRC_t cmDspRsrcInt( cmDspSysH_t h, int* vp, ... )
  1645. {
  1646. va_list vl;
  1647. va_start(vl,vp);
  1648. cmDspRC_t rc = cmDspRsrcIntV(h,vp,vl);
  1649. va_end(vl);
  1650. return rc;
  1651. }
  1652. cmDspRC_t cmDspRsrcUInt( cmDspSysH_t h, unsigned* vp, ... )
  1653. {
  1654. va_list vl;
  1655. va_start(vl,vp);
  1656. cmDspRC_t rc = cmDspRsrcUIntV(h,vp,vl);
  1657. va_end(vl);
  1658. return rc;
  1659. }
  1660. cmDspRC_t cmDspRsrcDbl( cmDspSysH_t h, double* vp, ... )
  1661. {
  1662. va_list vl;
  1663. va_start(vl,vp);
  1664. cmDspRC_t rc = cmDspRsrcDblV(h,vp,vl);
  1665. va_end(vl);
  1666. return rc;
  1667. }
  1668. cmDspRC_t cmDspRsrcReal( cmDspSysH_t h, cmReal_t* vp, ... )
  1669. {
  1670. va_list vl;
  1671. va_start(vl,vp);
  1672. cmDspRC_t rc = cmDspRsrcRealV(h,vp,vl);
  1673. va_end(vl);
  1674. return rc;
  1675. }
  1676. cmDspRC_t cmDspRsrcString( cmDspSysH_t h, const cmChar_t** vp, ... )
  1677. {
  1678. va_list vl;
  1679. va_start(vl,vp);
  1680. cmDspRC_t rc = cmDspRsrcStringV(h,vp,vl);
  1681. va_end(vl);
  1682. return rc;
  1683. }
  1684. cmDspRC_t cmDspRsrcArrayCount( cmDspSysH_t h, unsigned *np, ... )
  1685. {
  1686. va_list vl;
  1687. va_start(vl,np);
  1688. cmDspRC_t rc = cmDspRsrcArrayCountV(h,np,vl);
  1689. va_end(vl);
  1690. return rc;
  1691. }
  1692. cmDspRC_t cmDspRsrcBoolArray( cmDspSysH_t h, unsigned* np, bool** vpp, ... )
  1693. {
  1694. va_list vl;
  1695. va_start(vl,vpp);
  1696. cmDspRC_t rc = cmDspRsrcBoolArrayV(h,np,vpp,vl);
  1697. va_end(vl);
  1698. return rc;
  1699. }
  1700. cmDspRC_t cmDspRsrcIntArray( cmDspSysH_t h, unsigned* np, int** vpp, ... )
  1701. {
  1702. va_list vl;
  1703. va_start(vl,vpp);
  1704. cmDspRC_t rc = cmDspRsrcIntArrayV(h,np,vpp,vl);
  1705. va_end(vl);
  1706. return rc;
  1707. }
  1708. cmDspRC_t cmDspRsrcUIntArray( cmDspSysH_t h, unsigned* np, unsigned** vpp, ... )
  1709. {
  1710. va_list vl;
  1711. va_start(vl,vpp);
  1712. cmDspRC_t rc = cmDspRsrcUIntArrayV(h,np,vpp,vl);
  1713. va_end(vl);
  1714. return rc;
  1715. }
  1716. cmDspRC_t cmDspRsrcDblArray( cmDspSysH_t h, unsigned* np, double** vpp, ... )
  1717. {
  1718. va_list vl;
  1719. va_start(vl,vpp);
  1720. cmDspRC_t rc = cmDspRsrcDblArrayV(h,np,vpp,vl);
  1721. va_end(vl);
  1722. return rc;
  1723. }
  1724. cmDspRC_t cmDspRsrcRealArray( cmDspSysH_t h, unsigned* np, cmReal_t** vpp, ... )
  1725. {
  1726. va_list vl;
  1727. va_start(vl,vpp);
  1728. cmDspRC_t rc = cmDspRsrcRealArrayV(h,np,vpp,vl);
  1729. va_end(vl);
  1730. return rc;
  1731. }
  1732. cmDspRC_t cmDspRsrcStringArray( cmDspSysH_t h, unsigned* np, const cmChar_t*** vpp, ... )
  1733. {
  1734. va_list vl;
  1735. va_start(vl,vpp);
  1736. cmDspRC_t rc = cmDspRsrcStringArrayV(h,np,vpp,vl);
  1737. va_end(vl);
  1738. return rc;
  1739. }