GainProcessor.java
package org.hammer.audio.dsp;
import java.util.Objects;
import org.hammer.audio.core.AudioBlock;
/**
* Applies a finite non-negative linear gain and saturates samples to the normalized audio range.
*/
public final class GainProcessor implements DSPProcessor {
/** Conservative upper bound that prevents accidental extreme amplification. */
public static final float MAX_GAIN = 16.0f;
private final float linearFactor;
/**
* Creates a processor with one stable linear multiplier.
*
* @param gain finite multiplier in {@code [0, 16]}
*/
public GainProcessor(float gain) {
if (!Float.isFinite(gain) || gain < 0.0f || gain > MAX_GAIN) {
throw new IllegalArgumentException("gain must be finite and in [0, 16], was " + gain);
}
this.linearFactor = gain;
}
/** Returns the configured linear multiplier. */
public float gain() {
return linearFactor;
}
@Override
public AudioBlock process(AudioBlock input) {
Objects.requireNonNull(input, "input");
float[][] output = new float[input.channels()][input.frames()];
for (int channel = 0; channel < input.channels(); channel++) {
float[] source = input.channelView(channel);
float[] target = output[channel];
for (int frame = 0; frame < input.frames(); frame++) {
target[frame] = clamp(source[frame] * linearFactor);
}
}
return AudioBlock.wrap(input.format(), output, input.frameIndex(), input.timestampNanos());
}
private static float clamp(float sample) {
return Math.max(-1.0f, Math.min(1.0f, sample));
}
}