PhaseScopeSnapshot.java
package org.hammer.audio.snapshot;
import org.hammer.audio.core.AudioBlock;
/**
* Immutable snapshot for stereo phase-scope (X-Y) visualization.
*
* <p>Carries the left and right channel sample arrays from one block, normalized to {@code [-1,
* 1]}. The renderer is responsible for any pixel scaling.
*
* @author refactoring
*/
public final class PhaseScopeSnapshot {
private final float[] left;
private final float[] right;
private final long sourceFrameIndex;
private final long sourceTimestampNanos;
/**
* Build a phase-scope snapshot from an {@link AudioBlock}. Defensive copies are made of the
* channel arrays.
*
* @param block the source block; must have at least 2 channels. If not, an empty snapshot is
* produced.
* @return immutable snapshot
*/
public static PhaseScopeSnapshot fromBlock(AudioBlock block) {
if (block.channels() < 2) {
return new PhaseScopeSnapshot(
new float[0], new float[0], block.frameIndex(), block.timestampNanos());
}
return new PhaseScopeSnapshot(
block.channelView(0).clone(),
block.channelView(1).clone(),
block.frameIndex(),
block.timestampNanos());
}
/** Empty snapshot constant. */
public static final PhaseScopeSnapshot EMPTY =
new PhaseScopeSnapshot(new float[0], new float[0], 0L, 0L);
private PhaseScopeSnapshot(
float[] left, float[] right, long sourceFrameIndex, long sourceTimestampNanos) {
this.left = left;
this.right = right;
this.sourceFrameIndex = sourceFrameIndex;
this.sourceTimestampNanos = sourceTimestampNanos;
}
/**
* @return number of frames in this snapshot
*/
public int frames() {
return left.length;
}
/**
* @return read-only view of the left channel samples (do not mutate)
*/
public float[] leftView() {
return left;
}
/**
* @return read-only view of the right channel samples (do not mutate)
*/
public float[] rightView() {
return right;
}
/**
* @return source block frame index
*/
public long sourceFrameIndex() {
return sourceFrameIndex;
}
/**
* @return source block timestamp in nanos
*/
public long sourceTimestampNanos() {
return sourceTimestampNanos;
}
}