sclass PianoSampler2 > SlidingWindow { macro dprint { if (debug) printVars } bool debug; gettable L frequencies; *(int *channels, double *sampleRate, IQuerySound *sound, int *start, int *length) { init(); } *() { init(); } void init { frequencies = pianoFrequencies88(); } long haarFeaturesChecked; // one channel L measureWindow(DoubleRange window, Cl frequencies default frequencies()) { int channel = 0; assertEquals("window length", window.length(), length()); moveTo(ifloor(window.start)); ret map(frequencies(), f -> { var interval = f.interval()*sampleRate; int period1 = ifloor(doubleRatio(window.start, interval)); int period2 = ifloor(doubleRatio(window.end, interval))-1; if (period2 <= period1) ret complex(0); SumOfVibrations sum = new(this, channel, period1*interval, f!, period2-period1); ret sum.complexSum(); }); } Frequency lowestFrequency() { ret first(frequencies); } Frequency highestFrequency() { ret last(frequencies); } int minWindowSizeForBase() { ret iceil(sampleRate*lowestFrequency().interval()); } void makeWindow(DoubleRange r) { start = r.start; length = r.length; grab(); } void makeWindowAround(double t, double size) { double start = max(0, t-size)/2); makeWindow(DoubleRange(start, start+size)); } S stats() { ret renderVars(+haarFeaturesChecked); } IIntegralImage imageColumn(L intensities) { int n = l(intensities); double[] col = new[n]; for y to n: col[n-y-1] = abs(intensities.get(y)); double[] col2 = normalizeDoubles(col, 255); ret bwIntegralImageFromFunction(1, n, (x, y) -> ifloor(col2[y])); } }