Fix caching of processed audio. Add effect icon and name to tree

This commit is contained in:
2019-07-21 20:02:07 +01:00
parent c01fee3b73
commit 37d372b8f5
5 changed files with 91 additions and 16 deletions

View File

@@ -34,7 +34,7 @@ public class AudiobookRecorder extends JFrame {
public static final String SPHINX_MODEL = "resource:/edu/cmu/sphinx/models/en-us/en-us"; public static final String SPHINX_MODEL = "resource:/edu/cmu/sphinx/models/en-us/en-us";
static Properties config = new Properties(); static Properties config = new Properties();
HashMap<String, EffectGroup> effects; TreeMap<String, EffectGroup> effects;
String defaultEffectChain = "none"; String defaultEffectChain = "none";
@@ -748,7 +748,6 @@ public class AudiobookRecorder extends JFrame {
prefs.setProperty("chapter.close.pre-gap", Options.get("catenation.pre-chapter")); prefs.setProperty("chapter.close.pre-gap", Options.get("catenation.pre-chapter"));
prefs.setProperty("chapter.close.post-gap", Options.get("catenation.post-chapter")); prefs.setProperty("chapter.close.post-gap", Options.get("catenation.post-chapter"));
loadEffects();
buildBook(prefs); buildBook(prefs);
Options.set("path.last-book", book.getName()); Options.set("path.last-book", book.getName());
@@ -1684,7 +1683,6 @@ public class AudiobookRecorder extends JFrame {
prefs.loadFromXML(fis); prefs.loadFromXML(fis);
File r = f.getParentFile(); File r = f.getParentFile();
loadEffects();
buildBook(prefs); buildBook(prefs);
@@ -1716,6 +1714,8 @@ public class AudiobookRecorder extends JFrame {
book.setComment(prefs.getProperty("book.comment")); book.setComment(prefs.getProperty("book.comment"));
book.setACX(prefs.getProperty("book.acx")); book.setACX(prefs.getProperty("book.acx"));
loadEffects();
defaultEffectChain = prefs.getProperty("audio.effect.default"); defaultEffectChain = prefs.getProperty("audio.effect.default");
if (defaultEffectChain == null) { if (defaultEffectChain == null) {
defaultEffectChain = "none"; defaultEffectChain = "none";
@@ -2119,7 +2119,7 @@ public class AudiobookRecorder extends JFrame {
Thread t = new Thread(new Runnable() { Thread t = new Thread(new Runnable() {
public void run() { public void run() {
Sentence ns = (Sentence)next; Sentence ns = (Sentence)next;
ns.loadFile(); // Cache it ns.getProcessedAudioData(); // Cache it
} }
}); });
t.start(); t.start();
@@ -2649,7 +2649,7 @@ public class AudiobookRecorder extends JFrame {
} }
public void loadEffects() { public void loadEffects() {
effects = new HashMap<String,EffectGroup>(); effects = new TreeMap<String,EffectGroup>();
loadEffectsFromFolder(new File(Options.get("path.storage"), "System")); loadEffectsFromFolder(new File(Options.get("path.storage"), "System"));
if (book != null) { if (book != null) {
loadEffectsFromFolder(new File(Options.get("path.storage"), book.getName())); loadEffectsFromFolder(new File(Options.get("path.storage"), book.getName()));
@@ -2705,6 +2705,11 @@ public class AudiobookRecorder extends JFrame {
if (eff != null) { if (eff != null) {
group.addEffect(eff); group.addEffect(eff);
} }
} else if (e.getTagName().equals("pan")) {
Effect eff = (Effect)loadPan(e);
if (eff != null) {
group.addEffect(eff);
}
} else if (e.getTagName().equals("amplifier")) { } else if (e.getTagName().equals("amplifier")) {
Effect eff = (Effect)loadAmplifier(e); Effect eff = (Effect)loadAmplifier(e);
if (eff != null) { if (eff != null) {
@@ -2769,6 +2774,9 @@ public class AudiobookRecorder extends JFrame {
DelayLine line = new DelayLine(); DelayLine line = new DelayLine();
NodeList list = root.getChildNodes(); NodeList list = root.getChildNodes();
if (Utils.s2b(root.getAttribute("wetonly"))) {
line.setWetOnly(true);
}
for (int i = 0; i < list.getLength(); i++) { for (int i = 0; i < list.getLength(); i++) {
Node n = list.item(i); Node n = list.item(i);
@@ -2777,7 +2785,9 @@ public class AudiobookRecorder extends JFrame {
if (e.getTagName().equals("delay")) { if (e.getTagName().equals("delay")) {
int samples = Utils.s2i(e.getAttribute("samples")); int samples = Utils.s2i(e.getAttribute("samples"));
double gain = Utils.s2d(e.getAttribute("gain")); double gain = Utils.s2d(e.getAttribute("gain"));
DelayLineStore store = line.addDelayLine(samples, gain); double pan = Utils.s2d(e.getAttribute("pan"));
DelayLineStore store = line.addDelayLine(samples, gain, pan);
NodeList inner = e.getChildNodes(); NodeList inner = e.getChildNodes();
for (int j = 0; j < inner.getLength(); j++) { for (int j = 0; j < inner.getLength(); j++) {
@@ -2795,6 +2805,11 @@ public class AudiobookRecorder extends JFrame {
if (eff != null) { if (eff != null) {
store.addEffect(eff); store.addEffect(eff);
} }
} else if (ie.getTagName().equals("pan")) {
Effect eff = (Effect)loadPan(ie);
if (eff != null) {
store.addEffect(eff);
}
} else if (ie.getTagName().equals("amplifier")) { } else if (ie.getTagName().equals("amplifier")) {
Effect eff = (Effect)loadAmplifier(ie); Effect eff = (Effect)loadAmplifier(ie);
if (eff != null) { if (eff != null) {
@@ -2835,6 +2850,11 @@ public class AudiobookRecorder extends JFrame {
return a; return a;
} }
public Pan loadPan(Element root) {
Pan p = new Pan(Utils.s2d(root.getAttribute("pan")));
return p;
}
public Clipping loadClipping(Element root) { public Clipping loadClipping(Element root) {
Clipping c = new Clipping(Utils.s2d(root.getAttribute("clip"))); Clipping c = new Clipping(Utils.s2d(root.getAttribute("clip")));
return c; return c;

View File

@@ -31,6 +31,12 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
icn.add(Overlays.important, OverlayIcon.TOP_RIGHT); icn.add(Overlays.important, OverlayIcon.TOP_RIGHT);
} }
if (s.getEffectChain() != null) {
if (!s.getEffectChain().equals("none")) {
icn.add(Overlays.filter, OverlayIcon.BOTTOM_RIGHT);
}
}
ret.setIcon(icn); ret.setIcon(icn);
} else if (value instanceof Chapter) { } else if (value instanceof Chapter) {

View File

@@ -6,6 +6,8 @@ public class DelayLine implements Effect {
ArrayList<DelayLineStore> delayLines; ArrayList<DelayLineStore> delayLines;
boolean wetOnly = false;
public DelayLine() { public DelayLine() {
delayLines = new ArrayList<DelayLineStore>(); delayLines = new ArrayList<DelayLineStore>();
} }
@@ -19,6 +21,12 @@ public class DelayLine implements Effect {
for (int i = 0; i < samples.length; i++) { for (int i = 0; i < samples.length; i++) {
savedSamples[i] = new Sample(samples[i].left, samples[i].right); savedSamples[i] = new Sample(samples[i].left, samples[i].right);
} }
if (wetOnly) {
for (int i = 0; i < samples.length; i++) {
samples[i].left = 0d;
samples[i].right = 0d;
}
}
for (DelayLineStore d : delayLines) { for (DelayLineStore d : delayLines) {
Sample[] subSamples = new Sample[samples.length]; Sample[] subSamples = new Sample[samples.length];
@@ -62,6 +70,12 @@ public class DelayLine implements Effect {
return out; return out;
} }
public DelayLineStore addDelayLine(int samples, double gain, double pan) {
DelayLineStore s = new DelayLineStore(samples, gain, pan);
delayLines.add(s);
return s;
}
public DelayLineStore addDelayLine(int samples, double gain) { public DelayLineStore addDelayLine(int samples, double gain) {
DelayLineStore s = new DelayLineStore(samples, gain); DelayLineStore s = new DelayLineStore(samples, gain);
delayLines.add(s); delayLines.add(s);
@@ -88,4 +102,8 @@ public class DelayLine implements Effect {
s.init(sf); s.init(sf);
} }
} }
public void setWetOnly(boolean b) {
wetOnly = b;
}
} }

View File

@@ -6,12 +6,21 @@ import java.util.ArrayList;
public class DelayLineStore { public class DelayLineStore {
double gain; double gain;
int numSamples; int numSamples;
double pan;
ArrayList<Effect> effects; ArrayList<Effect> effects;
public DelayLineStore(int s, double g, double p) {
numSamples = s;
gain = g;
pan = p;
effects = new ArrayList<Effect>();
}
public DelayLineStore(int s, double g) { public DelayLineStore(int s, double g) {
numSamples = s; numSamples = s;
gain = g; gain = g;
pan = 0d;
effects = new ArrayList<Effect>(); effects = new ArrayList<Effect>();
} }
@@ -23,6 +32,14 @@ public class DelayLineStore {
for (Sample sample : samples) { for (Sample sample : samples) {
sample.left *= gain; sample.left *= gain;
sample.right *= gain; sample.right *= gain;
if (pan < 0) {
double p = 1 + pan;
sample.right *= p;
} else {
double p = 1 - pan;
sample.left *= p;
}
} }
} }

View File

@@ -64,6 +64,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
double storedLength = -1d; double storedLength = -1d;
Sample[] audioData = null; Sample[] audioData = null;
Sample[] processedAudio = null;
RecordingThread recordingThread; RecordingThread recordingThread;
@@ -391,7 +392,11 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} }
public String toString() { public String toString() {
return text; if (effectChain == null) return text;
if (effectChain.equals("none")) return text;
Effect e = AudiobookRecorder.window.effects.get(effectChain);
if (e == null) return text;
return text + " (" + e.toString() + ")";
} }
public boolean isRecording() { public boolean isRecording() {
@@ -560,6 +565,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public void clearCache() { public void clearCache() {
audioData = null; audioData = null;
processedAudio = null;
} }
public boolean lockedInCache() { public boolean lockedInCache() {
@@ -669,8 +675,11 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public void setGain(double g) { public void setGain(double g) {
if (g <= 0.0001d) g = 1.0d; if (g <= 0.0001d) g = 1.0d;
if (g == gain) return; if (g == gain) return;
if (gain != g) {
clearCache();
}
gain = g; gain = g;
clearCache();
} }
public double getGain() { public double getGain() {
@@ -952,10 +961,12 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public Sample[] getProcessedAudioData() { public Sample[] getProcessedAudioData() {
loadFile(); loadFile();
if (processedAudio != null) return processedAudio;
if (audioData == null) return null; if (audioData == null) return null;
Sample[] samples = new Sample[audioData.length]; processedAudio = new Sample[audioData.length];
for (int i = 0; i < audioData.length; i++) { for (int i = 0; i < audioData.length; i++) {
samples[i] = new Sample(audioData[i].left, audioData[i].right); processedAudio[i] = new Sample(audioData[i].left, audioData[i].right);
} }
// Add processing in here. // Add processing in here.
@@ -965,7 +976,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
if (eff != null) { if (eff != null) {
eff.init(getAudioFormat().getFrameRate()); eff.init(getAudioFormat().getFrameRate());
eff.process(samples); eff.process(processedAudio);
} }
if (effectChain != null) { if (effectChain != null) {
@@ -974,17 +985,17 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
eff = AudiobookRecorder.window.effects.get(effectChain); eff = AudiobookRecorder.window.effects.get(effectChain);
if (eff != null) { if (eff != null) {
eff.init(getAudioFormat().getFrameRate()); eff.init(getAudioFormat().getFrameRate());
eff.process(samples); eff.process(processedAudio);
} }
} }
} }
// Add final master gain stage // Add final master gain stage
for (int i = 0; i < samples.length; i++) { for (int i = 0; i < processedAudio.length; i++) {
samples[i].left = samples[i].left * gain; processedAudio[i].left = processedAudio[i].left * gain;
samples[i].right = samples[i].right * gain; processedAudio[i].right = processedAudio[i].right * gain;
} }
return samples; return processedAudio;
} }
public Sample[] getDoubleAudioData() { public Sample[] getDoubleAudioData() {
@@ -1028,6 +1039,9 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} }
public void setEffectChain(String key) { public void setEffectChain(String key) {
if ((effectChain != null) && (!effectChain.equals(key))) {
clearCache();
}
effectChain = key; effectChain = key;
} }