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

View File

@@ -31,6 +31,12 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
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);
} else if (value instanceof Chapter) {

View File

@@ -6,6 +6,8 @@ public class DelayLine implements Effect {
ArrayList<DelayLineStore> delayLines;
boolean wetOnly = false;
public DelayLine() {
delayLines = new ArrayList<DelayLineStore>();
}
@@ -19,6 +21,12 @@ public class DelayLine implements Effect {
for (int i = 0; i < samples.length; i++) {
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) {
Sample[] subSamples = new Sample[samples.length];
@@ -62,6 +70,12 @@ public class DelayLine implements Effect {
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) {
DelayLineStore s = new DelayLineStore(samples, gain);
delayLines.add(s);
@@ -88,4 +102,8 @@ public class DelayLine implements Effect {
s.init(sf);
}
}
public void setWetOnly(boolean b) {
wetOnly = b;
}
}

View File

@@ -6,12 +6,21 @@ import java.util.ArrayList;
public class DelayLineStore {
double gain;
int numSamples;
double pan;
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) {
numSamples = s;
gain = g;
pan = 0d;
effects = new ArrayList<Effect>();
}
@@ -23,6 +32,14 @@ public class DelayLineStore {
for (Sample sample : samples) {
sample.left *= 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;
Sample[] audioData = null;
Sample[] processedAudio = null;
RecordingThread recordingThread;
@@ -391,7 +392,11 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
}
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() {
@@ -560,6 +565,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public void clearCache() {
audioData = null;
processedAudio = null;
}
public boolean lockedInCache() {
@@ -669,8 +675,11 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public void setGain(double g) {
if (g <= 0.0001d) g = 1.0d;
if (g == gain) return;
if (gain != g) {
clearCache();
}
gain = g;
clearCache();
}
public double getGain() {
@@ -952,10 +961,12 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public Sample[] getProcessedAudioData() {
loadFile();
if (processedAudio != null) return processedAudio;
if (audioData == null) return null;
Sample[] samples = new Sample[audioData.length];
processedAudio = new Sample[audioData.length];
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.
@@ -965,7 +976,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
if (eff != null) {
eff.init(getAudioFormat().getFrameRate());
eff.process(samples);
eff.process(processedAudio);
}
if (effectChain != null) {
@@ -974,17 +985,17 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
eff = AudiobookRecorder.window.effects.get(effectChain);
if (eff != null) {
eff.init(getAudioFormat().getFrameRate());
eff.process(samples);
eff.process(processedAudio);
}
}
}
// Add final master gain stage
for (int i = 0; i < samples.length; i++) {
samples[i].left = samples[i].left * gain;
samples[i].right = samples[i].right * gain;
for (int i = 0; i < processedAudio.length; i++) {
processedAudio[i].left = processedAudio[i].left * gain;
processedAudio[i].right = processedAudio[i].right * gain;
}
return samples;
return processedAudio;
}
public Sample[] getDoubleAudioData() {
@@ -1028,6 +1039,9 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
}
public void setEffectChain(String key) {
if ((effectChain != null) && (!effectChain.equals(key))) {
clearCache();
}
effectChain = key;
}