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

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