Compare commits

..

15 Commits

Author SHA1 Message Date
2064184093 Release 0.4.4 2021-06-03 10:40:34 +01:00
2e6ea5eecc Fixes to effect and tree synchronisation 2021-04-17 14:46:36 +01:00
0dde64e5fc Merge branch 'master' of github.com:MajenkoProjects/AudiobookRecorder 2021-01-22 14:13:38 +00:00
28a3326a35 Improved archive routine 2021-01-22 14:13:27 +00:00
df6b893171 Merge pull request #27 from MajenkoProjects/dependabot/maven/launch4j/maven/com.thoughtworks.xstream-xstream-1.4.15
Bump xstream from 1.4.14-java7 to 1.4.15 in /launch4j/maven
2021-01-22 04:22:43 -08:00
ead577521d Normalized all file paths 2021-01-22 11:55:38 +00:00
dependabot[bot]
cc1c76bd47 Bump xstream from 1.4.14-java7 to 1.4.15 in /launch4j/maven
Bumps [xstream](https://github.com/x-stream/xstream) from 1.4.14-java7 to 1.4.15.
- [Release notes](https://github.com/x-stream/xstream/releases)
- [Commits](https://github.com/x-stream/xstream/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-21 17:03:20 +00:00
b74f1aedb4 Bump xtream version 2020-11-16 20:58:51 +00:00
67d1e787ee Merge pull request #26 from MajenkoProjects/dependabot/maven/launch4j/maven/com.thoughtworks.xstream-xstream-1.4.13-java7
Bump xstream from 1.4.10-java7 to 1.4.13-java7 in /launch4j/maven
2020-11-16 20:56:19 +00:00
11ca88ee38 Merge pull request #25 from MajenkoProjects/dependabot/maven/launch4j/maven/org.apache.ant-ant-1.9.15
Bump ant from 1.8.2 to 1.9.15 in /launch4j/maven
2020-11-16 20:56:09 +00:00
dependabot[bot]
ae4e3db0d7 Bump xstream from 1.4.10-java7 to 1.4.13-java7 in /launch4j/maven
Bumps [xstream](https://github.com/x-stream/xstream) from 1.4.10-java7 to 1.4.13-java7.
- [Release notes](https://github.com/x-stream/xstream/releases)
- [Commits](https://github.com/x-stream/xstream/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-16 20:41:30 +00:00
dependabot[bot]
4314790271 Bump ant from 1.8.2 to 1.9.15 in /launch4j/maven
Bumps ant from 1.8.2 to 1.9.15.

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-14 18:42:19 +00:00
9c58276119 More improvements to gain curve 2020-09-01 19:02:43 +01:00
16380a9752 Some improvements to gain curve calculations 2020-08-31 17:09:03 +01:00
b523d80c25 Move normalize chapter to queue system 2020-08-25 17:10:39 +01:00
8 changed files with 189 additions and 87 deletions

2
dist/linux/stub vendored
View File

@@ -5,6 +5,6 @@ java=java
if test -n "$JAVA_HOME"; then
java="$JAVA_HOME/bin/java"
fi
java_args=-Xmx1g
java_args=-Xmx8g
exec "$java" $java_args -jar $MYSELF "$@"
exit 1

View File

@@ -138,12 +138,12 @@
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10-java7</version>
<version>1.4.15</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.8.2</version>
<version>1.9.15</version>
</dependency>
</dependencies>

View File

@@ -1 +1 @@
version=0.4.3
version=0.4.4

View File

@@ -204,6 +204,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
public Queue<Runnable>processQueue = null;
public QueueMonitor queueMonitor = null;
boolean effectsUpdating = false; // crude lock
void buildToolbar(Container ob) {
Debug.trace();
toolBar = new MainToolBar(this);
@@ -637,10 +639,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
public void actionPerformed(ActionEvent e) {
Debug.trace();
Debug.d(e);
if (effectsUpdating) return;
if (selectedSentence != null) {
int i = effectChain.getSelectedIndex();
KVPair<String, String> p = effectChain.getItemAt(i);
if (p == null) return;
System.err.println("I want to select effect " + p.getKey());
selectedSentence.setEffectChain(p.getKey());
updateWaveform(true);
}
@@ -823,8 +827,6 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
locked.setSelected(s.isLocked());
attention.setSelected(s.getAttentionFlag());
setEffectChain(s.getEffectChain());
postSentenceGap.setEnabled(!s.isLocked());
gainPercent.setEnabled(!s.isLocked());
reprocessAudioFFT.setEnabled(!s.isLocked());
@@ -1689,12 +1691,17 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
JMenuObject o = (JMenuObject)e.getSource();
Chapter chap = (Chapter)o.getObject();
ProgressDialog ed = new ProgressDialog("Normalizing " + chap.getName());
NormalizeThread t = new NormalizeThread(chap, ed);
Thread nt = new Thread(t);
nt.start();
ed.setVisible(true);
for (Enumeration s = c.children(); s.hasMoreElements();) {
Sentence snt = (Sentence)s.nextElement();
if (!snt.isLocked()) {
queueJob(new SentenceJob(snt) {
public void run() {
sentence.normalize();
sentence.autoAddPeakGainPoints();
}
});
}
}
}
});
@@ -2346,7 +2353,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
book.save();
// Add the book to the tree
loadXMLBookStructure(new File(book.getLocation(), "audiobook.abx"));
loadXMLBookStructure(book.getLocation("audiobook.abx"));
updateOpenBookList();
} catch (Exception ex) {
ex.printStackTrace();
@@ -2444,41 +2451,6 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
playingThread.start();
}
class NormalizeThread implements Runnable {
ProgressDialog dialog;
Chapter chapter;
public NormalizeThread(Chapter c, ProgressDialog e) {
super();
Debug.trace();
dialog = e;
chapter = c;
}
@SuppressWarnings("unchecked")
public void run() {
Debug.trace();
int numKids = chapter.getChildCount();
int kidCount = 0;
double lastGain = -1;
double variance = Options.getInteger("audio.recording.variance") / 100d;
for (Enumeration s = chapter.children(); s.hasMoreElements();) {
kidCount++;
dialog.setProgress(kidCount * 2000 / numKids);
Sentence snt = (Sentence)s.nextElement();
if (lastGain == -1) {
lastGain = snt.normalize();
} else {
lastGain = snt.normalize(lastGain - variance, lastGain + variance);
}
snt.autoAddPeakGainPoints();
}
dialog.closeDialog();
}
}
class ExportThread implements Runnable {
ProgressDialog exportDialog;
Chapter chapter;
@@ -2842,6 +2814,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
public void run() {
Debug.trace();
try {
pd.setMessage("Purging backups...");
book.purgeBackups();
pd.setMessage("Archiving book...");
String name = book.getName();
File storageDir = new File(Options.get("path.storage"));
File bookDir = book.getLocation();
@@ -2928,6 +2905,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
zos.flush();
zos.close();
pd.setMessage("Cleaning up...");
while (fileList.size() > 0) {
File f = fileList.remove(fileList.size() - 1);
f.delete();
@@ -2941,7 +2920,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
public void archiveBook(Book book) {
Debug.trace();
int r = JOptionPane.showConfirmDialog(this, "This will stash the current book away\nin the archives folder in a compressed\nform. The existing book files will be deleted\nand the book closed.\n\nAre you sure you want to do this?", "Archive Book", JOptionPane.OK_CANCEL_OPTION);
int r = JOptionPane.showConfirmDialog(this, "This will stash the current book away\nin the archives folder in a compressed\nform. All backups will be purged, the existing book files will be deleted\nand the book closed.\n\nAre you sure you want to do this?", "Archive Book", JOptionPane.OK_CANCEL_OPTION);
if (r == JOptionPane.OK_OPTION) {
@@ -2952,17 +2931,23 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
Thread t = new Thread(runnable);
t.start();
pd.setVisible(true);
closeBook(book);
closeBook(book, false);
}
}
public void closeBook(Book b) {
closeBook(b, true);
}
public void closeBook(Book b, boolean save) {
if (selectedBook == b) {
setSelectedBook(null);
setSelectedSentence(null);
setSelectedChapter(null);
}
if (save) {
saveBook(b);
}
bookTreeModel.removeNodeFromParent(b);
updateOpenBookList();
}
@@ -3126,8 +3111,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
public void updateEffectChains(TreeMap<String, EffectGroup> effs) {
Debug.trace();
int sel = effectChain.getSelectedIndex();
KVPair<String, String> ent = effectChain.getItemAt(sel);
effectsUpdating = true;
System.err.println("Updating effect chains");
while (effectChain.getItemCount() > 0) {
effectChain.removeItemAt(0);
}
@@ -3139,15 +3124,40 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
KVPair<String, String> p = new KVPair<String, String>(k, e.toString());
effectChain.addItem(p);
}
if (ent != null) {
setEffectChain(ent.getKey());
// } else {
// setEffectChain(getBook().getDefaultEffect());
if (selectedSentence != null) {
String key = selectedSentence.getEffectChain();
for (int i = 0; i < effectChain.getItemCount(); i++) {
KVPair<String, String> p = effectChain.getItemAt(i);
if (p.getKey().equals(key)) {
effectChain.setSelectedIndex(i);
effectsUpdating = false;
return;
}
}
}
effectsUpdating = false;
}
public void showSelectedEffectChain(String key) {
Debug.trace();
effectsUpdating = true;
System.err.println("Looking for effect " + key + "...");
for (int i = 0; i < effectChain.getItemCount(); i++) {
KVPair<String, String> p = effectChain.getItemAt(i);
System.err.println(" Testing " + p.getKey() + "...");
if (p.getKey().equals(key)) {
System.err.println(" Found it.");
effectChain.setSelectedIndex(i);
effectsUpdating = false;
return;
}
}
effectsUpdating = false;
}
public void setEffectChain(String key) {
Debug.trace();
System.err.println("Setting effect " + key);
for (int i = 0; i < effectChain.getItemCount(); i++) {
KVPair<String, String> p = effectChain.getItemAt(i);
if (p.getKey().equals(key)) {
@@ -3270,8 +3280,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
}
newSentence.writeAudioData(startSamples);
newSentence.setPostGapType("continuation");
newSentence.setPostGap(Options.getInteger("catenation.short-sentence"));
newSentence.setPostGapType("sentence");
newSentence.setPostGap(Options.getInteger("catenation.post-sentence"));
selectedSentence.writeAudioData(endSamples);
selectedSentence.autoTrimSample();

View File

@@ -479,7 +479,7 @@ public class Book extends BookTreeNode {
}
AudiobookRecorder.window.setBookNotes(notes);
AudiobookRecorder.window.noiseFloorLabel.setNoiseFloor(getNoiseFloorDB());
// AudiobookRecorder.window.updateEffectChains(effects);
AudiobookRecorder.window.updateEffectChains(effects);
TreeNode p = getParent();
if (p instanceof BookTreeNode) {
BookTreeNode btn = (BookTreeNode)p;
@@ -502,6 +502,11 @@ public class Book extends BookTreeNode {
return location;
}
public File getLocation(String dir) {
Debug.trace();
return new File(location, dir);
}
public void setLocation(File l) {
Debug.trace();
location = l;
@@ -589,9 +594,7 @@ public class Book extends BookTreeNode {
Debug.trace();
effects = new TreeMap<String,EffectGroup>();
loadEffectsFromFolder(new File(Options.get("path.storage"), "System"));
if (location != null) {
loadEffectsFromFolder(location);
}
loadEffectsFromFolder(getLocation());
}
public void loadEffectsFromFolder(File dir) {

View File

@@ -8,8 +8,10 @@ public class CacheManager {
static int cacheSize = 10;
public static void addToCache(Cacheable c) {
Debug.trace();
while (cache.size() >= cacheSize) {
Cacheable ob = cache.remove(0);
if (ob != null) {
if (ob.lockedInCache()) {
cache.add(ob);
} else {
@@ -19,6 +21,7 @@ public class CacheManager {
ob.clearCache();
}
}
}
cache.add(c);
}
@@ -28,6 +31,7 @@ public class CacheManager {
}
public static void removeFromCache(Cacheable c) {
Debug.trace();
if (c instanceof Sentence) {
Sentence s = (Sentence)c;
}

View File

@@ -172,12 +172,7 @@ public class Chapter extends BookTreeNode {
Book book = getBook();
File bookRoot = new File(Options.get("path.storage"), book.getName());
if (!bookRoot.exists()) {
bookRoot.mkdirs();
}
File export = new File(bookRoot, "export");
File export = book.getLocation("export");
if (!export.exists()) {
export.mkdirs();
}

View File

@@ -235,6 +235,11 @@ public class Sentence extends BookTreeNode implements Cacheable {
peak = Utils.s2d(Book.getTextNode(root, "peak", "-1.000"));
isDetected = Utils.s2b(Book.getTextNode(root, "detected"));
if (sampleSize == 0) {
loadFile();
autoTrimSample();
}
gainPoints = new TreeMap<Integer, Double>();
Element gp = Book.getNode(root, "gainpoints");
if (gp != null) {
@@ -580,7 +585,7 @@ public class Sentence extends BookTreeNode implements Cacheable {
Debug.d("Get file for", id);
Book book = getBook();
if (book == null) return null;
File b = new File(book.getLocation(), "files");
File b = book.getLocation("files");
if (!b.exists()) {
b.mkdirs();
}
@@ -589,7 +594,7 @@ public class Sentence extends BookTreeNode implements Cacheable {
public File getTempFile() {
Debug.trace();
File b = new File(getBook().getLocation(), "files");
File b = getBook().getLocation("files");
if (!b.exists()) {
b.mkdirs();
}
@@ -803,7 +808,9 @@ public class Sentence extends BookTreeNode implements Cacheable {
public boolean lockedInCache() {
Debug.trace();
return id.equals("room-noise");
if (id.equals("room-noise")) return true;
if (isProcessing()) return true;
return false;
}
public int findNearestZeroCrossing(int pos, int range) {
@@ -976,12 +983,22 @@ public class Sentence extends BookTreeNode implements Cacheable {
int targetLow = Options.getInteger("audio.recording.rms.low");
int targetHigh = Options.getInteger("audio.recording.rms.high");
long ts = System.currentTimeMillis();
while ((int)getRMS() < targetLow) {
if (System.currentTimeMillis() - ts > 10000) {
System.err.println("Aborted gain boost: took too long");
return gain;
}
setGain(gain + 0.1);
if (gain >= 10.0d) break;
}
ts = System.currentTimeMillis();
while ((int)getRMS() > targetHigh) {
if (System.currentTimeMillis() - ts > 10000) {
System.err.println("Aborted gain cut: took too long");
return gain;
}
setGain(gain - 0.1);
}
@@ -1466,11 +1483,11 @@ public class Sentence extends BookTreeNode implements Cacheable {
synchronized public double[][] getProcessedAudioData(boolean effectsEnabled, boolean applyGain) {
Debug.trace();
Book book = getBook();
loadFile();
if (processedAudio != null) {
return processedAudio;
}
Book book = getBook();
loadFile();
if (audioData == null) return null;
processedAudio = new double[2][audioData[LEFT].length];
@@ -1497,7 +1514,12 @@ public class Sentence extends BookTreeNode implements Cacheable {
eff = book.effects.get(effectChain);
if (eff != null) {
eff.init(getAudioFormat().getFrameRate());
// There is a chance another thread could cripple the audio data cache
// so we'll just ignore any errors here.
try {
eff.process(processedAudio);
} catch (Exception ex) {
}
}
}
}
@@ -1741,6 +1763,7 @@ public class Sentence extends BookTreeNode implements Cacheable {
Debug.trace();
AudiobookRecorder.setSelectedSentence(this);
AudiobookRecorder.window.setSentenceNotes(notes);
AudiobookRecorder.window.showSelectedEffectChain(getEffectChain());
TreeNode p = getParent();
if (p instanceof BookTreeNode) {
BookTreeNode btn = (BookTreeNode)p;
@@ -1880,6 +1903,10 @@ public class Sentence extends BookTreeNode implements Cacheable {
}
public void adjustGainPoint(Integer loc, Double adj) {
adjustGainPoint(loc, adj, true);
}
public void adjustGainPoint(Integer loc, Double adj, boolean reload) {
if (gainPoints == null) {
gainPoints = new TreeMap<Integer, Double>();
return;
@@ -1888,8 +1915,10 @@ public class Sentence extends BookTreeNode implements Cacheable {
if (gp == null) return;
gp += adj;
gainPoints.put(loc, gp);
if (reload) {
refreshAllData();
}
}
public double[] calculateGains() {
double[] gains = new double[sampleSize];
@@ -1913,7 +1942,10 @@ public class Sentence extends BookTreeNode implements Cacheable {
double ystep = diff / (double)range;
for (int x = 0; x < range; x++) {
y += ystep;
try {
gains[x1 + x] = y;
} catch (Exception ex) {
}
}
x1 = x2;
}
@@ -2001,6 +2033,7 @@ public class Sentence extends BookTreeNode implements Cacheable {
public double[] getWaveProfile() {
if (waveProfile != null) return waveProfile;
double[][] samples = getProcessedAudioData();
if (samples[LEFT].length == 0) return null;
waveProfile = new double[samples[LEFT].length];
double rt = 0;
@@ -2030,6 +2063,11 @@ public class Sentence extends BookTreeNode implements Cacheable {
double peak = 0;
if (samples == null) {
System.err.println("Um.... no samples...?");
return -1;
}
for (int i = 0; i < samples[LEFT].length; i++) {
if (Math.abs(samples[LEFT][i]) > peak) {
peak = Math.abs(samples[LEFT][i]);
@@ -2065,13 +2103,52 @@ public class Sentence extends BookTreeNode implements Cacheable {
return -1;
}
int findNearestGainPoint(int pos) {
int closest = Integer.MAX_VALUE;
int cpos = -1;
if (gainPoints == null) return -1;
for (Integer loc : gainPoints.keySet()) {
int diff = pos - loc;
if (diff < 0) diff = 0 - diff;
if (diff < closest) {
closest = diff;
cpos = loc;
}
}
return cpos;
}
public void autoAddPeakGainPoints() {
long ts = System.currentTimeMillis();
while (true) {
if (System.currentTimeMillis() - ts > 10000) {
System.err.println("Terminated: running too long!");
return;
}
processedAudio = null;
double[][] samples = getProcessedAudioData();
int pos = findBiggestPeak();
if (pos == -1) return;
System.err.println("Biggest peak: " + pos);
int closest = findNearestGainPoint(pos);
if (closest >= 0) {
int diff = closest - pos;
if (diff < 0) diff = 0 - diff;
if (diff < 10) {
System.err.println("Readjusting location: " + closest + " - diff = " + diff);
pos = closest;
}
}
if ((Math.abs(samples[LEFT][pos]) < 0.708) && (Math.abs(samples[RIGHT][pos]) < 0.708)) {
System.err.println("Not a peak!");
System.err.println("No more peaks");
refreshAllData();
return;
}
@@ -2090,8 +2167,21 @@ public class Sentence extends BookTreeNode implements Cacheable {
addGainPoint(pos, 1d);
addGainPoint(end, 1d);
while (isClipping(start, end)) {
adjustGainPoint(pos, -0.05);
double val = 1d;
while (isClipping(pos - 10, pos + 10)) {
adjustGainPoint(pos, -0.05, false);
val -= 0.05d;
if (val < 0.1d) {
System.err.println("Aborting: gain too low");
break;
}
processedAudio = null; // Force a refresh
}
System.err.println("Result: " + gainPoints.get(pos));
try {
Thread.sleep(1);
} catch (Exception ex) {
}
}
}