Added RMS and clipping alert in tree view
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user