Added RMS and clipping alert in tree view

This commit is contained in:
2020-05-23 20:18:49 +01:00
parent 1005619211
commit 19bf57143c
94 changed files with 3437 additions and 204 deletions
@@ -799,6 +799,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
if (n instanceof Sentence) {
Sentence s = (Sentence)n;
s.refreshAllData();
//selectedSentence = s;
s.updateCrossings();
sampleWaveform.setSentence(s);
@@ -42,6 +42,10 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
icn.add(Overlays.attention, OverlayIcon.TOP_LEFT);
}
if (s.isClipping()) {
ret.setForeground(new Color(0xe0, 0x00, 0x00));
}
if (s.isLocked()) {
ret.setForeground(new Color(0x30, 0xb0, 0xFF));
icn.add(Overlays.locked, OverlayIcon.BOTTOM_LEFT);
@@ -125,10 +129,10 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
ctx.weightx = 0.0d;
ctx.gridx = 3;
ctx.anchor = GridBagConstraints.LINE_END;
int peak = s.getPeakDB();
int peak = (int)s.getRMS();
JLabel peakLabel = new JLabelFixedWidth(50, peak + "dB ");
peakLabel.setHorizontalAlignment(SwingConstants.RIGHT);
if (peak > 0) {
if ((peak < -23) || (peak > -18)) {
peakLabel.setForeground(new Color(0xCC, 0x00, 0x00));
}
p.add(peakLabel, ctx);
@@ -159,9 +163,22 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
ctx.anchor = GridBagConstraints.LINE_START;
ctx.weightx = 1.0d;
p.add(ret, ctx);
ctx.weightx = 0.0d;
ctx.gridx = 1;
ctx.anchor = GridBagConstraints.LINE_END;
int peak = (int)c.getRMS();
JLabel peakLabel = new JLabelFixedWidth(50, peak + "dB ");
peakLabel.setHorizontalAlignment(SwingConstants.RIGHT);
if ((peak < -23) || (peak > -18)) {
peakLabel.setForeground(new Color(0xCC, 0x00, 0x00));
}
p.add(peakLabel, ctx);
ctx.weightx = 0.0d;
ctx.gridx = 2;
ctx.anchor = GridBagConstraints.LINE_END;
p.add(time, ctx);
p.setOpaque(false);
return p;
@@ -420,4 +420,20 @@ public class Chapter extends BookTreeNode {
}
}
}
public double getRMS() {
double rms = 0;
int c = 0;
for (Enumeration o = children(); o.hasMoreElements();) {
Object ob = (Object)o.nextElement();
if (ob instanceof Sentence) {
Sentence s = (Sentence)ob;
rms += s.getRMS();
c++;
}
}
return rms / c;
}
}
@@ -95,6 +95,8 @@ public class Sentence extends BookTreeNode implements Cacheable {
Book parentBook = null;
double runtime = -1d;
double rms = -100d;
int clipping = 0;
double[][] audioData = null;
@@ -226,6 +228,8 @@ public class Sentence extends BookTreeNode implements Cacheable {
sampleSize = Utils.s2i(Book.getTextNode(root, "samples"));
processed = Utils.s2b(Book.getTextNode(root, "processed"));
runtime = Utils.s2d(Book.getTextNode(root, "time", "-1.000"));
rms = Utils.s2d(Book.getTextNode(root, "rms", "-100.000"));
clipping = Utils.s2i(Book.getTextNode(root, "clipping", "0"));
peak = Utils.s2d(Book.getTextNode(root, "peak", "-1.000"));
isDetected = Utils.s2b(Book.getTextNode(root, "detected"));
@@ -944,7 +948,7 @@ public class Sentence extends BookTreeNode implements Cacheable {
int gainint = (int)(gain * 100d);
gain = g;
if (gint != gainint) {
CacheManager.removeFromCache(this);
refreshAllData();
peak = -1;
reloadTree();
}
@@ -960,7 +964,6 @@ public class Sentence extends BookTreeNode implements Cacheable {
if (locked) return gain;
double max = getPeakValue(false);
double d = 0.708 / max;
if (d > 1d) d = 1d;
if (d < low) d = low;
if (d > high) d = high;
setGain(d);
@@ -975,7 +978,6 @@ public class Sentence extends BookTreeNode implements Cacheable {
if (locked) return gain;
double max = getPeakValue(false);
double d = 0.708 / max;
if (d > 1d) d = 1d;
setGain(d);
peak = -1;
getPeak();
@@ -1117,6 +1119,8 @@ public class Sentence extends BookTreeNode implements Cacheable {
CacheManager.removeFromCache(Sentence.this);
runtime = -1;
rms = -100d;
clipping = 0;
sampleSize = -1;
loadFile();
Debug.d("Ending size:", sampleSize);
@@ -1685,6 +1689,8 @@ public class Sentence extends BookTreeNode implements Cacheable {
sentenceNode.appendChild(Book.makeTextNode(doc, "time", getLength()));
sentenceNode.appendChild(Book.makeTextNode(doc, "peak", getPeak()));
sentenceNode.appendChild(Book.makeTextNode(doc, "detected", beenDetected()));
sentenceNode.appendChild(Book.makeTextNode(doc, "rms", getRMS()));
sentenceNode.appendChild(Book.makeTextNode(doc, "clipping", isClipping() ? 2 : 1));
Element gp = doc.createElement("gainpoints");
if (gainPoints != null) {
for (Integer loc : gainPoints.keySet()) {
@@ -1821,6 +1827,8 @@ public class Sentence extends BookTreeNode implements Cacheable {
public void refreshAllData() {
runtime = -1d;
rms = -100d;
clipping = 0;
peak = -1d;
sampleSize = -1;
audioData = null;
@@ -1833,6 +1841,8 @@ public class Sentence extends BookTreeNode implements Cacheable {
crossEndOffset = -1;
updateCrossings();
getPeakDB();
getRMS();
isClipping();
reloadTree();
}
@@ -1849,12 +1859,12 @@ public class Sentence extends BookTreeNode implements Cacheable {
gainPoints = new TreeMap<Integer, Double>();
}
gainPoints.put(loc, g);
CacheManager.removeFromCache(this);
refreshAllData();
}
public void removeGainPoint(Integer loc) {
gainPoints.remove(loc);
CacheManager.removeFromCache(this);
refreshAllData();
}
public void adjustGainPoint(Integer loc, Double adj) {
@@ -1866,7 +1876,7 @@ public class Sentence extends BookTreeNode implements Cacheable {
if (gp == null) return;
gp += adj;
gainPoints.put(loc, gp);
CacheManager.removeFromCache(this);
refreshAllData();
}
public double[] calculateGains() {
@@ -1900,4 +1910,55 @@ public class Sentence extends BookTreeNode implements Cacheable {
}
return gains;
}
public double getRMS() {
if (rms > -90d) return rms;
double[][] samples = getProcessedAudioData();
if (samples == null) {
return -100d;
}
double leftsq = 0d;
double rightsq = 0d;
int c = 0;
for (int i = crossStartOffset; i < crossEndOffset; i++) {
leftsq += (double)(samples[LEFT][i] * samples[LEFT][i]);
rightsq += (double)(samples[RIGHT][i] * samples[RIGHT][i]);
c++;
}
double left = Math.sqrt(leftsq / c);
double right = Math.sqrt(rightsq / c);
double l10 = Math.log10((left + right) / 2d);
rms = 20d * l10;
return rms;
}
public boolean isClipping() {
if (clipping > 0) {
if (clipping == 1) return false;
return true;
}
double[][] samples = getProcessedAudioData();
if (samples == null) {
return false;
}
clipping = 1;
for (int i = 0; i < samples[LEFT].length; i++) {
if (samples[LEFT][i] > 0.708) {
clipping = 2;
return true;
}
if (samples[RIGHT][i] > 0.708) {
clipping = 2;
return true;
}
}
return false;
}
}