sclass SubtractedAudio implements IAudioSample { IAudioSample source; int channels; // for now same value in all channels. value is actually positive // in terms of what is added 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(); } void subtractPlateau(double start, double end, double intensity) { if (start >= end) ret; _changeSumAt(start, -intensity); _changeSumAt(end, intensity); } // We will probably add plateaus rather randomly throughout an area, // so could optimize this doing something akin to LogNArray. void _changeSumAt(double time, double intensity) { double value = unnull(floorValue(subtractions, time)) + intensity; // create, overwrite or delete mapPutOrRemove(subtractions, time, nullIfZero(value)); Double next = subtractions.higherKey(time); while (next != null) { subtractions.put(next, subtractions.get(next) + intensity); next = subtractions.higherKey(next); } } public double readSumTable(int channel, double t) { double diff = unnull(floorValue(subtractions, t)); ret diff + source.readSumTable(channel, t); } }