libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmDspClass.c 44KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmFloatTypes.h"
  4. #include "cmRpt.h"
  5. #include "cmErr.h"
  6. #include "cmCtx.h"
  7. #include "cmMem.h"
  8. #include "cmMallocDebug.h"
  9. #include "cmLinkedHeap.h"
  10. #include "cmSymTbl.h"
  11. #include "cmPrefs.h"
  12. #include "cmJson.h"
  13. #include "cmDspValue.h"
  14. #include "cmMsgProtocol.h"
  15. #include "cmThread.h"
  16. #include "cmUdpPort.h"
  17. #include "cmUdpNet.h"
  18. #include "cmSerialPort.h"
  19. #include "cmTime.h"
  20. #include "cmAudioSys.h"
  21. #include "cmProcObj.h"
  22. #include "cmDspCtx.h"
  23. #include "cmDspClass.h"
  24. #include "cmDspSys.h"
  25. cmDspRC_t cmDspClassSetup(
  26. cmDspClass_t* classPtr,
  27. cmDspCtx_t* ctx,
  28. const cmChar_t* classLabel,
  29. cmDspClassFunc_t finalClassFunc,
  30. cmDspConsFunc_t allocFunc,
  31. cmDspFunc_t freeFunc,
  32. cmDspFunc_t resetFunc,
  33. cmDspFunc_t execFunc,
  34. cmDspFunc_t recvFunc,
  35. cmDspStoreFunc_t storeFunc,
  36. cmDspAttrSymFunc_t sysRecvFunc,
  37. const cmChar_t* doc )
  38. {
  39. classPtr->labelStr = classLabel;
  40. classPtr->doc = doc;
  41. classPtr->finalClassFunc = finalClassFunc;
  42. classPtr->allocFunc = allocFunc;
  43. classPtr->freeFunc = freeFunc;
  44. classPtr->resetFunc = resetFunc;
  45. classPtr->execFunc = execFunc;
  46. classPtr->recvFunc = recvFunc;
  47. classPtr->storeFunc = storeFunc;
  48. classPtr->sysRecvFunc = sysRecvFunc;
  49. cmErrSetup( &classPtr->err, ctx->rpt, classLabel);
  50. return kOkDspRC;
  51. }
  52. // default DSP instance system recv function
  53. cmDspRC_t _cmDspInstSysRecvFunc( cmDspCtx_t* ctx, struct cmDspInst_str* inst, unsigned attrSymId, const cmDspValue_t* value )
  54. {
  55. if( cmDsvIsSymbol(value) )
  56. {
  57. unsigned msgSymId = cmDsvSymbol(value);
  58. if( msgSymId == ctx->_disableSymId )
  59. {
  60. inst->flags = cmSetFlag(inst->flags,kDisableExecInstFl );
  61. //printf("%s disabled\n",cmStringNullGuard(cmDspInstLabel(ctx,inst)));
  62. }
  63. else
  64. {
  65. if( msgSymId == ctx->_enableSymId )
  66. {
  67. inst->flags = cmClrFlag(inst->flags,kDisableExecInstFl );
  68. //printf("%s enabled\n",cmStringNullGuard(cmDspInstLabel(ctx,inst)));
  69. }
  70. }
  71. }
  72. if( inst->classPtr->sysRecvFunc != NULL )
  73. return inst->classPtr->sysRecvFunc(ctx,inst,attrSymId,value);
  74. return kOkDspRC;
  75. }
  76. void* cmDspInstAllocate(
  77. cmDspCtx_t* ctx,
  78. cmDspClass_t* classPtr,
  79. const cmDspVarArg_t* argV,
  80. unsigned instByteCnt,
  81. unsigned instSymId,
  82. unsigned instId,
  83. unsigned storeSymId,
  84. unsigned va_cnt,
  85. va_list vl )
  86. {
  87. unsigned i;
  88. unsigned varCnt = 0;
  89. unsigned varDataByteCnt = 0;
  90. unsigned va_idx = 0;
  91. unsigned reqArgCnt = 0;
  92. // check for duplicate variable names
  93. for(i=0; argV[i].label != NULL; ++i)
  94. if( argV[i].label != NULL )
  95. {
  96. unsigned j = 0;
  97. for(j=0; argV[j].label != NULL; ++j)
  98. if( i != j && argV[j].label != NULL && strcmp(argV[i].label,argV[j].label) == 0 )
  99. {
  100. // two variables have the same name
  101. unsigned mask = kInDsvFl | kOutDsvFl;
  102. // we allow two variables to have the same name as long as they are not both inputs or outputs
  103. if( (argV[j].flags & mask) == (argV[i].flags & mask))
  104. cmDspClassErr(ctx,classPtr,kVarDuplicateDspRC,"The variable label '%s' is used by multiple variables.",argV[i].label);
  105. }
  106. }
  107. // determine the count and size of the instance variables
  108. for(i=0; argV[i].label != NULL; ++i,++varCnt)
  109. {
  110. unsigned rn = argV[i].rn;
  111. unsigned flags = argV[i].flags;
  112. // audio buffer sample count is determined automatically
  113. if( cmAllFlags( argV[i].flags, kAudioBufDsvFl | kOutDsvFl ) )
  114. {
  115. rn = ctx->ctx->ss->args.dspFramesPerCycle;
  116. flags = kSampleDsvFl | kMtxDsvFl;
  117. }
  118. // determine the space needed for matrices of known size
  119. if( cmIsFlag(flags,kMtxDsvFl) && (rn*argV[i].cn)>0 )
  120. {
  121. unsigned n = cmDsvByteCount( flags, rn, argV[i].cn );
  122. varDataByteCnt += n;
  123. }
  124. // determine the number of required arguments
  125. reqArgCnt += cmIsFlag(flags,kReqArgDsvFl) ? 1 : 0;
  126. }
  127. unsigned varRecdByteCnt = varCnt * sizeof(cmDspVar_t);
  128. unsigned ttlByteCnt = instByteCnt + varRecdByteCnt + varDataByteCnt;
  129. char* p = cmLHeapAllocZ(ctx->lhH, ttlByteCnt); // allocate the instance memory
  130. char* ep = p + ttlByteCnt; // record the end of the alloc'd memory
  131. cmDspInst_t* ip = (cmDspInst_t*)p; // set the instance ptr
  132. cmDspVar_t* varArray = (cmDspVar_t*)(p + instByteCnt); // set the instance variable recd array
  133. char* varDataPtr = (char*)(varArray + varCnt); // set the base of variable data buffer
  134. // setup the instance record
  135. ip->classPtr = classPtr;
  136. ip->symId = instSymId;
  137. ip->id = instId;
  138. ip->flags = kDisableExecInstFl;
  139. ip->presetGroupSymId = storeSymId;
  140. ip->varArray = varArray;
  141. ip->varCnt = varCnt;
  142. ip->freeFunc = classPtr->freeFunc;
  143. ip->resetFunc = classPtr->resetFunc;
  144. ip->execFunc = classPtr->execFunc;
  145. ip->recvFunc = classPtr->recvFunc;
  146. ip->storeFunc = classPtr->storeFunc;
  147. ip->sysRecvFunc = _cmDspInstSysRecvFunc;
  148. if( reqArgCnt > va_cnt )
  149. cmDspInstErr(ctx,ip,kVarArgParseFailDspRC,"The class requires %i arguments but only %i were given.",reqArgCnt,va_cnt);
  150. // setup the variable records
  151. for(i=0; i<varCnt; ++i)
  152. {
  153. unsigned flags = argV[i].flags;
  154. unsigned rn = argV[i].rn;
  155. // handle requests for audio output buffers
  156. if( cmAllFlags(argV[i].flags, kAudioBufDsvFl | kOutDsvFl ) )
  157. {
  158. // remove the audio buffer flag and reconstitute as a generic cmDspValue sample mtx type.
  159. //flags = cmClrFlag( argV[i].flags, kAudioBufDsvFl | kTypeDsvMask );
  160. flags = kSampleDsvFl | kMtxDsvFl;
  161. rn = ctx->ctx->ss->args.dspFramesPerCycle;
  162. }
  163. // the constId must be the same as the var index
  164. assert( i == argV[i].constId );
  165. bool reqArgFl = cmIsFlag(argV[i].flags,kReqArgDsvFl);
  166. bool optArgFl = cmIsFlag(argV[i].flags,kOptArgDsvFl);
  167. // verify that the required arg. exists
  168. if( reqArgFl && i>va_cnt )
  169. cmDspInstErr(ctx,ip,kVarArgParseFailDspRC,"The required argument '%s' is missing",argV[i].label);
  170. ip->varArray[i].flags = argV[i].flags; // store the original flag set as the var flags
  171. ip->varArray[i].constId = argV[i].constId;
  172. ip->varArray[i].symId = cmSymTblRegisterSymbol(ctx->stH,argV[i].label);
  173. ip->varArray[i].doc = argV[i].doc;
  174. ip->varArray[i].value.flags = argV[i].flags & kTypeDsvMask;
  175. // if this is a required or optional constructor arg. then assign it as the
  176. // default value for this variable
  177. if( va_idx < va_cnt && (reqArgFl || optArgFl) )
  178. {
  179. cmDspValue_t* vp = &ip->varArray[i].value;
  180. switch(ip->varArray[i].value.flags)
  181. {
  182. case kBoolDsvFl: cmDsvSetBool( vp, va_arg(vl,int )); break;
  183. case kCharDsvFl: cmDsvSetChar( vp, va_arg(vl,int )); break;
  184. case kUCharDsvFl: cmDsvSetUChar( vp, va_arg(vl,int )); break;
  185. case kShortDsvFl: cmDsvSetShort( vp, va_arg(vl,int )); break;
  186. case kUShortDsvFl: cmDsvSetUShort( vp, va_arg(vl,int )); break;
  187. case kLongDsvFl: cmDsvSetLong( vp, va_arg(vl,long )); break;
  188. case kULongDsvFl: cmDsvSetULong( vp, va_arg(vl,unsigned long )); break;
  189. case kIntDsvFl: cmDsvSetInt( vp, va_arg(vl,int )); break;
  190. case kUIntDsvFl: cmDsvSetUInt( vp, va_arg(vl,unsigned )); break;
  191. case kFloatDsvFl: cmDsvSetFloat( vp, va_arg(vl,double )); break;
  192. case kDoubleDsvFl: cmDsvSetDouble( vp, va_arg(vl,double )); break;
  193. case kSampleDsvFl: cmDsvSetSample( vp, va_arg(vl,double )); break;
  194. case kRealDsvFl: cmDsvSetReal( vp, va_arg(vl,double )); break;
  195. case kStrzDsvFl: cmDsvSetStrz( vp, va_arg(vl,cmChar_t* )); break;
  196. case kSymDsvFl: cmDsvSetSymbol( vp, va_arg(vl,unsigned )); break;
  197. default:
  198. cmDspInstErr(ctx,ip,kVarArgParseFailDspRC,"A var-args parse error occurred while parsing the variable '%s'.",argV[i].label);
  199. }
  200. // set the default value from the initial value
  201. cmDspValueSet(ctx, ip, i, vp, kSetDefaultDspFl );
  202. // store the fact that the default value was explicitely set.
  203. ip->varArray[i].flags = cmSetFlag(ip->varArray[i].flags,kDfltSetDsvFl);
  204. // track the number of va_list arg's read
  205. ++va_idx;
  206. }
  207. // assign memory to the matrix types of known size
  208. if( cmIsFlag(flags,kMtxDsvFl) && (rn*argV[i].cn)>0 )
  209. {
  210. cmDsvSetMtx( &ip->varArray[i].value, flags, varDataPtr, rn, argV[i].cn );
  211. unsigned n = cmDsvByteCount( flags, rn, argV[i].cn );
  212. varDataPtr += n;
  213. }
  214. }
  215. assert( varDataPtr == ep );
  216. return p;
  217. }
  218. #ifdef OSX_VER_10_5
  219. va_list _cmDspParseArgV( cmDspVarArg_t* a, va_list vl )
  220. #else
  221. void _cmDspParseArgV( cmDspVarArg_t* a, va_list vl )
  222. #endif
  223. {
  224. a->label = va_arg(vl,const char*);
  225. a->constId = va_arg(vl,unsigned);
  226. a->rn = va_arg(vl,unsigned);
  227. a->cn = va_arg(vl,unsigned);
  228. a->flags = va_arg(vl,unsigned);
  229. a->doc = va_arg(vl,const char*);
  230. #ifdef OSX_VER_10_5
  231. return vl;
  232. #endif
  233. }
  234. void* cmDspInstAllocateV(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned instByteCnt, unsigned instSymId, unsigned instId, unsigned storeSymId, unsigned va_cnt, va_list vl0, ... )
  235. {
  236. va_list vl1,vl2;
  237. va_start(vl1,vl0);
  238. va_copy(vl2,vl1);
  239. unsigned argCnt = 0;
  240. int repeatCnt;
  241. while( (repeatCnt = va_arg(vl1,int)) != 0 )
  242. {
  243. cmDspVarArg_t a;
  244. // do some value checking to possibly catch problems with the var_args format
  245. assert( repeatCnt > 0 && repeatCnt < 255 );
  246. argCnt += repeatCnt;
  247. #ifdef OSX_VER_10_5
  248. vl1 =
  249. #endif
  250. _cmDspParseArgV(&a,vl1);
  251. }
  252. va_end(vl1);
  253. cmDspVarArg_t aa[ argCnt+1 ];
  254. unsigned j=0;
  255. while( (repeatCnt = va_arg(vl2,int)) != 0 )
  256. {
  257. cmDspVarArg_t a;
  258. #ifdef OSX_VER_10_5
  259. vl2 =
  260. #endif
  261. _cmDspParseArgV(&a,vl2);
  262. cmDspArgSetupN(ctx,aa,argCnt,j,repeatCnt,a.label,a.constId,a.rn, a.cn, a.flags, a.doc );
  263. j += repeatCnt;
  264. }
  265. cmDspArgSetupNull(aa + argCnt);
  266. va_end(vl2);
  267. return cmDspInstAllocate(ctx,classPtr,aa,instByteCnt,instSymId,instId,storeSymId,va_cnt,vl0);
  268. }
  269. cmDspInstSymId_t* _cmDspInstFindAttrSymId( cmDspInst_t* inst, unsigned symId )
  270. {
  271. cmDspInstSymId_t* ip = inst->symIdList;
  272. for(; ip != NULL; ip=ip->link)
  273. if( ip->symId == symId )
  274. return ip;
  275. return NULL;
  276. }
  277. bool cmDspInstHasAttrSym( cmDspInst_t* inst, unsigned attrSymId )
  278. { return _cmDspInstFindAttrSymId(inst,attrSymId) != NULL; }
  279. cmDspRC_t cmDspInstRegisterAttrSym( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned symId )
  280. {
  281. cmDspInstSymId_t* ip;
  282. // if this symbol is already registered
  283. if((ip = _cmDspInstFindAttrSymId(inst,symId)) != NULL )
  284. return cmDspInstErr(ctx,inst,kOkDspRC,"The symbol '%s' is already registered with the instance.",cmStringNullGuard(cmSymTblLabel(ctx->stH,symId)));
  285. // try to find an unused symbol
  286. ip = inst->symIdList;
  287. for(; ip != NULL; ip=ip->link)
  288. if( ip->symId == cmInvalidId )
  289. break;
  290. // if no unused symbols were found then allocate a new one
  291. if( ip == NULL )
  292. {
  293. ip = cmLhAllocZ(ctx->lhH, cmDspInstSymId_t, 1 );
  294. ip->link = inst->symIdList;
  295. inst->symIdList = ip;
  296. }
  297. ip->symId = symId;
  298. return kOkDspRC;
  299. }
  300. cmDspRC_t cmDspInstRemoveAttrSym( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned symId )
  301. {
  302. cmDspInstSymId_t* ip;
  303. // if this symbol is already registered
  304. if((ip = _cmDspInstFindAttrSymId(inst,symId)) == NULL )
  305. return cmDspInstErr(ctx,inst,kOkDspRC,"The symbol '%s' is could not be found to be removed from the instance.",cmStringNullGuard(cmSymTblLabel(ctx->stH,symId)));
  306. // mark a symbol recd as inactive by setting the symbol id to cmInalidId
  307. ip->symId = cmInvalidId;
  308. return kOkDspRC;
  309. }
  310. cmDspRC_t _cmDspClassErrV( cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned instId, const cmChar_t* instLbl, cmDspRC_t rc, const cmChar_t* fmt, va_list vl )
  311. {
  312. va_list vl2;
  313. va_copy(vl2,vl);
  314. unsigned n = vsnprintf(NULL,0,fmt,vl2)+1;
  315. cmChar_t buf[n+1];
  316. vsnprintf(buf,n,fmt,vl);
  317. if( instId == cmInvalidId )
  318. cmErrMsg( &classPtr->err, rc, "%s DSP Class:%s",buf, classPtr->labelStr);
  319. else
  320. cmErrMsg( &classPtr->err, rc, "%s DSP Class:%s Inst:%i %s",buf, classPtr->labelStr,instId,instLbl==NULL?"":instLbl);
  321. va_end(vl2);
  322. return rc;
  323. }
  324. cmDspRC_t cmDspClassErr( cmDspCtx_t* ctx, cmDspClass_t* classPtr, cmDspRC_t rc, const cmChar_t* fmt, ... )
  325. {
  326. va_list vl;
  327. va_start(vl,fmt);
  328. rc = _cmDspClassErrV(ctx,classPtr,cmInvalidId,NULL,rc,fmt,vl);
  329. va_end(vl);
  330. return rc;
  331. }
  332. cmDspRC_t cmDspInstErr( cmDspCtx_t* ctx, cmDspInst_t* inst, cmDspRC_t rc, const cmChar_t* fmt, ... )
  333. {
  334. va_list vl;
  335. va_start(vl,fmt);
  336. rc = _cmDspClassErrV(ctx,inst->classPtr,inst->id,cmSymTblLabel(ctx->stH,inst->symId),rc,fmt,vl);
  337. va_end(vl);
  338. return rc;
  339. }
  340. void cmDspArgSetup(
  341. cmDspCtx_t* ctx,
  342. cmDspVarArg_t* arg,
  343. const cmChar_t* labelPrefix,
  344. unsigned labelId,
  345. unsigned constId,
  346. unsigned rn,
  347. unsigned cn,
  348. unsigned flags,
  349. const cmChar_t* docStr )
  350. {
  351. unsigned labelIdCharCnt = (unsigned)floor( labelId==0 ? 1.0 : log10(abs(labelId)) + 1.0 );
  352. int labelCharCnt = strlen(labelPrefix) + 1 + labelIdCharCnt + 1;
  353. cmChar_t label[ labelCharCnt + 1 ];
  354. const cmChar_t* lp;
  355. if( labelId == cmInvalidId )
  356. lp = labelPrefix;
  357. else
  358. {
  359. lp = label;
  360. label[labelCharCnt] = 0;
  361. snprintf(label,labelCharCnt,"%s-%i",labelPrefix,labelId);
  362. }
  363. // use the symbol table to hold the label string
  364. arg->label = cmSymTblLabel(ctx->stH,cmSymTblRegisterSymbol(ctx->stH,lp));
  365. arg->constId = constId;
  366. arg->rn = rn;
  367. arg->cn = cn;
  368. arg->flags = flags;
  369. arg->doc = cmLhAllocStr(ctx->lhH,docStr);;
  370. }
  371. unsigned cmDspArgCopy( cmDspVarArg_t* argArray, unsigned argN, unsigned dstIdx, const cmDspVarArg_t* s, unsigned sn )
  372. {
  373. assert( dstIdx + sn <= argN );
  374. unsigned i;
  375. for(i=0; i<sn; ++i)
  376. argArray[dstIdx+i] = s[i];
  377. return dstIdx + i;
  378. }
  379. unsigned cmDspArgSetupN(
  380. cmDspCtx_t* ctx,
  381. cmDspVarArg_t* arg,
  382. unsigned argN,
  383. unsigned dstIdx,
  384. unsigned cnt,
  385. const cmChar_t* labelPrefix,
  386. unsigned baseConstId,
  387. unsigned rn,
  388. unsigned cn,
  389. unsigned flags,
  390. const cmChar_t* staticDocStr )
  391. {
  392. assert( dstIdx + cnt <= argN );
  393. unsigned i;
  394. for(i=0; i<cnt; ++i)
  395. cmDspArgSetup(ctx,arg + dstIdx + i,labelPrefix, cnt==1 ? cmInvalidId : i, baseConstId + i, rn, cn, flags, staticDocStr );
  396. return dstIdx + i;
  397. }
  398. void cmDspArgSetupNull( cmDspVarArg_t* arg )
  399. { memset(arg,0,sizeof(*arg)); }
  400. const cmChar_t* cmDspInstLabel( cmDspCtx_t* ctx, cmDspInst_t* inst )
  401. {
  402. const char* noInstLbl = "<no_inst_lbl>";
  403. const char* lbl = noInstLbl;
  404. if( inst->symId == cmInvalidId )
  405. return lbl;
  406. if((lbl = cmSymTblLabel(ctx->stH,inst->symId)) == NULL )
  407. lbl = noInstLbl;
  408. return lbl;
  409. }
  410. cmDspRC_t _cmDspVarPtr( const cmDspInst_t* inst, unsigned varId, cmDspVar_t** retVarPtrPtr )
  411. {
  412. if( varId >= inst->varCnt )
  413. {
  414. *retVarPtrPtr = NULL;
  415. return cmErrMsg(&inst->classPtr->err,kVarNotFoundDspRC,"The variable id %i is invalid for DSP instance '%s' (id:%i) .", varId, inst->classPtr->labelStr, inst->id );
  416. }
  417. assert( inst->varArray[varId].constId == varId );
  418. *retVarPtrPtr = inst->varArray + varId;
  419. return kOkDspRC;
  420. }
  421. cmDspRC_t _cmDspVarAndValuePtr( cmDspInst_t* inst, unsigned varId, cmDspVar_t** varPtrPtr, cmDspValue_t** valPtrPtr )
  422. {
  423. cmDspRC_t rc;
  424. if((rc = _cmDspVarPtr(inst,varId,varPtrPtr)) != kOkDspRC )
  425. *valPtrPtr = NULL;
  426. else
  427. *valPtrPtr = cmDsvValuePtr(&(*varPtrPtr)->value);
  428. return rc;
  429. }
  430. cmDspRC_t _cmDspVarValuePtr( cmDspInst_t* inst, unsigned varId, cmDspValue_t** retValPtrPtr )
  431. {
  432. cmDspVar_t* varPtr = NULL;
  433. cmDspRC_t rc;
  434. if((rc = _cmDspVarPtr(inst,varId,&varPtr)) != kOkDspRC )
  435. *retValPtrPtr = NULL;
  436. else
  437. *retValPtrPtr = cmDsvValuePtr(&varPtr->value);
  438. return rc;
  439. }
  440. cmDspRC_t _cmDspVarDefaultPtr( cmDspInst_t* inst, unsigned varId, cmDspValue_t** retValPtrPtr )
  441. {
  442. cmDspVar_t* varPtr = NULL;
  443. cmDspRC_t rc;
  444. if((rc = _cmDspVarPtr(inst,varId,&varPtr)) != kOkDspRC )
  445. *retValPtrPtr = NULL;
  446. else
  447. *retValPtrPtr = &varPtr->dflt;
  448. return rc;
  449. }
  450. void _cmDspSendEvt( cmDspCtx_t* ctx, cmDspInst_t* srcInstPtr, unsigned srcVarId, const cmDspVar_t* varPtr )
  451. {
  452. cmDspEvt_t e;
  453. cmDspCb_t* cbp = varPtr->cbList;
  454. if( cbp == NULL )
  455. return;
  456. e.flags = kDfltEvtDspFlags;
  457. e.srcInstPtr = srcInstPtr;
  458. e.srcVarId = srcVarId;
  459. e.valuePtr = &varPtr->value;
  460. for(; cbp!=NULL; cbp=cbp->linkPtr)
  461. {
  462. e.dstVarId = cbp->dstVarId;
  463. e.dstDataPtr = cbp->dstDataPtr;
  464. if( cbp->dstInstPtr->recvFunc!=NULL)
  465. cbp->dstInstPtr->recvFunc(ctx,cbp->dstInstPtr,&e);
  466. }
  467. }
  468. cmDspVar_t* cmDspVarSymbolToPtr( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varSymId, unsigned flags )
  469. {
  470. unsigned i;
  471. for(i=0; i<inst->varCnt; ++i)
  472. if( inst->varArray[i].symId == varSymId )
  473. {
  474. if( flags==0 || cmAllFlags(inst->varArray[i].flags,flags) )
  475. return inst->varArray + i;
  476. }
  477. cmDspInstErr(ctx,inst,kVarNotFoundDspRC,"The variable '%s' could not be found in the instance '%s' (id:%i).",
  478. cmSymTblLabel( ctx->stH, varSymId), inst->classPtr->labelStr, inst->id );
  479. return NULL;
  480. }
  481. const cmDspVar_t* cmDspVarIdToCPtr( const cmDspInst_t* inst, unsigned varId )
  482. {
  483. cmDspVar_t* varPtr;
  484. if( _cmDspVarPtr(inst, varId, &varPtr) != kOkDspRC )
  485. return NULL;
  486. return varPtr;
  487. }
  488. cmDspVar_t* cmDspVarIdToPtr( cmDspInst_t* inst, unsigned varId )
  489. {
  490. cmDspVar_t* varPtr;
  491. if( _cmDspVarPtr(inst, varId, &varPtr) != kOkDspRC )
  492. return NULL;
  493. return varPtr;
  494. }
  495. const cmChar_t* cmDspVarLabel( cmDspCtx_t* ctx, const cmDspInst_t* inst, unsigned varId )
  496. {
  497. const cmDspVar_t* varPtr;
  498. if(( varPtr = cmDspVarIdToCPtr(inst,varId) ) == NULL )
  499. return NULL;
  500. return cmSymTblLabel( ctx->stH, varPtr->symId);
  501. }
  502. cmDspRC_t cmDspOutputEvent( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId )
  503. {
  504. cmDspRC_t rc;
  505. cmDspVar_t* varPtr;
  506. if((rc = _cmDspVarPtr(inst, varId, &varPtr )) != kOkDspRC )
  507. return rc;
  508. _cmDspSendEvt(ctx, inst, varId, varPtr );
  509. return rc;
  510. }
  511. cmDspRC_t cmDspVarPresetWrite( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId )
  512. {
  513. cmDspRC_t rc;
  514. const cmDspVar_t* varPtr;
  515. if((varPtr = cmDspVarIdToCPtr(inst,varId)) == NULL )
  516. return cmDspInstErr(ctx,inst,kVarNotFoundDspRC,"Var with id %i not found during preset store.");
  517. if((rc = cmDspSysPresetWriteValue(ctx->dspH, varPtr->symId, &varPtr->value )) != kOkDspRC )
  518. return cmDspInstErr(ctx,inst,kSubSysFailDspRC,"Var preset storage failed on var:'%s'.",cmStringNullGuard(cmSymTblLabel(ctx->stH,varPtr->symId)));
  519. return rc;
  520. }
  521. cmDspRC_t cmDspVarPresetRead( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId )
  522. {
  523. cmDspRC_t rc;
  524. cmDspVar_t* varPtr;
  525. cmDspValue_t value;
  526. if((varPtr = cmDspVarIdToPtr(inst,varId)) == NULL )
  527. return cmDspInstErr(ctx,inst,kVarNotFoundDspRC,"Var with id %i not found during preset recall.");
  528. if((rc = cmDspSysPresetReadValue(ctx->dspH, varPtr->symId, &value )) != kOkDspRC )
  529. return cmDspInstErr(ctx,inst,kSubSysFailDspRC,"Var preset recall failed on var:'%s'.",cmStringNullGuard(cmSymTblLabel(ctx->stH,varPtr->symId)));
  530. return cmDspValueSet(ctx,inst,varId,&value,0);
  531. }
  532. cmDspRC_t cmDspVarPresetRdWr( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, bool storeFl )
  533. {
  534. cmDspRC_t rc;
  535. if( storeFl )
  536. rc = cmDspVarPresetWrite(ctx,inst,varId);
  537. else
  538. rc = cmDspVarPresetRead(ctx,inst,varId);
  539. return rc;
  540. }
  541. double cmDspSampleRate( cmDspCtx_t* ctx )
  542. { return ctx->ctx->ss->args.srate; }
  543. unsigned cmDspSamplesPerCycle( cmDspCtx_t * ctx )
  544. { return ctx->ctx->ss->args.dspFramesPerCycle; }
  545. unsigned cmDspTypeFlags(const cmDspInst_t* inst, unsigned varId )
  546. {
  547. cmDspVar_t* varPtr;
  548. unsigned flags;
  549. if( _cmDspVarPtr(inst,varId,&varPtr) != kOkDspRC )
  550. return 0;
  551. cmDspValue_t* valPtr = cmDsvValuePtr(&varPtr->value);
  552. if( valPtr->flags != 0 )
  553. flags = valPtr->flags;
  554. else
  555. flags = varPtr->flags;
  556. return flags & kTypeDsvMask;
  557. }
  558. bool cmDspIsBool( const cmDspInst_t* inst, unsigned varId )
  559. { return cmIsFlag(cmDspTypeFlags(inst,varId),kBoolDsvFl); }
  560. bool cmDspIsInt( const cmDspInst_t* inst, unsigned varId )
  561. { return cmIsFlag(cmDspTypeFlags(inst,varId),kIntDsvFl); }
  562. bool cmDspIsUInt( const cmDspInst_t* inst, unsigned varId )
  563. { return cmIsFlag(cmDspTypeFlags(inst,varId),kUIntDsvFl); }
  564. bool cmDspIsDouble( const cmDspInst_t* inst, unsigned varId )
  565. { return cmIsFlag(cmDspTypeFlags(inst,varId),kDoubleDsvFl); }
  566. bool cmDspIsStrz( const cmDspInst_t* inst, unsigned varId )
  567. { return cmIsFlag(cmDspTypeFlags(inst,varId),kStrzDsvFl); }
  568. bool cmDspIsSymbol( const cmDspInst_t* inst, unsigned varId )
  569. { return cmIsFlag(cmDspTypeFlags(inst,varId),kSymDsvFl); }
  570. bool cmDspIsJson( const cmDspInst_t* inst, unsigned varId )
  571. { return cmIsFlag(cmDspTypeFlags(inst,varId),kJsonDsvFl); }
  572. bool cmDspBool( cmDspInst_t* inst, unsigned varId )
  573. {
  574. cmDspValue_t* vp;
  575. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  576. return 0;
  577. return cmDsvGetBool(vp);
  578. }
  579. int cmDspInt( cmDspInst_t* inst, unsigned varId )
  580. {
  581. cmDspValue_t* vp;
  582. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  583. return 0;
  584. return cmDsvGetInt(vp);
  585. }
  586. unsigned cmDspUInt( cmDspInst_t* inst, unsigned varId )
  587. {
  588. cmDspValue_t* vp;
  589. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  590. return 0;
  591. return cmDsvGetUInt(vp);
  592. }
  593. double cmDspDouble( cmDspInst_t* inst, unsigned varId )
  594. {
  595. cmDspValue_t* vp;
  596. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  597. return 0;
  598. return cmDsvGetDouble(vp);
  599. }
  600. cmSample_t cmDspSample( cmDspInst_t* inst, unsigned varId )
  601. {
  602. cmDspValue_t* vp;
  603. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  604. return 0;
  605. return cmDsvGetSample(vp);
  606. }
  607. cmReal_t cmDspReal( cmDspInst_t* inst, unsigned varId )
  608. {
  609. cmDspValue_t* vp;
  610. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  611. return 0;
  612. return cmDsvGetReal(vp);
  613. }
  614. void* cmDspPtr( cmDspInst_t* inst, unsigned varId )
  615. {
  616. cmDspValue_t* vp;
  617. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  618. return NULL;
  619. return cmDsvPtr(vp);
  620. }
  621. const cmChar_t* cmDspStrcz( cmDspInst_t* inst, unsigned varId )
  622. {
  623. cmDspValue_t* vp;
  624. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  625. return NULL;
  626. return cmDsvStrcz(vp);
  627. }
  628. unsigned cmDspSymbol( cmDspInst_t* inst, unsigned varId )
  629. {
  630. cmDspValue_t* vp;
  631. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  632. return cmInvalidId;
  633. return cmDsvSymbol(vp);
  634. }
  635. cmJsonNode_t* cmDspJson( cmDspInst_t* inst, unsigned varId )
  636. {
  637. cmDspValue_t* vp;
  638. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  639. return NULL;
  640. return cmDsvJson(vp);
  641. }
  642. bool cmDspDefaultBool( cmDspInst_t* inst, unsigned varId )
  643. {
  644. cmDspValue_t* vp;
  645. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  646. return 0;
  647. return cmDsvGetBool(vp);
  648. }
  649. int cmDspDefaultInt( cmDspInst_t* inst, unsigned varId )
  650. {
  651. cmDspValue_t* vp;
  652. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  653. return 0;
  654. return cmDsvGetInt(vp);
  655. }
  656. unsigned cmDspDefaultUInt( cmDspInst_t* inst, unsigned varId )
  657. {
  658. cmDspValue_t* vp;
  659. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  660. return 0;
  661. return cmDsvGetUInt(vp);
  662. }
  663. double cmDspDefaultDouble( cmDspInst_t* inst, unsigned varId )
  664. {
  665. cmDspValue_t* vp;
  666. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  667. return 0;
  668. return cmDsvGetDouble(vp);
  669. }
  670. cmSample_t cmDspDefaultSample( cmDspInst_t* inst, unsigned varId )
  671. {
  672. cmDspValue_t* vp;
  673. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  674. return 0;
  675. return cmDsvGetSample(vp);
  676. }
  677. cmReal_t cmDspDefaultReal( cmDspInst_t* inst, unsigned varId )
  678. {
  679. cmDspValue_t* vp;
  680. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  681. return 0;
  682. return cmDsvGetReal(vp);
  683. }
  684. const cmChar_t* cmDspDefaultStrcz( cmDspInst_t* inst, unsigned varId )
  685. {
  686. cmDspValue_t* vp;
  687. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  688. return NULL;
  689. return cmDsvGetStrcz(vp);
  690. }
  691. unsigned cmDspDefaultSymbol( cmDspInst_t* inst, unsigned varId )
  692. {
  693. cmDspValue_t* vp;
  694. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  695. return cmInvalidId;
  696. return cmDsvGetSymbol(vp);
  697. }
  698. cmJsonNode_t* cmDspDefaultJson( cmDspInst_t* inst, unsigned varId )
  699. {
  700. cmDspValue_t* vp;
  701. if(_cmDspVarDefaultPtr(inst,varId,&vp) != kOkDspRC )
  702. return NULL;
  703. return cmDsvGetJson(vp);
  704. }
  705. cmDspRC_t cmDspValueSet( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, const cmDspValue_t* svp, unsigned flags )
  706. {
  707. cmDspRC_t rc;
  708. cmDspVar_t* varPtr;
  709. // get a pointer to the var recd
  710. if((rc = _cmDspVarPtr(inst,varId,&varPtr)) != kOkDspRC )
  711. return rc;
  712. // get a pointer to the target value.
  713. cmDspValue_t* dvp = cmIsFlag(flags,kSetDefaultDspFl) ? &varPtr->dflt : cmDsvValuePtr(&varPtr->value);
  714. // store a pointer to the dst string memory in case we need to delete it later
  715. cmChar_t* rlsPtr = cmAllFlags(dvp->flags,kStrzDsvFl | kDynDsvFl) ? dvp->u.z : NULL;
  716. // set the dest type to the type shared with the source
  717. // ( this assumes that the dst may have multiple types but the source has one type)
  718. unsigned typeFlags = (varPtr->flags & svp->flags) & kTypeDsvMask;
  719. // if svp->flags is set to kNullDsvFl then use just the dst type
  720. if( typeFlags == 0 )
  721. typeFlags = varPtr->flags & kTypeDsvMask;
  722. // convert the source to the var type
  723. switch(typeFlags)
  724. {
  725. case kBoolDsvFl:
  726. cmDsvSetBool( dvp, cmDsvGetBool(svp));
  727. break;
  728. case kIntDsvFl:
  729. cmDsvSetInt( dvp, cmDsvGetInt(svp));
  730. break;
  731. case kUIntDsvFl:
  732. cmDsvSetUInt( dvp, cmDsvGetUInt(svp));
  733. break;
  734. case kDoubleDsvFl:
  735. cmDsvSetDouble(dvp, cmDsvGetDouble(svp));
  736. break;
  737. case kSampleDsvFl:
  738. cmDsvSetSample(dvp, cmDsvGetSample(svp));
  739. break;
  740. case kRealDsvFl:
  741. cmDsvSetReal(dvp, cmDsvGetReal(svp));
  742. break;
  743. case kPtrDsvFl:
  744. cmDsvSetPtr(dvp, cmDsvGetPtr(svp));
  745. break;
  746. case kSymDsvFl:
  747. cmDsvSetSymbol(dvp, cmDsvGetSymbol(svp));
  748. break;
  749. case kJsonDsvFl:
  750. cmDsvSetJson( dvp, cmDsvJson(svp));
  751. break;
  752. case kStrzDsvFl:
  753. {
  754. const cmChar_t* sp;
  755. if( cmDsvIsSymbol(svp) )
  756. sp = cmSymTblLabel(ctx->stH,cmDsvSymbol(svp));
  757. else
  758. sp = cmDsvGetStrcz(svp);
  759. // don't copy over myself
  760. if( sp == dvp->u.z )
  761. rlsPtr = NULL;
  762. else
  763. {
  764. // if the source == NULL then set the dst to NULL
  765. // (NULL should always be a legitimate value)
  766. if( sp == NULL )
  767. cmDsvSetStrcz(dvp,sp);
  768. else
  769. {
  770. // if the source should not be copied into internal memory
  771. if( cmIsFlag(flags,kNoAllocDspFl) )
  772. cmDsvSetStrcz(dvp,sp);
  773. else
  774. {
  775. // allocate memory to hold the new string
  776. unsigned n = strlen(sp)+1;
  777. cmChar_t* dp = cmLhResizeN(ctx->lhH,cmChar_t,rlsPtr,n);
  778. strncpy(dp,sp,n);
  779. cmDsvSetStrz(dvp, dp);
  780. dvp->flags = cmSetFlag(dvp->flags,kDynDsvFl);
  781. rlsPtr = NULL;
  782. }
  783. }
  784. }
  785. }
  786. break;
  787. default:
  788. { assert(0); }
  789. }
  790. // if the dst contained a dynamically alloc'd string prior to being
  791. // set with a new value - then release the memory used by the original
  792. // string here
  793. if( rlsPtr != NULL )
  794. cmLHeapFree(ctx->lhH,rlsPtr);
  795. // notify listeners of the change of value
  796. if( cmIsFlag(flags,kNoSendDspFl) == false )
  797. _cmDspSendEvt( ctx, inst, varId, varPtr );
  798. // notify the UI of the change of value
  799. if( cmIsFlag(varPtr->flags,kUiDsvFl) && cmIsFlag(flags,kNoUpdateUiDspFl)==false )
  800. {
  801. cmDspUiSendVar( ctx, inst, varPtr );
  802. }
  803. return rc;
  804. }
  805. cmDspRC_t cmDspApplyDefault( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId )
  806. {
  807. cmDspRC_t rc;
  808. cmDspVar_t* varPtr;
  809. // get a pointer to the var recd
  810. if((rc = _cmDspVarPtr(inst,varId,&varPtr)) != kOkDspRC )
  811. return rc;
  812. if( cmIsFlag(varPtr->flags,kDfltSetDsvFl) )
  813. {
  814. // unless the var has kSendDfltDsvFl set we don't transmit the default values
  815. unsigned flags = cmIsFlag(varPtr->flags,kSendDfltDsvFl) ? 0 : kNoSendDspFl;
  816. return cmDspValueSet(ctx, inst, varId, &varPtr->dflt, flags );
  817. }
  818. return kOkDspRC;
  819. }
  820. cmDspRC_t cmDspApplyAllDefaults( cmDspCtx_t* ctx, cmDspInst_t* inst )
  821. {
  822. cmDspRC_t rc = kOkDspRC;
  823. unsigned i;
  824. for(i=0; i<inst->varCnt; ++i)
  825. if((rc = cmDspApplyDefault(ctx,inst,inst->varArray[i].constId)) != kOkDspRC )
  826. return rc;
  827. return rc;
  828. }
  829. cmDspRC_t cmDspSetDefault( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, const cmDspValue_t* valPtr )
  830. {
  831. cmDspRC_t rc;
  832. cmDspVar_t* varPtr;
  833. // get a pointer to the var recd
  834. if((rc = _cmDspVarPtr(inst,varId,&varPtr)) != kOkDspRC )
  835. return rc;
  836. if(( cmDspValueSet( ctx, inst, varId, valPtr, kSetDefaultDspFl )) == kOkDspRC )
  837. {
  838. varPtr->flags = cmSetFlag(varPtr->flags, kDfltSetDsvFl);
  839. }
  840. return rc;
  841. }
  842. cmDspRC_t _cmDspDefaultSet( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, const cmDspValue_t* valPtr, bool nonInitValIsEqualFl )
  843. {
  844. cmDspRC_t rc;
  845. cmDspVar_t* varPtr;
  846. // get a pointer to the var recd
  847. if((rc = _cmDspVarPtr(inst,varId,&varPtr)) != kOkDspRC )
  848. return rc;
  849. // if the dflt value was previuosly set and the default value is
  850. // not equal to the non-intialized value for this var then the default value
  851. // has already been set to a legal value
  852. if( cmIsFlag(varPtr->flags,kDfltSetDsvFl) && nonInitValIsEqualFl==false )
  853. return kOkDspRC;
  854. return cmDspSetDefault(ctx,inst,varId,valPtr);
  855. }
  856. cmDspRC_t cmDspSetDefaultBool( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, bool nonInitVal, bool val )
  857. {
  858. cmDspValue_t v;
  859. double dv = cmDspDefaultBool(inst,varId);
  860. cmDsvSetBool(&v,val);
  861. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==nonInitVal);
  862. }
  863. cmDspRC_t cmDspSetDefaultInt( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, int nonInitVal, int val )
  864. {
  865. cmDspValue_t v;
  866. int dv = cmDspDefaultInt(inst,varId);
  867. cmDsvSetInt(&v,val);
  868. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==nonInitVal);
  869. }
  870. cmDspRC_t cmDspSetDefaultUInt( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, unsigned nonInitVal, unsigned val )
  871. {
  872. cmDspValue_t v;
  873. unsigned dv = cmDspDefaultUInt(inst,varId);
  874. cmDsvSetUInt(&v,val);
  875. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==nonInitVal);
  876. }
  877. cmDspRC_t cmDspSetDefaultDouble( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, double nonInitVal, double val )
  878. {
  879. cmDspValue_t v;
  880. double dv = cmDspDefaultDouble(inst,varId);
  881. cmDsvSetDouble(&v,val);
  882. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==nonInitVal);
  883. }
  884. cmDspRC_t cmDspSetDefaultSample( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, cmSample_t nonInitVal, cmSample_t val )
  885. {
  886. cmDspValue_t v;
  887. cmSample_t dv = cmDspDefaultSample(inst,varId);
  888. cmDsvSetSample(&v,val);
  889. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==nonInitVal);
  890. }
  891. cmDspRC_t cmDspSetDefaultReal( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, cmReal_t nonInitVal, cmReal_t val )
  892. {
  893. cmDspValue_t v;
  894. cmReal_t dv = cmDspDefaultReal(inst,varId);
  895. cmDsvSetReal(&v,val);
  896. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==nonInitVal);
  897. }
  898. cmDspRC_t cmDspSetDefaultSymbol( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, unsigned val )
  899. {
  900. cmDspValue_t v;
  901. unsigned dv = cmDspDefaultSymbol(inst,varId);
  902. cmDsvSetSymbol(&v,val);
  903. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==cmInvalidId);
  904. }
  905. cmDspRC_t cmDspSetDefaultStrcz( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, const cmChar_t* nonInitVal, const cmChar_t* val )
  906. {
  907. cmDspValue_t v;
  908. const cmChar_t* dv= cmDspDefaultStrcz(inst,varId);
  909. cmDsvSetStrcz(&v,val);
  910. bool fl = false; // assume the default and non-init value are not equal
  911. // if the pointers are the same then the strings must match
  912. if( dv == nonInitVal )
  913. fl = true;
  914. else
  915. // if both strings exist - then test if they are equal
  916. if( dv!=NULL && nonInitVal!=NULL)
  917. fl = strcmp(dv,nonInitVal)==0;
  918. return _cmDspDefaultSet(ctx,inst,varId,&v,fl);
  919. }
  920. cmDspRC_t cmDspSetDefaultJson( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, cmJsonNode_t* nonInitVal, cmJsonNode_t* val )
  921. {
  922. cmDspValue_t v;
  923. cmJsonNode_t* dv= cmDspDefaultJson(inst,varId);
  924. cmDsvSetJson(&v,val);
  925. return _cmDspDefaultSet(ctx,inst,varId,&v,dv==nonInitVal);
  926. }
  927. cmDspRC_t cmDspSetBool( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, bool val )
  928. {
  929. cmDspValue_t v;
  930. cmDsvSetBool(&v,val);
  931. return cmDspValueSet(ctx, inst, varId, &v, 0);
  932. }
  933. cmDspRC_t cmDspSetInt( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, int val )
  934. {
  935. cmDspValue_t v;
  936. cmDsvSetInt(&v,val);
  937. return cmDspValueSet(ctx, inst, varId, &v, 0);
  938. }
  939. cmDspRC_t cmDspSetUInt( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, unsigned val )
  940. {
  941. cmDspValue_t v;
  942. cmDsvSetUInt(&v,val);
  943. return cmDspValueSet(ctx, inst, varId, &v, 0);
  944. }
  945. cmDspRC_t cmDspSetDouble( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, double val )
  946. {
  947. cmDspValue_t v;
  948. cmDsvSetDouble(&v,val);
  949. return cmDspValueSet(ctx, inst, varId, &v, 0);
  950. }
  951. cmDspRC_t cmDspSetSample( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, cmSample_t val )
  952. {
  953. cmDspValue_t v;
  954. cmDsvSetSample(&v,val);
  955. return cmDspValueSet(ctx, inst, varId, &v, 0);
  956. }
  957. cmDspRC_t cmDspSetReal( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, cmReal_t val )
  958. {
  959. cmDspValue_t v;
  960. cmDsvSetReal(&v,val);
  961. return cmDspValueSet(ctx, inst, varId, &v, 0);
  962. }
  963. cmDspRC_t cmDspSetPtr( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, void* val )
  964. {
  965. cmDspValue_t v;
  966. cmDsvSetPtr(&v,val);
  967. return cmDspValueSet(ctx, inst, varId, &v, 0);
  968. }
  969. cmDspRC_t cmDspSetStrcz( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, const cmChar_t* val )
  970. {
  971. cmDspValue_t v;
  972. cmDsvSetStrcz(&v,val);
  973. return cmDspValueSet(ctx, inst, varId, &v, 0);
  974. }
  975. cmDspRC_t cmDspSetSymbol( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, unsigned val )
  976. {
  977. cmDspValue_t v;
  978. cmDsvSetSymbol(&v,val);
  979. return cmDspValueSet(ctx, inst, varId, &v, 0);
  980. }
  981. cmDspRC_t cmDspSetJson( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, cmJsonNode_t* val )
  982. {
  983. cmDspValue_t v;
  984. cmDsvSetJson(&v,val);
  985. return cmDspValueSet(ctx, inst, varId, &v, 0);
  986. }
  987. cmDspRC_t cmDspSetEvent( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
  988. {
  989. unsigned flags = kUpdateUiDspFl;
  990. // We will assume that all values should be reflected to the UI - unless
  991. // this event is known to have been generated by the UI (evt->kUiDspFl is set)
  992. // and evt->kUiEchoDspFl is not set.
  993. if( cmIsFlag(evt->flags,kUiDspFl)==true && cmIsFlag(evt->flags,kUiEchoDspFl)==false )
  994. flags = kNoUpdateUiDspFl;
  995. // Note: If the event target variable is not a UI variable
  996. // (i.e. cmDspVar_t.kUiDsvFl is not set) then calling cmDspValueSet()
  997. // with the kUpdateUiDspFl set has no effect.
  998. return cmDspValueSet(ctx,inst,evt->dstVarId, evt->valuePtr, flags);
  999. }
  1000. cmDspRC_t cmDspSetEventUi( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
  1001. { return cmDspValueSet(ctx,inst,evt->dstVarId, evt->valuePtr, kUpdateUiDspFl); }
  1002. cmDspRC_t cmDspSetEventUiId( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt, unsigned varId )
  1003. {
  1004. cmDspEvt_t e;
  1005. cmDspEvtCopy(&e,evt);
  1006. e.dstVarId = varId;
  1007. evt = &e;
  1008. return cmDspSetEventUi(ctx,inst,evt);
  1009. }
  1010. unsigned cmDspVarRows( cmDspInst_t* inst, unsigned varId )
  1011. {
  1012. cmDspValue_t* vp;
  1013. if(_cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  1014. return 0;
  1015. return cmDsvRows(vp);
  1016. }
  1017. unsigned cmDspVarCols( cmDspInst_t* inst, unsigned varId )
  1018. {
  1019. cmDspValue_t* vp;
  1020. if( _cmDspVarValuePtr(inst,varId,&vp) != kOkDspRC )
  1021. return 0;
  1022. return cmDsvCols(vp);
  1023. }
  1024. bool cmDspIsAudioInputConnected( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId )
  1025. {
  1026. cmDspValue_t* vp;
  1027. if( _cmDspVarValuePtr(inst,varId,&vp ) != kOkDspRC )
  1028. return false;
  1029. if( cmAllFlags(vp->flags, kSampleDsvFl | kMtxDsvFl ))
  1030. return true;
  1031. return false;
  1032. }
  1033. cmDspRC_t cmDspZeroAudioBuf( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId )
  1034. {
  1035. cmDspValue_t* valPtr;
  1036. cmDspVar_t* varPtr;
  1037. cmDspRC_t rc;
  1038. if((rc = _cmDspVarAndValuePtr(inst,varId,&varPtr,&valPtr)) != kOkDspRC )
  1039. return rc;
  1040. bool fl0 = cmAllFlags(valPtr->flags, kSampleDsvFl | kMtxDsvFl );
  1041. bool fl1 = cmIsFlag(varPtr->flags,kOutDsvFl);
  1042. if( fl0==false || fl1==false )
  1043. return cmDspInstErr(ctx,inst,kVarTypeErrDspRC,"The variable '%s' of DSP instance %s (id:%i) is not an output audio buffer.", cmDspVarLabel(ctx,inst,varId),inst->classPtr->labelStr,inst->id);
  1044. memset(cmDsvSampleMtx(valPtr), 0, cmDsvEleCount(valPtr)*sizeof(cmSample_t) );
  1045. return rc;
  1046. }
  1047. cmSample_t* cmDspAudioBuf( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, unsigned chIdx )
  1048. {
  1049. cmDspValue_t* vp;
  1050. cmDspVar_t* varPtr;
  1051. cmDspRC_t rc;
  1052. if((rc = _cmDspVarAndValuePtr(inst,varId,&varPtr,&vp )) != kOkDspRC )
  1053. return NULL;
  1054. if( !cmAllFlags(vp->flags, kSampleDsvFl | kMtxDsvFl ))
  1055. {
  1056. // this is an unconnected audio input
  1057. if( cmAllFlags(varPtr->flags,kInDsvFl | kAudioBufDsvFl ) )
  1058. return NULL;
  1059. cmDspInstErr(ctx,inst,kVarTypeErrDspRC,"The variable '%s' of DSP instance '%s' (id:%i) is not an audio buffer.", cmDspVarLabel(ctx,inst,varId),inst->classPtr->labelStr,inst->id);
  1060. return NULL;
  1061. }
  1062. if( chIdx >= cmDsvCols(vp) )
  1063. {
  1064. cmDspInstErr(ctx,inst,kVarTypeErrDspRC,"Channel index %i of audio buffer variable '%s' in DSP instance '%s' (id:%i) is outside the channel count (%i).",
  1065. chIdx,cmDspVarLabel(ctx,inst,varId),inst->classPtr->labelStr,inst->id,cmDsvCols(vp));
  1066. }
  1067. return cmDsvSampleMtx(vp) + (chIdx * cmDsvRows(vp));
  1068. }
  1069. unsigned cmDspAudioBufSmpCount( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, unsigned chIdx )
  1070. {
  1071. cmDspValue_t* vp;
  1072. cmDspRC_t rc;
  1073. if((rc = _cmDspVarValuePtr(inst,varId,&vp)) != kOkDspRC )
  1074. return 0;
  1075. if( !cmAllFlags(vp->flags, kSampleDsvFl | kMtxDsvFl ))
  1076. {
  1077. cmDspInstErr(ctx,inst,kVarTypeErrDspRC,"The variable '%s' of DSP instance '%s' (id:%i) is not an audio buffer or is an unconnected input audio buffer.", cmDspVarLabel(ctx,inst,varId),inst->classPtr->labelStr,inst->id);
  1078. return 0;
  1079. }
  1080. return cmDsvRows(vp);
  1081. }
  1082. cmDspRC_t cmDspInstInstallCb( cmDspCtx_t* ctx, cmDspInst_t* srcInstPtr, unsigned srcVarSymId, cmDspInst_t* dstInstPtr, unsigned dstVarSymId, void* dstDataPtr)
  1083. {
  1084. cmDspVar_t* srcVarPtr;
  1085. cmDspVar_t* dstVarPtr;
  1086. // get the src and dst var ptrs
  1087. if((srcVarPtr = cmDspVarSymbolToPtr(ctx,srcInstPtr,srcVarSymId,kOutDsvFl)) == NULL || (dstVarPtr = cmDspVarSymbolToPtr(ctx,dstInstPtr,dstVarSymId,kInDsvFl)) == NULL )
  1088. return cmDspInstErr(ctx,srcInstPtr,kInstCbInstallFailDspRC,"Callback installation failed for connection from '%s' (id:%i) var:'%s' to '%s' (id:%i) var:'%s'.",
  1089. srcInstPtr->classPtr->labelStr, srcInstPtr->id, cmSymTblLabel(ctx->stH,srcVarSymId), dstInstPtr->classPtr->labelStr, dstInstPtr->id, cmSymTblLabel(ctx->stH,dstVarSymId) );
  1090. // check for strict type conversion - this will fail for vars which allow multiple types
  1091. // (e.g. numbers and strings)
  1092. if( cmDsvCanConvertFlags(dstVarPtr->value.flags,srcVarPtr->value.flags) == false )
  1093. {
  1094. // if all the flags in the src are set in the dst then the match is ok
  1095. // (this will cover dst types which admit multiple types)
  1096. if( cmAllFlags(dstVarPtr->flags & kTypeDsvMask,srcVarPtr->flags & kTypeDsvMask) == false )
  1097. cmDspInstErr(ctx,srcInstPtr,kOkDspRC,"Data types may not be compatible for connection to '%s' id:%i var:'%s' from '%s'.",dstInstPtr->classPtr->labelStr, dstInstPtr->id, cmSymTblLabel(ctx->stH,dstVarSymId), cmSymTblLabel(ctx->stH,srcVarSymId));
  1098. }
  1099. if( cmIsFlag(srcVarPtr->flags, kAudioBufDsvFl) )
  1100. cmDspInstErr(ctx,srcInstPtr,kOkDspRC,"An audio source is being used as an event callback connection.");
  1101. if( cmIsFlag(dstVarPtr->flags, kAudioBufDsvFl ) )
  1102. cmDspInstErr(ctx,dstInstPtr,kOkDspRC,"An audio destination is the target of a callback connection.");
  1103. cmDspCb_t* r = cmLhAllocZ( ctx->lhH, cmDspCb_t, 1 );
  1104. r->srcVarSymId = srcVarSymId;
  1105. r->dstInstPtr = dstInstPtr;
  1106. r->dstVarId = dstVarPtr->constId;
  1107. r->dstDataPtr = dstDataPtr;
  1108. r->linkPtr = NULL;
  1109. cmDspCb_t* cp = srcVarPtr->cbList;
  1110. cmDspCb_t* pp = NULL;
  1111. for(; cp != NULL; cp = cp->linkPtr )
  1112. pp = cp;
  1113. if( pp == NULL )
  1114. srcVarPtr->cbList = r;
  1115. else
  1116. pp->linkPtr = r;
  1117. return kOkDspRC;
  1118. }
  1119. cmDspRC_t cmDspInstallCb( cmDspCtx_t* ctx, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, const cmChar_t* dstVarLabel, void* dstCbDataPtr)
  1120. {
  1121. unsigned srcVarSymId,dstVarSymId;
  1122. if( srcInstPtr == NULL && dstInstPtr == NULL )
  1123. return cmErrMsg(&ctx->cmCtx->err,kInstNotFoundDspRC,"The callback installation was passed a NULL source and destination processor instance pointer.");
  1124. if( srcInstPtr == NULL )
  1125. return cmErrMsg(&ctx->cmCtx->err,kInstNotFoundDspRC,"The callback installation was passed a NULL source processor instance pointer for connection to '%s'.",cmStringNullGuard(dstInstPtr->classPtr->labelStr));
  1126. if( dstInstPtr == NULL )
  1127. return cmErrMsg(&ctx->cmCtx->err,kInstNotFoundDspRC,"The callback installation was passed a NULL destination processor instance pointer for connection from '%s'.",cmStringNullGuard(srcInstPtr->classPtr->labelStr));
  1128. if((srcVarSymId = cmSymTblId( ctx->stH, srcVarLabel )) == cmInvalidId )
  1129. return cmDspInstErr(ctx,srcInstPtr,kSrcVarNotFoundDspRC,"Connection failed. The source variable '%s' could not found in '%s' (id:%i) for registration by '%s' (id:%i).",
  1130. srcVarLabel,srcInstPtr->classPtr->labelStr,srcInstPtr->id,dstInstPtr->classPtr->labelStr,dstInstPtr->id);
  1131. if((dstVarSymId = cmSymTblId( ctx->stH, dstVarLabel )) == cmInvalidId )
  1132. return cmDspInstErr(ctx,dstInstPtr,kSrcVarNotFoundDspRC,"Connection failed. The destination variable '%s' for the DSP instance '%s' (id:%i).",
  1133. dstVarLabel,dstInstPtr->classPtr->labelStr,dstInstPtr->id);
  1134. return cmDspInstInstallCb(ctx, srcInstPtr, srcVarSymId, dstInstPtr, dstVarSymId, dstCbDataPtr);
  1135. }
  1136. cmDspRC_t cmDspInstRemoveCb( cmDspCtx_t* ctx, cmDspInst_t* srcInstPtr, unsigned srcVarSymId, cmDspInst_t* dstInstPtr, unsigned dstVarId )
  1137. {
  1138. cmDspVar_t* varPtr;
  1139. if((varPtr = cmDspVarSymbolToPtr(ctx,srcInstPtr,srcVarSymId,kOutDsvFl)) == NULL )
  1140. return cmDspInstErr(ctx,srcInstPtr,kInstCbInstallFailDspRC,"Callback removal failed for instance '%s' (id:%i).",
  1141. srcInstPtr->classPtr->labelStr, srcInstPtr->id );
  1142. cmDspCb_t* cp = varPtr->cbList;
  1143. cmDspCb_t* pp = NULL;
  1144. for(; cp != NULL; cp = cp->linkPtr )
  1145. {
  1146. if( cp->srcVarSymId == srcVarSymId && cp->dstInstPtr == dstInstPtr && cp->dstVarId == dstVarId )
  1147. break;
  1148. pp = cp;
  1149. }
  1150. if( pp == NULL )
  1151. varPtr->cbList = cp->linkPtr;
  1152. else
  1153. pp->linkPtr = cp->linkPtr;
  1154. return kOkDspRC;
  1155. }
  1156. cmDspRC_t cmDspRemoveCb( cmDspCtx_t* ctx, cmDspInst_t* srcInstPtr, const cmChar_t* srcVarLabel, cmDspInst_t* dstInstPtr, unsigned dstVarId)
  1157. {
  1158. unsigned srcVarSymId;
  1159. if((srcVarSymId = cmSymTblId( ctx->stH, srcVarLabel )) == cmInvalidId )
  1160. return cmDspInstErr(ctx,srcInstPtr,kSrcVarNotFoundDspRC,"The variable '%s' could not found in '%s' (id:%i) do de-register for '%s' (id:%i).",
  1161. srcVarLabel,srcInstPtr->classPtr->labelStr,srcInstPtr->id,dstInstPtr->classPtr->labelStr,dstInstPtr->id);
  1162. return cmDspInstRemoveCb(ctx, srcInstPtr, srcVarSymId, dstInstPtr, dstVarId );
  1163. }
  1164. cmDspRC_t cmDspInstVarSetFlags( cmDspCtx_t* ctx, cmDspInst_t* instPtr, unsigned varId, unsigned flags )
  1165. {
  1166. cmDspVar_t* varPtr;
  1167. if(_cmDspVarPtr(instPtr, varId, &varPtr ) != kOkDspRC )
  1168. return cmDspInstErr(ctx,instPtr,kInstSetFlagsFailDspRC,"Set flags failed for DSP instance %s (id:%i).",instPtr->classPtr->labelStr,instPtr->id);
  1169. varPtr->flags = cmSetFlag(varPtr->flags,flags);
  1170. return kOkDspRC;
  1171. }