diff --git a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java index 5d96120..9f51f02 100644 --- a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java +++ b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java @@ -1012,16 +1012,17 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { newbook.setComment(info.getComment().trim()); newbook.setACX(info.getACX().trim()); - Chapter caud = new Chapter("audition", "Audition"); - Chapter copen = new Chapter("open", "Opening Credits"); - Chapter cone = new Chapter("0001", "Chapter 1"); - Chapter cclose = new Chapter("close", "Closing Credits"); + Chapter caud = new Chapter(UUID.randomUUID().toString(), "Audition"); + Chapter copen = new Chapter(UUID.randomUUID().toString(), "Opening Credits"); + Chapter cclose = new Chapter(UUID.randomUUID().toString(), "Closing Credits"); + Chapter cone = new Chapter(UUID.randomUUID().toString(), "Chapter 1"); newbook.add(caud); newbook.add(copen); - newbook.add(cone); newbook.add(cclose); + newbook.add(cone); + File bookRoot = new File(Options.get("path.storage"), newbook.getName()); if (!bookRoot.exists()) { bookRoot.mkdirs(); @@ -1030,6 +1031,10 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { File xml = new File(bookRoot, "audiobook.abx"); Document doc = newbook.buildDocument(); + File backup = new File(bookRoot, "audiobook.bak"); + if (xml.exists()) { + xml.renameTo(backup); + } // write the content into xml file TransformerFactory transformerFactory = TransformerFactory.newInstance(); @@ -1127,7 +1132,10 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { Sentence snt = (Sentence)s.nextElement(); if (!snt.isLocked()) { if (snt.getId().equals(snt.getText())) { - snt.doRecognition(); + Runnable r = snt.getRecognitionRunnable(); + snt.setQueued(); + speechProcessQueue.add(r); + speechProcessQueue.notify(); } } } @@ -1477,20 +1485,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { Chapter chap = (Chapter)o.getObject(); int pos = bookTreeModel.getIndexOfChild(book, chap); if (pos > 0) pos--; - - int id = Utils.s2i(chap.getId()); - if (id > 0) { - Chapter prevChap = (Chapter)bookTreeModel.getChild(book, pos); - id = Utils.s2i(prevChap.getId()); - if (id > 0) { - bookTreeModel.removeNodeFromParent(chap); - bookTreeModel.insertNodeInto(chap, book, pos); - } - } - book.renumberChapters(); + Chapter prevChap = (Chapter)bookTreeModel.getChild(book, pos); + bookTreeModel.removeNodeFromParent(chap); + bookTreeModel.insertNodeInto(chap, book, pos); } }); - moveUp.setEnabled(idNumber > 0); JMenuObject moveDown = new JMenuObject("Move Down", c, new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -1499,21 +1498,13 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { Chapter chap = (Chapter)o.getObject(); int pos = bookTreeModel.getIndexOfChild(book, chap); pos++; - int id = Utils.s2i(chap.getId()); - if (id > 0) { - Chapter nextChap = (Chapter)bookTreeModel.getChild(book, pos); - if (nextChap != null) { - id = Utils.s2i(nextChap.getId()); - if (id > 0) { - bookTreeModel.removeNodeFromParent(chap); - bookTreeModel.insertNodeInto(chap, book, pos); - } - } + Chapter nextChap = (Chapter)bookTreeModel.getChild(book, pos); + if (nextChap != null) { + bookTreeModel.removeNodeFromParent(chap); + bookTreeModel.insertNodeInto(chap, book, pos); } - book.renumberChapters(); } }); - moveDown.setEnabled(idNumber > 0); JMenu mergeWith = new JMenu("Merge chapter with"); for (Enumeration bc = book.children(); bc.hasMoreElements();) { @@ -1607,10 +1598,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { for (Enumeration s = c.children(); s.hasMoreElements();) { Sentence snt = (Sentence)s.nextElement(); if (!snt.isLocked()) { - if (snt.getId().equals(snt.getText())) { + if (!snt.beenDetected()) { Debug.d("Queueing recognition of", snt.getId()); synchronized(speechProcessQueue) { Runnable r = snt.getRecognitionRunnable(); + snt.setQueued(); speechProcessQueue.add(r); speechProcessQueue.notify(); } @@ -2241,6 +2233,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } catch (Exception ex) { ex.printStackTrace(); } + + gatherOrphans(); } public void loadBookStructure(File f) { @@ -4089,4 +4083,47 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { // DocumentListener *// + public boolean sentenceIdExists(String id) { + for (Enumeration c = book.children(); c.hasMoreElements();) { + Chapter chp = (Chapter)c.nextElement(); + for (Enumeration s = chp.children(); s.hasMoreElements();) { + Sentence snt = (Sentence)s.nextElement(); + if (snt.getId().equals(id)) return true; + } + } + return false; + } + + public void gatherOrphans() { + Chapter orphans = getChapterById("orphans"); + if (orphans == null) { + orphans = new Chapter("orphans", "Orphan Files"); + bookTreeModel.insertNodeInto(orphans, book, book.getChildCount()); + } + File bookRoot = new File(Options.get("path.storage"), book.getName()); + File[] files = new File(bookRoot, "files").listFiles(); + for (File f : files) { + String filename = f.getName(); + if (filename.startsWith(".")) continue; + if (filename.startsWith("backup")) continue; + if (filename.equals("room-noise")) continue; + if (filename.endsWith(".wav")) { + String id = filename.substring(0, filename.length() - 4); + Debug.d("Testing orphanicity of", id); + if (!sentenceIdExists(id)) { + Sentence newSentence = new Sentence(id, id); + bookTreeModel.insertNodeInto(newSentence, orphans, orphans.getChildCount()); + } + } + } + } + + public Chapter getChapterById(String id) { + for (Enumeration c = book.children(); c.hasMoreElements();) { + Chapter chp = (Chapter)c.nextElement(); + if (chp.getId().equals(id)) return chp; + } + return null; + } + } diff --git a/src/uk/co/majenko/audiobookrecorder/Book.java b/src/uk/co/majenko/audiobookrecorder/Book.java index 1fa7534..a15662a 100644 --- a/src/uk/co/majenko/audiobookrecorder/Book.java +++ b/src/uk/co/majenko/audiobookrecorder/Book.java @@ -168,18 +168,8 @@ public class Book extends BookTreeNode { public Chapter addChapter() { Debug.trace(); - Chapter lc = getLastChapter(); - if (lc == null) return new Chapter("1", "Chapter 1"); - try { - int lcid = Integer.parseInt(lc.getId()); - lcid++; - - Chapter nc = new Chapter(String.format("%04d", lcid), "Chapter " + lcid); - return nc; - } catch (Exception e) { - e.printStackTrace(); - } - return null; + String uuid = UUID.randomUUID().toString(); + return new Chapter(uuid, uuid); } public String getName() { diff --git a/src/uk/co/majenko/audiobookrecorder/BookTreeRenderer.java b/src/uk/co/majenko/audiobookrecorder/BookTreeRenderer.java index 38fd0e2..1c8e010 100644 --- a/src/uk/co/majenko/audiobookrecorder/BookTreeRenderer.java +++ b/src/uk/co/majenko/audiobookrecorder/BookTreeRenderer.java @@ -81,29 +81,37 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer { ctx.gridx = 0; ctx.gridy = 0; + ctx.weightx = 1.0d; ctx.fill = GridBagConstraints.HORIZONTAL; ctx.anchor = GridBagConstraints.LINE_START; + p.add(ret, ctx); - String effectChain = s.getEffectChain(); - if ((effectChain == null) || (effectChain.equals("none"))) { - ctx.weightx = 1.0d; - ctx.gridwidth = 2; - p.add(ret, ctx); - } else { - ctx.weightx = 1.0d; - ctx.gridwidth = 1; - p.add(ret, ctx); - Effect e = AudiobookRecorder.window.effects.get(effectChain); - JLabel eff = new JLabel(e.toString() + " "); + if (s.isDetecting()) { + JLabel eff = new JLabel(" recognising... "); ctx.weightx = 0.0d; - ctx.gridwidth = 1; ctx.gridx = 1; p.add(eff); + } else if (s.isQueued()) { + JLabel eff = new JLabel(" queued "); + ctx.weightx = 0.0d; + ctx.gridx = 1; + p.add(eff); + } else if (s.isQueued()) { + } + + String effectChain = s.getEffectChain(); + if ((effectChain != null) && (!effectChain.equals("none"))) { + Effect e = AudiobookRecorder.window.effects.get(effectChain); + if (e != null) { + JLabel eff = new JLabel(e.toString() + " "); + ctx.weightx = 0.0d; + ctx.gridx = 2; + p.add(eff); + } } - ctx.gridwidth = 1; ctx.weightx = 0.0d; - ctx.gridx = 2; + ctx.gridx = 3; ctx.anchor = GridBagConstraints.LINE_END; int peak = s.getPeakDB(); JLabel peakLabel = new JLabel(peak + "dB "); @@ -113,7 +121,7 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer { p.add(peakLabel, ctx); ctx.weightx = 0.0d; - ctx.gridx = 3; + ctx.gridx = 4; ctx.anchor = GridBagConstraints.LINE_END; p.add(time, ctx); diff --git a/src/uk/co/majenko/audiobookrecorder/Sentence.java b/src/uk/co/majenko/audiobookrecorder/Sentence.java index e9e9c9f..b942878 100644 --- a/src/uk/co/majenko/audiobookrecorder/Sentence.java +++ b/src/uk/co/majenko/audiobookrecorder/Sentence.java @@ -59,6 +59,9 @@ public class Sentence extends BookTreeNode implements Cacheable { boolean inSample; boolean attention = false; boolean processed = false; + boolean isDetected = false; + boolean detecting = false; + boolean queued = false; String effectChain = null; @@ -204,6 +207,10 @@ public class Sentence extends BookTreeNode implements Cacheable { processed = Utils.s2b(Book.getTextNode(root, "processed")); runtime = Utils.s2d(Book.getTextNode(root, "time", "-1.000")); peak = Utils.s2d(Book.getTextNode(root, "peak", "-1.000")); + isDetected = Utils.s2b(Book.getTextNode(root, "detected")); + + if (text == null) text = id; + if (text.equals("")) text = id; if ((crossStartOffset == -1) || (crossEndOffset == -1)) { updateCrossings(true); @@ -497,6 +504,7 @@ public class Sentence extends BookTreeNode implements Cacheable { public String getText() { Debug.trace(); + if (text == null) return id; return text; } @@ -693,8 +701,9 @@ public class Sentence extends BookTreeNode implements Cacheable { public void doRecognition() { Debug.trace(); + detecting = true; + queued = false; try { - setText("[recognising...]"); reloadTree(); String command = Options.get("process.command"); @@ -712,10 +721,13 @@ public class Sentence extends BookTreeNode implements Cacheable { } setText(res); + isDetected = true; + detecting = false; reloadTree(); } catch (Exception e) { e.printStackTrace(); } + detecting = false; } public void recognise() { @@ -1502,6 +1514,7 @@ public class Sentence extends BookTreeNode implements Cacheable { public void setEffectChain(String key) { Debug.trace(); + if (key == null) key = "none"; if ((effectChain != null) && (effectChain.equals(key))) { return; } @@ -1618,6 +1631,7 @@ public class Sentence extends BookTreeNode implements Cacheable { sentenceNode.appendChild(Book.makeTextNode(doc, "notes", getNotes())); sentenceNode.appendChild(Book.makeTextNode(doc, "time", getLength())); sentenceNode.appendChild(Book.makeTextNode(doc, "peak", getPeak())); + sentenceNode.appendChild(Book.makeTextNode(doc, "detected", beenDetected())); return sentenceNode; } @@ -1688,5 +1702,20 @@ public class Sentence extends BookTreeNode implements Cacheable { return (int)db; } + public boolean isDetecting() { + return detecting; + } + + public boolean beenDetected() { + return isDetected; + } + + public boolean isQueued() { + return queued; + } + + public void setQueued() { + queued = true; + } }