diff --git a/aligner.py b/aligner.py index 32e944a..bf1cbee 100644 --- a/aligner.py +++ b/aligner.py @@ -220,8 +220,9 @@ def interp_missing_1(ts): return np.array(tsl) -def interp_missing(ts_a, ts_b): +def interp_missing(ts_a_o, ts_b_o): """interpolate missing beats""" + ts_a, ts_b = np.array(ts_a_o), np.array(ts_b_o) # deep copy assert len(ts_a) == len(ts_b) ib_th = 0.2 #: sec (inter-beat interval threshold for interpolation) mn_a, mn_b = np.mean(np.diff(ts_a)), np.mean(np.diff(ts_b)) @@ -229,14 +230,62 @@ def interp_missing(ts_a, ts_b): idxs_interp_b = np.where(np.abs(np.diff(ts_b) - mn_b) > ib_th)[0] # join the two sets, and apply interpolation to both timeseries # (ensures they will have the same length afterwards) - idxs_interp = np.array(list(sorted(list(set(idxs_interp_b).union(set(idxs_interp_b)))))) + idxs_interp = list(sorted(list(set(idxs_interp_a).union(set(idxs_interp_b))))) tsl_a, tsl_b = list(ts_a), list(ts_b) + ma, mb = 0, 0 + #print('idxs_interp_a', str(list(idxs_interp_a))) + #print('idxs_interp_b', str(list(idxs_interp_b))) for k, i in enumerate(idxs_interp): - tsl_a.insert(i+k+1, ts_a[i] + (ts_a[i+1] - ts_a[i]) / 2) - tsl_b.insert(i+k+1, ts_b[i] + (ts_b[i+1] - ts_b[i]) / 2) - if len(idxs_interp) > 0: - print('interp_missing: added %d beats' % len(idxs_interp)) - return np.array(tsl_a), np.array(tsl_b) + ai = (ts_a[i+1] - ts_a[i]) + bi = (ts_b[i+1] - ts_b[i]) + # maybe we need to interpolate just on 'a' or 'b' side + # maybe we need to add more than 1 point + na, nb = int(np.round(ai / mn_a)), int(np.round(bi / mn_b)) + # + # maybe we need to merge adjacent + """ + if na == 0: + print('idx=%d: a interp (%.3f, %.3f), rm %d pts of %.3f interval' % (i, ts_a[i], ts_a[i+1], int(na-1), ai)) + print('idx=%d: b interp (%.3f, %.3f), rm %d pts of %.3f interval' % (i, ts_b[i], ts_b[i+1], int(nb-1), bi)) + print(' idx=%d: a1 %s' % (i, tsl_a[i+ma+1-3:i+ma+1+4])) + ts_a[i+1] = ts_a[i] + del tsl_a[i+ma] + print(' idx=%d: a2 %s' % (i, tsl_a[i+ma+1-3:i+ma+1+4])) + print(' idx=%d: b %s' % (i, tsl_b[i+mb+1-3:i+mb+1+4])) + if nb == 0: + print('idx=%d: a interp (%.3f, %.3f), rm %d pts of %.3f interval' % (i, ts_a[i], ts_a[i+1], int(na-1), ai)) + print('idx=%d: b interp (%.3f, %.3f), rm %d pts of %.3f interval' % (i, ts_b[i], ts_b[i+1], int(nb-1), bi)) + print(' idx=%d: b1 %s' % (i, tsl_b[i+mb+1-3:i+mb+1+4])) + ts_b[i+1] = ts_b[i] + del tsl_b[i+ma] + print(' idx=%d: b2 %s' % (i, tsl_b[i+mb+1-3:i+mb+1+4])) + print(' idx=%d: a %s' % (i, tsl_a[i+ma+1-3:i+ma+1+4])) + ai /= na if na != 0 else 1 + bi /= nb if nb != 0 else 1 + """ + ai /= na if na != 0 else 1 + bi /= nb if nb != 0 else 1 + # + #print('idx=%d: a interp (%.3f, %.3f), add %d pts of %.3f interval' % (i, ts_a[i], ts_a[i+1], int(na-1), ai)) + #print('idx=%d: b interp (%.3f, %.3f), add %d pts of %.3f interval' % (i, ts_b[i], ts_b[i+1], int(nb-1), bi)) + #print(' idx=%d: a1 %s' % (i, tsl_a[i+ma+1-3:i+ma+1+4])) + for pa in range(int(na-1)): + tsl_a.insert(i+ma+pa+1, ts_a[i] + ai * (pa+1)) + #print(' idx=%d: a2 %s' % (i, tsl_a[i+ma+1-3:i+ma+1+4])) + #print(' idx=%d: b1 %s' % (i, tsl_b[i+mb+1-3:i+mb+1+4])) + for pb in range(int(nb-1)): + tsl_b.insert(i+mb+pb+1, ts_b[i] + bi * (pb+1)) + #print(' idx=%d: b2 %s' % (i, tsl_b[i+mb+1-3:i+mb+1+4])) + ma += int(na-1) + mb += int(nb-1) + #if len(idxs_interp) > 0: + # print('interp_missing: added %d beats' % len(idxs_interp)) + if ma > 0 or mb > 0: + print('interp_missing: added ma=%d mb=%d beats' % (ma, mb)) + ll = len(ts_a) + min(ma, mb) + oa, ob = np.array(tsl_a)[:ll], np.array(tsl_b)[:ll] + print(len(ts_a), len(oa), len(ob)) + return oa, ob def align(annot_a, annot_b):