sclass AudioAdder extends AbstractAudioSample { new Cl sources; // for now same value in all channels new TreeMap additions; void addSource(IAudioSample source) { addUnlessNull(sources, source); } void grabSpecsFromSource(IAudioSample source) { if (source == null) ret; setSampleRate(source.sampleRate()); setChannels(source.channels()); } void addPlateau(double start, double end, double intensity) { if (start >= end) ret; _changeSumAt(start, intensity); _changeSumAt(end, -intensity); } void subtractPlateau(double start, double end, double intensity) { addPlateau(start, 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) { if (intensity == 0) ret; // create, overwrite or delete _incValue(time, intensity); printVars _changeSumAt(+time, +intensity, value := _getValue(time)); Double next = additions.higherKey(time); while (next != null) { _incValue(next, intensity); next = additions.higherKey(next); } } double _getValue(double time) { ret unnull(floorValue(additions, time)); } void _incValue(double time, double diff) { double before = _getValue(time); double value = before + diff; printVars _incValue(+time, +before, +value); mapPutOrRemove(additions, time, nullIfZero(value)); } public double readSumTable(int channel, double t) { double diff = unnull(floorValue(additions, t)); for (source : sources) diff += source.readSumTable(channel, t); ret diff; } }