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.

cmUiRtSysMstr.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. #include "cmGlobal.h"
  2. #include "cmFloatTypes.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmCtx.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include "cmJson.h"
  9. #include "cmThread.h"
  10. #include "cmUdpPort.h"
  11. #include "cmTime.h"
  12. #include "cmRtSysMsg.h"
  13. #include "cmRtNet.h"
  14. #include "cmRtSys.h"
  15. #include "cmUiDrvr.h"
  16. #include "cmUi.h"
  17. #include "cmUiRtSysMstr.h"
  18. enum
  19. {
  20. kLabelAmId,
  21. kInSliderAmId,
  22. kInMeterAmId,
  23. kInToneAmId,
  24. kInPassAmId,
  25. kInMuteAmId,
  26. kOutSliderAmId,
  27. kOutMeterAmId,
  28. kOutToneAmId,
  29. kOutPassAmId,
  30. kOutMuteAmId,
  31. kAmCnt
  32. };
  33. enum
  34. {
  35. kMinDb = 24,
  36. kMaxDb = -24,
  37. kMtrMin = 0,
  38. kMtrMax = 100
  39. };
  40. typedef struct cmAmPanel_str
  41. {
  42. unsigned rtSubIdx;
  43. unsigned panelId;
  44. unsigned updateId;
  45. unsigned wakeupId;
  46. unsigned msgCbId;
  47. unsigned audioCbId;
  48. unsigned updateCnt;
  49. unsigned wakeupCnt;
  50. unsigned msgCbCnt;
  51. unsigned audioCbCnt;
  52. unsigned baseOutId;
  53. unsigned iDevIdx;
  54. unsigned oDevIdx;
  55. unsigned iChCnt;
  56. unsigned oChCnt;
  57. unsigned a[ kAmCnt ];
  58. struct cmAmPanel_str* link;
  59. } cmAmPanel_t;
  60. typedef struct
  61. {
  62. cmErr_t err;
  63. unsigned appId;
  64. cmUiH_t uiH;
  65. cmRtSysH_t asH;
  66. unsigned nextId;
  67. cmAmPanel_t* list;
  68. } cmAm_t;
  69. cmUiRtMstrH_t cmUiRtMstrNullHandle = cmSTATIC_NULL_HANDLE;
  70. cmAm_t* _cmUiAmHandleToPtr( cmUiRtMstrH_t h )
  71. {
  72. cmAm_t* p = (cmAm_t*)h.h;
  73. assert( p!=NULL);
  74. return p;
  75. }
  76. cmAmRC_t _cmUiAmFreePanels( cmAm_t* p, bool callDriverFl )
  77. {
  78. cmAmRC_t rc = kOkAmRC;
  79. cmAmPanel_t* pp = p->list;
  80. while( pp != NULL )
  81. {
  82. cmAmPanel_t* np = pp->link;
  83. unsigned panelId = pp->panelId;
  84. if( callDriverFl )
  85. if( cmUiClearPanel( p->uiH, p->appId, panelId ) != kOkUiRC )
  86. {
  87. rc = cmErrMsg(&p->err,kUiFailAmRC,"The panel %i clear failed.",panelId);
  88. goto errLabel;
  89. }
  90. cmMemFree(pp);
  91. pp = np;
  92. }
  93. p->nextId = 0;
  94. p->list = NULL;
  95. errLabel:
  96. return rc;
  97. }
  98. cmAmRC_t _cmUiAmFree( cmAm_t* p )
  99. {
  100. _cmUiAmFreePanels(p,false);
  101. if( cmUiDestroyApp( p->uiH, p->appId ) != kOkUiRC )
  102. cmErrMsg(&p->err,kUiFailAmRC,"UI Mgr. app destroy failed.");
  103. cmMemFree(p);
  104. return kOkAmRC;
  105. }
  106. cmAmRC_t cmUiRtSysMstrAlloc( cmCtx_t* ctx, cmUiRtMstrH_t* hp, cmUiH_t uiH, cmRtSysH_t asH, unsigned appId )
  107. {
  108. cmAmRC_t rc = kOkAmRC;
  109. if((rc = cmUiRtSysMstrFree(hp)) != kOkAmRC )
  110. return rc;
  111. cmAm_t* p = cmMemAllocZ(cmAm_t,1);
  112. cmErrSetup(&p->err,&ctx->rpt,"Audio System Master UI");
  113. p->appId = appId;
  114. p->uiH = uiH;
  115. p->asH = asH;
  116. p->nextId = 0;
  117. // allocate the UI Mgr. app. slot for the audio system master control UI.
  118. if( cmUiCreateApp( uiH, appId, cmInvalidId ) != kOkUiRC )
  119. {
  120. rc = cmErrMsg(&p->err,kUiFailAmRC,"The UI Mgr. failed while creating the Audio System UI app. slot.");
  121. goto errLabel;
  122. }
  123. hp->h = p;
  124. errLabel:
  125. if( rc != kOkAmRC )
  126. _cmUiAmFree(p);
  127. return rc;
  128. }
  129. cmAmRC_t cmUiRtSysMstrFree( cmUiRtMstrH_t* hp )
  130. {
  131. cmAmRC_t rc = kOkAmRC;
  132. if(hp==NULL || cmUiRtSysMstrIsValid(*hp)==false )
  133. return kOkAmRC;
  134. cmAm_t* p = _cmUiAmHandleToPtr(*hp);
  135. if((rc = _cmUiAmFree(p)) != kOkAmRC )
  136. return rc;
  137. hp->h = NULL;
  138. return rc;
  139. }
  140. bool cmUiRtSysMstrIsValid( cmUiRtMstrH_t h )
  141. { return h.h != NULL; }
  142. cmAmRC_t cmUiRtSysMstrInitialize( cmUiRtMstrH_t amH, const cmRtSysCtx_t* c, const cmChar_t* inDevLabel, const cmChar_t* outDevLabel )
  143. {
  144. cmAmRC_t rc = kOkAmRC;
  145. cmAm_t* p = _cmUiAmHandleToPtr(amH);
  146. cmUiH_t uiH = p->uiH;
  147. unsigned panelId = cmInvalidId;
  148. unsigned colW = 50;
  149. unsigned ctlW = 45;
  150. unsigned n = 31;
  151. cmChar_t chNumStr[ n+1 ];
  152. int w;
  153. cmAmPanel_t* pp = NULL;
  154. // This function is called once for each audio sub-system.
  155. // If this is the first call in the sequence then clear the previous setup.
  156. if( c->rtSubIdx == 0 )
  157. {
  158. if((rc = _cmUiAmFreePanels(p,true)) != kOkAmRC )
  159. goto errLabel;
  160. assert(p->list == NULL );
  161. }
  162. // create the panel recd and link it to the beginning of the list
  163. pp = cmMemAllocZ(cmAmPanel_t,1);
  164. pp->link = p->list;
  165. p->list = pp;
  166. pp->rtSubIdx = c->rtSubIdx;
  167. pp->iDevIdx = c->ss->args.inDevIdx;
  168. pp->oDevIdx = c->ss->args.outDevIdx;
  169. pp->iChCnt = c->iChCnt;
  170. pp->oChCnt = c->oChCnt;
  171. pp->panelId = p->nextId++;
  172. pp->updateId = p->nextId++;
  173. pp->wakeupId = p->nextId++;
  174. pp->msgCbId = p->nextId++;
  175. pp->audioCbId = p->nextId++;
  176. pp->a[kLabelAmId] = p->nextId;
  177. pp->a[kInSliderAmId] = p->nextId += c->iChCnt;
  178. pp->a[kInMeterAmId] = p->nextId += c->iChCnt;
  179. pp->a[kInToneAmId] = p->nextId += c->iChCnt;
  180. pp->a[kInPassAmId] = p->nextId += c->iChCnt;
  181. pp->a[kInMuteAmId] = p->nextId += c->iChCnt;
  182. pp->baseOutId = p->nextId += c->iChCnt;
  183. pp->a[kOutSliderAmId] = pp->baseOutId;
  184. pp->a[kOutMeterAmId] = p->nextId += c->oChCnt;
  185. pp->a[kOutToneAmId] = p->nextId += c->oChCnt;
  186. pp->a[kOutPassAmId] = p->nextId += c->oChCnt;
  187. pp->a[kOutMuteAmId] = p->nextId += c->oChCnt;
  188. p->nextId += c->oChCnt;
  189. panelId = pp->panelId;
  190. if( cmUiCreatePanel(uiH, p->appId, panelId, "Master", 0 ) != kOkUiRC )
  191. {
  192. rc = cmErrMsg(&p->err,kUiFailAmRC,"Panel %i create failed.",panelId);
  193. goto errLabel;
  194. }
  195. cmUiSetFillRows( uiH, p->appId, panelId, true );
  196. cmUiCreateProgress(uiH, p->appId, panelId, pp->updateId, "Update", 0, 0, 1, 0 );
  197. cmUiCreateProgress(uiH, p->appId, panelId, pp->wakeupId, "Wakeup", 0, 0, 1, 0 );
  198. cmUiCreateProgress(uiH, p->appId, panelId, pp->msgCbId, "Message", 0, 0, 1, 0 );
  199. cmUiCreateProgress(uiH, p->appId, panelId, pp->audioCbId,"Audio", 0, 0, 1, 0 );
  200. cmUiSetFillRows( uiH, p->appId, panelId, false );
  201. cmUiNewLine( uiH, p->appId, panelId );
  202. cmUiCreateLabel( uiH, p->appId, panelId, cmInvalidId, inDevLabel, kInsideUiFl | kLeftUiFl );
  203. cmUiNewLine( uiH, p->appId, panelId );
  204. unsigned i;
  205. for(i=0; i<c->iChCnt; ++i)
  206. {
  207. snprintf(chNumStr,n,"%i",i);
  208. cmUiSetNextW( uiH, p->appId, panelId, ctlW );
  209. cmUiCreateLabel( uiH, p->appId, panelId, cmInvalidId, chNumStr, 0 );
  210. cmUiCreateVSlider(uiH, p->appId, panelId, pp->a[kInSliderAmId] + i, NULL, 0, kMinDb, kMaxDb, 0.1, 0 );
  211. cmUiPlaceRight( uiH, p->appId, panelId );
  212. cmUiCreateVMeter( uiH, p->appId, panelId, pp->a[kInMeterAmId] + i, NULL, 0, kMtrMin, kMtrMax, 0 );
  213. w = cmUiSetW( uiH, p->appId, panelId, ctlW );
  214. cmUiCreateCheck( uiH, p->appId, panelId, pp->a[kInToneAmId] + i, "T", 0, false );
  215. cmUiCreateCheck( uiH, p->appId, panelId, pp->a[kInPassAmId] + i, "P", 0, false );
  216. cmUiCreateCheck( uiH, p->appId, panelId, pp->a[kInMuteAmId] + i, "M", 0, false );
  217. cmUiSetW( uiH, p->appId, panelId, w );
  218. cmUiSetBaseCol( uiH, p->appId, panelId, 5 + (i+1)*colW);
  219. }
  220. cmUiSetBaseCol( uiH, p->appId, panelId, 0);
  221. cmUiNewLine( uiH, p->appId, panelId );
  222. cmUiCreateLabel( uiH,p->appId, panelId, cmInvalidId, outDevLabel, kInsideUiFl | kLeftUiFl );
  223. cmUiNewLine( uiH, p->appId, panelId );
  224. for(i=0; i<c->oChCnt; ++i)
  225. {
  226. snprintf(chNumStr,n,"%i",i);
  227. cmUiSetNextW( uiH, p->appId, panelId, ctlW );
  228. cmUiCreateLabel( uiH, p->appId, panelId, cmInvalidId, chNumStr, 0 );
  229. cmUiCreateVSlider(uiH, p->appId, panelId, pp->a[kOutSliderAmId] + i, NULL, 0, kMinDb, kMaxDb, 0.1, 0 );
  230. cmUiPlaceRight( uiH, p->appId, panelId );
  231. cmUiCreateVMeter( uiH, p->appId, panelId, pp->a[kOutMeterAmId] + i, NULL, 0, kMtrMin, kMtrMax, 0 );
  232. w = cmUiSetW( uiH, p->appId, panelId, ctlW );
  233. cmUiCreateCheck( uiH, p->appId, panelId, pp->a[kOutToneAmId] + i, "T", 0, false );
  234. cmUiCreateCheck( uiH, p->appId, panelId, pp->a[kOutPassAmId] + i, "P", 0, false );
  235. cmUiCreateCheck( uiH, p->appId, panelId, pp->a[kOutMuteAmId] + i, "M", 0, false );
  236. cmUiSetW( uiH, p->appId, panelId, w );
  237. cmUiSetBaseCol( uiH, p->appId, panelId, 5 + (i+1)*colW);
  238. }
  239. errLabel:
  240. return rc;
  241. }
  242. cmAmPanel_t* _cmUiAmFindPanel( cmAm_t* p, unsigned panelId, bool errFl )
  243. {
  244. cmAmPanel_t* pp = p->list;
  245. for(; pp!=NULL; pp=pp->link)
  246. if( pp->panelId == panelId )
  247. return pp;
  248. if( errFl )
  249. cmErrMsg(&p->err,kPanelNotFoundAmRC,"The panel %i was not found.",panelId);
  250. return NULL;
  251. }
  252. unsigned _cmUiAmCtlTypeId( cmAm_t* p, cmAmPanel_t* pp, cmUiCId_t cId, unsigned usrId,
  253. unsigned sliderId, unsigned toneId, unsigned passId, unsigned muteId )
  254. {
  255. switch( cId )
  256. {
  257. case kSliderUiCId:
  258. assert( pp->a[sliderId] <= usrId && usrId < pp->a[sliderId]+pp->oChCnt);
  259. return sliderId;
  260. break;
  261. case kCheckUiCId:
  262. if( pp->a[toneId] <= usrId && usrId < pp->a[toneId]+pp->oChCnt )
  263. return toneId;
  264. if( pp->a[passId] <= usrId && usrId < pp->a[passId]+pp->oChCnt )
  265. return passId;
  266. if( pp->a[muteId] <= usrId && usrId < pp->a[muteId]+pp->oChCnt )
  267. return muteId;
  268. break;
  269. default:
  270. break;
  271. }
  272. return cmInvalidId;
  273. }
  274. cmUiRC_t cmUiRtSysMstrOnUiEvent( cmUiRtMstrH_t h, const cmUiDriverArg_t* a )
  275. {
  276. cmUiRC_t rc = kOkUiRC;
  277. cmAm_t* p = _cmUiAmHandleToPtr(h);
  278. cmAmPanel_t* pp;
  279. cmRtSysMstr_t r;
  280. unsigned typeId;
  281. bool tabSelFl = a->dId==kSetValDId && a->cId == kPanelUiCId;
  282. if((pp = _cmUiAmFindPanel( p, a->panelId, !tabSelFl )) == NULL)
  283. {
  284. if( tabSelFl )
  285. return kOkUiRC;
  286. return cmErrLastRC(&p->err);
  287. }
  288. // if the panel tab was selected/deslected ival will be equal to 1/0
  289. if( a->usrId == pp->panelId )
  290. {
  291. cmRtSysStatusNotifyEnable(p->asH, pp->rtSubIdx, a->ival );
  292. return rc;
  293. }
  294. // based on the usrId determine which control generated the event
  295. if( a->usrId >= pp->baseOutId )
  296. typeId = _cmUiAmCtlTypeId(p,pp,a->cId,a->usrId,kOutSliderAmId,kOutToneAmId,kOutPassAmId,kOutMuteAmId);
  297. else
  298. typeId = _cmUiAmCtlTypeId(p,pp,a->cId,a->usrId,kInSliderAmId,kInToneAmId,kInPassAmId,kInMuteAmId);
  299. // this control is not a slider or check btn so ignore it
  300. if( typeId == cmInvalidId )
  301. return rc;
  302. unsigned asInFl = 0;
  303. unsigned asCtlId = cmInvalidId;
  304. unsigned asCh = a->usrId - pp->a[typeId];
  305. double asValue = 0;
  306. switch( typeId )
  307. {
  308. case kInSliderAmId:
  309. asInFl = 1;
  310. asCtlId = kSliderUiRtId;
  311. asValue = a->fval;
  312. break;
  313. case kInToneAmId:
  314. asInFl = 1;
  315. asCtlId = kToneUiRtId;
  316. asValue = a->ival;
  317. break;
  318. case kInPassAmId:
  319. asInFl = 1;
  320. asCtlId = kPassUiRtId;
  321. asValue = a->ival;
  322. break;
  323. case kInMuteAmId:
  324. asInFl = 1;;
  325. asCtlId = kMuteUiRtId;
  326. asValue = a->ival;
  327. break;
  328. case kOutSliderAmId:
  329. asCtlId = kSliderUiRtId;
  330. asValue = a->fval;
  331. break;
  332. case kOutToneAmId:
  333. asCtlId = kToneUiRtId;
  334. asValue = a->ival;
  335. break;
  336. case kOutPassAmId:
  337. asCtlId = kPassUiRtId;
  338. asValue = a->ival;
  339. break;
  340. case kOutMuteAmId:
  341. asCtlId = kMuteUiRtId;
  342. asValue = a->ival;
  343. break;
  344. }
  345. unsigned asDevIdx = asInFl ? pp->iDevIdx : pp->oDevIdx;
  346. r.hdr.rtSubIdx = pp->rtSubIdx;
  347. r.hdr.selId = kUiMstrSelRtId;
  348. r.devIdx = asDevIdx;
  349. r.chIdx = asCh;
  350. r.inFl = asInFl;
  351. r.ctlId = asCtlId;
  352. r.value = asValue;
  353. if( cmRtSysDeliverMsg(p->asH, &r, sizeof(r), cmInvalidId ) != kOkRtRC )
  354. rc = cmErrMsg(&p->err,kSubSysFailUiRC,"Audio System master control UI message delivery to the audio system failed.");
  355. return rc;
  356. }
  357. int _cmUiAmLinToDb( double v )
  358. {
  359. if( v <= 0 )
  360. return 0;
  361. v = round(20.0*log10(v)+100.0);
  362. return cmMin(kMtrMax,cmMax(kMtrMin,v));
  363. }
  364. cmUiRC_t cmUiRtSysMstrOnStatusEvent( cmUiRtMstrH_t h, const cmRtSysStatus_t* m, const double* iMeterArray, const double* oMeterArray )
  365. {
  366. cmAm_t* p = _cmUiAmHandleToPtr(h);
  367. cmAmPanel_t* pp = p->list;
  368. for(; pp!=NULL; pp=pp->link)
  369. if(pp->rtSubIdx == m->hdr.rtSubIdx )
  370. break;
  371. if( pp == NULL )
  372. return cmErrMsg(&p->err,kPanelNotFoundUiRC,"The panel associated with Audio system index %i could not be found.",m->hdr.rtSubIdx);
  373. cmUiSetInt(p->uiH, p->appId, pp->updateId, m->updateCnt != pp->updateCnt );
  374. cmUiSetInt(p->uiH, p->appId, pp->wakeupId, m->wakeupCnt != pp->wakeupCnt );
  375. cmUiSetInt(p->uiH, p->appId, pp->msgCbId, m->msgCbCnt != pp->msgCbCnt );
  376. cmUiSetInt(p->uiH, p->appId, pp->audioCbId, m->audioCbCnt != pp->audioCbCnt );
  377. pp->updateCnt = m->updateCnt;
  378. pp->wakeupCnt = m->wakeupCnt;
  379. pp->msgCbCnt = m->msgCbCnt;
  380. pp->audioCbCnt= m->audioCbCnt;
  381. unsigned i;
  382. for(i=0; i<m->iMeterCnt; ++i)
  383. cmUiSetInt(p->uiH, p->appId, pp->a[kInMeterAmId]+i, _cmUiAmLinToDb(iMeterArray[i]) );
  384. for(i=0; i<m->oMeterCnt; ++i)
  385. cmUiSetInt(p->uiH, p->appId, pp->a[kOutMeterAmId]+i, _cmUiAmLinToDb(oMeterArray[i]) );
  386. return kOkUiRC;
  387. }
  388. void cmUiRtSysMstrClearStatus( cmUiRtMstrH_t h )
  389. {
  390. cmAm_t* p = _cmUiAmHandleToPtr(h);
  391. cmAmPanel_t* pp = p->list;
  392. for(; pp!=NULL; pp=pp->link)
  393. {
  394. cmUiSetInt(p->uiH, p->appId, pp->updateId, 0 );
  395. cmUiSetInt(p->uiH, p->appId, pp->wakeupId, 0 );
  396. cmUiSetInt(p->uiH, p->appId, pp->msgCbId, 0 );
  397. cmUiSetInt(p->uiH, p->appId, pp->audioCbId, 0 );
  398. }
  399. }