seq.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. #include "main.h"
  2. #include "seq.h"
  3. #include <commctrl.h>
  4. #include <math.h>
  5. #include "resource.h"
  6. #ifdef SEQ_HAVE_PANEL
  7. cfg_int cfg_seq_showpanel("seq_showpanel",0);
  8. enum
  9. {
  10. ID_BASE = 0x6543,
  11. MUTE_ID = ID_BASE,
  12. VOL_ID = MUTE_ID+16,
  13. INS_ID_P = VOL_ID+16,
  14. INS_ID_B1 = INS_ID_P+16,
  15. INS_ID_B2 = INS_ID_B1+16,
  16. SPIN_ID = INS_ID_B2
  17. };
  18. static cfg_int cfg_ctrl_min("ctrl_min",0);
  19. static float g_tempo=1;
  20. static BOOL g_novol,g_noins;
  21. static char sysex1[256],sysex2[256];
  22. extern BYTE d_GMReset[6];
  23. extern BYTE d_XGReset[9];
  24. extern BYTE d_GSReset[11];
  25. #endif
  26. #define SEND_MSG(X) seq_shortmsg(preprocess(X))
  27. #define _sysex(A,B) seq_sysex(A,B)
  28. #define rsysex(A) seq_sysex(A,sizeof(A))
  29. #ifdef SEQ_HAVE_PANEL
  30. void seq_base::set_mute(UINT ch,BOOL st)
  31. {
  32. if (st)
  33. {
  34. mute_mask|=1<<ch;
  35. seq_shortmsg(0x07B0|ch);
  36. }
  37. else
  38. {
  39. mute_mask&=~(1<<ch);
  40. SEND_MSG(((DWORD)ctrl_tab[ch][7]<<16)|0x07B0|ch);
  41. }
  42. }
  43. #endif
  44. //debug hack
  45. #if 0
  46. #define timeGetTime timehack
  47. static DWORD timehack()
  48. {
  49. static DWORD t;
  50. return t++;
  51. }
  52. #endif
  53. DWORD seq_base::get_time()
  54. {
  55. #ifndef SEQ_HAVE_PANEL
  56. return timeGetTime()<<3;
  57. #else
  58. if (!hCtrl) return timeGetTime()<<3;//*8;
  59. EnterCriticalSection(&tm_sec);
  60. DWORD cur_t=timeGetTime();
  61. if (!last_time_ms) last_time_ms=cur_t;
  62. int d=cur_t-last_time_ms;
  63. if (d<0) d=0;
  64. last_time_ret+=(double)(d*8.0)*tempo;
  65. last_time_ms=cur_t;
  66. DWORD r=(DWORD)last_time_ret;
  67. LeaveCriticalSection(&tm_sec);
  68. return r;
  69. #endif
  70. }
  71. #ifdef SEQ_HAVE_PANEL
  72. BOOL CALLBACK seq_base::CtrlProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
  73. {
  74. seq_base* s;
  75. if (msg==WM_INITDIALOG)
  76. {
  77. SetWindowLongPtr(wnd,DWLP_USER,lp);
  78. s=(seq_base*)lp;
  79. if (s) s->hCtrl=wnd;
  80. }
  81. else
  82. {
  83. #if defined(_WIN64)
  84. s = (seq_base*)GetWindowLong(wnd, DWLP_USER);
  85. #else
  86. s = (seq_base*)GetWindowLong(wnd, DWL_USER);
  87. #endif
  88. }
  89. if (s)
  90. {
  91. s->do_msg(msg,wp,lp);
  92. }
  93. return 0;
  94. }
  95. static float ui2tempo(int x)
  96. {
  97. return (float)pow(4.0,0.02*(float)(x-50));
  98. }
  99. static int tempo2ui(float x)
  100. {
  101. return 50+(int) ((50.0 / log(4.0)) * log(x) );
  102. }
  103. static void do_ttext(HWND w,float t)
  104. {
  105. char tx[32] = {0};
  106. _itoa((UINT)(t*100.0),tx,10);
  107. char* p=tx;
  108. while(p && *p) p++;
  109. *(p++)='%';
  110. *p=0;
  111. SetDlgItemTextA(w,IDC_TDISP,tx);
  112. }
  113. BYTE* read_sysex_edit(HWND w,UINT *siz);
  114. void CreateControl(DWORD ex,HWND hCtrl,const char * cls,const char * name,DWORD style,UINT x,UINT y,UINT dx,UINT dy,HINSTANCE hDll,UINT id)
  115. {
  116. RECT r={(LONG)x,(LONG)y,(LONG)(x+dx),(LONG)(y+dy)};
  117. MapDialogRect(hCtrl,&r);
  118. HWND w = CreateWindowExA( ex, cls, name, WS_CHILD | WS_VISIBLE | style, r.left, r.top, r.right - r.left, r.bottom - r.top, hCtrl, 0, hDll, 0 ); // Must stay in ANSI
  119. if (w)
  120. {
  121. if (id) SetWindowLong(w,GWL_ID,id);
  122. SendMessage(w,WM_SETFONT,SendMessage(hCtrl,WM_GETFONT,0,0),MAKELONG(0,0));
  123. }
  124. }
  125. static cfg_int cfg_ctrl_x("ctrl_x",0x80000000),cfg_ctrl_y("ctrl_y",0x80000000);
  126. void seq_base::do_msg(UINT msg,WPARAM wp,LPARAM lp)
  127. {
  128. switch(msg)
  129. {
  130. case WM_CLOSE:
  131. ShowWindow(hCtrl,SW_SHOWMINIMIZED);
  132. break;
  133. case WM_INITDIALOG:
  134. {
  135. HINSTANCE hCCdll=GetModuleHandle(TEXT("comctl32.dll"));
  136. UINT n;
  137. HWND w;
  138. for(n=0;n<16;n++)
  139. {
  140. char tmp[16] = {0};
  141. itoa(n,tmp,10);
  142. CreateControl(0,hCtrl,TRACKBAR_CLASSA,0,TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,40+n*28,36,18,80,hCCdll,VOL_ID+n);
  143. CreateControl(0,hCtrl,"STATIC",tmp,0,46+n*28,25,8,8,0,0);
  144. CreateControl(0,hCtrl,"Button",0,BS_AUTOCHECKBOX | WS_TABSTOP,43+28*n,120,9,8,0,MUTE_ID+n);
  145. CreateControl(WS_EX_CLIENTEDGE,hCtrl,"EDIT",0,ES_AUTOHSCROLL | ES_NUMBER,36+28*n,138,26,12,0,INS_ID_P+n);
  146. CreateControl(0,hCtrl,"msctls_updown32",0,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,0,0,0,SPIN_ID+n);
  147. CreateControl(WS_EX_CLIENTEDGE,hCtrl,"EDIT",0,ES_AUTOHSCROLL | ES_NUMBER,36+28*n,150,26,12,0,INS_ID_B1+n);
  148. CreateControl(0,hCtrl,"msctls_updown32",0,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,0,0,0,SPIN_ID+n+16);
  149. CreateControl(WS_EX_CLIENTEDGE,hCtrl,"EDIT",0,ES_AUTOHSCROLL | ES_NUMBER,36+28*n,162,26,12,0,INS_ID_B2+n);
  150. CreateControl(0,hCtrl,"msctls_updown32",0,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,0,0,0,SPIN_ID+n+32);
  151. }
  152. w=GetDlgItem(hCtrl,IDC_TEMPO);
  153. SendMessage(w,TBM_SETRANGE,0,MAKELONG(0,100));
  154. SendMessage(w,TBM_SETPOS,1,tempo2ui(tempo));
  155. do_ttext(hCtrl,tempo);
  156. if (cfg_ctrl_x!=0x80000000 && cfg_ctrl_y!=0x80000000)
  157. {
  158. int max_x=GetSystemMetrics(SM_CXSCREEN)-10,max_y=GetSystemMetrics(SM_CYSCREEN)-10;
  159. if (cfg_ctrl_x>max_x) cfg_ctrl_x=max_x;
  160. if (cfg_ctrl_y>max_y) cfg_ctrl_y=max_y;
  161. SetWindowPos(hCtrl,0,cfg_ctrl_x,cfg_ctrl_y,0,0,SWP_NOZORDER|SWP_NOSIZE);
  162. }
  163. for(n=0;n<16;n++)
  164. {
  165. w=GetDlgItem(hCtrl,VOL_ID+n);
  166. SendMessage(w,TBM_SETRANGE,1,MAKELONG(0,0x7f));
  167. SendMessage(w,TBM_SETPOS,1,0x7f-90);
  168. }
  169. SendDlgItemMessage(hCtrl,IDC_NOVOL,BM_SETCHECK,novol,0);
  170. SetDlgItemTextA(hCtrl,IDC_SYSEX1,sysex1);
  171. SetDlgItemTextA(hCtrl,IDC_SYSEX2,sysex2);
  172. for(n=0;n<48;n++)
  173. {
  174. SendDlgItemMessage(hCtrl,SPIN_ID+n,UDM_SETRANGE,0,MAKELONG(127,0));
  175. }
  176. for(n=0;n<16;n++)
  177. {
  178. SendDlgItemMessage(hCtrl,INS_ID_P+n,EM_LIMITTEXT,3,0);
  179. SendDlgItemMessage(hCtrl,INS_ID_B1+n,EM_LIMITTEXT,3,0);
  180. SendDlgItemMessage(hCtrl,INS_ID_B2+n,EM_LIMITTEXT,3,0);
  181. }
  182. initialized=1;
  183. }
  184. break;
  185. case WM_COMMAND:
  186. {
  187. UINT n;
  188. if (HIWORD(wp)==0)
  189. {
  190. if (wp==IDC_SYSEX1_SEND || wp==IDC_SYSEX2_SEND)
  191. {
  192. UINT sl;
  193. BYTE* s=read_sysex_edit(GetDlgItem(hCtrl,(wp==IDC_SYSEX1_SEND)?IDC_SYSEX1:IDC_SYSEX2) , &sl);
  194. if (s)
  195. {
  196. _sysex(s,sl);
  197. free(s);
  198. }
  199. }
  200. else if (wp==IDC_NOVOL)
  201. {
  202. novol=SendMessage((HWND)lp,BM_GETCHECK,0,0);
  203. }
  204. else if (wp==IDC_NOINS)
  205. {
  206. noins=SendMessage((HWND)lp,BM_GETCHECK,0,0);
  207. }
  208. else if (wp==IDC_ALL_ON)
  209. {
  210. UINT n;
  211. for(n=0;n<16;n++)
  212. {
  213. if (mute_mask&(1<<n))
  214. {
  215. SendDlgItemMessage(hCtrl,MUTE_ID+n,BM_SETCHECK,0,0);
  216. set_mute(n,0);
  217. }
  218. }
  219. }
  220. else if (wp==IDC_ALL_OFF)
  221. {
  222. UINT n;
  223. for(n=0;n<16;n++)
  224. {
  225. if (!(mute_mask&(1<<n)))
  226. {
  227. SendDlgItemMessage(hCtrl,MUTE_ID+n,BM_SETCHECK,1,0);
  228. set_mute(n,1);
  229. }
  230. }
  231. }
  232. else if (wp==IDC_GMRESET)
  233. {
  234. rsysex(d_GMReset);
  235. }
  236. else if (wp==IDC_GSRESET)
  237. {
  238. rsysex(d_GSReset);
  239. }
  240. else if (wp==IDC_XGRESET)
  241. {
  242. rsysex(d_XGReset);
  243. }
  244. else for(n=0;n<16;n++)
  245. {
  246. if (wp==MUTE_ID+n)
  247. {
  248. set_mute(n,SendMessage((HWND)lp,BM_GETCHECK,0,0));
  249. break;
  250. }
  251. }
  252. }
  253. else if (HIWORD(wp)==EN_CHANGE)
  254. {
  255. if (initialized)
  256. {
  257. wp&=0xFFFF;
  258. UINT n;
  259. for(n=0;n<16;n++)
  260. {
  261. if (wp==INS_ID_P+n)
  262. {
  263. UINT p=GetDlgItemInt(hCtrl,wp,0,0)&0x7F;
  264. if (p!=ins_tab[n])
  265. {
  266. ins_tab[n]=p;
  267. SEND_MSG(0xC0|n|(p<<8));
  268. }
  269. break;
  270. }
  271. else if (wp==INS_ID_B1+n)
  272. {
  273. UINT p=GetDlgItemInt(hCtrl,wp,0,0)&0x7F;
  274. if (p!=ctrl_tab[n][0])
  275. {
  276. ctrl_tab[n][0]=p;
  277. SEND_MSG(0xB0|n|(p<<16));
  278. SEND_MSG(0xC0|n|(ins_tab[n]<<8));
  279. }
  280. break;
  281. }
  282. else if (wp==INS_ID_B2+n)
  283. {
  284. UINT p=GetDlgItemInt(hCtrl,wp,0,0)&0x7F;
  285. if (p!=ctrl_tab[n][0x20])
  286. {
  287. ctrl_tab[n][0x20]=p;
  288. SEND_MSG(0x20B0|n|(p<<16));
  289. SEND_MSG(0xC0|n|(ins_tab[n]<<8));
  290. }
  291. break;
  292. }
  293. }
  294. }
  295. }
  296. }
  297. break;
  298. case WM_VSCROLL:
  299. {
  300. HWND sb=(HWND)lp;
  301. if (sb)
  302. {
  303. UINT id=GetWindowLong(sb,GWL_ID);
  304. UINT n;
  305. for(n=0;n<16;n++)
  306. {
  307. if (id==VOL_ID+n)
  308. {
  309. UINT val=0x7f-SendMessage(sb,TBM_GETPOS,0,0);
  310. ctrl_tab[n][7]=val;
  311. SEND_MSG(0x7B0|n|(val<<16));
  312. break;
  313. }
  314. }
  315. }
  316. }
  317. break;
  318. case WM_HSCROLL:
  319. tempo=ui2tempo(SendDlgItemMessage(hCtrl,IDC_TEMPO,TBM_GETPOS,0,0));
  320. do_ttext(hCtrl,tempo);
  321. break;
  322. }
  323. }
  324. #endif
  325. seq_base::~seq_base()
  326. {
  327. #ifdef SEQ_HAVE_PANEL
  328. if (hCtrl)
  329. {
  330. cfg_ctrl_min=!!IsIconic(hCtrl);
  331. RECT r;
  332. GetWindowRect(hCtrl,&r);
  333. cfg_ctrl_x=r.left;
  334. cfg_ctrl_y=r.top;
  335. GetDlgItemTextA(hCtrl,IDC_SYSEX1,sysex1,256);
  336. GetDlgItemTextA(hCtrl,IDC_SYSEX2,sysex2,256);
  337. DestroyWindow(hCtrl);
  338. DeleteCriticalSection(&tm_sec);
  339. }
  340. g_tempo=tempo;
  341. g_novol=novol;
  342. g_noins=noins;
  343. #endif
  344. if (events) free(events);
  345. }
  346. seq_base::seq_base()
  347. {
  348. mf=0;
  349. kill=0;paused=0;
  350. smap=0;
  351. pan=0;vol=0;
  352. seek_to=0;
  353. n_events=0;
  354. events=0;
  355. c_loop=0;
  356. loop_start=0;
  357. memset(&notes,0,sizeof(notes));
  358. memset(&ctrl_tab,0,sizeof(ctrl_tab));
  359. memset(&ins_tab,0,sizeof(ins_tab));
  360. tm_ofs=0;
  361. p_time=0;
  362. hTrd=0;
  363. ins_set=0;
  364. #ifdef SEQ_HAVE_PANEL
  365. hCtrl=0;
  366. tempo=g_tempo;
  367. novol=g_novol;
  368. noins=g_noins;
  369. last_time_ms=0;
  370. last_time_ret=0;
  371. mute_mask=0;
  372. initialized=0;
  373. #endif
  374. }
  375. #define GET_TIME get_time()//timeGetTime()
  376. int IS_SPEC_C(int x) {return (x>=0x60 && x<=0x65) || x==6 || x==26 || x>=120;}
  377. #define n_sysex smap->pos
  378. DWORD seq_base::preprocess(DWORD e)
  379. {
  380. BYTE t=(BYTE)(e&0xF0);
  381. if (t==0xB0)
  382. {
  383. UINT v=(e>>16)&0xFF;
  384. BYTE c=(BYTE)(e>>8);
  385. #ifdef SEQ_HAVE_PANEL
  386. if (c==7)
  387. {
  388. if (mute_mask&(1<<(e&0xF))) v=0;
  389. }
  390. #endif
  391. e=(e&0xFFFF)|((v&0xFF)<<16);
  392. }
  393. else if (t==0xC0)
  394. {
  395. ins_set|=1<<(e&0xF);
  396. }
  397. return e;
  398. }
  399. void seq_base::send_sysex(int n)
  400. {
  401. #ifdef USE_LOG
  402. log_write("send_sysex()");
  403. #endif
  404. if (!smap || n>=n_sysex) return;
  405. _sysex(smap->data+smap->events[n].ofs,smap->events[n].len);
  406. }
  407. /*
  408. void seq_base::reset_ins()
  409. {
  410. UINT n;
  411. for(n=0;n<16;n++)
  412. {
  413. cb->shortmsg(0xC0|n);
  414. }
  415. }
  416. */
  417. BOOL seq_base::do_ctrl(DWORD e)
  418. {
  419. BYTE tp=(BYTE)(e&0xF0);
  420. BYTE ch=(BYTE)(e&0x0F);
  421. if (tp==0xC0)
  422. {
  423. #ifdef SEQ_HAVE_PANEL
  424. if (noins) return 0;
  425. #endif
  426. //if (!cfg_fctrl && (e>>8)==ins_tab[e&0xF]) return 0;
  427. UINT val=e>>8;
  428. ins_tab[ch]=val;
  429. #ifdef SEQ_HAVE_PANEL
  430. if (hCtrl) SetDlgItemInt(hCtrl,INS_ID_P+ch,val,0);
  431. #endif
  432. } else if (tp==0xB0)
  433. {
  434. UINT cn = (e>>8)&0x7F;
  435. UINT val= (e>>16)&0x7F;
  436. #ifdef SEQ_HAVE_PANEL
  437. if (cn==0)
  438. {
  439. if (noins) return 0;
  440. if (hCtrl) SetDlgItemInt(hCtrl,INS_ID_B1+ch,val,0);
  441. }
  442. else if (cn==0x20)
  443. {
  444. if (noins) return 0;
  445. if (hCtrl) SetDlgItemInt(hCtrl,INS_ID_B2+ch,val,0);
  446. }
  447. else if (cn==7)
  448. {
  449. if (novol) return 0;
  450. if (hCtrl) PostMessage(GetDlgItem(hCtrl,VOL_ID+(e&0xF)),TBM_SETPOS,1,0x7F-val);
  451. }
  452. else if (cn==0x27)
  453. {
  454. if (novol) return 0;
  455. }
  456. #endif
  457. if (!IS_SPEC_C(cn)) ctrl_tab[e&0xF][cn]=val;
  458. }
  459. else if (tp==0x90)
  460. {
  461. if (!(ins_set&(1<<ch)))
  462. {
  463. SEND_MSG(0xC0|ch);
  464. }
  465. }
  466. return 1;
  467. }
  468. void seq_base::reset()
  469. {
  470. int not,ch;
  471. for(ch=0;ch<16;ch++)
  472. {
  473. if (ctrl_tab[ch][0x40])
  474. {
  475. seq_shortmsg(0x40B0|ch);
  476. ctrl_tab[ch][0x40]=0;
  477. }
  478. if (ch==9) continue;
  479. for(not=0;not<128;not++)
  480. {
  481. if (note_state(ch,not))
  482. {
  483. seq_shortmsg((not<<8)|0x80|ch);
  484. note_off(ch,not);
  485. }
  486. }
  487. }
  488. }
  489. int seq_base::note_state(int ch,int note)
  490. {
  491. UINT pos=(ch<<7)+note;
  492. return notes[pos>>3]&(1<<(pos&0x7));
  493. }
  494. void seq_base::note_on(int ch,int note)
  495. {
  496. UINT pos=(ch<<7)+note;
  497. notes[pos>>3]|=(1<<(pos&0x7));
  498. }
  499. void seq_base::note_off(int ch,int note)
  500. {
  501. UINT pos=(ch<<7)+note;
  502. notes[pos>>3]&=~(1<<(pos&0x7));
  503. }
  504. UINT seq_base::do_seek(DWORD n,DWORD p)
  505. {
  506. UINT m,c;
  507. BYTE _ctrl_tab[16][128] = {0};
  508. BYTE _ins_tab[16] = {0};
  509. memcpy(_ctrl_tab,ctrl_tab,sizeof(_ctrl_tab));
  510. memcpy(_ins_tab,ins_tab,sizeof(_ins_tab));
  511. if (n==0)
  512. {
  513. memset(ins_tab,0,sizeof(ins_tab));
  514. for(m=0;m<16;m++)
  515. {
  516. _ctrl_tab[m][0]=_ctrl_tab[m][0x20]=0;
  517. }
  518. }
  519. while(n<n_events && p>events[n].tm)
  520. {
  521. DWORD e=events[n].ev;
  522. if (!(e&0x80000000))
  523. {
  524. if (do_ctrl(e))
  525. {
  526. if (((e&0xF0)==0xB0) && IS_SPEC_C((e>>8)&0xFF))
  527. {
  528. seq_shortmsg(e);
  529. }
  530. }
  531. }
  532. n++;
  533. }
  534. for(c=0;c<16;c++)
  535. {
  536. for(m=0;m<128;m++)
  537. {
  538. if (!IS_SPEC_C(m) && _ctrl_tab[c][m]!=ctrl_tab[c][m])
  539. {
  540. SEND_MSG(((DWORD)ctrl_tab[c][m]<<16)|(m<<8)|0xB0|c);
  541. }
  542. }
  543. if (_ins_tab[c]!=ins_tab[c])
  544. {
  545. SEND_MSG(((DWORD)ins_tab[c]<<8)|0xC0|c);
  546. }
  547. }
  548. return n;
  549. }
  550. DWORD WINAPI seq_base::seq_trd(void* p)
  551. {
  552. ((seq_base*)p)->thread();
  553. return 0;
  554. }
  555. void seq_base::sysexfunc(seq_base* cb,BYTE* s,UINT sz)
  556. {
  557. cb->seq_sysex(s,sz);
  558. }
  559. void seq_base::thread()
  560. {
  561. tm_ofs=-1;
  562. if (seq_play_start())
  563. {
  564. sysex_startup((SYSEXFUNC)sysexfunc,this);
  565. tm_ofs=GET_TIME;
  566. DWORD pos=0;
  567. while(!kill)
  568. {
  569. DWORD c_t=GET_TIME-tm_ofs;
  570. if (paused)
  571. {
  572. reset();
  573. while(paused && !kill) MIDI_callback::Idle();
  574. if (kill) break;
  575. tm_ofs=GET_TIME-c_t;
  576. }
  577. if (seek_to!=-1)
  578. {
  579. _seek:
  580. DWORD _p=seek_to > c_t ? pos : 0;
  581. c_t=seek_to;
  582. seek_to=-1;
  583. tm_ofs=GET_TIME-c_t;
  584. reset();
  585. pos=c_t ? do_seek(_p,c_t) : 0;
  586. }
  587. if (events[pos].tm+1600 < c_t)
  588. {
  589. reset();
  590. pos=do_seek(pos,c_t);
  591. }
  592. while(pos<n_events && events[pos].tm<=c_t && !kill)
  593. {
  594. DWORD e=events[pos++].ev;
  595. if (e)
  596. {
  597. if (e&0x80000000)
  598. {
  599. send_sysex(e&0x7FFFFFFF);
  600. }
  601. else
  602. {
  603. if ((e&0xF0)==0x90)
  604. {
  605. note_on(e&0xf,(e>>8)&0xFF);
  606. }
  607. else if ((e&0xF0)==0x80)
  608. {
  609. note_off(e&0xf,(e>>8)&0xFF);
  610. }
  611. if (do_ctrl(e))
  612. SEND_MSG(e);
  613. }
  614. }
  615. }
  616. if (pos>=n_events || c_t >= events[n_events-1].tm)
  617. {
  618. if (loop_start!=-1 && (--c_loop))
  619. {
  620. c_t=loop_start;
  621. tm_ofs=GET_TIME-c_t;
  622. pos=do_seek(0,c_t);
  623. continue;
  624. }
  625. if (cfg_eof_delay)
  626. {
  627. DWORD t=timeGetTime();
  628. do
  629. {
  630. MIDI_callback::Idle();
  631. } while(!kill && seek_to==-1 && t+cfg_eof_delay>timeGetTime());
  632. if (seek_to!=-1) {
  633. pos=0;
  634. goto _seek;
  635. }
  636. }
  637. if (!kill) MIDI_core::Eof();
  638. break;
  639. }
  640. if (kill) break;
  641. MIDI_callback::Idle();
  642. }
  643. reset();
  644. }
  645. seq_play_stop();
  646. }
  647. int seq_base::gettime()
  648. {
  649. if (paused)
  650. return (seek_to==-1) ? seek_to>>3 : p_time;
  651. else
  652. return (GET_TIME-tm_ofs)>>3;
  653. }
  654. int seq_base::settime(int tm)
  655. {
  656. seek_to=tm<<3;
  657. return 1;
  658. }
  659. void seq_base::pause()
  660. {
  661. paused=1;
  662. p_time=GET_TIME-tm_ofs;
  663. }
  664. void seq_base::unpause()
  665. {
  666. paused=0;
  667. }
  668. int seq_base::seq_cmd_start(DWORD cflags)
  669. {
  670. mf=MIDI_core::getFile();
  671. #ifdef SEQ_HAVE_PANEL
  672. mute_mask=0;
  673. #endif
  674. c_loop=cfg_loop_infinite ? -1 : cfg_loop_count;
  675. memset(notes,0,sizeof(notes));
  676. memset(ctrl_tab,-1,sizeof(ctrl_tab));
  677. memset(ins_tab,0,sizeof(ins_tab));
  678. UINT n;
  679. for(n=0;n<16;n++) ctrl_tab[n][7]=90;
  680. events=do_table(mf,8,&n_events,&loop_start,cflags);
  681. if (!events) return 0;
  682. if (!cfg_nosysex && mf->smap && mf->smap->pos)
  683. {
  684. smap=mf->smap;
  685. }
  686. else smap=0;
  687. kill=0;
  688. seek_to=-1;
  689. paused=0;
  690. #ifdef SEQ_HAVE_PANEL
  691. if (cfg_seq_showpanel)
  692. {
  693. InitializeCriticalSection(&tm_sec);
  694. WASABI_API_CREATEDIALOGPARAMW(IDD_EXT_IMM, MIDI_callback::GetMainWindow(), CtrlProc, (LPARAM)this);
  695. ShowWindow(hCtrl,cfg_ctrl_min ? SW_SHOWMINIMIZED : SW_SHOW);
  696. }
  697. else
  698. {
  699. tempo=1;
  700. novol=0;
  701. noins=0;
  702. }
  703. #endif
  704. DWORD id;
  705. hTrd=CreateThread(0,0,seq_trd,this,CREATE_SUSPENDED,&id);
  706. #ifndef _DEBUG
  707. SetThreadPriority(hTrd,THREAD_PRIORITY_TIME_CRITICAL);
  708. #endif
  709. ResumeThread(hTrd);
  710. return 1;
  711. }
  712. void seq_base::seq_cmd_stop()
  713. {
  714. #ifdef USE_LOG
  715. log_write("stopping sequencer");
  716. #endif
  717. if (hTrd)
  718. {
  719. #ifdef USE_LOG
  720. log_write("killing thread");
  721. #endif
  722. kill=1;
  723. if (WaitForSingleObject(hTrd,4000)!=WAIT_OBJECT_0)
  724. {
  725. #ifdef USE_LOG
  726. log_write("unable to kill thread");
  727. #endif
  728. TerminateThread(hTrd,0);
  729. }
  730. #ifdef USE_LOG
  731. else log_write("thread killed normally");
  732. #endif
  733. CloseHandle(hTrd);
  734. }
  735. }
  736. /*
  737. void seq_base::enum_ins()
  738. {
  739. DWORD ttab[256];
  740. memset(ttab,-1,sizeof(ttab));
  741. UINT tpt=0;
  742. UINT n;
  743. DWORD c_ins[16];
  744. memset(c_ins,0,sizeof(c_ins));
  745. c_ins[9]=0x80000000;
  746. for(n=0;n<n_events;n++)
  747. {
  748. DWORD t=events[n].ev;
  749. if (t&0xFF000000) continue;
  750. UINT c=t&0xF0;
  751. UINT ch=events[n].ev&0xF;
  752. if ((t&0xFFF0)==0x20B0)
  753. {
  754. c_ins[ch]=(c_ins[ch]&0xFFFF00FF)|((t>>8)&0xFF00);
  755. }
  756. else if ((t&0xFFF0)==0xB0)
  757. {
  758. c_ins[ch]=(c_ins[ch]&0xFF00FFFF)|(t&0xFF0000);
  759. }
  760. else if ((t&0xF0)==0xC0)
  761. {
  762. c_ins[ch]=(c_ins[ch]&0xFFFFFF00)|((t>>8)&0xFF);
  763. }
  764. else if ((t&0xF0)==0x90)
  765. {
  766. UINT n;
  767. for(n=0;n<256;n++)
  768. {
  769. if (ttab[n]==c_ins[ch]) goto ok;
  770. }
  771. cb->enum_ins(ttab[tpt]=c_ins[ch]);
  772. tpt=(tpt+1)&0xFF;
  773. ok:;
  774. }
  775. }
  776. }
  777. */