sclass PianoSampler2 > SlidingWindow { macro dprint { if (debug) printVars } bool debug; gettable L frequencies; *() { frequencies = pianoFrequencies88(); } long haarFeaturesChecked; // one channel L measureWindow(DoubleRange window, Cl frequencies default frequencies()) { int channel = 0; assertEquals("window length", window.length(), length()); moveTo(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 makeSmallestWindow(IQuerySound sound) { this.sound = sound; setAudio(new SlidingWindow(channels, sampleRate, sound, 0, minWindowSizeForBase()); } 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])); } }