diff -urN midi_prog-/pitdet.c midi_prog/pitdet.c --- midi_prog-/pitdet.c Thu Aug 13 00:00:00 2015 +++ midi_prog/pitdet.c Fri Aug 14 00:00:00 2015 @@ -32,27 +32,34 @@ pitch_init(&pd->arr[j], smp_freq, freq, wn, abuf_wsec); } - pd->oldest_sec = -1; - pd->newest_sec = -1; + pd->oldest.sec = -1; + pd->oldest.update = 0; + pd->newest.sec = -1; + pd->newest.update = 0; + + pd->max_v = -1; } void pitdet_add(struct pitdet *pd, double v) { int j; - double sec; + double sec, osec = -1, nsec = -1; - pd->oldest_sec = -1; - pd->newest_sec = -1; + pd->max_v = -1; for(j=0; jm; j++){ struct pitch *p = &pd->arr[j]; pitch_add(p, v); sec = tbuf_oldest_sec(&p->ab.tb); - if(pd->oldest_sec < 0 || sec > pd->oldest_sec) pd->oldest_sec = sec; + if(osec < 0 || sec > osec) osec = sec; sec = tbuf_newest_sec(&p->ab.tb); - if(pd->newest_sec < 0 || sec < pd->newest_sec) pd->newest_sec = sec; + if(nsec < 0 || sec < nsec) nsec = sec; + + if(p->ab.max_v > pd->max_v) pd->max_v = p->ab.max_v; } + 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; } diff -urN midi_prog-/pitdet.h midi_prog/pitdet.h --- midi_prog-/pitdet.h Thu Aug 13 00:00:00 2015 +++ midi_prog/pitdet.h Fri Aug 14 00:00:00 2015 @@ -7,7 +7,13 @@ int div; int m; struct pitch *arr; - double oldest_sec, newest_sec; + + struct{ + double sec; + int update; + } oldest, newest; + + double max_v; }; double pitdet_note_to_freq(double note); diff -urN midi_prog-/tool.c midi_prog/tool.c --- midi_prog-/tool.c Thu Aug 13 00:00:00 2015 +++ midi_prog/tool.c Fri Aug 14 00:00:00 2015 @@ -2,6 +2,79 @@ #include "in.h" #include "pitdet.h" +static void +show_spectre_modify_area(struct pitdet *pd, int ac, char **av, char *s, int *ret_js, int *ret_je) +{ + int show_w = opt_int("-show_w", ac, av, -1); + int cen, div, j, js, je; + + *ret_js = js = 0; + *ret_je = je = pd->m; + if(show_w < 0) return; + + div = pd->div; + cen = opt_int("-show_cen_note", ac, av, 64) * div; + + for(;;){ + int over, a, b; + int w = strlen(s) + je - js; + for(j=js; j 1 && j % div == div-1 && j != je-1) + w++; + if(w <= show_w) break; + + over = w - show_w; + /* + next_js = js + a + next_je = je - b + + (a + b)(1 + 1 / div) = over + a + b = over / (1 + 1 / div) = over * div / (div + 1) + b = over * div / (div + 1) - a + + (next_js + next_je) / 2 = cen + js + je + a - b - over = 2 cen + js + je + a - (over * div / (div + 1) - a) - over = 2 cen + js + je + 2a = 2 cen + over * (1 + div / (div + 1)) + 2a = 2cen + over * (1 + div / (div + 1)) - (js + je) + a = cen + ( over * (1 + div / (div + 1)) - (js + je) ) / 2 + + */ + a = cen + ( over * (1 + div / (div + 1)) - (js + je) ) / 2; + b = a > 0 ? over * div / (div + 1) - a : over; + js += a; + je -= b; + } + *ret_js = js; + *ret_je = je; +} + +static void +show_spectre(struct pitdet *pd, int ac, char **av) +{ + int j, js, je; + char s[32]; + double sec = pd->oldest.sec; + + sprintf(s, "sec=%f ", sec); + printf("%s", s); + + 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; + if(iv > 9) iv = 10; + putchar("-0123456789+"[ iv + 1]); + + if(pd->div > 1 && j % pd->div == pd->div-1 && j != je-1) putchar(' '); + } + putchar('\n'); +} + int main(int ac, char **av) { @@ -10,20 +83,16 @@ struct pitdet pd; int div = opt_int("-div", ac, av, 1); - double abuf_wsec = opt_double("-abuf_wsec", ac, av, 0.5); - double old_bak = 0, new_bak = 0; + double abuf_wsec = opt_double("-abuf_wsec", ac, av, 2.5); in_init(&in, ac, av); pitdet_init(&pd, in.smp_freq, div, abuf_wsec); while(in_do_mono(&in, &v) != EOF){ pitdet_add(&pd, v); - if( pd.oldest_sec > 0 && pd.newest_sec > 0 && - (pd.oldest_sec > old_bak || pd.newest_sec > new_bak) ){ - printf("%f %f\n", pd.oldest_sec, pd.newest_sec); - old_bak = pd.oldest_sec; - new_bak = pd.newest_sec; - } + if(!pd.oldest.update) continue; + if(pd.oldest.sec < 0) continue; + show_spectre(&pd, ac, av); } return 0; }