diff -urN midi_prog-/midtxt.c midi_prog/midtxt.c --- midi_prog-/midtxt.c 2015-06-09 00:00:00.000000000 +0900 +++ midi_prog/midtxt.c 2015-06-21 00:00:00.000000000 +0900 @@ -345,6 +345,74 @@ return strtol(sp, NULL, 0) * 12 + i; } +void +note_to_str(int note, char *buf) +{ + char *tbl[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", NULL }; + sprintf(buf, "%s%d", tbl[note % 12], note / 12); +} + +void +chord_notes_get(char *name, char *buf) +{ + struct{ + char *name; + int n; + int *lst; + } chord_info[] = { + { "", 3, (int []){ 4, 3, 5 } }, + { "m", 3, (int []){ 3, 4, 5 } }, + { "dim", 3, (int []){ 3, 3, 6 } }, + { "aug", 3, (int []){ 4, 4, 4 } }, + { "sus4", 3, (int []){ 5, 2, 5 } }, + { "7", 4, (int []){ 4, 3, 3, 2 } }, + { "M7", 4, (int []){ 4, 3, 4, 1 } }, + { "m7", 4, (int []){ 3, 4, 3, 2 } }, + { NULL, 0, NULL }, + }, *inf; + + char src[16], key[8], *sp, *dp, *p; + int base_note, key12, base12, si, i, n; + + strcpy(src, name); + sp = src; + dp = key; + *dp++ = *sp++; + if(*sp == '#') *dp++ = *sp++; + *dp++ = '0'; + *dp = '\0'; + key12 = str_to_note(key); + + if((p = strchr(sp, '/')) == NULL) ERR("format"); + *p++ = '\0'; + + for(inf=chord_info; inf->name; inf++) if(strcmp(inf->name, sp) == 0) break; + if(inf->name == NULL) ERR("foramt chord /"); + + base_note = str_to_note(p); + base12 = base_note % 12; + + n = inf->n; + si = 0; + if(key12 != base12){ + for(si=1; si < n; si++){ + key12 = (key12 + inf->lst[si-1]) % 12; + if(key12 == base12) break; + } + if(si >= n){ + MSG(name); + ERR("format chord"); + } + } + for(i=0; i= n-1) continue; + strcat(buf, ","); + buf += strlen(buf); + base_note += inf->lst[ (si + i) % n ]; + } +} + char * np_update(char *np) { @@ -357,27 +425,49 @@ len_to_delta_conv(int ac, char **av) { int div4 = opt_int("-div4", ac, av, 96); - char buf[BUFSZ], len_buf[BUFSZ], notes_buf[BUFSZ], opt_buf[BUFSZ], sla[8], *np, note_buf[BUFSZ]; - int len, len_on, ch, note, velo, delta; + int def_ch = opt_int("-ch", ac, av, 0); + int def_velo = opt_int("-velo", ac, av, 100); + int len, len_on, ch, note, velo, delta, l_ac, i; + char buf[BUFSZ], lbuf[BUFSZ], *l_av[AVSZ], notes_buf[BUFSZ], note_buf[BUFSZ]; + char *len_buf, *vp, *notes_str, *chord_str, *sla, *np; while(fgets(buf, sizeof(buf), stdin)){ if(buf[0] == '#' || buf[0] == ';' || buf[0] == '\n' || buf[0] == '\0') continue; - velo=100; - strcpy(opt_buf, ""); - if(sscanf(buf, "len=%s ch=%d note=%s %s", len_buf, &ch, notes_buf, opt_buf) <= 0){ + strcpy(lbuf, buf); + l_ac = ARR_N(l_av); + line_to_ac_av(lbuf, &l_ac, l_av); + + if((len_buf = opt_prefix("len=", l_ac, l_av)) == NULL){ fputs(buf, stdout); continue; } - strcpy(sla, ""); - if(sscanf(opt_buf, "velo=%d %s", &velo, sla) == 0){ - sscanf(opt_buf, "%s", sla); + len_get(len_buf, div4, &len, &len_on); + + notes_str = opt_prefix("note=", l_ac, l_av); + chord_str = opt_prefix("chord=", l_ac, l_av); + if(notes_str == NULL && chord_str == NULL) ERR("format, no note and no chord"); + + if(chord_str){ + notes_buf[0] = '\0'; + if(notes_str) strcpy(notes_buf, notes_str); + chord_notes_get(chord_str, notes_buf + strlen(notes_buf)); + notes_str = notes_buf; } - len_get(len_buf, div4, &len, &len_on); + ch = def_ch; + if((vp = opt_prefix("ch=", l_ac, l_av)) != NULL) ch = strtol(vp, NULL, 0); + + velo = def_velo; + if((vp = opt_prefix("velo=", l_ac, l_av)) != NULL) velo = strtol(vp, NULL, 0); + + sla = ""; + if((i = opt_idx("<", l_ac, l_av)) >= 0) sla = l_av[i]; + else if((i = opt_idx("-", l_ac, l_av)) >= 0) sla = l_av[i]; + else if((i = opt_idx(">", l_ac, l_av)) >= 0) sla = l_av[i]; if(strcmp(sla, "-") != 0 && strcmp(sla, ">") != 0){ - for(np=notes_buf; np && sscanf(np, "%[^,]", note_buf) == 1; np=np_update(np)){ + for(np=notes_str; np && sscanf(np, "%[^,]", note_buf) == 1; np=np_update(np)){ if((note = str_to_note(note_buf)) < 0){ printf("delta=0 cmd=f8\n"); }else{ @@ -390,7 +480,7 @@ if(strcmp(sla, "-") != 0 && strcmp(sla, "<") != 0){ delta = len_on; - for(np=notes_buf; np && sscanf(np, "%[^,]", note_buf) == 1; np=np_update(np)){ + for(np=notes_str; np && sscanf(np, "%[^,]", note_buf) == 1; np=np_update(np)){ if((note = str_to_note(note_buf)) < 0){ printf("delta=%d cmd=f8\n", delta); }else{ diff -urN midi_prog-/util.c midi_prog/util.c --- midi_prog-/util.c 2015-06-09 00:00:00.000000000 +0900 +++ midi_prog/util.c 2015-06-21 00:00:00.000000000 +0900 @@ -37,6 +37,22 @@ return strtod(s, NULL); } +void +line_to_ac_av(char *line, int *ac, char **av) +{ + int i, n = *ac; + for(i=0; i