Compare commits

..

14 Commits

32 changed files with 232 additions and 174 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.jar filter=lfs diff=lfs merge=lfs -text

View File

@@ -72,3 +72,15 @@ files) is placed.
When you export the book as MP3 a new folder "export" is created within the book's folder where the MP3 files are placed. When you export the book as MP3 a new folder "export" is created within the book's folder where the MP3 files are placed.
MP3 files are all tagged with the book title, chapter title, chapter number and comment. MP3 files are all tagged with the book title, chapter title, chapter number and comment.
Building
========
1. Check out this repo
2. Install `ant` and `default-jdk`
3. Install [git LFS support](https://help.github.com/articles/installing-git-large-file-storage/)
4. Pull the large files with `git lfs pull`
5. Build with `ant build`
6. Run with `java -jar ./AudiobookRecorder.jar`

Binary file not shown.

BIN
deps/mp3agic-0.9.1.jar vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

13
dist/linux/audiobookrecorder.desktop vendored Normal file
View File

@@ -0,0 +1,13 @@
[Desktop Entry]
Name=AudiobookRecorder
GenericName=Audiobook Recorder
X-GNOME-FullName=AudiobookRecorder
Comment=Record audiobooks with ease
Keywords=audio
Exec=AudiobookRecorder
Terminal=false
Type=Application
StartupNotify=true
Icon=AudiobookRecorder
Categories=AudioVideo;Audio;Recorder;
X-AppStream-Ignore=true

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
version=0.1.1 version=0.1.2

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -41,6 +41,10 @@ public class AudiobookRecorder extends JFrame {
JMenuItem bookNewChapter; JMenuItem bookNewChapter;
JMenuItem bookExportAudio; JMenuItem bookExportAudio;
JMenu bookVisitACX;
JMenuItem bookVisitTitle;
JMenuItem bookVisitAudition;
JMenuItem bookVisitProduce;
JMenuItem toolsMerge; JMenuItem toolsMerge;
JMenuItem toolsArchive; JMenuItem toolsArchive;
@@ -75,6 +79,7 @@ public class AudiobookRecorder extends JFrame {
JSpinner postSentenceGap; JSpinner postSentenceGap;
JCheckBox locked; JCheckBox locked;
JCheckBox attention;
JButtonSpacePlay reprocessAudioFFT; JButtonSpacePlay reprocessAudioFFT;
JButtonSpacePlay reprocessAudioPeak; JButtonSpacePlay reprocessAudioPeak;
@@ -91,7 +96,6 @@ public class AudiobookRecorder extends JFrame {
public Configuration sphinxConfig; public Configuration sphinxConfig;
public StreamSpeechRecognizer recognizer; public StreamSpeechRecognizer recognizer;
public static AudiobookRecorder window; public static AudiobookRecorder window;
void initSphinx() { void initSphinx() {
@@ -110,8 +114,6 @@ public class AudiobookRecorder extends JFrame {
void buildToolbar(Container ob) { void buildToolbar(Container ob) {
toolBar = new MainToolBar(this); toolBar = new MainToolBar(this);
toolBar.disableBook();
toolBar.disableSentence();
ob.add(toolBar, BorderLayout.NORTH); ob.add(toolBar, BorderLayout.NORTH);
} }
@@ -186,6 +188,33 @@ public class AudiobookRecorder extends JFrame {
bookMenu.add(bookNewChapter); bookMenu.add(bookNewChapter);
bookMenu.add(bookExportAudio); bookMenu.add(bookExportAudio);
bookVisitACX = new JMenu("Visit ACX");
bookMenu.add(bookVisitACX);
bookVisitTitle = new JMenuItem("Title");
bookVisitTitle.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Utils.browse("https://www.acx.com/titleview/" + book.getACX());
}
});
bookVisitACX.add(bookVisitTitle);
bookVisitAudition = new JMenuItem("Audition");
bookVisitAudition.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Utils.browse("https://www.acx.com/titleview/" + book.getACX() + "?bucket=AUDITION_READY");
}
});
bookVisitACX.add(bookVisitAudition);
bookVisitProduce = new JMenuItem("Produce");
bookVisitProduce.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Utils.browse("https://www.acx.com/titleview/" + book.getACX() + "?bucket=PRODUCE");
}
});
bookVisitACX.add(bookVisitProduce);
menuBar.add(bookMenu); menuBar.add(bookMenu);
toolsMenu = new JMenu("Tools"); toolsMenu = new JMenu("Tools");
@@ -405,9 +434,29 @@ public class AudiobookRecorder extends JFrame {
bookTreeModel.reload(selectedSentence); bookTreeModel.reload(selectedSentence);
} }
}); });
controlsTop.add(locked); controlsTop.add(locked);
attention = new JCheckBox("Flag for attention");
attention.setFocusable(false);
attention.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JCheckBox c = (JCheckBox)e.getSource();
if (c.isSelected()) {
if (selectedSentence != null) {
selectedSentence.setAttentionFlag(true);
}
} else {
if (selectedSentence != null) {
selectedSentence.setAttentionFlag(false);
}
}
bookTreeModel.reload(selectedSentence);
}
});
controlsTop.add(attention);
controlsTop.add(Box.createHorizontalGlue()); controlsTop.add(Box.createHorizontalGlue());
controlsTop.add(new JLabel("Post gap:")); controlsTop.add(new JLabel("Post gap:"));
controlsTop.add(postSentenceGap); controlsTop.add(postSentenceGap);
@@ -571,7 +620,7 @@ public class AudiobookRecorder extends JFrame {
} }
public void createNewBook() { public void createNewBook() {
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;
@@ -590,6 +639,7 @@ public class AudiobookRecorder extends JFrame {
prefs.setProperty("book.author", info.getAuthor()); prefs.setProperty("book.author", info.getAuthor());
prefs.setProperty("book.genre", info.getGenre()); prefs.setProperty("book.genre", info.getGenre());
prefs.setProperty("book.comment", info.getComment()); prefs.setProperty("book.comment", info.getComment());
prefs.setProperty("book.acx", info.getACX());
prefs.setProperty("chapter.audition.name", "Audition"); prefs.setProperty("chapter.audition.name", "Audition");
prefs.setProperty("chapter.audition.pre-gap", Options.get("catenation.pre-chapter")); prefs.setProperty("chapter.audition.pre-gap", Options.get("catenation.pre-chapter"));
prefs.setProperty("chapter.audition.post-gap", Options.get("catenation.post-chapter")); prefs.setProperty("chapter.audition.post-gap", Options.get("catenation.post-chapter"));
@@ -679,7 +729,7 @@ public class AudiobookRecorder extends JFrame {
sphinxConfig.setDictionaryPath("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict"); sphinxConfig.setDictionaryPath("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict");
sphinxConfig.setLanguageModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us.lm.bin"); sphinxConfig.setLanguageModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us.lm.bin");
sphinxConfig.setSampleRate((int)(book.getAudioFormat().getSampleRate() / 3f)); sphinxConfig.setSampleRate((int)(book.getAudioFormat().getSampleRate() / 4f));
StreamSpeechRecognizer recognizer; StreamSpeechRecognizer recognizer;
@@ -1004,6 +1054,40 @@ public class AudiobookRecorder extends JFrame {
menu.addSeparator(); menu.addSeparator();
menu.add(deleteChapter); menu.add(deleteChapter);
menu.show(bookTree, e.getX(), e.getY());
} else if (node instanceof Book) {
JPopupMenu menu = new JPopupMenu();
JMenuItem editData = new JMenuItem("Edit Data...");
editData.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
BookInfoPanel info = new BookInfoPanel(
book.getName(),
book.getAuthor(),
book.getGenre(),
book.getComment(),
book.getACX()
);
int r = JOptionPane.showConfirmDialog(AudiobookRecorder.this, info, "Edit Book", JOptionPane.OK_CANCEL_OPTION);
if (r != JOptionPane.OK_OPTION) return;
String tit = info.getTitle();
String aut = info.getAuthor();
String gen = info.getGenre();
String com = info.getComment();
String acx = info.getACX();
book.setAuthor(aut);
book.setGenre(gen);
book.setComment(com);
book.setACX(acx);
if (!(book.getName().equals(tit))) {
book.renameBook(tit);
}
}
});
menu.add(editData);
menu.show(bookTree, e.getX(), e.getY()); menu.show(bookTree, e.getX(), e.getY());
} }
@@ -1020,9 +1104,6 @@ public class AudiobookRecorder extends JFrame {
return; return;
} }
toolBar.disableBook();
toolBar.disableSentence();
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent();
if (selectedNode == null) { if (selectedNode == null) {
@@ -1053,9 +1134,6 @@ public class AudiobookRecorder extends JFrame {
return; return;
} }
toolBar.disableBook();
toolBar.disableSentence();
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent();
if (selectedNode == null) { if (selectedNode == null) {
@@ -1106,9 +1184,6 @@ public class AudiobookRecorder extends JFrame {
return; return;
} }
toolBar.disableBook();
toolBar.disableSentence();
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent();
if (selectedNode == null) { if (selectedNode == null) {
@@ -1158,9 +1233,6 @@ public class AudiobookRecorder extends JFrame {
return; return;
} }
toolBar.disableBook();
toolBar.disableSentence();
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent();
if (selectedNode == null) { if (selectedNode == null) {
@@ -1203,10 +1275,6 @@ public class AudiobookRecorder extends JFrame {
bookTree.setSelectionPath(new TreePath(recording.getPath())); bookTree.setSelectionPath(new TreePath(recording.getPath()));
bookTree.scrollPathToVisible(new TreePath(recording.getPath())); bookTree.scrollPathToVisible(new TreePath(recording.getPath()));
toolBar.enableBook();
toolBar.enableSentence();
toolBar.disableStop();
centralPanel.setFlash(false); centralPanel.setFlash(false);
recording = null; recording = null;
saveBookStructure(); saveBookStructure();
@@ -1280,6 +1348,7 @@ public class AudiobookRecorder extends JFrame {
prefs.setProperty("book.author", book.getAuthor()); prefs.setProperty("book.author", book.getAuthor());
prefs.setProperty("book.genre", book.getGenre()); prefs.setProperty("book.genre", book.getGenre());
prefs.setProperty("book.comment", book.getComment()); prefs.setProperty("book.comment", book.getComment());
prefs.setProperty("book.acx", book.getACX());
prefs.setProperty("audio.recording.samplerate", "" + book.getSampleRate()); prefs.setProperty("audio.recording.samplerate", "" + book.getSampleRate());
prefs.setProperty("audio.recording.resolution", "" + book.getResolution()); prefs.setProperty("audio.recording.resolution", "" + book.getResolution());
@@ -1306,6 +1375,7 @@ public class AudiobookRecorder extends JFrame {
prefs.setProperty(String.format("%s.sentence.%08d.start-offset", keybase, i), Integer.toString(snt.getStartOffset())); prefs.setProperty(String.format("%s.sentence.%08d.start-offset", keybase, i), Integer.toString(snt.getStartOffset()));
prefs.setProperty(String.format("%s.sentence.%08d.end-offset", keybase, i), Integer.toString(snt.getEndOffset())); prefs.setProperty(String.format("%s.sentence.%08d.end-offset", keybase, i), Integer.toString(snt.getEndOffset()));
prefs.setProperty(String.format("%s.sentence.%08d.locked", keybase, i), snt.isLocked() ? "true" : "false"); prefs.setProperty(String.format("%s.sentence.%08d.locked", keybase, i), snt.isLocked() ? "true" : "false");
prefs.setProperty(String.format("%s.sentence.%08d.attention", keybase, i), snt.getAttentionFlag() ? "true" : "false");
i++; i++;
} }
} }
@@ -1360,6 +1430,7 @@ public class AudiobookRecorder extends JFrame {
book.setAuthor(prefs.getProperty("book.author")); book.setAuthor(prefs.getProperty("book.author"));
book.setGenre(prefs.getProperty("book.genre")); book.setGenre(prefs.getProperty("book.genre"));
book.setComment(prefs.getProperty("book.comment")); book.setComment(prefs.getProperty("book.comment"));
book.setACX(prefs.getProperty("book.acx"));
int sr = Utils.s2i(prefs.getProperty("audio.recording.samplerate")); int sr = Utils.s2i(prefs.getProperty("audio.recording.samplerate"));
if (sr == 0) { if (sr == 0) {
@@ -1397,7 +1468,7 @@ public class AudiobookRecorder extends JFrame {
InputMap im = bookTree.getInputMap(JComponent.WHEN_FOCUSED); InputMap im = bookTree.getInputMap(JComponent.WHEN_FOCUSED);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "startPlayback"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "startStopPlayback");
roomNoise = new Sentence("room-noise", "Room Noise"); roomNoise = new Sentence("room-noise", "Room Noise");
@@ -1413,25 +1484,17 @@ public class AudiobookRecorder extends JFrame {
sampleWaveform.setAltMarkers(s.getStartCrossing(), s.getEndCrossing()); sampleWaveform.setAltMarkers(s.getStartCrossing(), s.getEndCrossing());
postSentenceGap.setValue(s.getPostGap()); postSentenceGap.setValue(s.getPostGap());
locked.setSelected(s.isLocked()); locked.setSelected(s.isLocked());
attention.setSelected(s.getAttentionFlag());
postSentenceGap.setEnabled(!s.isLocked()); postSentenceGap.setEnabled(!s.isLocked());
reprocessAudioFFT.setEnabled(!s.isLocked()); reprocessAudioFFT.setEnabled(!s.isLocked());
reprocessAudioPeak.setEnabled(!s.isLocked()); reprocessAudioPeak.setEnabled(!s.isLocked());
if (playing == null) {
toolBar.enableSentence();
toolBar.disableStop();
} else {
toolBar.disableSentence();
toolBar.enableStop();
}
} else { } else {
selectedSentence = null; selectedSentence = null;
toolBar.disableSentence();
sampleWaveform.clearData(); sampleWaveform.clearData();
toolBar.disableStop();
postSentenceGap.setValue(0); postSentenceGap.setValue(0);
locked.setSelected(false); locked.setSelected(false);
attention.setSelected(false);
} }
} }
}); });
@@ -1470,6 +1533,7 @@ public class AudiobookRecorder extends JFrame {
s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.audition.sentence.%08d.start-offset", i)))); s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.audition.sentence.%08d.start-offset", i))));
s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.audition.sentence.%08d.end-offset", i)))); s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.audition.sentence.%08d.end-offset", i))));
s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.audition.sentence.%08d.locked", i)))); s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.audition.sentence.%08d.locked", i))));
s.setAttentionFlag(Utils.s2b(prefs.getProperty(String.format("chapter.audition.sentence.%08d.attention", i))));
bookTreeModel.insertNodeInto(s, c, c.getChildCount()); bookTreeModel.insertNodeInto(s, c, c.getChildCount());
} }
@@ -1488,6 +1552,7 @@ public class AudiobookRecorder extends JFrame {
s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.open.sentence.%08d.start-offset", i)))); s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.open.sentence.%08d.start-offset", i))));
s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.open.sentence.%08d.end-offset", i)))); s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.open.sentence.%08d.end-offset", i))));
s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.open.sentence.%08d.locked", i)))); s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.open.sentence.%08d.locked", i))));
s.setAttentionFlag(Utils.s2b(prefs.getProperty(String.format("chapter.open.sentence.%08d.attention", i))));
bookTreeModel.insertNodeInto(s, c, c.getChildCount()); bookTreeModel.insertNodeInto(s, c, c.getChildCount());
} }
@@ -1512,6 +1577,7 @@ public class AudiobookRecorder extends JFrame {
s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.%04d.sentence.%08d.start-offset", cno, i)))); s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.%04d.sentence.%08d.start-offset", cno, i))));
s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.%04d.sentence.%08d.end-offset", cno, i)))); s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.%04d.sentence.%08d.end-offset", cno, i))));
s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.%04d.sentence.%08d.locked", cno, i)))); s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.%04d.sentence.%08d.locked", cno, i))));
s.setAttentionFlag(Utils.s2b(prefs.getProperty(String.format("chapter.%04d.sentence.%08d.attention", cno, i))));
bookTreeModel.insertNodeInto(s, c, c.getChildCount()); bookTreeModel.insertNodeInto(s, c, c.getChildCount());
} }
} }
@@ -1531,12 +1597,12 @@ public class AudiobookRecorder extends JFrame {
s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.close.sentence.%08d.start-offset", i)))); s.setStartOffset(Utils.s2i(prefs.getProperty(String.format("chapter.close.sentence.%08d.start-offset", i))));
s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.close.sentence.%08d.end-offset", i)))); s.setEndOffset(Utils.s2i(prefs.getProperty(String.format("chapter.close.sentence.%08d.end-offset", i))));
s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.close.sentence.%08d.locked", i)))); s.setLocked(Utils.s2b(prefs.getProperty(String.format("chapter.close.sentence.%08d.locked", i))));
s.setAttentionFlag(Utils.s2b(prefs.getProperty(String.format("chapter.close.sentence.%08d.attention", i))));
bookTreeModel.insertNodeInto(s, c, c.getChildCount()); bookTreeModel.insertNodeInto(s, c, c.getChildCount());
} }
bookTree.expandPath(new TreePath(book.getPath())); bookTree.expandPath(new TreePath(book.getPath()));
toolBar.enableBook();
statusLabel.setText("Noise floor: " + getNoiseFloorDB() + "dB"); statusLabel.setText("Noise floor: " + getNoiseFloorDB() + "dB");
book.setIcon(Icons.book); book.setIcon(Icons.book);
} }
@@ -1633,8 +1699,6 @@ public class AudiobookRecorder extends JFrame {
return; return;
} }
playing = selectedSentence; playing = selectedSentence;
toolBar.disableSentence();
toolBar.enableStop();
playingThread = new Thread(new Runnable() { playingThread = new Thread(new Runnable() {
public void run() { public void run() {
@@ -1661,6 +1725,7 @@ public class AudiobookRecorder extends JFrame {
play.stop(); play.stop();
play.close(); play.close();
play = null; play = null;
playing = null;
} catch (Exception e) { } catch (Exception e) {
playing = null; playing = null;
if (play != null) { if (play != null) {
@@ -1670,8 +1735,6 @@ public class AudiobookRecorder extends JFrame {
} }
play = null; play = null;
} }
toolBar.enableSentence();
toolBar.disableStop();
} }
}); });
@@ -1728,8 +1791,6 @@ public class AudiobookRecorder extends JFrame {
return; return;
} }
playing = selectedSentence; playing = selectedSentence;
toolBar.disableSentence();
toolBar.enableStop();
playingThread = new Thread(new Runnable() { playingThread = new Thread(new Runnable() {
public void run() { public void run() {
@@ -1798,8 +1859,6 @@ public class AudiobookRecorder extends JFrame {
} }
play = null; play = null;
} }
toolBar.enableSentence();
toolBar.disableStop();
} }
}); });
@@ -1848,7 +1907,7 @@ public class AudiobookRecorder extends JFrame {
if (equaliserWindow == null) { if (equaliserWindow == null) {
equaliserWindow = new JDialog(); equaliserWindow = new JDialog();
equaliserWindow.setTitle("Equaliser"); equaliserWindow.setTitle("Equaliser");
equaliserWindow.add(book.equaliser); equaliserWindow.add(new JScrollPane(book.equaliser));
equaliserWindow.pack(); equaliserWindow.pack();
} }
equaliserWindow.setVisible(true); equaliserWindow.setVisible(true);
@@ -2054,7 +2113,7 @@ public class AudiobookRecorder extends JFrame {
String name = AudiobookRecorder.this.book.getName(); String name = AudiobookRecorder.this.book.getName();
File storageDir = new File(Options.get("path.storage")); File storageDir = new File(Options.get("path.storage"));
File bookDir = new File(storageDir, name); File bookDir = new File(storageDir, name);
File archiveDir = new File(storageDir, "archive"); File archiveDir = new File(Options.get("path.archive"));
ArrayList<File> fileList = gatherFiles(bookDir); ArrayList<File> fileList = gatherFiles(bookDir);
@@ -2139,7 +2198,7 @@ public class AudiobookRecorder extends JFrame {
} }
public void openArchive() { public void openArchive() {
JFileChooser jc = new JFileChooser(new File(Options.get("path.storage"), "archive")); JFileChooser jc = new JFileChooser(new File(Options.get("path.archive")));
FileNameExtensionFilter filter = new FileNameExtensionFilter("Audiobook Archives", "abz"); FileNameExtensionFilter filter = new FileNameExtensionFilter("Audiobook Archives", "abz");
jc.addChoosableFileFilter(filter); jc.addChoosableFileFilter(filter);
jc.setFileFilter(filter); jc.setFileFilter(filter);

View File

@@ -17,6 +17,7 @@ public class Book extends DefaultMutableTreeNode {
String author; String author;
String genre; String genre;
String comment; String comment;
String ACX;
int sampleRate; int sampleRate;
int channels; int channels;
@@ -32,31 +33,18 @@ public class Book extends DefaultMutableTreeNode {
super(bookname); super(bookname);
name = bookname; name = bookname;
equaliser = new Equaliser(); equaliser = new Equaliser();
AudiobookRecorder.window.setTitle("AudioBook Recorder :: " + name);
} }
public void setAuthor(String a) { public void setAuthor(String a) { author = a; }
author = a; public void setGenre(String g) { genre = g; }
} public void setComment(String c) { comment = c; }
public void setACX(String c) { ACX = c; }
public void setGenre(String g) { public String getAuthor() { return author; }
genre = g; public String getGenre() { return genre; }
} public String getComment() { return comment; }
public String getACX() { if (ACX == null) return ""; return ACX; }
public void setComment(String c) {
comment = c;
}
public String getAuthor() {
return author;
}
public String getGenre() {
return genre;
}
public String getComment() {
return comment;
}
public Chapter getClosingCredits() { public Chapter getClosingCredits() {
return getChapterById("close"); return getChapterById("close");
@@ -124,23 +112,28 @@ public class Book extends DefaultMutableTreeNode {
public void setUserObject(Object o) { public void setUserObject(Object o) {
if (o instanceof String) { if (o instanceof String) {
String newName = (String)o; String newName = (String)o;
if (newName.equals(name)) return;
renameBook(newName);
}
}
File oldDir = new File(Options.get("path.storage"), name); public void renameBook(String newName) {
File newDir = new File(Options.get("path.storage"), newName); File oldDir = new File(Options.get("path.storage"), name);
File newDir = new File(Options.get("path.storage"), newName);
if (newDir.exists()) { if (newDir.exists()) {
JOptionPane.showMessageDialog(AudiobookRecorder.window, "Book already exists", "Error", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(AudiobookRecorder.window, "Book already exists", "Error", JOptionPane.ERROR_MESSAGE);
return; return;
} }
if (oldDir.exists() && oldDir.isDirectory()) { if (oldDir.exists() && oldDir.isDirectory()) {
oldDir.renameTo(newDir); oldDir.renameTo(newDir);
name = newName; name = newName;
AudiobookRecorder.window.saveBookStructure(); AudiobookRecorder.window.saveBookStructure();
AudiobookRecorder.window.bookTreeModel.reload(this); AudiobookRecorder.window.bookTreeModel.reload(this);
Options.set("path.last-book", name); Options.set("path.last-book", name);
Options.savePreferences(); Options.savePreferences();
} AudiobookRecorder.window.setTitle("AudioBook Recorder :: " + name);
} }
} }

View File

@@ -4,6 +4,7 @@ import javax.swing.*;
import javax.swing.event.*; import javax.swing.event.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.util.regex.*;
public class BookInfoPanel extends JPanel { public class BookInfoPanel extends JPanel {
@@ -11,8 +12,9 @@ public class BookInfoPanel extends JPanel {
JTextField author; JTextField author;
JTextField genre; JTextField genre;
JTextField comment; JTextField comment;
JTextField acx;
public BookInfoPanel(String t, String a, String g, String c) { public BookInfoPanel(String t, String a, String g, String c, String x) {
super(); super();
setLayout(new GridBagLayout()); setLayout(new GridBagLayout());
GridBagConstraints con = new GridBagConstraints(); GridBagConstraints con = new GridBagConstraints();
@@ -56,37 +58,36 @@ public class BookInfoPanel extends JPanel {
con.gridx = 0; con.gridx = 0;
con.gridy++; con.gridy++;
add(new JLabel("AXC Code:"), con);
con.gridx = 1;
acx = new JTextField(x);
acx.setPreferredSize(new Dimension(200, 20));
add(acx, con);
con.gridx = 0;
con.gridy++;
} }
public String getTitle() { public String getTitle() { return title.getText(); }
return title.getText(); public String getAuthor() { return author.getText(); }
public String getGenre() { return genre.getText(); }
public String getComment() { return comment.getText(); }
public String getACX() {
Pattern p = Pattern.compile("\\/titleview\\/([A-Z0-9]{14})");
Matcher m = p.matcher(acx.getText());
if (m.find()) {
System.err.println(m);
return m.group(1);
}
return acx.getText();
} }
public String getAuthor() { public void setTitle(String t) { title.setText(t); }
return author.getText(); public void setAuthor(String a) { author.setText(a); }
} public void setGenre(String g) { genre.setText(g); }
public void setComment(String c) { comment.setText(c); }
public void setACX(String a) { acx.setText(a); }
public String getGenre() {
return genre.getText();
}
public String getComment() {
return comment.getText();
}
public void setTitle(String t) {
title.setText(t);
}
public void setAuthor(String a) {
author.setText(a);
}
public void setGenre(String g) {
genre.setText(g);
}
public void setComment(String c) {
comment.setText(c);
}
} }

View File

@@ -11,8 +11,11 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
if (value instanceof Sentence) { if (value instanceof Sentence) {
Sentence s = (Sentence)value; Sentence s = (Sentence)value;
if (s.isLocked()) { if (s.getAttentionFlag()) {
ret.setForeground(new Color(0x20, 0x00, 0x00)); ret.setForeground(new Color(0xFF, 0xFF, 0x00));
ret.setIcon(Icons.attention);
} else if (s.isLocked()) {
ret.setForeground(new Color(0x00, 0x80, 0xFF));
ret.setIcon(Icons.locked); ret.setIcon(Icons.locked);
} else if (s.getStartOffset() == 0) { } else if (s.getStartOffset() == 0) {
ret.setIcon(Icons.important); ret.setIcon(Icons.important);

View File

@@ -40,12 +40,7 @@ public class DonationPanel extends JPanel {
JButton donate = new JButton("Donate!"); JButton donate = new JButton("Donate!");
donate.addActionListener(new ActionListener() { donate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (Desktop.isDesktopSupported()) { Utils.browse("https://paypal.me/majenko");
try {
Desktop.getDesktop().browse(new URI("https://paypal.me/majenko"));
} catch (Exception ex) {
}
}
} }
}); });

View File

@@ -31,4 +31,5 @@ public class Icons {
static public final ImageIcon zoomIn = new ImageIcon(Icons.class.getResource("icons/zoom-in.png")); static public final ImageIcon zoomIn = new ImageIcon(Icons.class.getResource("icons/zoom-in.png"));
static public final ImageIcon zoomOut = new ImageIcon(Icons.class.getResource("icons/zoom-out.png")); static public final ImageIcon zoomOut = new ImageIcon(Icons.class.getResource("icons/zoom-out.png"));
static public final ImageIcon dollar = new ImageIcon(Icons.class.getResource("icons/dollar.png")); static public final ImageIcon dollar = new ImageIcon(Icons.class.getResource("icons/dollar.png"));
static public final ImageIcon attention = new ImageIcon(Icons.class.getResource("icons/attention.png"));
} }

View File

@@ -124,31 +124,4 @@ public class MainToolBar extends JToolBar {
setFloatable(false); setFloatable(false);
} }
public void enableBook() {
newChapter.setEnabled(true);
recordRoomNoise.setEnabled(true);
}
public void disableBook() {
newChapter.setEnabled(false);
recordRoomNoise.setEnabled(false);
}
public void enableSentence() {
playSentence.setEnabled(true);
playonSentence.setEnabled(true);
}
public void disableSentence() {
playSentence.setEnabled(false);
playonSentence.setEnabled(false);
}
public void enableStop() {
stopPlaying.setEnabled(true);
}
public void disableStop() {
stopPlaying.setEnabled(false);
}
} }

View File

@@ -22,6 +22,7 @@ public class Options extends JDialog {
JComboBox<KVPair> bitDepth; JComboBox<KVPair> bitDepth;
JComboBox<KVPair> trimMethod; JComboBox<KVPair> trimMethod;
JTextField storageFolder; JTextField storageFolder;
JTextField archiveFolder;
JSpinner preChapterGap; JSpinner preChapterGap;
JSpinner postChapterGap; JSpinner postChapterGap;
JSpinner postSentenceGap; JSpinner postSentenceGap;
@@ -256,6 +257,7 @@ public class Options extends JDialog {
playbackList = addDropdown(optionsPanel, "Playback device:", getPlaybackMixerList(), get("audio.playback.device")); playbackList = addDropdown(optionsPanel, "Playback device:", getPlaybackMixerList(), get("audio.playback.device"));
addSeparator(optionsPanel); addSeparator(optionsPanel);
storageFolder = addFilePath(optionsPanel, "Storage folder:", get("path.storage"), true); storageFolder = addFilePath(optionsPanel, "Storage folder:", get("path.storage"), true);
archiveFolder = addFilePath(optionsPanel, "Archive folder:", get("path.archive"), true);
addSeparator(optionsPanel); addSeparator(optionsPanel);
@@ -281,28 +283,20 @@ public class Options extends JDialog {
cacheSize = addSpinner(optionsPanel, "Cache size:", 0, 5000, 1, getInteger("cache.size"), ""); cacheSize = addSpinner(optionsPanel, "Cache size:", 0, 5000, 1, getInteger("cache.size"), "");
addSeparator(optionsPanel); addSeparator(optionsPanel);
tabs.add("Options", new JScrollPane(optionsPanel));
tabs.add("Options", optionsPanel);
equaliser = new Equaliser(); equaliser = new Equaliser();
for (int i = 0; i < 31; i++) { for (int i = 0; i < 31; i++) {
equaliser.setChannel(i, Options.getFloat("audio.eq." + i)); equaliser.setChannel(i, Options.getFloat("audio.eq." + i));
} }
tabs.add("Default EQ", new JScrollPane(equaliser));
tabs.add("Default EQ", equaliser);
JPanel startScript = new JPanel(); JPanel startScript = new JPanel();
startScript.setLayout(new BorderLayout()); startScript.setLayout(new BorderLayout());
startupScript = new JTextArea(get("scripts.startup")); startupScript = new JTextArea(get("scripts.startup"));
startScript.add(startupScript, BorderLayout.CENTER); startScript.add(startupScript, BorderLayout.CENTER);
tabs.add("Startup Script", startScript); tabs.add("Startup Script", startScript);
add(tabs, BorderLayout.CENTER); add(tabs, BorderLayout.CENTER);
setTitle("Options"); setTitle("Options");
setModalityType(Dialog.ModalityType.APPLICATION_MODAL); setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
@@ -462,6 +456,7 @@ public class Options extends JDialog {
defaultPrefs.put("catenation.post-paragraph", "2000"); defaultPrefs.put("catenation.post-paragraph", "2000");
defaultPrefs.put("path.storage", (new File(System.getProperty("user.home"), "Recordings")).toString()); defaultPrefs.put("path.storage", (new File(System.getProperty("user.home"), "Recordings")).toString());
defaultPrefs.put("path.archive", (new File(new File(System.getProperty("user.home"), "Recordings"),"archive")).toString());
defaultPrefs.put("path.ffmpeg", ""); defaultPrefs.put("path.ffmpeg", "");
defaultPrefs.put("audio.export.bitrate", "256000"); defaultPrefs.put("audio.export.bitrate", "256000");
@@ -598,6 +593,7 @@ public class Options extends JDialog {
set("audio.recording.trim", ((KVPair)trimMethod.getSelectedItem()).key); set("audio.recording.trim", ((KVPair)trimMethod.getSelectedItem()).key);
set("audio.playback.device", ((KVPair)playbackList.getSelectedItem()).key); set("audio.playback.device", ((KVPair)playbackList.getSelectedItem()).key);
set("path.storage", storageFolder.getText()); set("path.storage", storageFolder.getText());
set("path.archive", archiveFolder.getText());
set("path.ffmpeg", ffmpegLocation.getText()); set("path.ffmpeg", ffmpegLocation.getText());
set("catenation.pre-chapter", preChapterGap.getValue()); set("catenation.pre-chapter", preChapterGap.getValue());
set("catenation.post-chapter", postChapterGap.getValue()); set("catenation.post-chapter", postChapterGap.getValue());

View File

@@ -32,6 +32,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
boolean recording; boolean recording;
boolean inSample; boolean inSample;
boolean attention = false;
TargetDataLine line; TargetDataLine line;
AudioInputStream inputStream; AudioInputStream inputStream;
@@ -579,30 +580,23 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
setText("[recognising...]"); setText("[recognising...]");
AudiobookRecorder.window.bookTreeModel.reload(this); AudiobookRecorder.window.bookTreeModel.reload(this);
AudioInputStream s = AudioSystem.getAudioInputStream(getFile());
AudioFormat format = getAudioFormat(); AudioFormat format = getAudioFormat();
int frameSize = format.getFrameSize(); byte[] inData = getRawAudioData();
int length = (int)s.getFrameLength(); int inLength = inData.length;
byte[] data = new byte[length * frameSize]; int bps = format.getFrameSize();
int inSamples = inLength / bps;
s.read(data); int outSamples = inSamples / 4;
byte[] outData = new byte[outSamples * bps];
int channels = format.getChannels(); for (int i = 0; i < outSamples; i++) {
int newLen = (length / 3); for (int j = 0; j < bps; j++) {
byte[] decimated = new byte[newLen * 2]; outData[i * bps + j] = inData[(i * 4) * bps + j];
for (int i = 0; i < newLen; i++) {
if (channels == 1) {
decimated[i * 2] = data[i * 6];
decimated[i * 2 + 1] = data[i * 6 + 1];
} else {
decimated[i * 2] = data[i * 12];
decimated[i * 2 + 1] = data[i * 12 + 1];
} }
} }
ByteArrayInputStream bas = new ByteArrayInputStream(decimated); ByteArrayInputStream bas = new ByteArrayInputStream(outData);
recognizer.startRecognition(bas); recognizer.startRecognition(bas);
SpeechResult result; SpeechResult result;
String res = ""; String res = "";
@@ -633,7 +627,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
AudioInputStream s = AudioSystem.getAudioInputStream(getFile()); AudioInputStream s = AudioSystem.getAudioInputStream(getFile());
AudioFormat format = getAudioFormat(); AudioFormat format = getAudioFormat();
sphinxConfig.setSampleRate((int)(format.getSampleRate() / 3f)); sphinxConfig.setSampleRate((int)(format.getSampleRate() / 4f));
StreamSpeechRecognizer recognizer; StreamSpeechRecognizer recognizer;
@@ -739,4 +733,12 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
sentence.updateCrossings(); sentence.updateCrossings();
return sentence; return sentence;
} }
public void setAttentionFlag(boolean f) {
attention = f;
}
public boolean getAttentionFlag() {
return attention;
}
} }

View File

@@ -8,6 +8,7 @@ import java.awt.image.*;
import javax.swing.border.*; import javax.swing.border.*;
import java.util.*; import java.util.*;
import java.io.*; import java.io.*;
import java.net.*;
public class Utils { public class Utils {
public static Image getScaledImage(Image srcImg, int w, int h){ public static Image getScaledImage(Image srcImg, int w, int h){
@@ -46,4 +47,12 @@ public class Utils {
return 0.0f; return 0.0f;
} }
public static void browse(String url) {
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (Exception ex) {
}
}
}
} }