package com.zzx.factorytest.utils;
public class SinglePower {
// Maximum signal amplitude for 16-bit data.
private static final float MAX_16_BIT = 32768;
private static final float FUDGE = 0.6f;
public final static double calculatePowerDb(short[] sdata, int off, int length) {
// Calculate the sum of the values, and the sum of the squared values.
// We need longs to avoid running out of bits.
double sum = 0;
double sqsum = 0;
for (int i = 0; i < length; i++) {
final long v = sdata[off + i];
sum += v;
sqsum += v * v;
}
// sqsum is the sum of all (signal+bias)², so
// sqsum = sum(signal²) + samples * bias²
// hence
// sum(signal²) = sqsum - samples * bias²
// Bias is simply the average value, i.e.
// bias = sum / samples
// Since power = sum(signal²) / samples, we have
// power = (sqsum - samples * sum² / samples²) / samples
// so
// power = (sqsum - sum² / samples) / samples
double power = (sqsum - sum * sum / length) / length;
// Scale to the range 0 - 1.
power /= MAX_16_BIT * MAX_16_BIT;
// Convert to dB, with 0 being max power. Add a fudge factor to make
// a "real" fully saturated input come to 0 dB.
return Math.log10(power) * 10f + FUDGE;
}
public final static void biasAndRange(short[] sdata, int off, int samples,
float[] out)
{
// Find the max and min signal values, and calculate the bias.
short min = 32767;
short max = -32768;
int total = 0;
for (int i = off; i < off + samples; ++i) {
final short val = sdata[i];
total += val;
if (val < min)
min = val;
if (val > max)
max = val;
}
final float bias = (float) total / (float) samples;
final float bmin = min + bias;
final float bmax = max - bias;
final float range = Math.abs(bmax - bmin) / 2f;
out[0] = bias;
out[1] = range;
}
}