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.

cmDspSys.c 78KB

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