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

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