sclass SubtractedAudio implements IAudioSample { IAudioSample source; int channels; // for now same value in all channels new TreeMap subtractions; *() {} *(IAudioSample *source) {} void setSource(IAudioSample source) { this.source = source; channels = source.channels(); } public double sampleRate() { ret source.sampleRate(); } public int channels() { ret channels; } public simplyCached DoubleRange bounds() { ret source.bounds(); } // If you subtract plateaus left to right, this is O(log n) in the // number of subtracted plateaus. void subtractPlateau(double start, double end, double intensity) { if (start >= end) ret; _changeSumAt(start, intensity); _changeSumAt(end, -intensity); } void _changeSumAt(double time, double intensity) { double oldValue = unnull(floorValue(subtractions, time)); // create or overwrite subtractions.put(time, oldValue + intensity); Double next = subtractions.higherKey(time); while (next != null) { subtractions.put(next, subtractions.get(next) + intensity); next = subtractions.higherKey(next); } } public double readTableSum(int channel, double t) { double diff = unnull(floorValue(subtractions, t)); ret diff + source.readTableSum(channel, t); } }