sclass SlidingWindow implements IAudioSample { // general params double sampleRate; int channels; // length of window int length; // in samples per channel // start of window double start; // at which index in data array is our first value? int boundaryIndex; // in data // Here they are: the partial sums of the 16 bit audio samples // in an array of 6-byte integers. Channels are stored interleaved. HalfLongs data; // query original sound (channel, time -> short-range) IQuerySound getSample; public double sampleRate() { ret sampleRate; } public int channels() { ret channels; } public DoubleRange bounds() { ret DoubleRange(start, start+length); } // result is in the range -32768*(end-start) to 32767*(end-start) public double sampleSum(int channel, double start, double end) { // We could do linear interpolation here if we weren't so basic. int a = ifloor(start-this.start), b = ifloor(end); ret getEntry(channel, b-1)-getEntry(channel, a-1); } // Get an entry of the sum table - allow for out-of-bounds // requests (those just default to silence). long getEntry(int channel, int i) { if (i < 0) ret 0; i = min(i, length-1); // do the shift i = (i+boundaryIndex) % length; ret data.get(i*channels+channel); } void setEntry(int channel, int i, long l) { // do the shift i = (i+boundaryIndex) % length; data.set(i*channels+channel, l); } // constructor - perform integration of the raw audio data *(int *channels, double *sampleRate, IQuerySound *getSample) { length = lengthLevel2_shortArrays(samples); data = new HalfLongs(length*channels); long[] sums = new[channels]; int iSample = 0, iChunk = 0, iInArray = 0; short[] chunk = null; for i to length: for c to channels: setEntry(iSample++, sums[c] += clampToShort(iround(getSample.getSample(c, start+i)))); } short getSample_short(int channel, double time) { ret clampToShort(iround(getSample.getSample(c, time))); } void shiftRight { start++; boundaryIndex = mod(boundaryIndex+1, length); for c to channels: { setEntry(c, length-1, getSample_short(c, )); } } }