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 del = new JMenuObject("Delete phrase", s);
|
||||
JMenuObject dup = new JMenuObject("Duplicate phrase", s);
|
||||
|
||||
|
||||
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() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JMenuObject o = (JMenuObject)e.getSource();
|
||||
@@ -740,6 +756,8 @@ public class AudiobookRecorder extends JFrame {
|
||||
menu.addSeparator();
|
||||
menu.add(ins);
|
||||
menu.add(del);
|
||||
menu.addSeparator();
|
||||
menu.add(dup);
|
||||
menu.show(bookTree, e.getX(), e.getY());
|
||||
} else if (node instanceof Chapter) {
|
||||
Chapter c = (Chapter)node;
|
||||
@@ -1542,21 +1560,52 @@ public class AudiobookRecorder extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void playSelectedSentence() {
|
||||
if (selectedSentence == null) return;
|
||||
|
||||
if (playing != null) return;
|
||||
|
||||
if (getNoiseFloor() == 0) {
|
||||
alertNoRoomNoise();
|
||||
return;
|
||||
}
|
||||
playing = selectedSentence;
|
||||
|
||||
toolBar.disableSentence();
|
||||
toolBar.enableStop();
|
||||
|
||||
|
||||
playingThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
playing.play();
|
||||
playing = null;
|
||||
Sentence s = playing;
|
||||
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.disableStop();
|
||||
}
|
||||
@@ -1564,7 +1613,6 @@ public class AudiobookRecorder extends JFrame {
|
||||
|
||||
playingThread.setDaemon(true);
|
||||
playingThread.start();
|
||||
|
||||
}
|
||||
|
||||
class ExportThread implements Runnable {
|
||||
@@ -1726,9 +1774,6 @@ public class AudiobookRecorder extends JFrame {
|
||||
play = null;
|
||||
}
|
||||
playing = null;
|
||||
if (selectedSentence != null) {
|
||||
selectedSentence.stopPlaying();
|
||||
}
|
||||
}
|
||||
|
||||
public void alertNoRoomNoise() {
|
||||
@@ -1872,7 +1917,6 @@ public class AudiobookRecorder extends JFrame {
|
||||
|
||||
public void mergeChapter(Properties prefs, String chid) {
|
||||
Chapter c = book.addChapter();
|
||||
System.err.println("Added chapter " + c.getId());
|
||||
c.setName("Merged-" + prefs.getProperty("chapter." + chid + ".name"));
|
||||
c.setPostGap(Utils.s2i(prefs.getProperty("chapter." + chid + ".post-gap")));
|
||||
c.setPreGap(Utils.s2i(prefs.getProperty("chapter." + chid + ".pre-gap")));
|
||||
|
||||
@@ -23,6 +23,7 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
||||
if (s.isInSample()) {
|
||||
ret.setIcon(Icons.star);
|
||||
}
|
||||
|
||||
} else if (value instanceof Chapter) {
|
||||
ret.setIcon(Icons.chapter);
|
||||
} else if (value instanceof Book) {
|
||||
|
||||
@@ -200,4 +200,18 @@ public class Chapter extends DefaultMutableTreeNode {
|
||||
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 recording;
|
||||
boolean playing;
|
||||
|
||||
boolean inSample;
|
||||
|
||||
TargetDataLine line;
|
||||
AudioInputStream inputStream;
|
||||
AudioFormat storedFormat = null;
|
||||
double storedLength = -1d;
|
||||
|
||||
int[] storedAudioData = null;
|
||||
|
||||
@@ -148,6 +149,8 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
}
|
||||
|
||||
storedAudioData = null;
|
||||
storedFormat = null;
|
||||
storedLength = -1;
|
||||
|
||||
if (!id.equals("room-noise")) {
|
||||
String tm = Options.get("audio.recording.trim");
|
||||
@@ -421,7 +424,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
File f = getFile();
|
||||
try {
|
||||
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
||||
AudioFormat format = s.getFormat();
|
||||
AudioFormat format = getAudioFormat();
|
||||
|
||||
int[] samples = null;
|
||||
|
||||
@@ -503,7 +506,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
try {
|
||||
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
||||
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
||||
AudioFormat format = eq.getFormat();
|
||||
AudioFormat format = getAudioFormat();
|
||||
IIRControls controls = eq.getControls();
|
||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
||||
|
||||
@@ -519,63 +522,20 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
}
|
||||
|
||||
public AudioFormat getAudioFormat() {
|
||||
if (storedFormat != null) return storedFormat;
|
||||
|
||||
File f = getFile();
|
||||
try {
|
||||
AudioInputStream s = AudioSystem.getAudioInputStream(f);
|
||||
AudioFormat format = s.getFormat();
|
||||
return format;
|
||||
storedFormat = s.getFormat();
|
||||
s.close();
|
||||
return storedFormat;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
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() {
|
||||
File f = getFile();
|
||||
try {
|
||||
@@ -584,7 +544,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
||||
|
||||
|
||||
AudioFormat format = eq.getFormat();
|
||||
AudioFormat format = getAudioFormat();
|
||||
IIRControls controls = eq.getControls();
|
||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
||||
|
||||
@@ -634,7 +594,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
recognizer = new StreamSpeechRecognizer(sphinxConfig);
|
||||
|
||||
AudioInputStream s = AudioSystem.getAudioInputStream(getFile());
|
||||
AudioFormat format = s.getFormat();
|
||||
AudioFormat format = getAudioFormat();
|
||||
int frameSize = format.getFrameSize();
|
||||
int length = (int)s.getFrameLength();
|
||||
byte[] data = new byte[length * frameSize];
|
||||
@@ -742,4 +702,32 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
}
|
||||
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