Programmable real-time audio signal processing application
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.

Fl_DevCfgGroup.cpp 29KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. #include <FL/Fl.H>
  2. #include <FL/Fl_Widget.H>
  3. #include <FL/Fl_Group.H>
  4. #include <FL/Fl_Tabs.H>
  5. #include <FL/Fl_Button.H>
  6. #include <FL/Fl_Check_Button.H>
  7. #include <FL/Fl_Box.H>
  8. #include <Fl/Fl_Input.H>
  9. #include <Fl/Fl_Value_Input.H>
  10. #include <Fl/Fl_Menu_Button.H>
  11. #include "cmGlobal.h"
  12. #include "cmFloatTypes.h"
  13. #include "cmRpt.h"
  14. #include "cmErr.h"
  15. #include "cmCtx.h"
  16. #include "cmMem.h"
  17. #include "cmMallocDebug.h"
  18. #include "cmThread.h"
  19. #include "cmJson.h"
  20. #include "cmTime.h"
  21. #include "cmAudioPort.h"
  22. #include "cmMidi.h"
  23. #include "cmMidiPort.h"
  24. #include "cmUdpPort.h"
  25. #include "cmRtSysMsg.h"
  26. #include "cmRtNet.h"
  27. #include "cmRtSys.h"
  28. #include "cmDevCfg.h"
  29. #include "Fl_DevCfgGroup.h"
  30. #define DEVCFG_NONE_STR "None"
  31. Fl_DevCfgGroup::Fl_DevCfgGroup(cmDevCfgH_t dcH,
  32. int xx, int yy, int ww, int hh, const char* label )
  33. : Fl_Group(xx,yy,ww,hh,label),
  34. _dcH(dcH)
  35. {
  36. typedef enum
  37. {
  38. kInvalidTId,
  39. kLabelTId,
  40. kBtnTId,
  41. kMenuBtnTId,
  42. kChkBtnTId,
  43. kInputTId,
  44. kValueTId
  45. } type_t;
  46. typedef struct
  47. {
  48. unsigned id;
  49. type_t tid;
  50. int x;
  51. int y;
  52. int w;
  53. int h;
  54. int flags;
  55. const char* label;
  56. } recd_t;
  57. const int r = -1; // current row
  58. const int rn = -2; // next row
  59. const int cn = -1; // next column
  60. int r00 = 50;
  61. int c0 = 2;
  62. int c3 = 400;
  63. int c4 = 650;
  64. int lw = 250; // device/port/preset label widths
  65. int vw = 75; // value widths
  66. int iw = 125;
  67. int dw = 400;
  68. int w = 100;
  69. int h = 25;
  70. int fl = 0;
  71. int fl1 = FL_WHEN_CHANGED;
  72. recd_t a[] =
  73. {
  74. { kLocLabelCId, kLabelTId, c0,r00, w, h, fl, "Location:" },
  75. { kLocMenuCId, kMenuBtnTId, c0, rn, lw, h, fl, NULL },
  76. { kLocDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" },
  77. { kLocStringCId, kInputTId, c0, rn, lw, h, fl1, NULL },
  78. { kLocStoreBtnCId, kBtnTId, cn, r, w, h, fl, "Create" },
  79. { kMidiLabelCId, kLabelTId, c0, rn, w, h, fl, "MIDI:" },
  80. { kMidiCfgMenuCId, kMenuBtnTId, c0, rn, lw, h, fl, NULL },
  81. { kMidiDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" },
  82. { kMidiCfgDescCId, kLabelTId, c0, rn, dw, h, fl, NULL },
  83. { kMidiCfgStringCId, kInputTId, c0, rn, lw, h, fl1, NULL },
  84. { kMidiApplyBtnCId, kBtnTId, cn, r, w, h, fl, "Store" },
  85. { kMidiDevMenuCId, kMenuBtnTId, c0, rn, lw, h, fl1, NULL },
  86. { kMidiDevLabelCId, kLabelTId, cn, r, w, h, fl, "MIDI Device"},
  87. { kMidiPortMenuCId, kMenuBtnTId, c0, rn, lw, h, fl1, NULL },
  88. { kMidiPortLabelCId, kLabelTId, cn, r, w, h, fl, "MIDI Port"},
  89. { kMidiInputCheckCId, kChkBtnTId, c0, rn, w, h, fl1, "Input"},
  90. { kAudioLabelCId, kLabelTId, c3,r00, w, h, fl, "Audio:" },
  91. { kAudioCfgMenuCId, kMenuBtnTId, c3, rn, lw, h, fl, NULL },
  92. { kAudioDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" },
  93. { kAudioCfgDescCId, kLabelTId, c3, rn, dw, h*2,fl, NULL },
  94. { kAudioCfgStringCId, kInputTId, c3, rn, lw, h, fl1, NULL },
  95. { kAudioApplyBtnCId, kBtnTId, cn, r, w, h, fl, "Store" },
  96. { kAudioInDevMenuCId, kMenuBtnTId, c3, rn, lw, h, fl1, NULL },
  97. { kAudioInDevLabelCId, kLabelTId, cn, r, w, h, fl, "Audio Input"},
  98. { kAudioOutDevMenuCId, kMenuBtnTId, c3, rn, lw, h, fl1, NULL },
  99. { kAudioOutDevLabelCId, kLabelTId, cn, r, w, h, fl1, "Audio Output"},
  100. { kAudioMsgQueSizeValCId,kValueTId, c3, rn, vw, h, fl1, "Msg Queue Bytes" },
  101. { kAudioDevFpCValCId, kValueTId, c4, r, vw, h, fl1, "Audio Frames" },
  102. { kAudioDspFpCValCId, kValueTId, c3, rn, vw, h, fl1, "DSP Frames" },
  103. { kAudioBufCntValCId, kValueTId, c4, r, vw, h, fl1, "Buffer Count" },
  104. { kAudioSrateMenuCId, kMenuBtnTId, c3, rn, w, h, fl1, "Rate" },
  105. { kAudioSyncInCheckCId, kChkBtnTId, c4, r, w, h, fl1, "Sync to Input"},
  106. { kAudioNetNodeStringCId,kInputTId, c3, rn, vw, h, fl1, "Net Node Label"},
  107. { kAudioBcastAddrStringCId,kInputTId, c4, r, iw, h, fl1, "Bcast Address"},
  108. { kAudioIpAddrStringCId, kInputTId, c3, rn, iw, h, fl1, "IP Address"},
  109. { kAudioIpPortValCId, kValueTId, c4, r, vw, h, fl1, "IP Port"},
  110. { kAudioActiveCheckCId, kChkBtnTId, c3, rn, w, h, fl1, "Active"},
  111. /*
  112. { kNetLabelCId, kLabelTId, c3, rn, w, h, fl, "Remote Network Nodes:" },
  113. { kNetCfgMenuCId, kMenuBtnTId, c3, rn, lw, h, fl, NULL },
  114. { kNetDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" },
  115. { kNetCfgDescCId, kLabelTId, c3, rn, dw, h, fl, NULL },
  116. { kNetCfgStringCId, kInputTId, c3, rn, lw, h, fl, NULL },
  117. { kNetApplyBtnCId, kBtnTId, cn, r, w, h, fl, "Store" },
  118. { kNetSockAddrStringCId, kInputTId, c3, rn, w, h, fl1, "IP Address" },
  119. { kNetPortNumbValCId, kValueTId, c4, r, vw, h, fl1, "IP Port" },
  120. { kNetLocalCheckCId, kChkBtnTId, c3, rn, w, h, fl1, "Local"},
  121. { kNetActiveCheckCId, kChkBtnTId, cn, r, vw, h, fl1, "Active"},
  122. */
  123. { kInvalidCId, kInvalidTId, 0, 0, 0, 0, 0, NULL }
  124. };
  125. const recd_t* d = a;
  126. int y = r00;
  127. int x = c0;
  128. int ny = 0;
  129. int nx = 0;
  130. for(; d->id != kInvalidCId; ++d)
  131. {
  132. Fl_Widget* wp = NULL;
  133. ctl_t* c = new ctl_t;
  134. c->id = d->id;
  135. c->p = this;
  136. switch( d->y )
  137. {
  138. case r: break;
  139. case rn: y = ny; break;
  140. default: y = d->y; break;
  141. }
  142. switch( d->x )
  143. {
  144. case cn: x = nx; break;
  145. default: x = d->x; break;
  146. }
  147. switch( d->tid )
  148. {
  149. case kLabelTId:
  150. wp = c->u.box = new Fl_Box(x,y,d->w,d->h,d->label);
  151. wp->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
  152. break;
  153. case kBtnTId:
  154. wp = c->u.btn = new Fl_Button(x,y,d->w,d->h,d->label);
  155. break;
  156. case kMenuBtnTId:
  157. wp = c->u.mbt = new Fl_Menu_Button(x,y,d->w,d->h,d->label);
  158. break;
  159. case kChkBtnTId:
  160. wp = c->u.chk = new Fl_Check_Button(x,y,d->w,d->h,d->label);
  161. break;
  162. case kInputTId:
  163. wp = c->u.inp = new Fl_Input(x,y,d->w,d->h,d->label);
  164. wp->align(FL_ALIGN_RIGHT);
  165. break;
  166. case kValueTId:
  167. wp = c->u.val = new Fl_Value_Input(x,y,d->w,d->h,d->label);
  168. wp->align(FL_ALIGN_RIGHT);
  169. break;
  170. default:
  171. break;
  172. }
  173. if( wp != NULL )
  174. {
  175. if( cmIsFlag(d->flags,FL_WHEN_CHANGED) )
  176. wp->when(FL_WHEN_CHANGED);
  177. ny = y + d->h + 2;
  178. nx = x + d->w + 2;
  179. wp->callback(Fl_DevCfgGroup::_s_ctl_cb,c);
  180. _ctlV.push_back(c);
  181. }
  182. }
  183. //_loadMenuButtons();
  184. _syncLoc();
  185. }
  186. Fl_DevCfgGroup::~Fl_DevCfgGroup()
  187. {
  188. unsigned i;
  189. for(i=0; i<_ctlV.size(); ++i)
  190. delete _ctlV[i];
  191. }
  192. void Fl_DevCfgGroup::onEnableAudio( bool enableFl )
  193. {
  194. if( enableFl )
  195. {
  196. deactivate();
  197. }
  198. else
  199. {
  200. activate();
  201. parent()->redraw();
  202. }
  203. }
  204. bool Fl_DevCfgGroup::_loadLocBtn()
  205. {
  206. ctl_t* c;
  207. if((c = _idToCtl(kLocMenuCId)) == NULL )
  208. return false;
  209. int val = c->u.mbt->value();
  210. c->u.mbt->clear();
  211. unsigned i;
  212. for(i=0; i<cmDevCfgLocCount(_dcH); ++i)
  213. c->u.mbt->add(cmStringNullGuard(cmDevCfgLocLabel(_dcH,i)),0,_s_ctl_cb,c);
  214. _restoreMenuValue(kLocMenuCId, val );
  215. if((c = _idToCtl(kLocStoreBtnCId)) != NULL)
  216. c->u.btn->deactivate();
  217. return true;
  218. }
  219. void Fl_DevCfgGroup::_recallLoc()
  220. {
  221. ctl_t* c;
  222. const char* s;
  223. if((s = _getMenuCtl(kLocMenuCId)) == NULL )
  224. goto errLabel;
  225. if( cmDevCfgLocRecall(_dcH,s) != kOkDcRC )
  226. goto errLabel;
  227. if((c = _idToCtl(kLocStringCId)) == NULL )
  228. goto errLabel;
  229. c->u.inp->copy_label(s);
  230. errLabel:
  231. _syncLoc();
  232. }
  233. void Fl_DevCfgGroup::_storeLoc()
  234. {
  235. ctl_t* c;
  236. const char* s;
  237. if((c = _idToCtl(kLocStringCId)) == NULL )
  238. goto errLabel;
  239. if((s = c->u.inp->value()) == NULL )
  240. goto errLabel;
  241. if( cmDevCfgLocStore(_dcH,s) != kOkDcRC )
  242. goto errLabel;
  243. errLabel:
  244. _syncLoc();
  245. }
  246. void Fl_DevCfgGroup::_deleteLoc()
  247. {
  248. const char* s;
  249. if((s = _getMenuCtl(kLocMenuCId)) == NULL )
  250. goto errLabel;
  251. if( cmDevCfgLocDelete(_dcH,s) != kOkDcRC )
  252. goto errLabel;
  253. errLabel:
  254. _syncLoc();
  255. }
  256. // load MIDI device menu from the MIDI driver
  257. void Fl_DevCfgGroup::_loadMidiDevBtn()
  258. {
  259. unsigned j;
  260. ctl_t* c;
  261. if((c = _idToCtl(kMidiDevMenuCId)) == NULL )
  262. return;
  263. int val = c->u.mbt->value();
  264. c->u.mbt->clear();
  265. for(j=0; j<cmMpDeviceCount(); ++j)
  266. {
  267. c->u.mbt->add(cmStringNullGuard(cmMpDeviceName(j)),0,_s_ctl_cb,c);
  268. }
  269. _restoreMenuValue(kMidiDevMenuCId, val );
  270. }
  271. // Load the MIDI port menu from the MIDI driver accoring
  272. // to the MIDI device seleted in the MIDI device menu
  273. void Fl_DevCfgGroup::_loadMidiPortBtn()
  274. {
  275. ctl_t* c;
  276. if((c = _idToCtl(kMidiDevMenuCId)) == NULL )
  277. return;
  278. int devIdx = c->u.mbt->value();
  279. if((c = _idToCtl(kMidiInputCheckCId)) == NULL )
  280. return;
  281. unsigned flags = c->u.chk->value() ? kInMpFl : kOutMpFl;
  282. unsigned n = devIdx<0 ? 0 : cmMpDevicePortCount(devIdx,flags);
  283. if((c = _idToCtl(kMidiPortMenuCId)) == NULL )
  284. return;
  285. c->u.mbt->clear();
  286. int val = c->u.mbt->value();
  287. for(unsigned j=0; j<n; ++j)
  288. c->u.mbt->add(cmStringNullGuard(cmMpDevicePortName(devIdx,flags,j)),0,_s_ctl_cb,c);
  289. _restoreMenuValue(kMidiPortMenuCId, val );
  290. }
  291. // Load the audio device menu from the audio port driver.
  292. void Fl_DevCfgGroup::_loadAudioDevBtn( unsigned id, unsigned devIdx )
  293. {
  294. ctl_t* c;
  295. unsigned i;
  296. if((c = _idToCtl(id)) == NULL )
  297. return;
  298. unsigned n = cmApDeviceCount();
  299. bool inputFl = id == kAudioInDevMenuCId;
  300. int val = c->u.mbt->value();
  301. c->u.mbt->clear();
  302. for(i=0; i<n; ++i)
  303. if( cmApDeviceChannelCount( i, inputFl ) > 0 )
  304. {
  305. const cmChar_t* str;
  306. if((str = cmApDeviceLabel(i)) != NULL )
  307. {
  308. bool activeFl = cmDevCfgAudioIsDeviceActive(_dcH, str, inputFl );
  309. if( devIdx == i )
  310. activeFl = false;
  311. c->u.mbt->add(str,0,NULL,NULL, activeFl ? FL_MENU_INACTIVE : 0);
  312. }
  313. }
  314. c->u.mbt->add(DEVCFG_NONE_STR,0,_s_ctl_cb,c);
  315. _restoreMenuValue(id, val );
  316. if( devIdx == cmInvalidIdx )
  317. _setMenuBtnWithString(id,DEVCFG_NONE_STR);
  318. }
  319. // Load the sample rate menu with constant values.
  320. void Fl_DevCfgGroup::_loadAudioSrateBtn()
  321. {
  322. ctl_t* c;
  323. if((c = _idToCtl(kAudioSrateMenuCId)) == NULL )
  324. return;
  325. int val = c->u.mbt->value();
  326. char* p = 0;
  327. c->u.mbt->add("96000",0,NULL,p+96000);
  328. c->u.mbt->add("48000",0,NULL,p+48000);
  329. c->u.mbt->add("44100",0,NULL,p+44100);
  330. c->u.mbt->add("22050",0,NULL,p+22050);
  331. if( val < 0 || val >= c->u.mbt->size() )
  332. _setSrate(kAsDfltSrate);
  333. else
  334. if( c->u.mbt->size() > 0 )
  335. {
  336. c->u.mbt->value(val);
  337. c->u.mbt->copy_label( c->u.mbt->mvalue()->label() );
  338. }
  339. }
  340. // Load a cfg menu with the labels of the cfg records from cmDevCfg.
  341. // (but don't update the label yet).
  342. void Fl_DevCfgGroup::_loadCfgMenu(cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned deleteCtlId )
  343. {
  344. ctl_t* c;
  345. if((c = _idToCtl(menuCtlId)) == NULL )
  346. return;
  347. // get the current value of the menu
  348. int val = c->u.mbt->value();
  349. // empty the menu
  350. c->u.mbt->clear();
  351. // get the count of cfg recds
  352. unsigned n = cmDevCfgCount(_dcH,typeId);
  353. const cmChar_t* label;
  354. // reload the menu from cmDevCfg
  355. for(unsigned i=0; i<n; ++i)
  356. if((label = cmDevCfgLabel(_dcH,typeId,i)) != NULL )
  357. c->u.mbt->add(label,0,_s_ctl_cb,c);
  358. // get the count of menu items
  359. int sz = c->u.mbt->size();
  360. // if the original value is no longer valid then set the value to
  361. // the most likely valid value - zero.
  362. if( val < 0 || val >= sz )
  363. val = 0;
  364. // if the menu is not empty then set the value
  365. if( sz > 0 )
  366. c->u.mbt->value(val);
  367. // update the 'delete' btn
  368. if((c = _idToCtl(deleteCtlId)) != NULL )
  369. {
  370. // if the menu is empty deactivate the delete btn
  371. if( sz > 0 )
  372. c->u.btn->activate();
  373. else
  374. c->u.btn->deactivate();
  375. }
  376. }
  377. // Load the cfg label edit string, description and type
  378. // specific fields from the cmDevCfg based on the currently
  379. // selected cfg menu item.
  380. void Fl_DevCfgGroup::_recallCfg(cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned strCtlId, unsigned descCtlId, unsigned storeCtlId )
  381. {
  382. const Fl_Menu_Item* mip;
  383. ctl_t* c;
  384. // get the cfg menu
  385. if((c = _idToCtl(menuCtlId)) == NULL )
  386. return;
  387. // get the current value of the cfg menu
  388. int menuIdx = c->u.mbt->value();
  389. if( menuIdx == -1 )
  390. return;
  391. // get the current menu item from the cfg menu
  392. if((mip = c->u.mbt->mvalue()) == NULL)
  393. return;
  394. // update the cfg menu label
  395. c->u.mbt->copy_label( mip->label() );
  396. // set the cfg string text
  397. if((c = _idToCtl(strCtlId)) != NULL )
  398. c->u.inp->value( mip->label() );
  399. // set the desc string
  400. if((c = _idToCtl(descCtlId)) != NULL )
  401. {
  402. const cmChar_t* s = cmDevCfgDesc(_dcH, typeId, menuIdx );
  403. c->u.box->copy_label( s==NULL ? "" : s );
  404. }
  405. // disable to store btn
  406. if((c = _idToCtl(storeCtlId)) != NULL )
  407. c->u.btn->deactivate();
  408. switch( typeId )
  409. {
  410. case kMidiDcmTId:
  411. {
  412. const cmDcmMidi_t* r = cmDevCfgMidiCfg(_dcH,menuIdx);
  413. // set the midi device from the cfg recd
  414. _setMenuBtnWithString(kMidiDevMenuCId,r==NULL ? "" : r->devLabelStr);
  415. _setCheckCtl( kMidiInputCheckCId, r==NULL ? 0 : r->inputFl );
  416. // sync the midi port menu to the device
  417. _loadMidiPortBtn();
  418. }
  419. break;
  420. case kAudioDcmTId:
  421. {
  422. const cmDcmAudio_t* r = cmDevCfgAudioCfg(_dcH,menuIdx);
  423. _setMenuBtnWithString(kAudioInDevMenuCId, r==NULL ? "" : (r->inDevLabelStr==NULL ? DEVCFG_NONE_STR : r->inDevLabelStr));
  424. _setMenuBtnWithString(kAudioOutDevMenuCId,r==NULL ? "" : (r->outDevLabelStr==NULL ? DEVCFG_NONE_STR : r->outDevLabelStr));
  425. _setValueCtl(kAudioMsgQueSizeValCId, r==NULL ? 0 : r->rtSysArgs.msgQueueByteCnt);
  426. _setValueCtl(kAudioDevFpCValCId, r==NULL ? 0 : r->rtSysArgs.devFramesPerCycle);
  427. _setValueCtl(kAudioDspFpCValCId, r==NULL ? 0 : r->rtSysArgs.dspFramesPerCycle);
  428. _setValueCtl(kAudioBufCntValCId, r==NULL ? 0 : r->rtSysArgs.audioBufCnt);
  429. _setCheckCtl(kAudioSyncInCheckCId, r==NULL ? 0 : r->rtSysArgs.syncInputFl);
  430. _setInputCtl(kAudioNetNodeStringCId, r==NULL ? "" : r->netNodeLabel);
  431. _setInputCtl(kAudioBcastAddrStringCId, r==NULL ? "" : r->bcastAddr);
  432. _setInputCtl(kAudioIpAddrStringCId, r==NULL ? "" : r->ipAddr);
  433. _setValueCtl(kAudioIpPortValCId, r==NULL ? 0 : r->ipPort);
  434. _setCheckCtl(kAudioActiveCheckCId, r==NULL ? 0 : r->activeFl);
  435. _setSrate( r==NULL ? kAsDfltSrate : r->rtSysArgs.srate);
  436. //cmDevCfgAudioSetDefaultCfgIndex(_dcH,menuIdx);
  437. _loadAudioDevBtn(kAudioInDevMenuCId, r->rtSysArgs.inDevIdx );
  438. _loadAudioDevBtn(kAudioOutDevMenuCId, r->rtSysArgs.outDevIdx );
  439. }
  440. break;
  441. /*
  442. case kNetDcmTId:
  443. {
  444. const cmDcmNet_t* r = cmDevCfgNetCfg(_dcH,menuIdx);
  445. _setInputCtl(kNetSockAddrStringCId, r==NULL ? "" : r->sockAddr);
  446. _setValueCtl(kNetPortNumbValCId, r==NULL ? 0 : r->portNumber);
  447. _setCheckCtl(kNetActiveCheckCId, r==NULL ? 0 : r->activeFl);
  448. }
  449. break;
  450. */
  451. default:
  452. assert(0);
  453. break;
  454. }
  455. }
  456. void Fl_DevCfgGroup::_syncLoc()
  457. {
  458. ctl_t* c;
  459. unsigned idx;
  460. _loadLocBtn();
  461. if((idx = cmDevCfgLocCurIndex(_dcH)) == cmInvalidIdx )
  462. return;
  463. if((c = _idToCtl(kLocMenuCId)) == NULL )
  464. return;
  465. assert((int)idx < c->u.mbt->size() );
  466. if( (int)idx >= c->u.mbt->size() )
  467. return;
  468. c->u.mbt->value(idx);
  469. _setMenuBtnLabel(kLocMenuCId,kLocStringCId);
  470. // Load the menu's based on the currently
  471. // available hardware.
  472. _loadMidiDevBtn();
  473. _loadMidiPortBtn();
  474. _loadAudioDevBtn(kAudioInDevMenuCId,cmInvalidId);
  475. _loadAudioDevBtn(kAudioOutDevMenuCId,cmInvalidId);
  476. _loadAudioSrateBtn();
  477. // Set the default values for some fields. These values will only be
  478. // used if there is no availabe cmDevCfg data.
  479. _idToCtl(kAudioMsgQueSizeValCId)->u.val->value(kAsDfltMsgQueueByteCnt);
  480. _idToCtl(kAudioDevFpCValCId)->u.val->value(kAsDfltDevFramesPerCycle);
  481. _idToCtl(kAudioDspFpCValCId)->u.val->value(kAsDfltDspFramesPerCycle);
  482. _idToCtl(kAudioBufCntValCId)->u.val->value(kAsDfltBufCnt);
  483. _idToCtl(kAudioSyncInCheckCId)->u.chk->value(kAsDfltSyncToInputFl);
  484. // set the bounds for the IP port value
  485. _idToCtl(kAudioIpPortValCId)->u.val->bounds(0,65535);
  486. _idToCtl(kAudioIpPortValCId)->u.val->step(1);
  487. // Load the MIDI cfg information from cmDevCfg.
  488. _loadCfgMenu(kMidiDcmTId, kMidiCfgMenuCId, kMidiDeleteBtnCId );
  489. _recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId );
  490. // Load the Audio cfg information from cmDevCfg.
  491. _loadCfgMenu(kAudioDcmTId, kAudioCfgMenuCId, kAudioDeleteBtnCId );
  492. // Display the default audio configuration
  493. // if((c = _idToCtl(kAudioCfgMenuCId)) != NULL )
  494. // if((idx = cmDevCfgAudioGetDefaultCfgIndex(_dcH)) != cmInvalidIdx )
  495. // if( c->u.mbt->size() < (int)idx )
  496. // c->u.mbt->value(idx);
  497. _recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId );
  498. // Load the network cfg information from cmDevCfg.
  499. //_loadCfgMenu(kNetDcmTId, kNetCfgMenuCId, kNetDeleteBtnCId );
  500. //_recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId );
  501. }
  502. // Called when the MIDI 'Store' cfg button is pressed.
  503. // Creates or edits a MIDI cfg recd in cmDevCfg.
  504. void Fl_DevCfgGroup::_createMidiCfg()
  505. {
  506. const cmChar_t* cfgStr = _getInputCtl(kMidiCfgStringCId);
  507. const cmChar_t* devStr = _getMenuCtl(kMidiDevMenuCId);
  508. const cmChar_t* portStr = _getMenuCtl(kMidiPortMenuCId);
  509. bool inputFl = _getCheckCtl(kMidiInputCheckCId);
  510. // create or edit a MIDI cfg recd
  511. if( cmDevCfgNameMidiPort(_dcH,cfgStr,devStr,portStr,inputFl) == kOkDcRC )
  512. {
  513. // a MIDI cfg recd may have been created so reload the MIDI cfg menu btn
  514. _loadCfgMenu(kMidiDcmTId,kMidiCfgMenuCId,kMidiDeleteBtnCId);
  515. // set the MIDI cfg menu btn to display the label of the cfg just edited or creaed
  516. _setMenuBtnWithString(kMidiCfgMenuCId,cfgStr);
  517. // update the other MIDI fields based on the current cfg menu value
  518. _recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId );
  519. }
  520. }
  521. // Called when the Audio 'Store' button is pressed.
  522. // Creates or edits an audio cfg recd in the cmDevCfg.
  523. void Fl_DevCfgGroup::_createAudioCfg()
  524. {
  525. const cmChar_t* cfgStr = _getInputCtl(kAudioCfgStringCId);
  526. const cmChar_t* inDevStr = _getMenuCtl(kAudioInDevMenuCId);
  527. const cmChar_t* outDevStr = _getMenuCtl(kAudioOutDevMenuCId);
  528. bool syncInFl = _getCheckCtl(kAudioSyncInCheckCId);
  529. unsigned msgQueCnt = _getValueCtl(kAudioMsgQueSizeValCId);
  530. unsigned devFpC = _getValueCtl(kAudioDevFpCValCId);
  531. unsigned dspFpC = _getValueCtl(kAudioDspFpCValCId);
  532. unsigned bufCnt = _getValueCtl(kAudioBufCntValCId);
  533. const cmChar_t* nodeStr = _getInputCtl(kAudioNetNodeStringCId);
  534. const cmChar_t* bcastAddr = _getInputCtl(kAudioBcastAddrStringCId);
  535. const cmChar_t* ipAddr = _getInputCtl(kAudioIpAddrStringCId);
  536. cmUdpPort_t ipPort = _getValueCtl(kAudioIpPortValCId);
  537. bool activeFl = _getCheckCtl(kAudioActiveCheckCId);
  538. double srate = _getSrate();
  539. if( strcmp(inDevStr,DEVCFG_NONE_STR)==0 )
  540. inDevStr = NULL;
  541. if( strcmp(outDevStr,DEVCFG_NONE_STR)==0 )
  542. outDevStr = NULL;
  543. // create or edit a audio cfg recd
  544. if( cmDevCfgNameAudioPort(_dcH,cfgStr,inDevStr,outDevStr,syncInFl,msgQueCnt,devFpC,dspFpC,bufCnt,srate,nodeStr,bcastAddr,ipAddr,ipPort,activeFl) == kOkDcRC )
  545. {
  546. // a new cfg recd may have been created so reload audio cfg menu
  547. _loadCfgMenu(kAudioDcmTId,kAudioCfgMenuCId,kAudioDeleteBtnCId);
  548. // set the cfg menu to display the label of the cfg just edited or created
  549. _setMenuBtnWithString(kAudioCfgMenuCId,cfgStr);
  550. // update the other audio fields based on the current cfg menu value
  551. _recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId );
  552. }
  553. }
  554. /*
  555. // Called when the Net 'Store' button is pressed.
  556. // Creates or edits a net cfg recd in the cmDevCfg.
  557. void Fl_DevCfgGroup::_createNetCfg()
  558. {
  559. const cmChar_t* cfgStr = _idToCtl(kNetCfgStringCId)->u.inp->value();
  560. const cmChar_t* addrStr = _idToCtl(kNetSockAddrStringCId)->u.inp->value();
  561. unsigned portNum = _idToCtl(kNetPortNumbValCId)->u.val->value();
  562. bool activeFl= _idToCtl(kNetActiveCheckCId)->u.chk->value();
  563. // create or edit a NET cfg recd
  564. if( cmDevCfgNameNetPort(_dcH,cfgStr,addrStr,portNum,activeFl) == kOkDcRC )
  565. {
  566. // a NET cfg recd may have been created so reload the NET cfg menu btn
  567. _loadCfgMenu(kNetDcmTId,kNetCfgMenuCId,kNetDeleteBtnCId);
  568. // set the NET cfg menu btn to display the label of the cfg just edited or creaed
  569. _setMenuBtnWithString(kNetCfgMenuCId,cfgStr);
  570. // update the other net fields based on the current cfg menu value
  571. _recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId );
  572. }
  573. }
  574. */
  575. void Fl_DevCfgGroup::_deleteCfg( cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned inpCtlId, unsigned descCtlId, unsigned storeCtlId, unsigned deleteCtlId )
  576. {
  577. ctl_t* c;
  578. const cmChar_t* s;
  579. int idx;
  580. if((s = _getMenuCtl(menuCtlId)) == NULL )
  581. goto errLabel;
  582. if(cmDevCfgDeleteCfg(_dcH, typeId, s ) != kOkDcRC )
  583. goto errLabel;
  584. if(( c = _idToCtl(menuCtlId)) == NULL )
  585. goto errLabel;
  586. if((idx = c->u.mbt->find_index(s)) < 0 )
  587. goto errLabel;
  588. c->u.mbt->remove(idx);
  589. if( c->u.mbt->size() > 0 )
  590. c->u.mbt->value(0);
  591. _loadCfgMenu(typeId,menuCtlId,deleteCtlId);
  592. _recallCfg(typeId,menuCtlId,inpCtlId,descCtlId,storeCtlId);
  593. errLabel:
  594. return;
  595. }
  596. void Fl_DevCfgGroup::_restoreMenuValue( unsigned menuCtlId, int val, int dfltVal )
  597. {
  598. ctl_t* c;
  599. if((c = _idToCtl(menuCtlId)) == NULL )
  600. return;
  601. if( val < 0 || val >= c->u.mbt->size() )
  602. val = dfltVal;
  603. if( c->u.mbt->size() > 0 )
  604. c->u.mbt->value(val);
  605. else
  606. c->u.mbt->value(-1);
  607. _setMenuBtnLabel(menuCtlId);
  608. }
  609. void Fl_DevCfgGroup::_setMenuBtnLabel( unsigned menuCtlId, unsigned inpCtlId )
  610. {
  611. ctl_t* c;
  612. const Fl_Menu_Item* mip;
  613. const char* s;
  614. if((c = _idToCtl(menuCtlId)) == NULL )
  615. goto errLabel;
  616. int v;
  617. if((v = c->u.mbt->value()) == -1 )
  618. goto errLabel;
  619. if((mip = c->u.mbt->mvalue()) == NULL )
  620. goto errLabel;
  621. if((s = mip->label()) == NULL || strlen(s)==0)
  622. s = ""; // the menu is empty or the label is invalid
  623. c->u.mbt->copy_label(s);
  624. if( inpCtlId != cmInvalidId )
  625. {
  626. if((c = _idToCtl(inpCtlId)) == NULL )
  627. goto errLabel;
  628. c->u.inp->copy_label(s);
  629. }
  630. errLabel:
  631. return;
  632. }
  633. void Fl_DevCfgGroup::_setMenuBtnWithString( unsigned menuCtlId, const char* string )
  634. {
  635. ctl_t* c;
  636. int idx;
  637. if((c = _idToCtl(menuCtlId)) == NULL )
  638. goto errLabel;
  639. if((idx = c->u.mbt->find_index(string)) < 0 )
  640. goto errLabel;
  641. c->u.mbt->value(idx);
  642. c->u.mbt->copy_label(string);
  643. errLabel:
  644. return;
  645. }
  646. void Fl_DevCfgGroup::_setCheckCtl( unsigned ctlId, int val )
  647. {
  648. ctl_t* c;
  649. if((c = _idToCtl(ctlId)) == NULL )
  650. return;
  651. c->u.chk->value(val);
  652. }
  653. void Fl_DevCfgGroup::_setValueCtl( unsigned ctlId, double val )
  654. {
  655. ctl_t* c;
  656. if((c = _idToCtl(ctlId)) == NULL )
  657. return;
  658. c->u.val->value(val);
  659. }
  660. void Fl_DevCfgGroup::_setInputCtl( unsigned ctlId, const cmChar_t* val )
  661. {
  662. ctl_t* c;
  663. if((c = _idToCtl(ctlId)) == NULL )
  664. return;
  665. c->u.inp->value(val);
  666. }
  667. const cmChar_t* Fl_DevCfgGroup::_getMenuCtl( unsigned ctlId )
  668. {
  669. ctl_t* c;
  670. const Fl_Menu_Item* mip;
  671. if((c = _idToCtl(ctlId)) == NULL)
  672. goto errLabel;
  673. if( c->u.mbt->value() == -1 )
  674. goto errLabel;
  675. if((mip = c->u.mbt->mvalue()) == NULL)
  676. goto errLabel;
  677. if( mip->label() == NULL )
  678. goto errLabel;
  679. return mip->label();
  680. errLabel:
  681. return "";
  682. }
  683. const cmChar_t* Fl_DevCfgGroup::_getInputCtl( unsigned ctlId )
  684. {
  685. ctl_t* c;
  686. if((c = _idToCtl(ctlId)) == NULL)
  687. goto errLabel;
  688. if( c->u.inp->value() == NULL )
  689. goto errLabel;
  690. return c->u.inp->value();
  691. errLabel:
  692. return "";
  693. }
  694. double Fl_DevCfgGroup::_getValueCtl( unsigned ctlId )
  695. {
  696. ctl_t* c;
  697. if((c = _idToCtl(ctlId)) == NULL)
  698. return 0;
  699. return c->u.val->value();
  700. }
  701. bool Fl_DevCfgGroup::_getCheckCtl( unsigned ctlId )
  702. {
  703. ctl_t* c;
  704. if((c = _idToCtl(ctlId)) == NULL)
  705. return 0;
  706. return c->u.chk->value();
  707. }
  708. double Fl_DevCfgGroup::_getSrate()
  709. {
  710. ctl_t* c;
  711. const Fl_Menu_Item* mip;
  712. if((c = _idToCtl(kAudioSrateMenuCId)) == NULL )
  713. return kAsDfltSrate;
  714. assert( c->u.mbt->value() != -1);
  715. if((mip = c->u.mbt->mvalue()) == NULL )
  716. return kAsDfltSrate;
  717. return (char*)mip->user_data() - (char*)NULL;
  718. }
  719. void Fl_DevCfgGroup::_setSrate( double srate )
  720. {
  721. ctl_t* c;
  722. if((c = _idToCtl(kAudioSrateMenuCId)) == NULL )
  723. return;
  724. int i;
  725. for(i=0; i<c->u.mbt->size(); ++i)
  726. {
  727. const Fl_Menu_Item* mip = &c->u.mbt->menu()[i];
  728. if( mip != NULL && ((char*)mip->user_data() - (char*)NULL) == srate)
  729. {
  730. c->u.mbt->value(i);
  731. c->u.mbt->copy_label( mip->label() );
  732. return;
  733. }
  734. }
  735. }
  736. void Fl_DevCfgGroup::_enableStoreBtn( unsigned ctlId )
  737. {
  738. ctl_t* c;
  739. if((c = _idToCtl(ctlId)) == NULL )
  740. return;
  741. c->u.btn->activate();
  742. }
  743. Fl_DevCfgGroup::ctl_t* Fl_DevCfgGroup::_idToCtl( unsigned id )
  744. {
  745. unsigned i = 0;
  746. for(i=0; i<_ctlV.size(); ++i)
  747. if( _ctlV[i]->id == id )
  748. return _ctlV[i];
  749. assert(0);
  750. return NULL;
  751. }
  752. void Fl_DevCfgGroup::_s_ctl_cb( Fl_Widget* w, void* arg )
  753. {
  754. ctl_t* c = (ctl_t*)arg;
  755. switch( c->id )
  756. {
  757. // ------------------------------------------------------------
  758. // Location
  759. case kLocLabelCId:
  760. break;
  761. case kLocMenuCId:
  762. c->p->_recallLoc();
  763. break;
  764. case kLocStoreBtnCId:
  765. c->p->_storeLoc();
  766. break;
  767. case kLocStringCId:
  768. c->p->_enableStoreBtn(kLocStoreBtnCId);
  769. break;
  770. case kLocDeleteBtnCId:
  771. c->p->_deleteLoc();
  772. break;
  773. // ------------------------------------------------------------
  774. // MIDI
  775. case kMidiCfgMenuCId:
  776. c->p->_recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId );
  777. break;
  778. case kMidiDeleteBtnCId:
  779. c->p->_deleteCfg(kMidiDcmTId,kMidiCfgMenuCId,kMidiCfgStringCId,kMidiCfgDescCId,kMidiApplyBtnCId,kMidiDeleteBtnCId);
  780. break;
  781. case kMidiCfgStringCId:
  782. c->p->_enableStoreBtn(kMidiApplyBtnCId);
  783. break;
  784. case kMidiApplyBtnCId:
  785. c->p->_createMidiCfg();
  786. c->p->_recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId );
  787. break;
  788. case kMidiDevMenuCId:
  789. c->p->_setMenuBtnLabel(c->id);
  790. c->p->_loadMidiPortBtn();
  791. c->p->_enableStoreBtn(kMidiApplyBtnCId);
  792. break;
  793. case kMidiPortMenuCId:
  794. c->p->_setMenuBtnLabel(c->id);
  795. c->p->_enableStoreBtn(kMidiApplyBtnCId);
  796. break;
  797. case kMidiInputCheckCId:
  798. c->p->_enableStoreBtn(kMidiApplyBtnCId);
  799. break;
  800. // ------------------------------------------------------------
  801. // Audio
  802. case kAudioLabelCId:
  803. break;
  804. case kAudioCfgMenuCId:
  805. c->p->_recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId );
  806. break;
  807. case kAudioDeleteBtnCId:
  808. c->p->_deleteCfg(kAudioDcmTId,kAudioCfgMenuCId,kAudioCfgStringCId,kAudioCfgDescCId, kAudioApplyBtnCId, kAudioDeleteBtnCId);
  809. break;
  810. case kAudioCfgStringCId:
  811. c->p->_enableStoreBtn(kAudioApplyBtnCId);
  812. break;
  813. case kAudioApplyBtnCId:
  814. c->p->_createAudioCfg();
  815. c->p->_recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId );
  816. break;
  817. case kAudioInDevMenuCId:
  818. c->p->_setMenuBtnLabel(c->id);
  819. c->p->_enableStoreBtn(kAudioApplyBtnCId);
  820. break;
  821. case kAudioOutDevMenuCId:
  822. c->p->_setMenuBtnLabel(c->id);
  823. c->p->_enableStoreBtn(kAudioApplyBtnCId);
  824. break;
  825. case kAudioSrateMenuCId:
  826. c->p->_setMenuBtnLabel(c->id);
  827. c->p->_enableStoreBtn(kAudioApplyBtnCId);
  828. break;
  829. case kAudioActiveCheckCId:
  830. case kAudioMsgQueSizeValCId:
  831. case kAudioDevFpCValCId:
  832. case kAudioDspFpCValCId:
  833. case kAudioBufCntValCId:
  834. case kAudioSyncInCheckCId:
  835. case kAudioNetNodeStringCId:
  836. case kAudioBcastAddrStringCId:
  837. case kAudioIpAddrStringCId:
  838. case kAudioIpPortValCId:
  839. c->p->_enableStoreBtn(kAudioApplyBtnCId);
  840. break;
  841. // ------------------------------------------------------------
  842. // Network
  843. /*
  844. case kNetLabelCId:
  845. break;
  846. case kNetCfgMenuCId:
  847. c->p->_recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId );
  848. break;
  849. case kNetDeleteBtnCId:
  850. c->p->_deleteCfg(kNetDcmTId,kNetCfgMenuCId,kNetCfgStringCId,kNetCfgDescCId, kNetApplyBtnCId, kNetDeleteBtnCId);
  851. break;
  852. case kNetCfgStringCId:
  853. c->p->_enableStoreBtn(kNetApplyBtnCId);
  854. break;
  855. case kNetApplyBtnCId:
  856. c->p->_createNetCfg();
  857. c->p->_recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId );
  858. c->p->_enableStoreBtn(kNetApplyBtnCId);
  859. break;
  860. case kNetSockAddrStringCId:
  861. case kNetPortNumbValCId:
  862. case kNetActiveCheckCId:
  863. c->p->_enableStoreBtn(kNetApplyBtnCId);
  864. break;
  865. */
  866. default:
  867. break;
  868. }
  869. }