Added duplicate sentence and moved all playing out of Sentence and into main program
This commit is contained in:
@@ -693,6 +693,7 @@ public class AudiobookRecorder extends JFrame {
|
|||||||
|
|
||||||
JMenuObject ins = new JMenuObject("Insert phrase above", s);
|
JMenuObject ins = new JMenuObject("Insert phrase above", s);
|
||||||
JMenuObject del = new JMenuObject("Delete phrase", s);
|
JMenuObject del = new JMenuObject("Delete phrase", s);
|
||||||
|
JMenuObject dup = new JMenuObject("Duplicate phrase", s);
|
||||||
|
|
||||||
|
|
||||||
ins.addActionListener(new ActionListener() {
|
ins.addActionListener(new ActionListener() {
|
||||||
@@ -718,6 +719,21 @@ public class AudiobookRecorder extends JFrame {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dup.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
try {
|
||||||
|
JMenuObject o = (JMenuObject)e.getSource();
|
||||||
|
Sentence s = (Sentence)o.getObject();
|
||||||
|
Sentence newSentence = s.cloneSentence();
|
||||||
|
Chapter c = (Chapter)s.getParent();
|
||||||
|
int idx = bookTreeModel.getIndexOfChild(c, s);
|
||||||
|
bookTreeModel.insertNodeInto(newSentence, c, idx);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
rec.addActionListener(new ActionListener() {
|
rec.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
JMenuObject o = (JMenuObject)e.getSource();
|
JMenuObject o = (JMenuObject)e.getSource();
|
||||||
@@ -740,6 +756,8 @@ public class AudiobookRecorder extends JFrame {
|
|||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
menu.add(ins);
|
menu.add(ins);
|
||||||
menu.add(del);
|
menu.add(del);
|
||||||
|
menu.addSeparator();
|
||||||
|
menu.add(dup);
|
||||||
menu.show(bookTree, e.getX(), e.getY());
|
menu.show(bookTree, e.getX(), e.getY());
|
||||||
} else if (node instanceof Chapter) {
|
} else if (node instanceof Chapter) {
|
||||||
Chapter c = (Chapter)node;
|
Chapter c = (Chapter)node;
|
||||||
@@ -1542,21 +1560,52 @@ public class AudiobookRecorder extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void playSelectedSentence() {
|
public void playSelectedSentence() {
|
||||||
if (selectedSentence == null) return;
|
if (selectedSentence == null) return;
|
||||||
|
|
||||||
if (playing != null) return;
|
if (playing != null) return;
|
||||||
|
if (getNoiseFloor() == 0) {
|
||||||
|
alertNoRoomNoise();
|
||||||
|
return;
|
||||||
|
}
|
||||||
playing = selectedSentence;
|
playing = selectedSentence;
|
||||||
|
|
||||||
toolBar.disableSentence();
|
toolBar.disableSentence();
|
||||||
toolBar.enableStop();
|
toolBar.enableStop();
|
||||||
|
|
||||||
|
|
||||||
playingThread = new Thread(new Runnable() {
|
playingThread = new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
playing.play();
|
Sentence s = playing;
|
||||||
playing = null;
|
byte[] data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
AudioFormat format = s.getAudioFormat();
|
||||||
|
play = AudioSystem.getSourceDataLine(format, Options.getPlaybackMixer());
|
||||||
|
play.open(format);
|
||||||
|
play.start();
|
||||||
|
|
||||||
|
bookTree.scrollPathToVisible(new TreePath(s.getPath()));
|
||||||
|
data = s.getRawAudioData();
|
||||||
|
for (int pos = 0; pos < data.length; pos += 1024) {
|
||||||
|
sampleWaveform.setPlayMarker(pos / format.getFrameSize());
|
||||||
|
int l = data.length - pos;
|
||||||
|
if (l > 1024) l = 1024;
|
||||||
|
play.write(data, pos, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
play.drain();
|
||||||
|
play.stop();
|
||||||
|
play.close();
|
||||||
|
play = null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
playing = null;
|
||||||
|
if (play != null) {
|
||||||
|
play.drain();
|
||||||
|
play.stop();
|
||||||
|
play.close();
|
||||||
|
}
|
||||||
|
play = null;
|
||||||
|
}
|
||||||
toolBar.enableSentence();
|
toolBar.enableSentence();
|
||||||
toolBar.disableStop();
|
toolBar.disableStop();
|
||||||
}
|
}
|
||||||
@@ -1564,7 +1613,6 @@ public class AudiobookRecorder extends JFrame {
|
|||||||
|
|
||||||
playingThread.setDaemon(true);
|
playingThread.setDaemon(true);
|
||||||
playingThread.start();
|
playingThread.start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExportThread implements Runnable {
|
class ExportThread implements Runnable {
|
||||||
@@ -1726,9 +1774,6 @@ public class AudiobookRecorder extends JFrame {
|
|||||||
play = null;
|
play = null;
|
||||||
}
|
}
|
||||||
playing = null;
|
playing = null;
|
||||||
if (selectedSentence != null) {
|
|
||||||
selectedSentence.stopPlaying();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void alertNoRoomNoise() {
|
public void alertNoRoomNoise() {
|
||||||
@@ -1872,7 +1917,6 @@ public class AudiobookRecorder extends JFrame {
|
|||||||
|
|
||||||
public void mergeChapter(Properties prefs, String chid) {
|
public void mergeChapter(Properties prefs, String chid) {
|
||||||
Chapter c = book.addChapter();
|
Chapter c = book.addChapter();
|
||||||
System.err.println("Added chapter " + c.getId());
|
|
||||||
c.setName("Merged-" + prefs.getProperty("chapter." + chid + ".name"));
|
c.setName("Merged-" + prefs.getProperty("chapter." + chid + ".name"));
|
||||||
c.setPostGap(Utils.s2i(prefs.getProperty("chapter." + chid + ".post-gap")));
|
c.setPostGap(Utils.s2i(prefs.getProperty("chapter." + chid + ".post-gap")));
|
||||||
c.setPreGap(Utils.s2i(prefs.getProperty("chapter." + chid + ".pre-gap")));
|
c.setPreGap(Utils.s2i(prefs.getProperty("chapter." + chid + ".pre-gap")));
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
|||||||
if (s.isInSample()) {
|
if (s.isInSample()) {
|
||||||
ret.setIcon(Icons.star);
|
ret.setIcon(Icons.star);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (value instanceof Chapter) {
|
} else if (value instanceof Chapter) {
|
||||||
ret.setIcon(Icons.chapter);
|
ret.setIcon(Icons.chapter);
|
||||||
} else if (value instanceof Book) {
|
} else if (value instanceof Book) {
|
||||||
|
|||||||
@@ -200,4 +200,18 @@ public class Chapter extends DefaultMutableTreeNode {
|
|||||||
wavFile.delete();
|
wavFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getChapterLength() {
|
||||||
|
double totalTime = Options.getInteger("audio.recording.pre-chapter") / 1000d;
|
||||||
|
for (Enumeration s = children(); s.hasMoreElements();) {
|
||||||
|
Sentence sentence = (Sentence)s.nextElement();
|
||||||
|
totalTime += sentence.getLength();
|
||||||
|
if (s.hasMoreElements()) {
|
||||||
|
totalTime += (sentence.getPostGap() / 1000d);
|
||||||
|
} else {
|
||||||
|
totalTime += Options.getInteger("audio.recording.post-chapter") / 1000d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,13 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
boolean locked;
|
boolean locked;
|
||||||
|
|
||||||
boolean recording;
|
boolean recording;
|
||||||
boolean playing;
|
|
||||||
|
|
||||||
boolean inSample;
|
boolean inSample;
|
||||||
|
|
||||||
TargetDataLine line;
|
TargetDataLine line;
|
||||||
AudioInputStream inputStream;
|
AudioInputStream inputStream;
|
||||||
|
AudioFormat storedFormat = null;
|
||||||
|
double storedLength = -1d;
|
||||||
|
|
||||||
int[] storedAudioData = null;
|
int[] storedAudioData = null;
|
||||||
|
|
||||||
@@ -148,6 +149,8 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
storedAudioData = null;
|
storedAudioData = null;
|
||||||
|
storedFormat = null;
|
||||||
|
storedLength = -1;
|
||||||
|
|
||||||
if (!id.equals("room-noise")) {
|
if (!id.equals("room-noise")) {
|
||||||
String tm = Options.get("audio.recording.trim");
|
String tm = Options.get("audio.recording.trim");
|
||||||
@@ -421,7 +424,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
File f = getFile();
|
File f = getFile();
|
||||||
try {
|
try {
|
||||||
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
||||||
AudioFormat format = s.getFormat();
|
AudioFormat format = getAudioFormat();
|
||||||
|
|
||||||
int[] samples = null;
|
int[] samples = null;
|
||||||
|
|
||||||
@@ -503,7 +506,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
try {
|
try {
|
||||||
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
||||||
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
||||||
AudioFormat format = eq.getFormat();
|
AudioFormat format = getAudioFormat();
|
||||||
IIRControls controls = eq.getControls();
|
IIRControls controls = eq.getControls();
|
||||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
||||||
|
|
||||||
@@ -519,63 +522,20 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AudioFormat getAudioFormat() {
|
public AudioFormat getAudioFormat() {
|
||||||
|
if (storedFormat != null) return storedFormat;
|
||||||
|
|
||||||
File f = getFile();
|
File f = getFile();
|
||||||
try {
|
try {
|
||||||
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
||||||
AudioFormat format = s.getFormat();
|
storedFormat = s.getFormat();
|
||||||
return format;
|
s.close();
|
||||||
|
return storedFormat;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void play() {
|
|
||||||
File f = getFile();
|
|
||||||
try {
|
|
||||||
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
|
||||||
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
|
||||||
|
|
||||||
AudioFormat format = eq.getFormat();
|
|
||||||
|
|
||||||
IIRControls controls = eq.getControls();
|
|
||||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
|
||||||
|
|
||||||
int frameSize = format.getFrameSize();
|
|
||||||
|
|
||||||
updateCrossings();
|
|
||||||
|
|
||||||
int pos = crossStartOffset * frameSize;
|
|
||||||
|
|
||||||
SourceDataLine play = AudioSystem.getSourceDataLine(format, Options.getPlaybackMixer());
|
|
||||||
play.open(format);
|
|
||||||
|
|
||||||
play.start();
|
|
||||||
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
|
|
||||||
eq.skip(pos);
|
|
||||||
|
|
||||||
playing = true;
|
|
||||||
while ((pos < crossEndOffset * frameSize) && playing) {
|
|
||||||
AudiobookRecorder.window.sampleWaveform.setPlayMarker((pos - crossStartOffset) / frameSize);
|
|
||||||
int nr = eq.read(buffer);
|
|
||||||
pos += nr;
|
|
||||||
|
|
||||||
|
|
||||||
play.write(buffer, 0, nr);
|
|
||||||
};
|
|
||||||
play.drain();
|
|
||||||
play.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopPlaying() {
|
|
||||||
playing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getRawAudioData() {
|
public byte[] getRawAudioData() {
|
||||||
File f = getFile();
|
File f = getFile();
|
||||||
try {
|
try {
|
||||||
@@ -584,7 +544,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
||||||
|
|
||||||
|
|
||||||
AudioFormat format = eq.getFormat();
|
AudioFormat format = getAudioFormat();
|
||||||
IIRControls controls = eq.getControls();
|
IIRControls controls = eq.getControls();
|
||||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
||||||
|
|
||||||
@@ -634,7 +594,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
recognizer = new StreamSpeechRecognizer(sphinxConfig);
|
recognizer = new StreamSpeechRecognizer(sphinxConfig);
|
||||||
|
|
||||||
AudioInputStream s = AudioSystem.getAudioInputStream(getFile());
|
AudioInputStream s = AudioSystem.getAudioInputStream(getFile());
|
||||||
AudioFormat format = s.getFormat();
|
AudioFormat format = getAudioFormat();
|
||||||
int frameSize = format.getFrameSize();
|
int frameSize = format.getFrameSize();
|
||||||
int length = (int)s.getFrameLength();
|
int length = (int)s.getFrameLength();
|
||||||
byte[] data = new byte[length * frameSize];
|
byte[] data = new byte[length * frameSize];
|
||||||
@@ -742,4 +702,32 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
|||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the length of the sample in seconds */
|
||||||
|
public double getLength() {
|
||||||
|
if (storedLength > -1d) return storedLength;
|
||||||
|
AudioFormat format = getAudioFormat();
|
||||||
|
float sampleFrequency = format.getFrameRate();
|
||||||
|
int length = crossEndOffset - crossStartOffset;
|
||||||
|
double time = (double)length / (double)sampleFrequency;
|
||||||
|
storedLength = time;
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Sentence cloneSentence() throws IOException {
|
||||||
|
Sentence sentence = new Sentence();
|
||||||
|
sentence.setPostGap(getPostGap());
|
||||||
|
if (!id.equals(text)) {
|
||||||
|
sentence.setText(text);
|
||||||
|
}
|
||||||
|
sentence.setStartOffset(getStartOffset());
|
||||||
|
sentence.setEndOffset(getEndOffset());
|
||||||
|
|
||||||
|
File from = getFile();
|
||||||
|
File to = sentence.getFile();
|
||||||
|
Files.copy(from.toPath(), to.toPath());
|
||||||
|
|
||||||
|
sentence.updateCrossings();
|
||||||
|
return sentence;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user