AudioAnalysis.java
package com.shengzhiai.yugu.audio;
import com.shengzhiai.yugu.model.Warning;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Result of the local audio precheck: detected format, levels and the findings (local codes 90101
* to 90105).
*/
public final class AudioAnalysis {
private final AudioFormat format;
private final long sizeBytes;
private final int sampleRate;
private final int channels;
private final int bitsPerSample;
private final double durationSeconds;
private final boolean levelsMeasured;
private final int peak;
private final double rms;
private final List<Warning> issues;
AudioAnalysis(AudioFormat format, long sizeBytes, int sampleRate, int channels, int bitsPerSample,
double durationSeconds, boolean levelsMeasured, int peak, double rms, List<Warning> issues) {
this.format = format;
this.sizeBytes = sizeBytes;
this.sampleRate = sampleRate;
this.channels = channels;
this.bitsPerSample = bitsPerSample;
this.durationSeconds = durationSeconds;
this.levelsMeasured = levelsMeasured;
this.peak = peak;
this.rms = rms;
this.issues = Collections.unmodifiableList(new ArrayList<>(issues));
}
/** @return detected container */
public AudioFormat getFormat() {
return format;
}
/** @return payload size in bytes */
public long getSizeBytes() {
return sizeBytes;
}
/** @return sample rate, 0 when unknown */
public int getSampleRate() {
return sampleRate;
}
/** @return channels, 0 when unknown */
public int getChannels() {
return channels;
}
/** @return bits per sample, 0 when unknown */
public int getBitsPerSample() {
return bitsPerSample;
}
/** @return duration in seconds, -1 when unknown (compressed formats) */
public double getDurationSeconds() {
return durationSeconds;
}
/** @return true when peak and RMS were measured (16 bit PCM only) */
public boolean isLevelsMeasured() {
return levelsMeasured;
}
/** @return absolute peak of the 16 bit samples */
public int getPeak() {
return peak;
}
/** @return RMS of the 16 bit samples */
public double getRms() {
return rms;
}
/** @return RMS in dBFS, negative infinity for digital silence */
public double getRmsDbfs() {
return rms <= 0 ? Double.NEGATIVE_INFINITY : 20 * Math.log10(rms / 32768.0);
}
/** @return every finding, never null */
public List<Warning> getIssues() {
return issues;
}
/** @return findings that make {@code REJECT} mode throw before upload: 90101, 90102, 90103, 90105 */
public List<Warning> getRejectingIssues() {
List<Warning> out = new ArrayList<>();
for (Warning w : issues) {
if (AudioPrecheck.isRejecting(w.getCode())) {
out.add(w);
}
}
return out;
}
/**
* @param code local code
* @return true when the analysis found this issue
*/
public boolean hasIssue(int code) {
for (Warning w : issues) {
if (w.getCode() == code) {
return true;
}
}
return false;
}
@Override
public String toString() {
return "AudioAnalysis{format=" + format + ", size=" + sizeBytes + ", sampleRate=" + sampleRate
+ ", channels=" + channels + ", bits=" + bitsPerSample + ", duration=" + durationSeconds
+ ", peak=" + peak + ", rms=" + Math.round(rms * 10) / 10.0 + ", issues=" + issues + '}';
}
}