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.

cmUiAudioSysMstr.c 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  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 "cmUdpNet.h"
  12. #include "cmAudioSysMsg.h"
  13. #include "cmAudioSys.h"
  14. #include "cmUiDrvr.h"
  15. #include "cmUi.h"
  16. #include "cmUiAudioSysMstr.h"
  17. enum
  18. {
  19. kLabelAmId,
  20. kInSliderAmId,
  21. kInMeterAmId,
  22. kInToneAmId,
  23. kInPassAmId,
  24. kInMuteAmId,
  25. kOutSliderAmId,
  26. kOutMeterAmId,
  27. kOutToneAmId,
  28. kOutPassAmId,
  29. kOutMuteAmId,
  30. kAmCnt
  31. };
  32. enum
  33. {
  34. kMinDb = 24,
  35. kMaxDb = -24,
  36. kMtrMin = 0,
  37. kMtrMax = 100
  38. };
  39. typedef struct cmAmPanel_str
  40. {
  41. unsigned asSubIdx;
  42. unsigned panelId;
  43. unsigned updateId;
  44. unsigned wakeupId;
  45. unsigned msgCbId;
  46. unsigned audioCbId;
  47. unsigned updateCnt;
  48. unsigned wakeupCnt;
  49. unsigned msgCbCnt;
  50. unsigned audioCbCnt;
  51. unsigned baseOutId;
  52. unsigned iDevIdx;
  53. unsigned oDevIdx;
  54. unsigned iChCnt;
  55. unsigned oChCnt;
  56. unsigned a[ kAmCnt ];
  57. struct cmAmPanel_str* link;
  58. } cmAmPanel_t;
  59. typedef struct
  60. {
  61. cmErr_t err;
  62. unsigned appId;
  63. cmUiH_t uiH;
  64. cmAudioSysH_t asH;
  65. unsigned nextId;
  66. cmAmPanel_t* list;
  67. } cmAm_t;
  68. cmUiASMstrH_t cmUiASMstrNullHandle = cmSTATIC_NULL_HANDLE;
  69. cmAm_t* _cmUiAmHandleToPtr( cmUiASMstrH_t h )
  70. {
  71. cmAm_t* p = (cmAm_t*)h.h;
  72. assert( p!=NULL);
  73. return p;
  74. }
  75. cmAmRC_t _cmUiAmFreePanels( cmAm_t* p, bool callDriverFl )
  76. {
  77. cmAmRC_t rc = kOkAmRC;
  78. cmAmPanel_t* pp = p->list;
  79. while( pp != NULL )
  80. {
  81. cmAmPanel_t* np = pp->link;
  82. unsigned panelId = pp->panelId;
  83. if( callDriverFl )
  84. if( cmUiClearPanel( p->uiH, panelId ) != kOkUiRC )
  85. {
  86. rc = cmErrMsg(&p->err,kUiFailAmRC,"The panel %i clear failed.",panelId);
  87. goto errLabel;
  88. }
  89. cmMemFree(pp);
  90. pp = np;
  91. }
  92. p->nextId = 0;
  93. p->list = NULL;
  94. errLabel:
  95. return rc;
  96. }
  97. cmAmRC_t _cmUiAmFree( cmAm_t* p )
  98. {
  99. _cmUiAmFreePanels(p,false);
  100. cmMemFree(p);
  101. return kOkAmRC;
  102. }
  103. cmAmRC_t cmUiAudioSysMstrAlloc( cmCtx_t* ctx, cmUiASMstrH_t* hp, cmUiH_t uiH, cmAudioSysH_t asH, unsigned appId )
  104. {
  105. cmAmRC_t rc = kOkAmRC;
  106. if((rc = cmUiAudioSysMstrFree(hp)) != kOkAmRC )
  107. return rc;
  108. cmAm_t* p = cmMemAllocZ(cmAm_t,1);
  109. cmErrSetup(&p->err,&ctx->rpt,"Audio System Master UI");
  110. p->appId = appId;
  111. p->uiH = uiH;
  112. p->asH = asH;
  113. p->nextId = 0;
  114. hp->h = p;
  115. return rc;
  116. }
  117. cmAmRC_t cmUiAudioSysMstrFree( cmUiASMstrH_t* hp )
  118. {
  119. cmAmRC_t rc = kOkAmRC;
  120. if(hp==NULL || cmUiAudioSysMstrIsValid(*hp)==false )
  121. return kOkAmRC;
  122. cmAm_t* p = _cmUiAmHandleToPtr(*hp);
  123. if((rc = _cmUiAmFree(p)) != kOkAmRC )
  124. return rc;
  125. hp->h = NULL;
  126. return rc;
  127. }
  128. bool cmUiAudioSysMstrIsValid( cmUiASMstrH_t h )
  129. { return h.h != NULL; }
  130. cmAmRC_t cmUiAudioSysMstrInitialize( cmUiASMstrH_t amH, const cmAudioSysSsInitMsg_t* m, const cmChar_t* inDevLabel, const cmChar_t* outDevLabel )
  131. {
  132. cmAmRC_t rc = kOkAmRC;
  133. cmAm_t* p = _cmUiAmHandleToPtr(amH);
  134. cmUiH_t uiH = p->uiH;
  135. cmUiSetAppId( p->uiH, p->appId );
  136. if( m->asSubIdx == 0 )
  137. {
  138. if((rc = _cmUiAmFreePanels(p,true)) != kOkAmRC )
  139. return rc;
  140. assert(p->list == NULL );
  141. }
  142. // create the panel recd and link it to the beginning of the list
  143. cmAmPanel_t* pp = cmMemAllocZ(cmAmPanel_t,1);
  144. pp->link = p->list;
  145. p->list = pp;
  146. pp->asSubIdx = m->asSubIdx;
  147. pp->iDevIdx = m->inDevIdx;
  148. pp->oDevIdx = m->outDevIdx;
  149. pp->iChCnt = m->inChCnt;
  150. pp->oChCnt = m->outChCnt;
  151. pp->panelId = p->nextId++;
  152. pp->updateId = p->nextId++;
  153. pp->wakeupId = p->nextId++;
  154. pp->msgCbId = p->nextId++;
  155. pp->audioCbId = p->nextId++;
  156. pp->a[kLabelAmId] = p->nextId;
  157. pp->a[kInSliderAmId] = p->nextId += m->inChCnt;
  158. pp->a[kInMeterAmId] = p->nextId += m->inChCnt;
  159. pp->a[kInToneAmId] = p->nextId += m->inChCnt;
  160. pp->a[kInPassAmId] = p->nextId += m->inChCnt;
  161. pp->a[kInMuteAmId] = p->nextId += m->inChCnt;
  162. pp->baseOutId = p->nextId += m->inChCnt;
  163. pp->a[kOutSliderAmId] = pp->baseOutId;
  164. pp->a[kOutMeterAmId] = p->nextId += m->outChCnt;
  165. pp->a[kOutToneAmId] = p->nextId += m->outChCnt;
  166. pp->a[kOutPassAmId] = p->nextId += m->outChCnt;
  167. pp->a[kOutMuteAmId] = p->nextId += m->outChCnt;
  168. p->nextId += m->outChCnt;
  169. unsigned panelId = pp->panelId;
  170. unsigned colW = 50;
  171. unsigned ctlW = 45;
  172. unsigned n = 31;
  173. cmChar_t chNumStr[ n+1 ];
  174. int w;
  175. if( cmUiCreatePanel(uiH, panelId, "Master" ) != kOkUiRC )
  176. {
  177. rc = cmErrMsg(&p->err,kUiFailAmRC,"Panel %i create failed.",panelId);
  178. goto errLabel;
  179. }
  180. cmUiSetFillRows( uiH, panelId, true );
  181. cmUiCreateProgress(uiH, panelId, pp->updateId, "Update", 0, 0, 1, 0 );
  182. cmUiCreateProgress(uiH, panelId, pp->wakeupId, "Wakeup", 0, 0, 1, 0 );
  183. cmUiCreateProgress(uiH, panelId, pp->msgCbId, "Message", 0, 0, 1, 0 );
  184. cmUiCreateProgress(uiH, panelId, pp->audioCbId,"Audio", 0, 0, 1, 0 );
  185. cmUiSetFillRows( uiH, panelId, false );
  186. cmUiNewLine( uiH, panelId );
  187. cmUiCreateLabel( uiH, panelId, cmInvalidId, inDevLabel, kInsideUiFl | kLeftUiFl );
  188. cmUiNewLine( uiH, panelId );
  189. unsigned i;
  190. for(i=0; i<m->inChCnt; ++i)
  191. {
  192. snprintf(chNumStr,n,"%i",i);
  193. cmUiSetNextW( uiH, panelId, ctlW );
  194. cmUiCreateLabel( uiH, panelId, cmInvalidId, chNumStr, 0 );
  195. cmUiCreateVSlider(uiH, panelId, pp->a[kInSliderAmId] + i, NULL, 0, kMinDb, kMaxDb, 0.1, 0 );
  196. cmUiPlaceRight( uiH, panelId );
  197. cmUiCreateVMeter( uiH, panelId, pp->a[kInMeterAmId] + i, NULL, 0, kMtrMin, kMtrMax, 0 );
  198. w = cmUiSetW( uiH, panelId, ctlW );
  199. cmUiCreateCheck( uiH, panelId, pp->a[kInToneAmId] + i, "T", 0, false );
  200. cmUiCreateCheck( uiH, panelId, pp->a[kInPassAmId] + i, "P", 0, false );
  201. cmUiCreateCheck( uiH, panelId, pp->a[kInMuteAmId] + i, "M", 0, false );
  202. cmUiSetW( uiH, panelId, w );
  203. cmUiSetBaseCol( uiH, panelId, 5 + (i+1)*colW);
  204. }
  205. cmUiSetBaseCol( uiH, panelId, 0);
  206. cmUiNewLine( uiH, panelId );
  207. cmUiCreateLabel( uiH,panelId, cmInvalidId, outDevLabel, kInsideUiFl | kLeftUiFl );
  208. cmUiNewLine( uiH, panelId );
  209. for(i=0; i<m->outChCnt; ++i)
  210. {
  211. snprintf(chNumStr,n,"%i",i);
  212. cmUiSetNextW( uiH, panelId, ctlW );
  213. cmUiCreateLabel( uiH, panelId, cmInvalidId, chNumStr, 0 );
  214. cmUiCreateVSlider(uiH, panelId, pp->a[kOutSliderAmId] + i, NULL, 0, kMinDb, kMaxDb, 0.1, 0 );
  215. cmUiPlaceRight( uiH, panelId );
  216. cmUiCreateVMeter( uiH, panelId, pp->a[kOutMeterAmId] + i, NULL, 0, kMtrMin, kMtrMax, 0 );
  217. w = cmUiSetW( uiH, panelId, ctlW );
  218. cmUiCreateCheck( uiH, panelId, pp->a[kOutToneAmId] + i, "T", 0, false );
  219. cmUiCreateCheck( uiH, panelId, pp->a[kOutPassAmId] + i, "P", 0, false );
  220. cmUiCreateCheck( uiH, panelId, pp->a[kOutMuteAmId] + i, "M", 0, false );
  221. cmUiSetW( uiH, panelId, w );
  222. cmUiSetBaseCol( uiH, panelId, 5 + (i+1)*colW);
  223. }
  224. errLabel:
  225. return rc;
  226. }
  227. cmAmPanel_t* _cmUiAmFindPanel( cmAm_t* p, unsigned panelId )
  228. {
  229. cmAmPanel_t* pp = p->list;
  230. for(; pp!=NULL; pp=pp->link)
  231. if( pp->panelId == panelId )
  232. return pp;
  233. cmErrMsg(&p->err,kPanelNotFoundAmRC,"The panel %i was not found.",panelId);
  234. return NULL;
  235. }
  236. unsigned _cmUiAmCtlTypeId( cmAm_t* p, cmAmPanel_t* pp, cmUiCId_t cId, unsigned usrId,
  237. unsigned sliderId, unsigned toneId, unsigned passId, unsigned muteId )
  238. {
  239. switch( cId )
  240. {
  241. case kSliderUiCId:
  242. assert( pp->a[sliderId] <= usrId && usrId < pp->a[sliderId]+pp->oChCnt);
  243. return sliderId;
  244. break;
  245. case kCheckUiCId:
  246. if( pp->a[toneId] <= usrId && usrId < pp->a[toneId]+pp->oChCnt )
  247. return toneId;
  248. if( pp->a[passId] <= usrId && usrId < pp->a[passId]+pp->oChCnt )
  249. return passId;
  250. if( pp->a[muteId] <= usrId && usrId < pp->a[muteId]+pp->oChCnt )
  251. return muteId;
  252. break;
  253. default:
  254. assert(0);
  255. break;
  256. }
  257. return cmInvalidId;
  258. }
  259. cmUiRC_t cmUiAudioSysMstrOnUiEvent( cmUiASMstrH_t h, const cmUiDriverArg_t* a )
  260. {
  261. cmUiRC_t rc = kOkUiRC;
  262. cmAm_t* p = _cmUiAmHandleToPtr(h);
  263. cmAmPanel_t* pp;
  264. cmAudioSysMstr_t r;
  265. unsigned typeId;
  266. if((pp = _cmUiAmFindPanel( p, a->panelId )) == NULL)
  267. return cmErrLastRC(&p->err);
  268. if( a->usrId == pp->panelId )
  269. {
  270. cmAudioSysStatusNotifyEnable(p->asH, pp->asSubIdx, a->ival );
  271. return rc;
  272. }
  273. if( a->usrId >= pp->baseOutId )
  274. typeId = _cmUiAmCtlTypeId(p,pp,a->cId,a->usrId,kOutSliderAmId,kOutToneAmId,kOutPassAmId,kOutMuteAmId);
  275. else
  276. typeId = _cmUiAmCtlTypeId(p,pp,a->cId,a->usrId,kInSliderAmId,kInToneAmId,kInPassAmId,kInMuteAmId);
  277. assert( typeId != cmInvalidId );
  278. if( typeId == cmInvalidId )
  279. return cmErrMsg(&p->err,kCtlNotFoundUiRC,"The type of a UI control could not be determined.");
  280. unsigned asInFl = 0;
  281. unsigned asCtlId = cmInvalidId;
  282. unsigned asCh = a->usrId - pp->a[typeId];
  283. double asValue = 0;
  284. switch( typeId )
  285. {
  286. case kInSliderAmId:
  287. asInFl = 1;
  288. asCtlId = kSliderUiAsId;
  289. asValue = a->fval;
  290. break;
  291. case kInToneAmId:
  292. asInFl = 1;
  293. asCtlId = kToneUiAsId;
  294. asValue = a->ival;
  295. break;
  296. case kInPassAmId:
  297. asInFl = 1;
  298. asCtlId = kPassUiAsId;
  299. asValue = a->ival;
  300. break;
  301. case kInMuteAmId:
  302. asInFl = 1;;
  303. asCtlId = kMuteUiAsId;
  304. asValue = a->ival;
  305. break;
  306. case kOutSliderAmId:
  307. asCtlId = kSliderUiAsId;
  308. asValue = a->fval;
  309. break;
  310. case kOutToneAmId:
  311. asCtlId = kToneUiAsId;
  312. asValue = a->ival;
  313. break;
  314. case kOutPassAmId:
  315. asCtlId = kPassUiAsId;
  316. asValue = a->ival;
  317. break;
  318. case kOutMuteAmId:
  319. asCtlId = kMuteUiAsId;
  320. asValue = a->ival;
  321. break;
  322. }
  323. unsigned asDevIdx = asInFl ? pp->iDevIdx : pp->oDevIdx;
  324. r.asSubIdx = pp->asSubIdx;
  325. r.uiId = kUiMstrSelAsId;
  326. r.selId = cmInvalidId;
  327. r.instId = cmAudioSysFormUiInstId(asDevIdx,asCh,asInFl,asCtlId);
  328. r.instVarId = cmInvalidId;
  329. r.value = asValue;
  330. if( cmAudioSysDeliverMsg(p->asH, &r, sizeof(r), cmInvalidId ) != kOkAsRC )
  331. rc = cmErrMsg(&p->err,kSubSysFailUiRC,"Audio System master control UI message delivery to the audio system failed.");
  332. return rc;
  333. }
  334. cmUiRC_t cmUiAudioSysMstrOnStatusEvent( cmUiASMstrH_t h, const cmAudioSysStatus_t* m, const double* iMeterArray, const double* oMeterArray )
  335. {
  336. cmAm_t* p = _cmUiAmHandleToPtr(h);
  337. cmAmPanel_t* pp = p->list;
  338. for(; pp!=NULL; pp=pp->link)
  339. if(pp->asSubIdx == m->asSubIdx )
  340. break;
  341. if( pp == NULL )
  342. return cmErrMsg(&p->err,kPanelNotFoundUiRC,"The panel associated with Audio system index %i could not be found.",m->asSubIdx);
  343. cmUiSetAppId(p->uiH,p->appId);
  344. cmUiSetInt(p->uiH, pp->updateId, m->updateCnt != pp->updateCnt );
  345. cmUiSetInt(p->uiH, pp->wakeupId, m->wakeupCnt != pp->wakeupCnt );
  346. cmUiSetInt(p->uiH, pp->msgCbId, m->msgCbCnt != pp->msgCbCnt );
  347. cmUiSetInt(p->uiH, pp->audioCbId, m->audioCbCnt != pp->audioCbCnt );
  348. pp->updateCnt = m->updateCnt;
  349. pp->wakeupCnt = m->wakeupCnt;
  350. pp->msgCbCnt = m->msgCbCnt;
  351. pp->audioCbCnt= m->audioCbCnt;
  352. cmUiSetAppId(p->uiH,cmInvalidId);
  353. return kOkUiRC;
  354. }