diff -urN midi_prog-/Makefile midi_prog/Makefile --- midi_prog-/Makefile Fri Aug 7 00:00:00 2015 +++ midi_prog/Makefile Wed Aug 12 00:00:00 2015 @@ -9,7 +9,7 @@ VCD_OBJS = vcd.o in.o filter.o out.o wrt.o util.o 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 +TOOL_OBJS = tool.o in.o out.o util.o buf.o pitch.o all: $(TARG) vcd voco midtxt tool diff -urN midi_prog-/pitch.c midi_prog/pitch.c --- midi_prog-/pitch.c Thu Jan 1 09:00:00 1970 +++ midi_prog/pitch.c Wed Aug 12 00:00:00 2015 @@ -0,0 +1,69 @@ +#include "pitch.h" + +double +pitch_wn(double freq, double next_freq) +{ + /* + wn / (2 * freq) = (wn + 1) / (2 * next_freq) + + next_freq * wn = freq * wn + freq + (next_freq - freq) * wn = freq + + wn = freq / (next_freq - freq) + = 1 / (next_freq / freq - 1) + + + 440 * e( (69-69)/12 * l(2) ) = 440.00000000000000000000 + 440 * e( (70-69)/12 * l(2) ) = 466.16376151808991640200 + + wn = 1 / (466.163761518089916402 / 440 - 1) + = 16.81715374510576755683 + */ + + return freq / (next_freq - freq); +} + +double +pitch_wsec(double freq, double wn) +{ + return 0.5 * wn / freq; +} + +double +pitch_freq(double wsec, double wn) +{ + /* + T = 2 * wsec / wn + f = wn / (2 * wsec) + = 0.5 * wn / wsec + + wsec = 0.5 * wn / freq + freq = 0.5 * wn / wsec + + */ + return 0.5 * wn / wsec; +} + +void +pitch_init(struct pitch *p, double smp_freq, double freq, int wn, + double abuf_wsec) +{ + p->freq = freq; + p->wn = wn; + sbuf_init(&p->sb, smp_freq, pitch_wsec(p->freq, wn)); + abuf_init(&p->ab, 2*96, abuf_wsec); +} + +void +pitch_add(struct pitch *p, double v) +{ + struct tbuf *stb = &p->sb.tb; + double sec = tbuf_next_sec(stb); + double complex arg = I * 2 * M_PI * p->freq * sec; + + sbuf_add(&p->sb, v * cexp(-arg)); + + if(tbuf_is_over_sec(&p->ab.tb, sec - stb->wsec * 0.5)){ + abuf_add(&p->ab, cabs( sbuf_sum_mean_all(&p->sb) ) ); + } +} diff -urN midi_prog-/pitch.h midi_prog/pitch.h --- midi_prog-/pitch.h Thu Jan 1 09:00:00 1970 +++ midi_prog/pitch.h Wed Aug 12 00:00:00 2015 @@ -0,0 +1,21 @@ +#ifndef __PITCH_H__ +#define __PITCH_H__ + +#include "buf.h" + +struct pitch{ + double freq; + int wn; + struct sbuf sb; + struct abuf ab; +}; + +double pitch_wn(double freq, double next_freq); +double pitch_wsec(double freq, double wn); +double pitch_freq(double wsec, double wn); + +void pitch_init(struct pitch *p, double smp_freq, double freq, int wn, + double abuf_wsec); +void pitch_add(struct pitch *p, double v); + +#endif diff -urN midi_prog-/tool.c midi_prog/tool.c --- midi_prog-/tool.c Mon Aug 10 00:00:00 2015 +++ midi_prog/tool.c Wed Aug 12 00:00:00 2015 @@ -1,6 +1,6 @@ #include "util.h" #include "in.h" -#include "buf.h" +#include "pitch.h" int main(int ac, char **av) @@ -8,19 +8,22 @@ in_rec_t in; double v; - struct sbuf sb; + struct pitch p; double freq = 440.0; - int wn = 8; - double wsec = wn / freq; + double next_freq = 440 * pow(2, (70-69)/12.0); + int wn = (int) pitch_wn(freq, next_freq); + double abuf_wsec = opt_double("-abuf_wsec", ac, av, 0.5); + double sec, sec_bak = -1; in_init(&in, ac, av); - sbuf_init(&sb, in.smp_freq, wsec); + pitch_init(&p, in.smp_freq, freq, wn, abuf_wsec); while(in_do_mono(&in, &v) != EOF){ - double complex arg = I * 2 * M_PI * freq * tbuf_next_sec(&sb.tb); - sbuf_add(&sb, v * cexp(-arg)); - v = cabs( sbuf_sum_mean_all(&sb) ); - printf("v=%f\n", v); + pitch_add(&p, v); + sec = tbuf_newest_sec(&p.ab.tb); + if(sec <= sec_bak) continue; + printf("sec=%f v=%f\n", sec, p.ab.sum); + sec_bak = sec; } return 0; }