sclass PianoSampler2 > SlidingWindow { macro dprint { if (debug) printVars } bool debug; bool printFactor; gettable L frequencies; Double fixedFactor; *(int *channels, double *sampleRate, IQuerySound *sound, int *start, int *length) { init(); } *() { init(); } void init { frequencies = pianoFrequencies88(); } long haarFeaturesChecked; // one channel L measureWindow() { ret measureWindow(bounds()); } L measureWindow(DoubleRange timeRange, Cl frequencies default frequencies()) { int channel = 0; moveToCenter(iround(timeRange.center())); ret map(frequencies(), f -> { var interval = f.interval()*sampleRate; int period1 = iceil(doubleRatio(timeRange.start, interval)); int period2 = ifloor(doubleRatio(timeRange.end, interval))-1; if (period2 <= period1) ret complex(0); int periods = period2-period1; SumOfVibrations sum = new(this, channel, period1*interval, f!, periods); haarFeaturesChecked += periods*2; 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 = ifloor(r.start); length = iceil(r.end())-start; 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 factor = fixedFactor != null ? fixedFactor : normalizationFactor(col, 255); if (printFactor) printVars(+factor, log := log10(factor)); double[] col2 = doubleMul(col, factor); ret bwIntegralImageFromFunction(1, n, (x, y) -> ifloor(col2[y])); } void loadSound(IQuerySound sound, int channels) { this.sound = sound; this.channels = channels; } }