diff -urN midi_prog-/pitch.c midi_prog/pitch.c --- midi_prog-/pitch.c Thu Aug 27 00:00:00 2015 +++ midi_prog/pitch.c Thu Sep 10 00:00:00 2015 @@ -67,3 +67,70 @@ abuf_add(&p->ab, cabs( sbuf_sum_mean_all(&p->sb) ) ); } } + +void +onoff_stat_init(struct onoff_stat *ost, struct abuf *ab, int ac, char **av) +{ + double lmt_sec = opt_double("-lmt_sec", ac, av, 2.0/32); + chatt_init(&ost->ct, lmt_sec); + chatt_init(&ost->ct2, lmt_sec); + + ost->ab = ab; + ost->v = 0; + ost->on_sec = -1; + ost->off_sec = 0; + + ost->thres = opt_double("-thres", ac, av, 0.03); + ost->mean_thres = opt_double("-mean_thres", ac, av, 0.1); + ost->mean = -1; +} + +int +onoff_stat_add(struct onoff_stat *ost, double v, double max_v) +{ + struct tbuf *tb = &ost->ab->tb; + double sec; + + abuf_add(ost->ab, v); + sec = tbuf_newest_sec(tb); + return onoff_stat_add_sec(ost, sec, max_v); +} + +int +onoff_stat_add_sec(struct onoff_stat *ost, double sec, double max_v) +{ + struct tbuf *tb = &ost->ab->tb; + double v = tbuf_get_dbl(tb, sec); + int onoff = v >= max_v * ost->thres; + int chg = chatt_add(&ost->ct, sec, onoff), chg2, chg_v = -1; + + if(ost->mean >= 0){ + ost->mean = abuf_mean(ost->ab, ost->on_sec, sec); + chg2 = chatt_add(&ost->ct2, sec, v >= ost->mean * ost->mean_thres); + } + + if(!ost->v){ + if(ost->mean >= 0 && chg2 && ost->ct2.onoff){ + ost->on_sec = ost->ct2.sec; + chg_v = 1; + }else if(chg && ost->ct.onoff){ + ost->on_sec = ost->ct.sec; + chg_v = 1; + + ost->mean = abuf_mean(ost->ab, ost->on_sec, sec); + chatt_set(&ost->ct2, 1); + } + }else{ + if(chg && !ost->ct.onoff){ + ost->off_sec = ost->ct.sec; + chg_v = 0; + + ost->mean = -1; + }else if(chg2 && !ost->ct2.onoff){ + ost->off_sec = ost->ct2.sec; + chg_v = 0; + } + } + if(chg_v >= 0) ost->v = chg_v; + return chg_v; +} diff -urN midi_prog-/pitch.h midi_prog/pitch.h --- midi_prog-/pitch.h Thu Aug 27 00:00:00 2015 +++ midi_prog/pitch.h Thu Sep 10 00:00:00 2015 @@ -18,4 +18,20 @@ double tick_freq, double abuf_wsec); void pitch_add(struct pitch *p, double v); +struct onoff_stat{ + struct abuf *ab; + struct chatt ct, ct2; + int v; + double on_sec; + double off_sec; + + double thres; + double mean_thres; + double mean; +}; + +void onoff_stat_init(struct onoff_stat *ost, struct abuf *ab, int ac, char **av); +int onoff_stat_add(struct onoff_stat *ost, double v, double max_v); +int onoff_stat_add_sec(struct onoff_stat *ost, double sec, double max_v); + #endif diff -urN midi_prog-/tool.c midi_prog/tool.c --- midi_prog-/tool.c Wed Sep 9 00:00:00 2015 +++ midi_prog/tool.c Thu Sep 10 00:00:00 2015 @@ -100,32 +100,24 @@ } struct note_onoff{ - struct chatt ct, ct2; + struct onoff_stat ost; struct abuf ab; struct pitdet *pd; int note; - double on_sec; double pre_release; int cut_over_tone; - double peak, peak_thres; int onoff; } note_onoff[ NOTE_N ]; void note_onoff_init(struct note_onoff *nto, struct pitdet *pd, int note, int ac, char **av) { - double lmt_sec = opt_double("-lmt_sec", ac, av, 2.0/32); - chatt_init(&nto->ct, lmt_sec); + onoff_stat_init(&nto->ost, &nto->ab, ac, av); abuf_init(&nto->ab, pd->tick_freq, 2*4*4); nto->pd = pd; nto->note = note; - nto->on_sec = -1; nto->pre_release = opt_double("-pre_release", ac, av, 0); nto->cut_over_tone = opt_idx("-cut_over_tone", ac, av) > 0; - - chatt_init(&nto->ct2, lmt_sec); - nto->peak = -1; - nto->peak_thres = opt_double("-peak_thres", ac, av, 0.1); nto->onoff = 0; } @@ -173,45 +165,18 @@ note_onoff_add(struct note_onoff *nto, double sec, int onoff, double v, int ch) { double on_sec, off_sec; - int tick, velo; - int chg, chg2, chg_a = -1; + int tick, velo, chg_v; abuf_add(&nto->ab, v); - chg = chatt_add(&nto->ct, sec, onoff); - if(nto->peak >= 0){ - nto->peak = MAX(nto->peak, v); - chg2 = chatt_add(&nto->ct2, sec, v > nto->peak * nto->peak_thres); - } + chg_v = onoff_stat_add_sec(&nto->ost, sec, nto->pd->max_v); - if(!nto->onoff){ - if(nto->peak >= 0 && chg2 && nto->ct2.onoff){ - nto->on_sec = nto->ct2.sec; - chg_a = 1; - }else if(chg && nto->ct.onoff){ - nto->on_sec = nto->ct.sec; - chg_a = 1; - - nto->peak = abuf_max(&nto->ab, nto->on_sec, sec, NULL); - chatt_set(&nto->ct2, 1); - } - }else{ - if(chg && !nto->ct.onoff){ - off_sec = nto->ct.sec; - chg_a = 0; - - nto->peak = -1; - }else if(chg2 && !nto->ct2.onoff){ - off_sec = nto->ct2.sec; - chg_a = 0; - } - } - if(chg_a < 0) return; - if((nto->onoff = chg_a) > 0) return; - if(nto->on_sec < 0) return; + if(chg_v < 0) return; + if((nto->onoff = chg_v) > 0) return; + if(nto->ost.on_sec < 0) return; - on_sec = nto->on_sec; - nto->on_sec = -1; + on_sec = nto->ost.on_sec; + off_sec = nto->ost.off_sec; if(nto->pre_release > 0){ double off_lmt = on_sec + 1.0 / nto->pd->tick_freq;