#include #include #include #include #include #include "cui/cui.h" #include "cui/scpanel.h" #include "cui/button.h" #include "cui/handler.h" #include "cui/menu.h" #include "cui/num.h" #include "cui/tab.h" #include "cui/kbd.h" #include "cui/timer.h" #include "cui/arg.h" FILE *fp = NULL; #define BUFN 4096 char buf[ BUFN ], *bp = buf; void set_char(char c) { if(bp - buf >=BUFN) ERR("BUFN give up"); *bp++ = c; } void set_str(char *s) { while(*s) set_char(*s++); } void set_int(int n, int v) { while(n--) set_char((v >> n*8) & 0xff); } void wrt(void) { int i, n = bp - buf; if(n <= 0) return; for(i=0; ich[ p->midi_ch ]; int hi = onoff ? 9 : 8; int low = p->midi_ch; set_char3_wrt((hi<<4) | low, note, ch->velo); } static void arpe_note_off(void *prm) { struct test4 *p = (struct test4 *)prm; struct test4_ch *ch = &p->ch[ p->midi_ch ]; if(ch->arpe_note < 0) return; note_onoff(ch->arpe_note, FALSE, prm); ch->arpe_note = -1; } static int repeat_hdr(cui obj, int evt, int val, void *prm) { struct test4 *p = (struct test4 *)prm; struct test4_ch *ch = &p->ch[ p->midi_ch ]; int i, note, prev = ch->arpe_note; arpe_note_off(prm); for(note=0; note<128; note++) if(cui_kbd_get(ch->kbd, note)) break; if(note < 128){ for(i=0; i<128; i++){ note = (prev + 1 + i) % 128; if(cui_kbd_get(ch->kbd, note)) break; } note_onoff(note, TRUE, prm); ch->arpe_note = note; } return TRUE; } int t4_btn_hdr(cui obj, int evt, int val, void *prm) { /* CUI_EVT_BUTTON */ struct test4 *p = (struct test4 *)prm; struct test4_ch *ch = &p->ch[ p->midi_ch ]; if(obj == p->mn_ch){ cui_num_vp_set(p->prog, &ch->prog); cui_num_vp_set(p->vol, &ch->vol); cui_num_vp_set(p->velo, &ch->velo); cui_hide(p->ch[ p->bak_ch ].kbd); cui_show(ch->kbd); cui_menu_popup_vp_set(p->pmode, &ch->pmode); cui_num_vp_set(p->msec, &ch->msec); p->bak_ch = p->midi_ch; }else if(obj == p->prog){ set_char2_wrt((0xc<<4) | p->midi_ch, ch->prog); }else if(obj == p->vol){ set_char3_wrt((0xb<<4) | p->midi_ch, 7 /* vol msb */, ch->vol); }else if(obj == ch->kbd){ char *s = cui_menu_popup_str_get(p->pmode); if(strcmp(s, "Immediate") == 0){ int onoff = val & 0x100; int note = val & ~0x100; note_onoff(note, onoff, prm); } }else if(obj == p->pmode){ char *s = cui_menu_popup_str_get(p->pmode); cui_show_hide(p->on, strcmp(s, "Chord") == 0); cui_show_hide(p->msec, strcmp(s, "Arpeggio") == 0); cui_show_hide(p->play, strcmp(s, "Arpeggio") == 0); cui_show_hide(p->repeat, strcmp(s, "Arpeggio") == 0); }else if(obj == p->on){ int note; for(note=0; note<128; note++){ if(!cui_kbd_get(ch->kbd, note)) continue; note_onoff(note, val, prm); } }else if(obj == p->play){ int note, prev; prev = -1; for(note=0; note<128; note++){ if(!cui_kbd_get(ch->kbd, note)) continue; if(prev >= 0) note_onoff(prev, FALSE, prm); note_onoff(note, TRUE, prm); usleep(ch->msec * 1000); prev = note; } note_onoff(prev, FALSE, prm); }else if(obj == p->repeat){ cui_timer_set(obj, val ? ch->msec : -1, FALSE); arpe_note_off(prm); }else return FALSE; return TRUE; } int main(int ac, char **av) { int init_ret = cui_init(av); int w = cui_arg_int(av, "-w", 45, NULL); int h = cui_arg_int(av, "-h", 11, NULL); cui root = cui_scpanel_new(NULL, 0, 0, w, h, "cui_midi"); cui bs4 = cui_scpanel_sheet_get(root); struct test4 t4; int div = cui_arg_int(av, "-div", 96, NULL); int i; cui_hide(bs4); t4.midi_ch = t4.bak_ch = 0; for(i=0; i<16; i++){ t4.ch[i].prog = 0; t4.ch[i].vol = 0; t4.ch[i].velo = 64; t4.ch[i].pmode = 0; t4.ch[i].msec = 200; t4.ch[i].arpe_note = -1; } t4.mn_ch = cui_menu_int_new(bs4, 0, 0, 2+1, 0, 0, 15); cui_wlb_name_new(bs4, "ch ", NULL, NULL); cui_menu_int_vp_set(t4.mn_ch, &t4.midi_ch); t4.prog = cui_num_new(bs4, CUI_CHILD_X, CUI_CHILD_Y2+1, 3+3, 0, 0, 127, 0); cui_wlb_name_new(bs4, "prog ", NULL, NULL); t4.vol = cui_num_new(bs4, CUI_CHILD_X2+2, CUI_CHILD_Y, 3+3, 0, 0, 127, 0); cui_wlb_name_new(bs4, "vol (msb) ", NULL, NULL); t4.velo = cui_num_new(bs4, CUI_CHILD_X2+2, CUI_CHILD_Y, 3+3, 0, 0, 127, 0); cui_wlb_name_new(bs4, "velo ", NULL, NULL); for(i=0; i<16; i++){ t4.ch[i].kbd = cui_kbd_new(bs4, 0, cui_y2(t4.velo->parent)+1, 40); cui_hide(t4.ch[i].kbd); cui_bind(t4.ch[i].kbd, CUI_EVT_BUTTON, t4_btn_hdr, &t4); } t4.pmode = cui_menu_popup_new(bs4, 0, CUI_CHILD_Y2+1, 9+1, (char *[]){ "Immediate", "Chord", "Arpeggio", NULL}, 0); t4.on = cui_ckbox_new(bs4, CUI_CHILD_X2+2, CUI_CHILD_Y, "ON", FALSE); cui_hide(t4.on); t4.msec = cui_num_new(bs4, CUI_CHILD_X, CUI_CHILD_Y, 4+3, 200, 0, 1000, 0); cui_hide(t4.msec); t4.play = cui_button_new(bs4, CUI_CHILD_X2+2, CUI_CHILD_Y, "play"); cui_hide(t4.play); t4.repeat = cui_ckbox_new(bs4, CUI_CHILD_X2+2, CUI_CHILD_Y, "repeat", FALSE); cui_hide(t4.repeat); cui_wh_fit(bs4); cui_show(bs4); cui_bind(t4.mn_ch, CUI_EVT_BUTTON, t4_btn_hdr, &t4); cui_bind(t4.prog, CUI_EVT_BUTTON, t4_btn_hdr, &t4); cui_bind(t4.vol, CUI_EVT_BUTTON, t4_btn_hdr, &t4); cui_bind(t4.pmode, CUI_EVT_BUTTON, t4_btn_hdr, &t4); cui_bind(t4.on, CUI_EVT_BUTTON, t4_btn_hdr, &t4); cui_bind(t4.play, CUI_EVT_BUTTON, t4_btn_hdr, &t4); cui_bind(t4.repeat, CUI_EVT_BUTTON, t4_btn_hdr, &t4); cui_bind(t4.repeat, CUI_EVT_TIMER, repeat_hdr, &t4); cui_handler_call(t4.mn_ch, CUI_EVT_BUTTON, cui_menu_int_get(t4.mn_ch)); fp = stdout; set_str("MThd"); set_int(4, 6); set_int(2, 0); set_int(2, 1); set_int(2, div); set_str("MTrk"); set_int(4, 0); wrt(); cui_main(root, NULL); cui_fini(init_ret); return 0; } /* EOF */