libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cmDspClass.c 44KB

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