Added Audiobooks Unleashed support

This commit is contained in:
2021-06-10 01:17:45 +01:00
parent 2064184093
commit 0c357fe959
6 changed files with 216 additions and 30 deletions

View File

@@ -456,6 +456,9 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Debug.trace(); Debug.trace();
if (selectedSentence != null) { if (selectedSentence != null) {
if ((e.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK) {
selectedSentence.clearPeakGainPoints();
}
selectedSentence.autoAddPeakGainPoints(); selectedSentence.autoAddPeakGainPoints();
updateWaveform(true); updateWaveform(true);
} }
@@ -1076,7 +1079,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
public void createNewBook() { public void createNewBook() {
Debug.trace(); Debug.trace();
BookInfoPanel info = new BookInfoPanel("", "", "", "", ""); BookInfoPanel info = new BookInfoPanel("", "", "", "", "", "");
int r = JOptionPane.showConfirmDialog(this, info, "New Book", JOptionPane.OK_CANCEL_OPTION); int r = JOptionPane.showConfirmDialog(this, info, "New Book", JOptionPane.OK_CANCEL_OPTION);
if (r != JOptionPane.OK_OPTION) return; if (r != JOptionPane.OK_OPTION) return;
@@ -1631,7 +1634,10 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
} }
}); });
JMenuObject exportChapter = new JMenuObject("Export chapter", c, new ActionListener() { JMenu exportChapter = new JMenu("Export chapter...");
JMenuObject exportChapterACX = new JMenuObject("For ACX", c, new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Debug.trace(); Debug.trace();
JMenuObject o = (JMenuObject)e.getSource(); JMenuObject o = (JMenuObject)e.getSource();
@@ -1639,7 +1645,22 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
ProgressDialog ed = new ProgressDialog("Exporting " + chap.getName()); ProgressDialog ed = new ProgressDialog("Exporting " + chap.getName());
ExportThread t = new ExportThread(chap, ed); ExportThread t = new ExportThread(chap, ed, "%t - %02n");
Thread nt = new Thread(t);
nt.start();
ed.setVisible(true);
}
});
JMenuObject exportChapterABU = new JMenuObject("For Audiobooks Unleashed", c, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Debug.trace();
JMenuObject o = (JMenuObject)e.getSource();
Chapter chap = (Chapter)o.getObject();
ProgressDialog ed = new ProgressDialog("Exporting " + chap.getName());
ExportThread t = new ExportThread(chap, ed, "%I_%03i");
Thread nt = new Thread(t); Thread nt = new Thread(t);
nt.start(); nt.start();
ed.setVisible(true); ed.setVisible(true);
@@ -1696,6 +1717,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
if (!snt.isLocked()) { if (!snt.isLocked()) {
queueJob(new SentenceJob(snt) { queueJob(new SentenceJob(snt) {
public void run() { public void run() {
sentence.clearPeakGainPoints();
sentence.normalize(); sentence.normalize();
sentence.autoAddPeakGainPoints(); sentence.autoAddPeakGainPoints();
} }
@@ -1748,6 +1770,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
menu.addSeparator(); menu.addSeparator();
menu.add(importWav); menu.add(importWav);
menu.add(exportChapter); menu.add(exportChapter);
exportChapter.add(exportChapterACX);
exportChapter.add(exportChapterABU);
menu.addSeparator(); menu.addSeparator();
menu.add(deleteChapter); menu.add(deleteChapter);
menu.addSeparator(); menu.addSeparator();
@@ -1801,12 +1825,24 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
menu.addSeparator(); menu.addSeparator();
menu.add(new JMenuObject("Export All Audio", book, new ActionListener() { JMenu exportAll = new JMenu("Export All Audio...");
menu.add(exportAll);
exportAll.add(new JMenuObject("For ACX", book, new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Debug.trace(); Debug.trace();
JMenuObject src = (JMenuObject)(e.getSource()); JMenuObject src = (JMenuObject)(e.getSource());
Book thisBook = (Book)(src.getObject()); Book thisBook = (Book)(src.getObject());
exportAudio(thisBook); exportAudio(thisBook, "%t - %n");
}
}));
exportAll.add(new JMenuObject("For Audiobooks Unleashed", book, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Debug.trace();
JMenuObject src = (JMenuObject)(e.getSource());
Book thisBook = (Book)(src.getObject());
exportAudio(thisBook, "%I_%03i");
} }
})); }));
@@ -2454,12 +2490,14 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
class ExportThread implements Runnable { class ExportThread implements Runnable {
ProgressDialog exportDialog; ProgressDialog exportDialog;
Chapter chapter; Chapter chapter;
String format;
public ExportThread(Chapter c, ProgressDialog e) { public ExportThread(Chapter c, ProgressDialog e, String f) {
super(); super();
Debug.trace(); Debug.trace();
exportDialog = e; exportDialog = e;
chapter = c; chapter = c;
format = f;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -2467,7 +2505,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
Debug.trace(); Debug.trace();
try { try {
chapter.exportChapter(exportDialog); chapter.exportChapter(exportDialog, format);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -2477,7 +2515,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void exportAudio(Book book) { public void exportAudio(Book book, String format) {
Debug.trace(); Debug.trace();
for (Enumeration o = book.children(); o.hasMoreElements();) { for (Enumeration o = book.children(); o.hasMoreElements();) {
@@ -2485,7 +2523,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
if (c.getChildCount() == 0) continue; if (c.getChildCount() == 0) continue;
ProgressDialog ed = new ProgressDialog("Exporting " + c.getName()); ProgressDialog ed = new ProgressDialog("Exporting " + c.getName());
ExportThread t = new ExportThread(c, ed); ExportThread t = new ExportThread(c, ed, format);
Thread nt = new Thread(t); Thread nt = new Thread(t);
nt.start(); nt.start();
ed.setVisible(true); ed.setVisible(true);
@@ -3539,7 +3577,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
book.getAuthor(), book.getAuthor(),
book.getGenre(), book.getGenre(),
book.getComment(), book.getComment(),
book.getACX() book.getACX(),
book.getISBN()
); );
tabs.add("Data", info); tabs.add("Data", info);
@@ -3580,6 +3619,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
String gen = info.getGenre(); String gen = info.getGenre();
String com = info.getComment(); String com = info.getComment();
String acx = info.getACX(); String acx = info.getACX();
String isbn = info.getISBN();
i = defEff.getSelectedIndex(); i = defEff.getSelectedIndex();
KVPair<String, String> de = defEff.getItemAt(i); KVPair<String, String> de = defEff.getItemAt(i);
@@ -3590,6 +3630,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
book.setGenre(gen); book.setGenre(gen);
book.setComment(com); book.setComment(com);
book.setACX(acx); book.setACX(acx);
book.setISBN(isbn);
// if (!(book().getName().equals(tit))) { // if (!(book().getName().equals(tit))) {
// book().renameBook(tit); // book().renameBook(tit);
// } // }

View File

@@ -43,6 +43,7 @@ public class Book extends BookTreeNode {
String genre; String genre;
String comment; String comment;
String ACX; String ACX;
String ISBN;
String manuscript; String manuscript;
String defaultEffect = "none"; String defaultEffect = "none";
Sentence roomNoise = null; Sentence roomNoise = null;
@@ -81,6 +82,7 @@ public class Book extends BookTreeNode {
genre = getTextNode(root, "genre"); genre = getTextNode(root, "genre");
comment = getTextNode(root, "comment"); comment = getTextNode(root, "comment");
ACX = getTextNode(root, "acx"); ACX = getTextNode(root, "acx");
ISBN = getTextNode(root, "isbn");
manuscript = getTextNode(root, "manuscript"); manuscript = getTextNode(root, "manuscript");
notes = getTextNode(root, "notes"); notes = getTextNode(root, "notes");
@@ -133,6 +135,7 @@ public class Book extends BookTreeNode {
genre = getTextNode(root, "genre"); genre = getTextNode(root, "genre");
comment = getTextNode(root, "comment"); comment = getTextNode(root, "comment");
ACX = getTextNode(root, "acx"); ACX = getTextNode(root, "acx");
ISBN = getTextNode(root, "isbn");
manuscript = getTextNode(root, "manuscript"); manuscript = getTextNode(root, "manuscript");
notes = getTextNode(root, "notes"); notes = getTextNode(root, "notes");
@@ -183,12 +186,14 @@ public class Book extends BookTreeNode {
public void setGenre(String g) { Debug.trace(); genre = g; } public void setGenre(String g) { Debug.trace(); genre = g; }
public void setComment(String c) { Debug.trace(); comment = c; } public void setComment(String c) { Debug.trace(); comment = c; }
public void setACX(String c) { Debug.trace(); ACX = c; } public void setACX(String c) { Debug.trace(); ACX = c; }
public void setISBN(String c) { Debug.trace(); ISBN = c; }
public String getTitle() { Debug.trace(); return name; } public String getTitle() { Debug.trace(); return name; }
public String getAuthor() { Debug.trace(); return author; } public String getAuthor() { Debug.trace(); return author; }
public String getGenre() { Debug.trace(); return genre; } public String getGenre() { Debug.trace(); return genre; }
public String getComment() { Debug.trace(); return comment; } public String getComment() { Debug.trace(); return comment; }
public String getACX() { Debug.trace(); if (ACX == null) return ""; return ACX; } public String getACX() { Debug.trace(); if (ACX == null) return ""; return ACX; }
public String getISBN() { Debug.trace(); if (ISBN == null) return ""; return ISBN; }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Chapter getChapterById(String id) { public Chapter getChapterById(String id) {
@@ -378,6 +383,7 @@ public class Book extends BookTreeNode {
root.appendChild(makeTextNode(doc, "comment", comment)); root.appendChild(makeTextNode(doc, "comment", comment));
root.appendChild(makeTextNode(doc, "genre", genre)); root.appendChild(makeTextNode(doc, "genre", genre));
root.appendChild(makeTextNode(doc, "acx", ACX)); root.appendChild(makeTextNode(doc, "acx", ACX));
root.appendChild(makeTextNode(doc, "isbn", ISBN));
root.appendChild(makeTextNode(doc, "manuscript", manuscript)); root.appendChild(makeTextNode(doc, "manuscript", manuscript));
root.appendChild(makeTextNode(doc, "notes", notes)); root.appendChild(makeTextNode(doc, "notes", notes));

View File

@@ -16,8 +16,9 @@ public class BookInfoPanel extends JPanel {
JTextField genre; JTextField genre;
JTextField comment; JTextField comment;
JTextField acx; JTextField acx;
JTextField isbn;
public BookInfoPanel(String t, String a, String g, String c, String x) { public BookInfoPanel(String t, String a, String g, String c, String x, String i) {
super(); super();
Debug.trace(); Debug.trace();
setLayout(new GridBagLayout()); setLayout(new GridBagLayout());
@@ -62,7 +63,7 @@ public class BookInfoPanel extends JPanel {
con.gridx = 0; con.gridx = 0;
con.gridy++; con.gridy++;
add(new JLabel("AXC Code:"), con); add(new JLabel("ACX Code:"), con);
con.gridx = 1; con.gridx = 1;
acx = new JTextField(x); acx = new JTextField(x);
acx.setPreferredSize(new Dimension(200, 20)); acx.setPreferredSize(new Dimension(200, 20));
@@ -71,13 +72,22 @@ public class BookInfoPanel extends JPanel {
con.gridx = 0; con.gridx = 0;
con.gridy++; con.gridy++;
add(new JLabel("ISBN:"), con);
con.gridx = 1;
isbn = new JTextField(i);
isbn.setPreferredSize(new Dimension(200, 20));
add(isbn, con);
con.gridx = 0;
con.gridy++;
} }
public String getTitle() { Debug.trace(); return title.getText(); } public String getTitle() { Debug.trace(); return title.getText(); }
public String getAuthor() { Debug.trace(); return author.getText(); } public String getAuthor() { Debug.trace(); return author.getText(); }
public String getGenre() { Debug.trace(); return genre.getText(); } public String getGenre() { Debug.trace(); return genre.getText(); }
public String getComment() { Debug.trace(); return comment.getText(); } public String getComment() { Debug.trace(); return comment.getText(); }
public String getISBN() { Debug.trace(); return isbn.getText(); }
public String getACX() { public String getACX() {
Debug.trace(); Debug.trace();
Pattern p = Pattern.compile("\\/titleview\\/([A-Z0-9]{14})"); Pattern p = Pattern.compile("\\/titleview\\/([A-Z0-9]{14})");
@@ -93,5 +103,6 @@ public class BookInfoPanel extends JPanel {
public void setGenre(String g) { Debug.trace(); genre.setText(g); } public void setGenre(String g) { Debug.trace(); genre.setText(g); }
public void setComment(String c) { Debug.trace(); comment.setText(c); } public void setComment(String c) { Debug.trace(); comment.setText(c); }
public void setACX(String a) { Debug.trace(); acx.setText(a); } public void setACX(String a) { Debug.trace(); acx.setText(a); }
public void setISBN(String i) { Debug.trace(); isbn.setText(i); }
} }

View File

@@ -9,15 +9,20 @@ public class CacheManager {
public static void addToCache(Cacheable c) { public static void addToCache(Cacheable c) {
Debug.trace(); Debug.trace();
int iterations = 0;
while (cache.size() >= cacheSize) { while (cache.size() >= cacheSize) {
iterations++;
if (iterations > cacheSize * 2) {
System.err.println("Cache locked. Flushing.");
cache.clear();
cache.add(c);
return;
}
Cacheable ob = cache.remove(0); Cacheable ob = cache.remove(0);
if (ob != null) { if (ob != null) {
if (ob.lockedInCache()) { if (ob.lockedInCache()) {
cache.add(ob); cache.add(ob);
} else { } else {
if (ob instanceof Sentence) {
Sentence s = (Sentence)ob;
}
ob.clearCache(); ob.clearCache();
} }
} }
@@ -32,9 +37,6 @@ public class CacheManager {
public static void removeFromCache(Cacheable c) { public static void removeFromCache(Cacheable c) {
Debug.trace(); Debug.trace();
if (c instanceof Sentence) {
Sentence s = (Sentence)c;
}
cache.remove(c); cache.remove(c);
c.clearCache(); c.clearCache();
} }

View File

@@ -102,6 +102,22 @@ public class Chapter extends BookTreeNode {
} }
} }
public int getSequenceNumber() {
Book book = getBook();
int i = 1;
while (true) {
Chapter c = book.getChapter(i);
if (c == null) {
return -1;
}
System.err.println(c.getName());
if (c.getName().equals(name)) {
return i;
}
i++;
}
}
public String getId() { public String getId() {
Debug.trace(); Debug.trace();
return id; return id;
@@ -162,8 +178,93 @@ public class Chapter extends BookTreeNode {
return postGap; return postGap;
} }
public String createFilename(String format) {
String out = "";
char[] chars = format.toCharArray();
int mode = 0; // nothing
int len = 0;
boolean zeros = false;
boolean first = true;
Book book = getBook();
for (char c : chars) {
switch (mode) {
case 0:
switch (c) {
case '%': {
mode = 1;
len = 0;
zeros = false;
first = true;
}
break;
default: out += c; break;
}
break;
case 1:
switch (c) {
case '0': len = len * 10; first = false; break;
case '1': len = len * 10 + 1; first = false; break;
case '2': len = len * 10 + 2; first = false; break;
case '3': len = len * 10 + 3; first = false; break;
case '4': len = len * 10 + 4; first = false; break;
case '5': len = len * 10 + 5; first = false; break;
case '6': len = len * 10 + 6; first = false; break;
case '7': len = len * 10 + 7; first = false; break;
case '8': len = len * 10 + 8; first = false; break;
case '9': len = len * 10 + 9; first = false; break;
case 't':
if (len > 0)
out += String.format("%" + len + "s", book.getTitle());
else
out += book.getTitle();
mode = 0;
break;
case 'n':
if (len > 0)
out += String.format("%" + len + "s", name);
else
out += name;
mode = 0;
break;
case '%':
out += '%';
mode = 0;
break;
case 'I':
if (len > 0)
out += String.format("%" + len + "s", book.getISBN());
else
out += book.getISBN();
mode = 0;
break;
case 'A':
if (len > 0)
out += String.format("%" + len + "s", book.getACX());
else
out += book.getACX();
mode = 0;
break;
case 'i':
if (len > 0)
out += String.format("%0" + len + "d", getSequenceNumber());
else
out += getId();
mode = 0;
break;
}
}
}
return out;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void exportChapter(ProgressDialog exportDialog) throws public void exportChapter(ProgressDialog exportDialog, String fnformat) throws
FileNotFoundException, IOException, InputFormatException, NotSupportedException, FileNotFoundException, IOException, InputFormatException, NotSupportedException,
EncoderException, UnsupportedTagException, InvalidDataException { EncoderException, UnsupportedTagException, InvalidDataException {
Debug.trace(); Debug.trace();
@@ -214,7 +315,9 @@ public class Chapter extends BookTreeNode {
File exportFile = new File(export, name + ".wax"); File exportFile = new File(export, name + ".wax");
File wavFile = new File(export, name + ".wav"); File wavFile = new File(export, name + ".wav");
File mp3File = new File(export, name + "-untagged.mp3"); File mp3File = new File(export, name + "-untagged.mp3");
File taggedFile = new File(export, book.getName() + " - " + name + ".mp3");
File taggedFile = new File(export, createFilename(fnformat) + ".mp3");
FileOutputStream fos = new FileOutputStream(exportFile); FileOutputStream fos = new FileOutputStream(exportFile);
data = getBook().getRoomNoise(Utils.s2i(Options.get("catenation.pre-chapter"))); data = getBook().getRoomNoise(Utils.s2i(Options.get("catenation.pre-chapter")));

View File

@@ -1815,33 +1815,40 @@ public class Sentence extends BookTreeNode implements Cacheable {
} }
public boolean beenDetected() { public boolean beenDetected() {
Debug.trace();
return isDetected; return isDetected;
} }
public boolean isProcessing() { public boolean isProcessing() {
Debug.trace();
return state == PROCESSING; return state == PROCESSING;
} }
public boolean isQueued() { public boolean isQueued() {
Debug.trace();
return state == QUEUED; return state == QUEUED;
} }
public void setProcessing() { public void setProcessing() {
Debug.trace();
state = PROCESSING; state = PROCESSING;
reloadTree(); reloadTree();
} }
public void setQueued() { public void setQueued() {
Debug.trace();
state = QUEUED; state = QUEUED;
reloadTree(); reloadTree();
} }
public void setDequeued() { public void setDequeued() {
Debug.trace();
state = IDLE; state = IDLE;
reloadTree(); reloadTree();
} }
public Book getBook() { public Book getBook() {
Debug.trace();
if (parentBook != null) { if (parentBook != null) {
Debug.d("Returning parent book"); Debug.d("Returning parent book");
return parentBook; // Override for room noise which isn't attached to a book tree return parentBook; // Override for room noise which isn't attached to a book tree
@@ -2120,11 +2127,24 @@ public class Sentence extends BookTreeNode implements Cacheable {
return cpos; return cpos;
} }
int findGainPointBetween(int start, int end) {
for (Integer loc : gainPoints.keySet()) {
if (loc >= start && loc <= end) {
return loc;
}
}
return -1;
}
public void clearPeakGainPoints() {
gainPoints.clear();
}
public void autoAddPeakGainPoints() { public void autoAddPeakGainPoints() {
long ts = System.currentTimeMillis(); long ts = System.currentTimeMillis();
while (true) { while (true) {
if (System.currentTimeMillis() - ts > 10000) { if (System.currentTimeMillis() - ts > 30000) {
System.err.println("Terminated: running too long!"); System.err.println("Terminated: running too long!");
return; return;
} }
@@ -2136,6 +2156,12 @@ public class Sentence extends BookTreeNode implements Cacheable {
System.err.println("Biggest peak: " + pos); System.err.println("Biggest peak: " + pos);
if ((Math.abs(samples[LEFT][pos]) < 0.708) && (Math.abs(samples[RIGHT][pos]) < 0.708)) {
System.err.println("No more peaks");
refreshAllData();
return;
}
int closest = findNearestGainPoint(pos); int closest = findNearestGainPoint(pos);
if (closest >= 0) { if (closest >= 0) {
int diff = closest - pos; int diff = closest - pos;
@@ -2146,12 +2172,6 @@ public class Sentence extends BookTreeNode implements Cacheable {
} }
} }
if ((Math.abs(samples[LEFT][pos]) < 0.708) && (Math.abs(samples[RIGHT][pos]) < 0.708)) {
System.err.println("No more peaks");
refreshAllData();
return;
}
int start = findPreviousZero(pos); int start = findPreviousZero(pos);
int end = findNextZero(pos); int end = findNextZero(pos);
if (start == -1) { if (start == -1) {
@@ -2163,9 +2183,12 @@ public class Sentence extends BookTreeNode implements Cacheable {
return; return;
} }
addGainPoint(start, 1d); int betweenStart = findGainPointBetween(start, pos - 1);
int betweenEnd = findGainPointBetween(pos + 1, end);
if (betweenStart == -1) addGainPoint(start, 1d);
addGainPoint(pos, 1d); addGainPoint(pos, 1d);
addGainPoint(end, 1d); if (betweenEnd == -1) addGainPoint(end, 1d);
double val = 1d; double val = 1d;