diff -urN midi_prog-/Makefile midi_prog/Makefile --- midi_prog-/Makefile 2015-08-13 00:00:00.000000000 +0900 +++ midi_prog/Makefile 2015-08-25 00:00:00.000000000 +0900 @@ -10,8 +10,9 @@ VOCO_OBJS = voco.o vco.o wave.o in.o filter.o out.o util.o MIDTXT_OBJS = midtxt.o rd.o wrt.o util.o TOOL_OBJS = tool.o in.o out.o util.o buf.o pitch.o pitdet.o +RAWMIX2_OBJS = rawmix2.o in.o out.o util.o -all: $(TARG) vcd voco midtxt tool +all: $(TARG) vcd voco midtxt tool rawmix2 $(TARG): $(OBJS) $(CC) -o $@ $(OBJS) $(LIB) @@ -28,10 +29,14 @@ tool: $(TOOL_OBJS) $(CC) -o $@ $(TOOL_OBJS) -lm +rawmix2: $(RAWMIX2_OBJS) + $(CC) -o $@ $(RAWMIX2_OBJS) + clean: rm -f $(TARG) $(OBJS) *~ rm -f vcd $(VCD_OBJS) voco $(VOCO_OBJS) rm -f midtxt $(MIDTXT_OBJS) rm -f tool $(TOOL_OBJS) + rm -f rawmix2 $(RAWMIX2_OBJS) # EOF diff -urN midi_prog-/buf.c midi_prog/buf.c --- midi_prog-/buf.c 2015-08-10 00:00:00.000000000 +0900 +++ midi_prog/buf.c 2015-08-26 00:34:39.000000000 +0900 @@ -152,6 +152,12 @@ return v + (rbuf_get_arr_cpx(rb, arr_idx((si + 1), rb->n)) - v) * d; } +void +rbuf_set_dbl(struct rbuf *rb, int si, double v) +{ + rbuf_set_arr_dbl(rb, arr_idx(si, rb->n), v); +} + /* tbuf */ @@ -229,6 +235,13 @@ return rbuf_get_cpx(&tb->rb, sridx); } +void +tbuf_set_dbl(struct tbuf *tb, double sec, double v) +{ + double sridx = tbuf_sec_to_sridx(tb, sec); + rbuf_set_dbl(&tb->rb, (int)sridx, v); +} + /* sbuf */ diff -urN midi_prog-/buf.h midi_prog/buf.h --- midi_prog-/buf.h 2015-08-10 00:00:00.000000000 +0900 +++ midi_prog/buf.h 2015-08-26 00:34:19.000000000 +0900 @@ -36,6 +36,8 @@ double rbuf_get_dbl(struct rbuf *rb, double sridx); double complex rbuf_get_cpx(struct rbuf *rb, double sridx); +void rbuf_set_dbl(struct rbuf *rb, int si, double v); + struct tbuf{ struct rbuf rb; @@ -60,6 +62,8 @@ double tbuf_get_dbl(struct tbuf *tb, double sec); double complex tbuf_get_cpx(struct tbuf *tb, double sec); +void tbuf_set_dbl(struct tbuf *tb, double sec, double v); + struct sbuf{ struct tbuf tb; diff -urN midi_prog-/note.c midi_prog/note.c --- midi_prog-/note.c 2015-06-25 00:00:00.000000000 +0900 +++ midi_prog/note.c 2015-08-25 00:00:00.000000000 +0900 @@ -6,6 +6,7 @@ static int note_pure = 0, note_base = -1, note_pure_cent = 25; static int pure_enable[MIDI_CH_N]; static double note_base_freq; +static int adj_cent = 0; static struct{ int h, l; @@ -30,6 +31,8 @@ int ch, v; char *s; + adj_cent = opt_int("-adj_cent", ac, av, 0); + note_pure = opt_idx("-pure", ac, av) >= 0; note_pure_cent = opt_int("-pure_cent", ac, av, note_pure_cent); @@ -102,13 +105,13 @@ static double note_to_freq(int note) { - return 440 * pow(2, (note - 69) / 12.0); + return 440 * pow(2, (note - 69 + adj_cent *0.01) / 12.0); } static double freq_to_note(double freq) { - return (log(freq / 440) / log(2)) * 12 + 69; + return (log(freq / 440) / log(2)) * 12 + 69 - adj_cent * 0.01; } static int diff -urN midi_prog-/pitdet.c midi_prog/pitdet.c --- midi_prog-/pitdet.c 2015-08-22 00:00:00.000000000 +0900 +++ midi_prog/pitdet.c 2015-08-25 00:00:00.000000000 +0900 @@ -14,7 +14,7 @@ void pitdet_init(struct pitdet *pd, double smp_freq, int adj_cent, - int div, double abuf_wsec) + int div, double abuf_wsec, double thres) { int j; @@ -39,6 +39,61 @@ pd->newest.update = 0; pd->max_v = -1; + pd->thres = thres; + + if((pd->wk = malloc(sizeof(*pd->wk) * pd->m)) == NULL) ERR("No Mem"); +} + +static void +shadow_cut(struct pitdet *pd, double sec) +{ + int j; + + for(j=0; jm; j++){ + double v; + int onoff = pitdet_onoff(pd, sec, j, &v); + pd->wk[j].stat = onoff ? 0 : -1; + if(onoff) pd->wk[j].v = v; + } + + while(1){ + int t = -1; + double v_max = 0; + for(j=0; jm; j++){ + if(pd->wk[j].stat != 0) continue; + if(t < 0 || pd->wk[j].v > v_max){ + t = j; + v_max = pd->wk[j].v; + } + } + if(t < 0) break; + pd->wk[t].stat++; + + for(j=0; jm; j++){ + double a, x, k; + + if(pd->wk[j].stat != 0) continue; + + /* + wn/(2*freq) = (wn+a)/(2*freq[j]) + a = wn*freq[j]/freq - wn + = wn*(freq[j]/freq - 1) + */ + a = pd->arr[t].wn * (pd->arr[j].freq / pd->arr[t].freq - 1); + x = a * M_PI; + k = sin(x) / x; + k = ABS(k); + + pd->wk[j].v -= pd->wk[t].v * k; + if(!pitdet_onoff_judge(pd, pd->wk[j].v)) pd->wk[j].stat = -1; + } + } + + for(j=0; jm; j++){ + struct pitch *p = &pd->arr[j]; + double v = pd->wk[j].stat >= 0 ? pd->wk[j].v : -1; + tbuf_set_dbl(&p->ab.tb, sec, v); + } } void @@ -63,4 +118,27 @@ } if((pd->oldest.update = (pd->oldest.sec != osec)) != 0) pd->oldest.sec = osec; if((pd->newest.update = (pd->newest.sec != nsec)) != 0) pd->newest.sec = nsec; + + if(pd->oldest.update && pd->oldest.sec >= 0) shadow_cut(pd, pd->oldest.sec); +} + +int +pitdet_sec_to_tick(struct pitdet *pd, double sec) +{ + struct tbuf *tb = &pd->arr[0].ab.tb; + return (int) tbuf_sec_to_sridx(tb, sec); +} + +int +pitdet_onoff_judge(struct pitdet *pd, double v) +{ + return v / pd->max_v >= pd->thres; +} + +int +pitdet_onoff(struct pitdet *pd, double sec, int j, double *ret_v) +{ + double v = tbuf_get_dbl(&pd->arr[j].ab.tb, sec); + if(ret_v) *ret_v = v; + return pitdet_onoff_judge(pd, v); } diff -urN midi_prog-/pitdet.h midi_prog/pitdet.h --- midi_prog-/pitdet.h 2015-08-22 00:00:00.000000000 +0900 +++ midi_prog/pitdet.h 2015-08-25 00:00:00.000000000 +0900 @@ -15,14 +15,24 @@ } oldest, newest; double max_v; + double thres; + + struct{ + int stat; + double v; + } *wk; }; double pitdet_note_to_freq(struct pitdet *pd, double note); double pitdet_freq_to_note(struct pitdet *pd, double freq); void pitdet_init(struct pitdet *pd, double smp_freq, int adj_cent, - int div, double abuf_wsec); + int div, double abuf_wsec, double thres); void pitdet_add(struct pitdet *pd, double v); +int pitdet_sec_to_tick(struct pitdet *pd, double sec); +int pitdet_onoff_judge(struct pitdet *pd, double v); +int pitdet_onoff(struct pitdet *pd, double sec, int j, double *ret_v); + #endif diff -urN midi_prog-/rawmix2.c midi_prog/rawmix2.c --- midi_prog-/rawmix2.c 1970-01-01 09:00:00.000000000 +0900 +++ midi_prog/rawmix2.c 2015-08-25 00:00:00.000000000 +0900 @@ -0,0 +1,37 @@ +#include "util.h" +#include "in.h" +#include "out.h" + +int +main(int ac, char **av) +{ + FILE *fp_l = fp_get("-l", ac, av, "-", "r"); + FILE *fp_r = fp_get("-r", ac, av, "-", "r"); + FILE *fp_o = fp_get("-o", ac, av, "-", "w"); + struct out_rec otr; + in_rec_t in_l, in_r; + + if(fp_l == NULL || fp_r == NULL || fp_o == NULL) ERR("Can't open"); + + out_init(&otr, ac, av); + otr.fp = fp_o; + + in_init(&in_l, ac, av); + in_l.fp = fp_l; + in_l.ch_num = 1; + + in_init(&in_r, ac, av); + in_r.fp = fp_r; + in_r.ch_num = 1; + + while(1){ + double v[2]; + if(in_do(&in_l, &v[0]) == EOF) break; + if(in_do(&in_r, &v[1]) == EOF) break; + out_do2(&otr, v); + } + + fclose(fp_l); + fclose(fp_r); + return 0; +} diff -urN midi_prog-/tool.c midi_prog/tool.c --- midi_prog-/tool.c 2015-08-22 00:00:00.000000000 +0900 +++ midi_prog/tool.c 2015-08-25 00:00:00.000000000 +0900 @@ -55,51 +55,6 @@ int j, js, je; char s[32]; double sec = pd->oldest.sec; - int test_off = opt_idx("-test_off", ac, av) > 0; - struct{ - int stat; - double v; - } *wk; - - if((wk = malloc(sizeof(*wk) * pd->m)) == NULL) ERR("No Mem"); - - for(j=0; jm; j++){ - struct pitch *p = &pd->arr[j]; - wk[j].stat = 0; - wk[j].v = tbuf_get_dbl(&p->ab.tb, sec); - } - - while(!test_off){ - int t = -1, j; - double v_max = 0; - for(j=0; jm; j++){ - if(wk[j].stat != 0) continue; - if(t < 0 || wk[j].v > v_max){ - t = j; - v_max = wk[j].v; - } - } - if(t < 0) break; - wk[t].stat++; - - for(j=0; jm; j++){ - double a, x, k; - - if(wk[j].stat != 0) continue; - - /* - wn/(2*freq) = (wn+a)/(2*freq[j]) - a = wn*freq[j]/freq - wn - = wn*(freq[j]/freq - 1) - */ - a = pd->arr[t].wn * (pd->arr[j].freq / pd->arr[t].freq - 1); - x = a * M_PI; - k = sin(x) / x; - k = k < 0 ? -k : k; - - wk[j].v -= wk[t].v * k; - } - } sprintf(s, "sec=%f ", sec); printf("%s", s); @@ -107,7 +62,8 @@ show_spectre_modify_area(pd, ac, av, s, &js, &je); for(j=js; jarr[j]; + double v = tbuf_get_dbl(&p->ab.tb, sec); int iv = (int)(10 * v / pd->max_v); if(iv < 0) iv = -1; @@ -117,8 +73,65 @@ if(pd->div > 1 && j % pd->div == pd->div-1 && j != je-1) putchar(' '); } putchar('\n'); +} + +#define NOTE_N 128 - free(wk); +struct chatt{ + double lmt_sec, sec, chg_try_sec; + int onoff; +} chatt[ NOTE_N ]; + +void +chatt_init(struct chatt *ct, double lmt_sec) +{ + ct->lmt_sec = lmt_sec; + ct->sec = 0; + ct->chg_try_sec = -1; + ct->onoff = 0; +} + +int +chatt_add(struct chatt *ct, double sec, int onoff) +{ + if(onoff == ct->onoff){ + ct->chg_try_sec = -1; + return 0; + } + if(sec - ct->sec < ct->lmt_sec) return 0; + + if(ct->chg_try_sec < 0){ + ct->chg_try_sec = sec; + return 0; + } + if(sec - ct->chg_try_sec < ct->lmt_sec) return 0; + + ct->sec = ct->chg_try_sec; + ct->onoff = onoff; + ct->chg_try_sec = -1; + return 1; +} + +static void +midi_out(struct pitdet *pd) +{ + double sec = pd->oldest.sec; + int i, k; + int tick, ch = 0, velo = 100; + + for(i=0; idiv; k++){ + int j = i * pd->div + k; + onoff |= pitdet_onoff(pd, sec, j, NULL); + } + if(!chatt_add(&chatt[i], sec, onoff)) continue; + + tick = pitdet_sec_to_tick(pd, chatt[i].sec); + printf("abs=%08d %s ch=%d note=%d velo=%d\n", + tick, chatt[i].onoff ? "on " : "off", ch, i, velo); + fflush(stdout); + } } int @@ -126,20 +139,36 @@ { in_rec_t in; double v; + int i; struct pitdet pd; int adj_cent = opt_int("-adj_cent", ac, av, 0); int div = opt_int("-div", ac, av, 1); double abuf_wsec = opt_double("-abuf_wsec", ac, av, 2.5); + int show = opt_idx("-show", ac, av) > 0; + int midi = opt_idx("-midi", ac, av) > 0; + double lmt_sec = opt_double("-lmt_sec", ac, av, 2.0/32); + double thres = opt_double("-thres", ac, av, 0.1); + int sec, s; + + for(i=0; i max_v){ + max_v = v; + idx = i; + } + p = (double *)( (char *)p + next_bytes ); + } + if(ret_v) *ret_v = max_v; + return idx; +} + +FILE * +fp_get(char *key, int ac, char **av, char *def_fn, char *mode) +{ + char *fn = opt_str(key, ac, av, def_fn); + if(fn == NULL) return NULL; + if(strcmp(fn, "-") == 0) return strcmp(mode, "r") == 0 ? stdin : stdout; + return fopen(fn, mode); +} + /* EOF */ diff -urN midi_prog-/util.h midi_prog/util.h --- midi_prog-/util.h 2015-06-21 00:00:00.000000000 +0900 +++ midi_prog/util.h 2015-08-25 00:00:00.000000000 +0900 @@ -16,6 +16,9 @@ #define ARR_N(arr) ( sizeof (arr) / sizeof *(arr) ) #define MIX(a, b, rate) ( (a) * (1 - (rate)) + (b) * (rate) ) +#define ABS(v) ( (v) < 0 ? -(v) : (v) ) +#define MAX(a, b) ( (a) > (b) ? (a) : (b) ) +#define MIN(a, b) ( (a) < (b) ? (a) : (b) ) int opt_idx(char *key, int ac, char **av); char *opt_str(char *key, int ac, char **av, char *def); @@ -40,4 +43,8 @@ int stklst_allsize(struct stklst *p); void *stklst_to_arr(struct stklst *p); +int dbl_max_idx(double *p, int next_bytes, int n, double *ret_v); + +FILE *fp_get(char *key, int ac, char **av, char *def_fn, char *mode); + #endif diff -urN midi_prog-/voco.c midi_prog/voco.c --- midi_prog-/voco.c 2015-06-09 00:00:00.000000000 +0900 +++ midi_prog/voco.c 2015-08-25 00:00:00.000000000 +0900 @@ -18,15 +18,6 @@ double v_c[2], v_v[2]; } *voco_inf; -FILE * -fp_get(char *key, int ac, char **av, char *def_fn, char *mode) -{ - char *fn = opt_str(key, ac, av, def_fn); - if(fn == NULL) return NULL; - if(strcmp(fn, "-") == 0) return strcmp(mode, "r") == 0 ? stdin : stdout; - return fopen(fn, mode); -} - double * adj_vol_init(int ac, char **av) {