Fix caching of processed audio. Add effect icon and name to tree
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user