Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 94139e6ac6 | |||
| c0cc2432ff | |||
| f86aaa3782 |
@@ -1 +1 @@
|
||||
version=0.3.6
|
||||
version=0.3.7
|
||||
|
||||
BIN
resources/uk/co/majenko/audiobookrecorder/icons/processing.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/processing.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 489 B |
BIN
resources/uk/co/majenko/audiobookrecorder/icons/queued.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/queued.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 717 B |
@@ -11,6 +11,7 @@ import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
@@ -18,6 +19,7 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Desktop;
|
||||
@@ -177,6 +179,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
|
||||
JSpinner postSentenceGap;
|
||||
JSpinner gainPercent;
|
||||
Timer waveformUpdater = new Timer();
|
||||
JCheckBox locked;
|
||||
JCheckBox attention;
|
||||
JCheckBox rawAudio;
|
||||
@@ -203,7 +206,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
|
||||
public static AudiobookRecorder window;
|
||||
|
||||
public Queue<Runnable>speechProcessQueue = null;
|
||||
public Queue<Runnable>processQueue = null;
|
||||
public QueueMonitor queueMonitor = null;
|
||||
|
||||
void buildToolbar(Container ob) {
|
||||
Debug.trace();
|
||||
@@ -419,7 +423,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
Debug.debugEnabled = CLI.isSet("debug");
|
||||
Debug.traceEnabled = CLI.isSet("trace");
|
||||
|
||||
speechProcessQueue = new ArrayDeque<Runnable>();
|
||||
processQueue = new ArrayDeque<Runnable>();
|
||||
|
||||
try {
|
||||
|
||||
@@ -444,8 +448,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
|
||||
Options.loadPreferences();
|
||||
|
||||
queueMonitor = new QueueMonitor(processQueue);
|
||||
|
||||
for (int i = 0; i < Options.getInteger("process.threads"); i++) {
|
||||
WorkerThread worker = new WorkerThread(speechProcessQueue);
|
||||
WorkerThread worker = new WorkerThread(processQueue, queueMonitor);
|
||||
queueMonitor.addThread(worker);
|
||||
worker.start();
|
||||
}
|
||||
|
||||
@@ -529,11 +536,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Debug.trace();
|
||||
if (selectedSentence != null) {
|
||||
selectedSentence.autoTrimSampleFFT();
|
||||
sampleWaveform.setMarkers(selectedSentence.getStartOffset(), selectedSentence.getEndOffset());
|
||||
sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing());
|
||||
postSentenceGap.setValue(selectedSentence.getPostGap());
|
||||
gainPercent.setValue((int)(selectedSentence.getGain() * 100d));
|
||||
queueJob(new SentenceJob(selectedSentence) {
|
||||
public void run() {
|
||||
sentence.autoTrimSampleFFT();
|
||||
updateWaveformMarkers();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -542,11 +550,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Debug.trace();
|
||||
if (selectedSentence != null) {
|
||||
selectedSentence.autoTrimSamplePeak();
|
||||
sampleWaveform.setMarkers(selectedSentence.getStartOffset(), selectedSentence.getEndOffset());
|
||||
sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing());
|
||||
postSentenceGap.setValue(selectedSentence.getPostGap());
|
||||
gainPercent.setValue((int)(selectedSentence.getGain() * 100d));
|
||||
queueJob(new SentenceJob(selectedSentence) {
|
||||
public void run() {
|
||||
sentence.autoTrimSamplePeak();
|
||||
updateWaveformMarkers();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -654,8 +663,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
doCutSplit.setEnabled(false);
|
||||
selectCutMode.setSelected(false);
|
||||
selectSplitMode.setSelected(false);
|
||||
|
||||
bookTreeModel.reload(selectedSentence);
|
||||
selectedSentence.reloadTree();
|
||||
}
|
||||
});
|
||||
controlsTop.add(locked);
|
||||
@@ -676,7 +684,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
selectedSentence.setAttentionFlag(false);
|
||||
}
|
||||
}
|
||||
bookTreeModel.reload(selectedSentence);
|
||||
selectedSentence.reloadTree();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -744,10 +752,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
centralPanel.add(sampleControl, BorderLayout.SOUTH);
|
||||
|
||||
statusBar = new JPanel();
|
||||
statusBar.setLayout(new FlowLayout(FlowLayout.CENTER));
|
||||
add(statusBar, BorderLayout.SOUTH);
|
||||
|
||||
statusLabel = new JLabel("Noise floor: " + getNoiseFloorDB() + "dB");
|
||||
statusBar.add(statusLabel);
|
||||
statusBar.add(queueMonitor);
|
||||
|
||||
buildToolbar(centralPanel);
|
||||
|
||||
@@ -931,12 +941,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
Debug.trace();
|
||||
if (ev.getPropertyName().equals("dividerLocation")) {
|
||||
if ((bookTreeModel != null) && (book != null)) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
Debug.trace();
|
||||
bookTreeModel.reload(book);
|
||||
}
|
||||
});
|
||||
Debug.trace();
|
||||
book.reloadTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1039,6 +1045,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
|
||||
public static void main(String args[]) {
|
||||
Debug.trace();
|
||||
Properties props = System.getProperties();
|
||||
props.setProperty("sun.java2d.opengl", "true");
|
||||
try {
|
||||
config.load(AudiobookRecorder.class.getResourceAsStream("config.txt"));
|
||||
} catch (Exception e) {
|
||||
@@ -1191,10 +1199,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
if (!snt.isLocked()) {
|
||||
if (snt.getId().equals(snt.getText())) {
|
||||
Runnable r = snt.getRecognitionRunnable();
|
||||
snt.setQueued();
|
||||
speechProcessQueue.add(r);
|
||||
speechProcessQueue.notify();
|
||||
queueJob(new SentenceJob(snt) {
|
||||
public void run() {
|
||||
sentence.doRecognition();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1227,7 +1236,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
JMenuObject o = (JMenuObject)e.getSource();
|
||||
Sentence s = (Sentence)o.getObject();
|
||||
if (!s.isLocked()) {
|
||||
s.recognise();
|
||||
queueJob(new SentenceJob(s) {
|
||||
public void run() {
|
||||
sentence.doRecognition();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1304,7 +1317,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
String type = (String)o.getObject2();
|
||||
sent.setPostGapType(type);
|
||||
sent.setPostGap(Options.getInteger("catenation.post-sentence"));
|
||||
bookTreeModel.reload(sent);
|
||||
sent.reloadTree();
|
||||
}
|
||||
});
|
||||
setGapType.add(gapTypeSentence);
|
||||
@@ -1317,7 +1330,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
String type = (String)o.getObject2();
|
||||
sent.setPostGapType(type);
|
||||
sent.setPostGap(Options.getInteger("catenation.short-sentence"));
|
||||
bookTreeModel.reload(sent);
|
||||
sent.reloadTree();
|
||||
}
|
||||
});
|
||||
setGapType.add(gapTypeContinuation);
|
||||
@@ -1330,7 +1343,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
String type = (String)o.getObject2();
|
||||
sent.setPostGapType(type);
|
||||
sent.setPostGap(Options.getInteger("catenation.post-paragraph"));
|
||||
bookTreeModel.reload(sent);
|
||||
sent.reloadTree();
|
||||
}
|
||||
});
|
||||
setGapType.add(gapTypeParagraph);
|
||||
@@ -1343,7 +1356,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
String type = (String)o.getObject2();
|
||||
sent.setPostGapType(type);
|
||||
sent.setPostGap(Options.getInteger("catenation.post-section"));
|
||||
bookTreeModel.reload(sent);
|
||||
sent.reloadTree();
|
||||
}
|
||||
});
|
||||
setGapType.add(gapTypeSection);
|
||||
@@ -1472,14 +1485,19 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Debug.trace();
|
||||
JMenuObject o = (JMenuObject)e.getSource();
|
||||
Chapter chap = (Chapter)o.getObject();
|
||||
Chapter c = (Chapter)o.getObject();
|
||||
for (Enumeration s = c.children(); s.hasMoreElements();) {
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
if (!snt.isProcessed()) {
|
||||
queueJob(new SentenceJob(snt) {
|
||||
public void run() {
|
||||
sentence.autoTrimSampleFFT();
|
||||
updateWaveformMarkers();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ProgressDialog ed = new ProgressDialog("Auto-trimming " + chap.getName());
|
||||
|
||||
AutoTrimThread t = new AutoTrimThread(chap, ed, AutoTrimThread.Peak, AutoTrimThread.NewOnly);
|
||||
Thread nt = new Thread(t);
|
||||
nt.start();
|
||||
ed.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1487,14 +1505,18 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Debug.trace();
|
||||
JMenuObject o = (JMenuObject)e.getSource();
|
||||
Chapter chap = (Chapter)o.getObject();
|
||||
|
||||
ProgressDialog ed = new ProgressDialog("Auto-trimming " + chap.getName());
|
||||
|
||||
AutoTrimThread t = new AutoTrimThread(chap, ed, AutoTrimThread.FFT, AutoTrimThread.NewOnly);
|
||||
Thread nt = new Thread(t);
|
||||
nt.start();
|
||||
ed.setVisible(true);
|
||||
Chapter c = (Chapter)o.getObject();
|
||||
for (Enumeration s = c.children(); s.hasMoreElements();) {
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
if (!snt.isProcessed()) {
|
||||
queueJob(new SentenceJob(snt) {
|
||||
public void run() {
|
||||
sentence.autoTrimSampleFFT();
|
||||
updateWaveformMarkers();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1502,14 +1524,16 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Debug.trace();
|
||||
JMenuObject o = (JMenuObject)e.getSource();
|
||||
Chapter chap = (Chapter)o.getObject();
|
||||
|
||||
ProgressDialog ed = new ProgressDialog("Auto-trimming " + chap.getName());
|
||||
|
||||
AutoTrimThread t = new AutoTrimThread(chap, ed, AutoTrimThread.Peak, AutoTrimThread.All);
|
||||
Thread nt = new Thread(t);
|
||||
nt.start();
|
||||
ed.setVisible(true);
|
||||
Chapter c = (Chapter)o.getObject();
|
||||
for (Enumeration s = c.children(); s.hasMoreElements();) {
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
queueJob(new SentenceJob(snt) {
|
||||
public void run() {
|
||||
sentence.autoTrimSamplePeak();
|
||||
updateWaveformMarkers();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1517,14 +1541,16 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Debug.trace();
|
||||
JMenuObject o = (JMenuObject)e.getSource();
|
||||
Chapter chap = (Chapter)o.getObject();
|
||||
|
||||
ProgressDialog ed = new ProgressDialog("Auto-trimming " + chap.getName());
|
||||
|
||||
AutoTrimThread t = new AutoTrimThread(chap, ed, AutoTrimThread.FFT, AutoTrimThread.All);
|
||||
Thread nt = new Thread(t);
|
||||
nt.start();
|
||||
ed.setVisible(true);
|
||||
Chapter c = (Chapter)o.getObject();
|
||||
for (Enumeration s = c.children(); s.hasMoreElements();) {
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
queueJob(new SentenceJob(snt) {
|
||||
public void run() {
|
||||
sentence.autoTrimSampleFFT();
|
||||
updateWaveformMarkers();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1597,7 +1623,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
for (Enumeration s = c.children(); s.hasMoreElements();) {
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
snt.setLocked(true);
|
||||
bookTreeModel.reload(snt);
|
||||
snt.reloadTree();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1610,7 +1636,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
for (Enumeration s = c.children(); s.hasMoreElements();) {
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
snt.setLocked(false);
|
||||
bookTreeModel.reload(snt);
|
||||
snt.reloadTree();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1659,12 +1685,9 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
if (!snt.isLocked()) {
|
||||
if (!snt.beenDetected()) {
|
||||
Debug.d("Queueing recognition of", snt.getId());
|
||||
synchronized(speechProcessQueue) {
|
||||
Runnable r = snt.getRecognitionRunnable();
|
||||
snt.setQueued();
|
||||
speechProcessQueue.add(r);
|
||||
speechProcessQueue.notify();
|
||||
}
|
||||
Runnable r = snt.getRecognitionRunnable();
|
||||
snt.setQueued();
|
||||
queueJob(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2073,7 +2096,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
if (recording == null) return;
|
||||
recording.stopRecording();
|
||||
|
||||
bookTreeModel.reload(book);
|
||||
book.reloadTree();
|
||||
|
||||
bookTree.expandPath(new TreePath(((DefaultMutableTreeNode)recording.getParent()).getPath()));
|
||||
bookTree.setSelectionPath(new TreePath(recording.getPath()));
|
||||
@@ -2188,8 +2211,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
bookTree.setEditable(true);
|
||||
bookTree.setUI(new CustomTreeUI(mainScroll));
|
||||
|
||||
bookTree.setCellRenderer(new BookTreeRenderer());
|
||||
|
||||
try {
|
||||
bookTree.setCellRenderer(new BookTreeRenderer());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
bookTree.setCellRenderer(new BookTreeRenderer());
|
||||
}
|
||||
|
||||
InputMap im = bookTree.getInputMap(JComponent.WHEN_FOCUSED);
|
||||
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "startStopPlayback");
|
||||
@@ -2283,7 +2310,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
} else {
|
||||
book.setIcon(Icons.book);
|
||||
}
|
||||
bookTreeModel.reload(book);
|
||||
book.reloadTree();
|
||||
|
||||
bookTree.expandPath(new TreePath(book.getPath()));
|
||||
|
||||
@@ -2319,7 +2346,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
ImageIcon i = new ImageIcon(cf.getAbsolutePath());
|
||||
Image ri = Utils.getScaledImage(i.getImage(), 22, 22);
|
||||
book.setIcon(new ImageIcon(ri));
|
||||
bookTreeModel.reload(book);
|
||||
book.reloadTree();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -2719,55 +2746,6 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
}
|
||||
}
|
||||
|
||||
class AutoTrimThread implements Runnable {
|
||||
ProgressDialog dialog;
|
||||
Chapter chapter;
|
||||
int type;
|
||||
int scope;
|
||||
|
||||
public final static int FFT = 0;
|
||||
public final static int Peak = 1;
|
||||
public final static int NewOnly = 0;
|
||||
public final static int All = 1;
|
||||
|
||||
public AutoTrimThread(Chapter c, ProgressDialog e, int t, int sc) {
|
||||
super();
|
||||
Debug.trace();
|
||||
dialog = e;
|
||||
chapter = c;
|
||||
type = t;
|
||||
scope = sc;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void run() {
|
||||
Debug.trace();
|
||||
|
||||
int numKids = chapter.getChildCount();
|
||||
int kidCount = 0;
|
||||
for (Enumeration s = chapter.children(); s.hasMoreElements();) {
|
||||
kidCount++;
|
||||
dialog.setProgress(kidCount * 2000 / numKids);
|
||||
Sentence snt = (Sentence)s.nextElement();
|
||||
if (scope == NewOnly) {
|
||||
if (snt.isProcessed()) continue;
|
||||
}
|
||||
switch (type) {
|
||||
case FFT:
|
||||
snt.autoTrimSampleFFT();
|
||||
break;
|
||||
case Peak:
|
||||
snt.autoTrimSamplePeak();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dialog.closeDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ExportThread implements Runnable {
|
||||
ProgressDialog exportDialog;
|
||||
Chapter chapter;
|
||||
@@ -3503,7 +3481,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
ImageIcon i = new ImageIcon(dest.getAbsolutePath());
|
||||
Image ri = Utils.getScaledImage(i.getImage(), 22, 22);
|
||||
book.setIcon(new ImageIcon(ri));
|
||||
bookTreeModel.reload(book);
|
||||
book.reloadTree();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -3516,16 +3494,42 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
updateWaveform(false);
|
||||
}
|
||||
|
||||
public void updateWaveform(boolean force) {
|
||||
TimerTask waveformUpdaterTask = null;
|
||||
|
||||
synchronized public void updateWaveform(boolean force) {
|
||||
Debug.trace();
|
||||
if (selectedSentence != null) {
|
||||
if ((!force) && (sampleWaveform.getId() != null) && (sampleWaveform.getId().equals(selectedSentence.getId()))) return;
|
||||
sampleWaveform.setId(selectedSentence.getId());
|
||||
if (rawAudio.isSelected()) {
|
||||
sampleWaveform.setData(selectedSentence.getRawAudioData());
|
||||
} else {
|
||||
sampleWaveform.setData(selectedSentence.getDoubleAudioData(effectsEnabled));
|
||||
|
||||
synchronized (waveformUpdater) {
|
||||
try {
|
||||
if (waveformUpdaterTask != null) {
|
||||
waveformUpdaterTask.cancel();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
waveformUpdaterTask = new TimerTask() {
|
||||
public void run() {
|
||||
sampleWaveform.setId(selectedSentence.getId());
|
||||
if (rawAudio.isSelected()) {
|
||||
sampleWaveform.setData(selectedSentence.getRawAudioData());
|
||||
} else {
|
||||
sampleWaveform.setData(selectedSentence.getDoubleAudioData(effectsEnabled));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
waveformUpdater.schedule(waveformUpdaterTask, 20);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public void updateWaveformMarkers() {
|
||||
if (selectedSentence != null) {
|
||||
sampleWaveform.setMarkers(selectedSentence.getStartOffset(), selectedSentence.getEndOffset());
|
||||
sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4185,4 +4189,14 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void queueJob(Runnable r) {
|
||||
synchronized(processQueue) {
|
||||
processQueue.add(r);
|
||||
if (r instanceof SentenceJob) {
|
||||
SentenceJob sj = (SentenceJob)r;
|
||||
sj.setQueued();
|
||||
}
|
||||
processQueue.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.UUID;
|
||||
import java.util.Properties;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -217,7 +218,7 @@ public class Book extends BookTreeNode {
|
||||
oldDir.renameTo(newDir);
|
||||
name = newName;
|
||||
AudiobookRecorder.window.saveBookStructure();
|
||||
AudiobookRecorder.window.bookTreeModel.reload(this);
|
||||
reloadTree();
|
||||
Options.set("path.last-book", name);
|
||||
Options.savePreferences();
|
||||
AudiobookRecorder.window.setTitle("AudioBook Recorder :: " + name);
|
||||
@@ -447,4 +448,12 @@ public class Book extends BookTreeNode {
|
||||
public void setLocation(File l) {
|
||||
location = l;
|
||||
}
|
||||
|
||||
public void reloadTree() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
AudiobookRecorder.window.bookTreeModel.reload(Book.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@ package uk.co.majenko.audiobookrecorder;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTree;
|
||||
@@ -84,7 +86,8 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
||||
}
|
||||
|
||||
|
||||
JLabel time = new JLabel(Utils.secToTime(s.getLength(), "mm:ss.SSS") + " ");
|
||||
JLabel time = new JLabelFixedWidth(75, " " + Utils.secToTime(s.getLength(), "ss.SSS") + " ");
|
||||
time.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
|
||||
ctx.gridx = 0;
|
||||
ctx.gridy = 0;
|
||||
@@ -93,17 +96,18 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
||||
ctx.anchor = GridBagConstraints.LINE_START;
|
||||
p.add(ret, ctx);
|
||||
|
||||
if (s.isDetecting()) {
|
||||
JLabel eff = new JLabel(" recognising... ");
|
||||
if (s.isProcessing()) {
|
||||
JLabel eff = new JLabel();
|
||||
eff.setIcon(Icons.processing);
|
||||
ctx.weightx = 0.0d;
|
||||
ctx.gridx = 1;
|
||||
p.add(eff);
|
||||
} else if (s.isQueued()) {
|
||||
JLabel eff = new JLabel(" queued ");
|
||||
JLabel eff = new JLabel();
|
||||
eff.setIcon(Icons.queued);
|
||||
ctx.weightx = 0.0d;
|
||||
ctx.gridx = 1;
|
||||
p.add(eff);
|
||||
} else if (s.isQueued()) {
|
||||
}
|
||||
|
||||
String effectChain = s.getEffectChain();
|
||||
@@ -121,7 +125,8 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
||||
ctx.gridx = 3;
|
||||
ctx.anchor = GridBagConstraints.LINE_END;
|
||||
int peak = s.getPeakDB();
|
||||
JLabel peakLabel = new JLabel(peak + "dB ");
|
||||
JLabel peakLabel = new JLabelFixedWidth(50, peak + "dB ");
|
||||
peakLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
if (peak > 0) {
|
||||
peakLabel.setForeground(new Color(0xCC, 0x00, 0x00));
|
||||
}
|
||||
|
||||
@@ -40,4 +40,6 @@ public class Icons {
|
||||
static public final ImageIcon disable = new ImageIcon(Icons.class.getResource("icons/disable-effects.png"));
|
||||
static public final ImageIcon manuscript = new ImageIcon(Icons.class.getResource("icons/manuscript.png"));
|
||||
static public final ImageIcon tooltip = new ImageIcon(Icons.class.getResource("icons/tooltip.png"));
|
||||
static public final ImageIcon queued = new ImageIcon(Icons.class.getResource("icons/queued.png"));
|
||||
static public final ImageIcon processing = new ImageIcon(Icons.class.getResource("icons/processing.png"));
|
||||
}
|
||||
|
||||
38
src/uk/co/majenko/audiobookrecorder/JLabelFixedWidth.java
Normal file
38
src/uk/co/majenko/audiobookrecorder/JLabelFixedWidth.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package uk.co.majenko.audiobookrecorder;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import java.awt.Dimension;
|
||||
|
||||
public class JLabelFixedWidth extends JLabel {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
Dimension size;
|
||||
public JLabelFixedWidth(int w, String txt) {
|
||||
super(txt);
|
||||
JLabel t = new JLabel(txt);
|
||||
size = t.getPreferredSize();
|
||||
size.width = w;
|
||||
}
|
||||
|
||||
public JLabelFixedWidth(int w) {
|
||||
super();
|
||||
JLabel t = new JLabel("nothing");
|
||||
size = t.getPreferredSize();
|
||||
size.width = w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
71
src/uk/co/majenko/audiobookrecorder/QueueMonitor.java
Normal file
71
src/uk/co/majenko/audiobookrecorder/QueueMonitor.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package uk.co.majenko.audiobookrecorder;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Queue;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Color;
|
||||
|
||||
public class QueueMonitor extends JPanel {
|
||||
|
||||
ArrayList<WorkerThread> threadList = new ArrayList<WorkerThread>();
|
||||
Queue queue;
|
||||
|
||||
public QueueMonitor(Queue q) {
|
||||
super();
|
||||
queue = q;
|
||||
}
|
||||
|
||||
public void addThread(WorkerThread t) {
|
||||
threadList.add(t);
|
||||
}
|
||||
|
||||
public void purgeQueue() {
|
||||
synchronized (queue) {
|
||||
queue.clear();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(100 + (24 * threadList.size()), 24);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
Rectangle size = g.getClipBounds();
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(0, 0, size.width - 1, size.height - 1);
|
||||
g.setColor(new Color(10, 10, 10));
|
||||
g.drawRect(0, 0, size.width - 1, size.height - 1);
|
||||
g.setFont(getFont());
|
||||
|
||||
for (int i = 0; i < threadList.size(); i++) {
|
||||
WorkerThread t = threadList.get(i);
|
||||
if (t.isRunning()) {
|
||||
g.setColor(new Color(50, 200, 0));
|
||||
} else {
|
||||
g.setColor(new Color(80, 0, 0));
|
||||
}
|
||||
g.fillOval(i * 24 + 4, 4, 22 - 8, 22 - 8);
|
||||
}
|
||||
|
||||
g.setColor(getForeground());
|
||||
g.drawString("Queued: " + queue.size(), threadList.size() * 24 + 4, 16);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.io.FileInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.AudioFileFormat;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.util.UUID;
|
||||
@@ -65,8 +66,11 @@ public class Sentence extends BookTreeNode implements Cacheable {
|
||||
boolean attention = false;
|
||||
boolean processed = false;
|
||||
boolean isDetected = false;
|
||||
boolean detecting = false;
|
||||
boolean queued = false;
|
||||
|
||||
int state = IDLE;
|
||||
static final int IDLE = 0;
|
||||
static final int QUEUED = 1;
|
||||
static final int PROCESSING = 2;
|
||||
|
||||
String effectChain = null;
|
||||
|
||||
@@ -706,8 +710,6 @@ public class Sentence extends BookTreeNode implements Cacheable {
|
||||
|
||||
public void doRecognition() {
|
||||
Debug.trace();
|
||||
detecting = true;
|
||||
queued = false;
|
||||
try {
|
||||
reloadTree();
|
||||
|
||||
@@ -727,12 +729,10 @@ public class Sentence extends BookTreeNode implements Cacheable {
|
||||
|
||||
setText(res);
|
||||
isDetected = true;
|
||||
detecting = false;
|
||||
reloadTree();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
detecting = false;
|
||||
}
|
||||
|
||||
public void recognise() {
|
||||
@@ -1670,9 +1670,11 @@ public class Sentence extends BookTreeNode implements Cacheable {
|
||||
Debug.trace();
|
||||
if (id.equals("room-noise")) return;
|
||||
if (getParent() == null) return;
|
||||
synchronized (AudiobookRecorder.window.bookTreeModel) {
|
||||
AudiobookRecorder.window.bookTreeModel.reload(this);
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
AudiobookRecorder.window.bookTreeModel.reload(Sentence.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public double getPeak() {
|
||||
@@ -1707,20 +1709,31 @@ public class Sentence extends BookTreeNode implements Cacheable {
|
||||
return (int)db;
|
||||
}
|
||||
|
||||
public boolean isDetecting() {
|
||||
return detecting;
|
||||
}
|
||||
|
||||
public boolean beenDetected() {
|
||||
return isDetected;
|
||||
}
|
||||
|
||||
public boolean isProcessing() {
|
||||
return state == PROCESSING;
|
||||
}
|
||||
|
||||
public boolean isQueued() {
|
||||
return queued;
|
||||
return state == QUEUED;
|
||||
}
|
||||
|
||||
public void setProcessing() {
|
||||
state = PROCESSING;
|
||||
reloadTree();
|
||||
}
|
||||
|
||||
public void setQueued() {
|
||||
queued = true;
|
||||
state = QUEUED;
|
||||
reloadTree();
|
||||
}
|
||||
|
||||
public void setDequeued() {
|
||||
state = IDLE;
|
||||
reloadTree();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
25
src/uk/co/majenko/audiobookrecorder/SentenceJob.java
Normal file
25
src/uk/co/majenko/audiobookrecorder/SentenceJob.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package uk.co.majenko.audiobookrecorder;
|
||||
|
||||
import java.lang.Runnable;
|
||||
|
||||
public abstract class SentenceJob implements Runnable {
|
||||
protected Sentence sentence;
|
||||
|
||||
public SentenceJob(Sentence s) {
|
||||
sentence = s;
|
||||
}
|
||||
|
||||
public void setQueued() {
|
||||
sentence.setQueued();
|
||||
}
|
||||
|
||||
public void setDequeued() {
|
||||
sentence.setDequeued();
|
||||
}
|
||||
|
||||
public void setProcessing() {
|
||||
sentence.setProcessing();
|
||||
}
|
||||
|
||||
public abstract void run();
|
||||
}
|
||||
@@ -5,9 +5,13 @@ import java.util.Queue;
|
||||
public class WorkerThread extends Thread {
|
||||
private static int instance = 0;
|
||||
private final Queue<Runnable> queue;
|
||||
private final QueueMonitor monitor;
|
||||
|
||||
public WorkerThread(Queue<Runnable> queue) {
|
||||
private boolean running = false;
|
||||
|
||||
public WorkerThread(Queue<Runnable> queue, QueueMonitor mon) {
|
||||
this.queue = queue;
|
||||
monitor = mon;
|
||||
setName("Worker Thread " + (instance++));
|
||||
}
|
||||
|
||||
@@ -30,8 +34,19 @@ public class WorkerThread extends Thread {
|
||||
work = queue.remove();
|
||||
}
|
||||
|
||||
// Process the work item
|
||||
running = true;
|
||||
monitor.repaint();
|
||||
if (work instanceof SentenceJob) {
|
||||
SentenceJob sj = (SentenceJob)work;
|
||||
sj.setProcessing();
|
||||
}
|
||||
work.run();
|
||||
if (work instanceof SentenceJob) {
|
||||
SentenceJob sj = (SentenceJob)work;
|
||||
sj.setDequeued();
|
||||
}
|
||||
running = false;
|
||||
monitor.repaint();
|
||||
}
|
||||
catch ( InterruptedException ie ) {
|
||||
ie.printStackTrace();
|
||||
@@ -40,4 +55,8 @@ public class WorkerThread extends Thread {
|
||||
}
|
||||
Debug.d(getName(), "died");
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user