Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c34f909b21 | |||
| 955227e9e3 | |||
| e626da0c5e | |||
| 6adb22b9ac |
@@ -35,3 +35,4 @@ Third party software
|
||||
* JAVE ffmpeg wrapper: http://www.sauronsoftware.it/projects/jave/
|
||||
* JTattoo: http://www.sauronsoftware.it/projects/jave/
|
||||
* Icons from, or based on, Oxygen: https://github.com/KDE/oxygen-icons
|
||||
* JEQ, the Java Equaliser: https://sourceforge.net/projects/jeq/
|
||||
|
||||
@@ -1 +1 @@
|
||||
version=0.0.7
|
||||
version=0.0.8
|
||||
|
||||
BIN
resources/uk/co/majenko/audiobookrecorder/icons/eq.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/eq.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 817 B |
BIN
resources/uk/co/majenko/audiobookrecorder/icons/mic.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/mic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 588 B |
@@ -48,6 +48,8 @@ public class AudiobookRecorder extends JFrame {
|
||||
|
||||
JScrollPane mainScroll;
|
||||
|
||||
JDialog equaliserWindow = null;
|
||||
|
||||
Book book = null;
|
||||
|
||||
JTree bookTree;
|
||||
@@ -83,7 +85,10 @@ public class AudiobookRecorder extends JFrame {
|
||||
|
||||
Random rng = new Random();
|
||||
|
||||
SourceDataLine play;
|
||||
SourceDataLine play = null;
|
||||
|
||||
public TargetDataLine microphone = null;
|
||||
public AudioInputStream microphoneStream = null;
|
||||
|
||||
public Configuration sphinxConfig;
|
||||
public StreamSpeechRecognizer recognizer;
|
||||
@@ -225,6 +230,9 @@ public class AudiobookRecorder extends JFrame {
|
||||
|
||||
|
||||
Options.loadPreferences();
|
||||
|
||||
execScript(Options.get("scripts.startup"));
|
||||
|
||||
CacheManager.setCacheSize(Options.getInteger("cache.size"));
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
@@ -949,6 +957,11 @@ public class AudiobookRecorder extends JFrame {
|
||||
if (recording != null) return;
|
||||
if (book == null) return;
|
||||
|
||||
if (microphone == null) {
|
||||
JOptionPane.showMessageDialog(this, "Microphone not started. Start microphone first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
toolBar.disableBook();
|
||||
toolBar.disableSentence();
|
||||
|
||||
@@ -977,6 +990,11 @@ public class AudiobookRecorder extends JFrame {
|
||||
if (recording != null) return;
|
||||
if (book == null) return;
|
||||
|
||||
if (microphone == null) {
|
||||
JOptionPane.showMessageDialog(this, "Microphone not started. Start microphone first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
toolBar.disableBook();
|
||||
toolBar.disableSentence();
|
||||
|
||||
@@ -1024,6 +1042,11 @@ public class AudiobookRecorder extends JFrame {
|
||||
if (recording != null) return;
|
||||
if (book == null) return;
|
||||
|
||||
if (microphone == null) {
|
||||
JOptionPane.showMessageDialog(this, "Microphone not started. Start microphone first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
toolBar.disableBook();
|
||||
toolBar.disableSentence();
|
||||
|
||||
@@ -1147,6 +1170,10 @@ public class AudiobookRecorder extends JFrame {
|
||||
prefs.setProperty("book.genre", book.getGenre());
|
||||
prefs.setProperty("book.comment", book.getComment());
|
||||
|
||||
for (int i = 0; i < 31; i++) {
|
||||
prefs.setProperty("audio.eq." + i, String.format("%.3f", book.equaliser.getChannel(i)));
|
||||
}
|
||||
|
||||
for (Enumeration<Chapter> o = book.children(); o.hasMoreElements();) {
|
||||
|
||||
Chapter c = o.nextElement();
|
||||
@@ -1212,6 +1239,14 @@ public class AudiobookRecorder extends JFrame {
|
||||
book.setGenre(prefs.getProperty("book.genre"));
|
||||
book.setComment(prefs.getProperty("book.comment"));
|
||||
|
||||
for (int i = 0; i < 31; i++) {
|
||||
if (prefs.getProperty("audio.eq." + i) == null) {
|
||||
book.equaliser.setChannel(i, Options.getFloat("audio.eq." + i));
|
||||
} else {
|
||||
book.equaliser.setChannel(i, Utils.s2f(prefs.getProperty("audio.eq." + i)));
|
||||
}
|
||||
}
|
||||
|
||||
bookTreeModel = new DefaultTreeModel(book);
|
||||
bookTree = new JTree(bookTreeModel);
|
||||
bookTree.setEditable(true);
|
||||
@@ -1632,4 +1667,78 @@ public class AudiobookRecorder extends JFrame {
|
||||
public void alertNoRoomNoise() {
|
||||
JOptionPane.showMessageDialog(this, "You must record room noise\nbefore recording or playback", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
public void showEqualiser() {
|
||||
if (equaliserWindow == null) {
|
||||
equaliserWindow = new JDialog();
|
||||
equaliserWindow.setTitle("Equaliser");
|
||||
equaliserWindow.add(book.equaliser);
|
||||
equaliserWindow.pack();
|
||||
}
|
||||
equaliserWindow.setVisible(true);
|
||||
}
|
||||
|
||||
public boolean enableMicrophone() {
|
||||
AudioFormat format = new AudioFormat(
|
||||
Options.getInteger("audio.recording.samplerate"),
|
||||
16,
|
||||
Options.getInteger("audio.recording.channels"),
|
||||
true,
|
||||
false
|
||||
);
|
||||
|
||||
Mixer.Info mixer = Options.getRecordingMixer();
|
||||
|
||||
microphone = null;
|
||||
|
||||
try {
|
||||
microphone = AudioSystem.getTargetDataLine(format, mixer);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
microphone = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (microphone == null) {
|
||||
JOptionPane.showMessageDialog(AudiobookRecorder.window, "Sample format not supported", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
microphoneStream = new AudioInputStream(microphone);
|
||||
|
||||
try {
|
||||
microphone.open();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
microphone = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
microphone.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void disableMicrophone() {
|
||||
try {
|
||||
microphoneStream.close();
|
||||
microphone.stop();
|
||||
microphone.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void execScript(String s) {
|
||||
if (s == null) return;
|
||||
String[] lines = s.split("\n");
|
||||
|
||||
for (String line : lines) {
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(line);
|
||||
p.waitFor();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.*;
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import javax.swing.tree.*;
|
||||
import davaguine.jeq.core.IIRControls;
|
||||
|
||||
public class Book extends DefaultMutableTreeNode {
|
||||
|
||||
@@ -18,9 +19,14 @@ public class Book extends DefaultMutableTreeNode {
|
||||
|
||||
ImageIcon icon;
|
||||
|
||||
public Equaliser equaliser;
|
||||
|
||||
float[] eqChannels = new float[31];
|
||||
|
||||
public Book(String bookname) {
|
||||
super(bookname);
|
||||
name = bookname;
|
||||
equaliser = new Equaliser();
|
||||
}
|
||||
|
||||
public void setAuthor(String a) {
|
||||
|
||||
84
src/uk/co/majenko/audiobookrecorder/Equaliser.java
Normal file
84
src/uk/co/majenko/audiobookrecorder/Equaliser.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package uk.co.majenko.audiobookrecorder;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import javax.swing.tree.*;
|
||||
import javax.sound.sampled.*;
|
||||
import davaguine.jeq.core.IIRControls;
|
||||
|
||||
public class Equaliser extends JPanel {
|
||||
|
||||
EqualiserChannel channels[];
|
||||
|
||||
|
||||
public Equaliser() {
|
||||
super();
|
||||
|
||||
channels = new EqualiserChannel[31];
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
JPanel inner = new JPanel();
|
||||
|
||||
inner.setLayout(new FlowLayout());
|
||||
|
||||
for (int i = 0; i < 31; i++) {
|
||||
channels[i] = new EqualiserChannel();
|
||||
inner.add(channels[i]);
|
||||
}
|
||||
|
||||
add(inner, BorderLayout.CENTER);
|
||||
|
||||
|
||||
JButton smooth = new JButton("Smooth curve");
|
||||
smooth.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Float ave[] = new Float[31];
|
||||
for (int i = 1; i < 30; i++) {
|
||||
ave[i] = (channels[i-1].getValue() + channels[i].getValue() + channels[i+1].getValue()) / 3.0f;
|
||||
}
|
||||
|
||||
for (int i = 1; i < 30; i++) {
|
||||
channels[i].setValue(ave[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
JButton def = new JButton("Set as default");
|
||||
def.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
for (int i = 0; i < 31; i++) {
|
||||
Options.set("audio.eq." + i, channels[i].getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JPanel buttons = new JPanel();
|
||||
buttons.setLayout(new FlowLayout());
|
||||
buttons.add(smooth);
|
||||
buttons.add(def);
|
||||
|
||||
add(buttons, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
public float getChannel(int c) {
|
||||
return channels[c].getValue();
|
||||
}
|
||||
|
||||
public void setChannel(int c, float v) {
|
||||
channels[c].setValue(v);
|
||||
}
|
||||
|
||||
public void apply(IIRControls c, int chans) {
|
||||
for (int i = 0; i < 31; i++) {
|
||||
c.setBandDbValue(i, 0, channels[i].getValue());
|
||||
if (chans == 2) {
|
||||
c.setBandDbValue(i, 1, channels[i].getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
src/uk/co/majenko/audiobookrecorder/EqualiserChannel.java
Normal file
78
src/uk/co/majenko/audiobookrecorder/EqualiserChannel.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package uk.co.majenko.audiobookrecorder;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import javax.swing.tree.*;
|
||||
import javax.sound.sampled.*;
|
||||
|
||||
public class EqualiserChannel extends JPanel {
|
||||
|
||||
float value;
|
||||
JSlider slider;
|
||||
JTextField textbox;
|
||||
|
||||
public EqualiserChannel() {
|
||||
super();
|
||||
|
||||
value = 0;
|
||||
|
||||
slider = new JSlider(-120, 120, 0);
|
||||
textbox = new JTextField();
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
slider.setOrientation(SwingConstants.VERTICAL);
|
||||
add(slider, BorderLayout.CENTER);
|
||||
textbox = new JTextField("0.0");
|
||||
add(textbox, BorderLayout.SOUTH);
|
||||
|
||||
textbox.setPreferredSize(new Dimension(40, 20));
|
||||
slider.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
value = (float)slider.getValue() / 10.0f;
|
||||
textbox.setText(String.format("%.1f", value));
|
||||
}
|
||||
});
|
||||
|
||||
textbox.addFocusListener(new FocusListener() {
|
||||
public void focusGained(FocusEvent e) {
|
||||
textbox.selectAll();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
value = Utils.s2f(textbox.getText());
|
||||
if (value < -12f) value = -12f;
|
||||
if (value > 12f) value = 12f;
|
||||
|
||||
slider.setValue((int)(value * 10));
|
||||
textbox.setText(String.format("%.1f", value));
|
||||
}
|
||||
});
|
||||
|
||||
textbox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
value = Utils.s2f(textbox.getText());
|
||||
if (value < -12f) value = -12f;
|
||||
if (value > 12f) value = 12f;
|
||||
|
||||
slider.setValue((int)(value * 10));
|
||||
textbox.setText(String.format("%.1f", value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public float getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(float v) {
|
||||
value = v;
|
||||
slider.setValue((int)(value * 10));
|
||||
textbox.setText(String.format("%.1f", value));
|
||||
}
|
||||
}
|
||||
@@ -26,5 +26,6 @@ public class Icons {
|
||||
static public final ImageIcon spinner1 = new ImageIcon(Icons.class.getResource("icons/spinner1.png"));
|
||||
static public final ImageIcon spinner2 = new ImageIcon(Icons.class.getResource("icons/spinner2.png"));
|
||||
static public final ImageIcon spinner3 = new ImageIcon(Icons.class.getResource("icons/spinner3.png"));
|
||||
|
||||
static public final ImageIcon eq = new ImageIcon(Icons.class.getResource("icons/eq.png"));
|
||||
static public final ImageIcon mic = new ImageIcon(Icons.class.getResource("icons/mic.png"));
|
||||
}
|
||||
|
||||
20
src/uk/co/majenko/audiobookrecorder/JSliderOb.java
Normal file
20
src/uk/co/majenko/audiobookrecorder/JSliderOb.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package uk.co.majenko.audiobookrecorder;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class JSliderOb extends JSlider {
|
||||
Object object;
|
||||
|
||||
public JSliderOb(int a, int b, int c) {
|
||||
super(a, b, c);
|
||||
}
|
||||
|
||||
public void setObject(Object o) {
|
||||
object = o;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
19
src/uk/co/majenko/audiobookrecorder/JTextFieldOb.java
Normal file
19
src/uk/co/majenko/audiobookrecorder/JTextFieldOb.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package uk.co.majenko.audiobookrecorder;
|
||||
import javax.swing.*;
|
||||
|
||||
public class JTextFieldOb extends JTextField {
|
||||
Object object;
|
||||
|
||||
public JTextFieldOb(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public void setObject(Object o) {
|
||||
object = o;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public class MainToolBar extends JToolBar {
|
||||
JButton playSentence;
|
||||
JButton playonSentence;
|
||||
JButton stopPlaying;
|
||||
JButton eq;
|
||||
JToggleButton mic;
|
||||
|
||||
AudiobookRecorder root;
|
||||
|
||||
@@ -99,6 +101,37 @@ public class MainToolBar extends JToolBar {
|
||||
});
|
||||
add(stopPlaying);
|
||||
|
||||
addSeparator();
|
||||
eq = new JButton(Icons.eq);
|
||||
eq.setToolTipText("Equaliser");
|
||||
eq.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
root.showEqualiser();
|
||||
}
|
||||
});
|
||||
|
||||
add(eq);
|
||||
|
||||
addSeparator();
|
||||
|
||||
mic = new JToggleButton(Icons.mic);
|
||||
mic.setToolTipText("Enable/disable microphone");
|
||||
mic.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JToggleButton b = (JToggleButton)e.getSource();
|
||||
if (b.isSelected()) {
|
||||
if (!root.enableMicrophone()) {
|
||||
b.setSelected(false);
|
||||
}
|
||||
} else {
|
||||
root.disableMicrophone();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
add(mic);
|
||||
|
||||
|
||||
setFloatable(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,46 +30,13 @@ public class Options extends JDialog {
|
||||
JCheckBox enableParsing;
|
||||
JSpinner cacheSize;
|
||||
|
||||
JSliderOb[] sliders;
|
||||
JTextFieldOb[] eqvals;
|
||||
Equaliser equaliser;
|
||||
|
||||
JTextArea startupScript;
|
||||
|
||||
static HashMap<String, String> defaultPrefs;
|
||||
static Preferences prefs = null;
|
||||
|
||||
static class JSliderOb extends JSlider {
|
||||
Object object;
|
||||
|
||||
public JSliderOb(int a, int b, int c) {
|
||||
super(a, b, c);
|
||||
}
|
||||
|
||||
public void setObject(Object o) {
|
||||
object = o;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
public class JTextFieldOb extends JTextField {
|
||||
Object object;
|
||||
|
||||
public JTextFieldOb(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public void setObject(Object o) {
|
||||
object = o;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class KVPair implements Comparable {
|
||||
public String key;
|
||||
public String value;
|
||||
@@ -311,81 +278,25 @@ public class Options extends JDialog {
|
||||
|
||||
tabs.add("Options", optionsPanel);
|
||||
|
||||
|
||||
|
||||
JPanel eqPanel = new JPanel();
|
||||
|
||||
eqPanel.setLayout(new GridBagLayout());
|
||||
|
||||
constraint.gridx = 0;
|
||||
constraint.gridy = 0;
|
||||
|
||||
sliders = new JSliderOb[31];
|
||||
eqvals = new JTextFieldOb[31];
|
||||
equaliser = new Equaliser();
|
||||
|
||||
for (int i = 0; i < 31; i++) {
|
||||
sliders[i] = new JSliderOb(-120, 120, (int)(Options.getFloat("audio.eq." + i) * 10));
|
||||
sliders[i].setOrientation(SwingConstants.VERTICAL);
|
||||
constraint.gridx = i;
|
||||
constraint.gridy = 0;
|
||||
eqPanel.add(sliders[i], constraint);
|
||||
eqvals[i] = new JTextFieldOb(String.format("%.1f", Options.getFloat("audio.eq." + i)));
|
||||
constraint.gridy = 1;
|
||||
eqPanel.add(eqvals[i], constraint);
|
||||
|
||||
sliders[i].setObject(eqvals[i]);
|
||||
eqvals[i].setObject(sliders[i]);
|
||||
|
||||
eqvals[i].setPreferredSize(new Dimension(40, 20));
|
||||
|
||||
sliders[i].addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
JSliderOb o = (JSliderOb)e.getSource();
|
||||
String v = String.format("%.1f", (float)o.getValue() / 10.0f);
|
||||
JTextFieldOb tf = (JTextFieldOb)o.getObject();
|
||||
tf.setText(v);
|
||||
}
|
||||
});
|
||||
|
||||
eqvals[i].addFocusListener(new FocusListener() {
|
||||
public void focusGained(FocusEvent e) {
|
||||
JTextFieldOb o = (JTextFieldOb)e.getSource();
|
||||
o.selectAll();
|
||||
equaliser.setChannel(i, Options.getFloat("audio.eq." + i));
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
JTextFieldOb o = (JTextFieldOb)e.getSource();
|
||||
String v = o.getText();
|
||||
float f = Utils.s2f(v);
|
||||
if (f < -12f) f = -12f;
|
||||
if (f > 12f) f = 12f;
|
||||
JSliderOb s = (JSliderOb)o.getObject();
|
||||
s.setValue((int)(f * 10));
|
||||
o.setText(String.format("%.1f", f));
|
||||
}
|
||||
});
|
||||
tabs.add("Default EQ", equaliser);
|
||||
|
||||
eqvals[i].addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JTextFieldOb o = (JTextFieldOb)e.getSource();
|
||||
String v = o.getText();
|
||||
float f = Utils.s2f(v);
|
||||
if (f < -12f) f = -12f;
|
||||
if (f > 12f) f = 12f;
|
||||
JSliderOb s = (JSliderOb)o.getObject();
|
||||
s.setValue((int)(f * 10));
|
||||
o.setText(String.format("%.1f", f));
|
||||
o.selectAll();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
tabs.add("EQ", eqPanel);
|
||||
JPanel startScript = new JPanel();
|
||||
startScript.setLayout(new BorderLayout());
|
||||
startupScript = new JTextArea(get("scripts.startup"));
|
||||
startScript.add(startupScript, BorderLayout.CENTER);
|
||||
|
||||
tabs.add("Startup Script", startScript);
|
||||
|
||||
add(tabs, BorderLayout.CENTER);
|
||||
|
||||
|
||||
|
||||
setTitle("Options");
|
||||
|
||||
setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
|
||||
@@ -582,6 +493,8 @@ public class Options extends JDialog {
|
||||
defaultPrefs.put("audio.eq.29", "-11.00");
|
||||
defaultPrefs.put("audio.eq.30", "-12.00");
|
||||
|
||||
defaultPrefs.put("scripts.startup", "");
|
||||
|
||||
if (prefs == null) {
|
||||
prefs = Preferences.userNodeForPackage(AudiobookRecorder.class);
|
||||
}
|
||||
@@ -684,9 +597,11 @@ public class Options extends JDialog {
|
||||
set("cache.size", cacheSize.getValue());
|
||||
|
||||
for (int i = 0; i < 31; i++) {
|
||||
set("audio.eq." + i, eqvals[i].getText());
|
||||
set("audio.eq." + i, equaliser.getChannel(i));
|
||||
}
|
||||
|
||||
set("scripts.startup", startupScript.getText());
|
||||
|
||||
savePreferences();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,75 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
TargetDataLine line;
|
||||
AudioInputStream inputStream;
|
||||
|
||||
Thread recordingThread = null;
|
||||
|
||||
int[] storedAudioData = null;
|
||||
|
||||
RecordingThread recordingThread;
|
||||
|
||||
static class RecordingThread implements Runnable {
|
||||
|
||||
boolean running = false;
|
||||
boolean recording = false;
|
||||
|
||||
File tempFile;
|
||||
File wavFile;
|
||||
|
||||
AudioFormat format;
|
||||
|
||||
public RecordingThread(File tf, File wf, AudioFormat af) {
|
||||
tempFile = tf;
|
||||
wavFile = wf;
|
||||
format = af;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
running = true;
|
||||
recording = true;
|
||||
byte[] buf = new byte[AudiobookRecorder.window.microphone.getBufferSize()];
|
||||
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||
int len = 0;
|
||||
AudiobookRecorder.window.microphone.flush();
|
||||
int nr = 0;
|
||||
while (recording) {
|
||||
nr = AudiobookRecorder.window.microphoneStream.read(buf, 0, buf.length);
|
||||
len += nr;
|
||||
fos.write(buf, 0, nr);
|
||||
}
|
||||
nr = AudiobookRecorder.window.microphoneStream.read(buf, 0, buf.length);
|
||||
len += nr;
|
||||
fos.write(buf, 0, nr);
|
||||
fos.close();
|
||||
|
||||
FileInputStream fis = new FileInputStream(tempFile);
|
||||
AudioInputStream ais = new AudioInputStream(fis, format, len / format.getFrameSize());
|
||||
fos = new FileOutputStream(wavFile);
|
||||
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, fos);
|
||||
fos.close();
|
||||
ais.close();
|
||||
fis.close();
|
||||
|
||||
tempFile.delete();
|
||||
|
||||
recording = false;
|
||||
running = false;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
running = false;
|
||||
recording = false;
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
public void stopRecording() {
|
||||
recording = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Sentence() {
|
||||
super("");
|
||||
id = UUID.randomUUID().toString();
|
||||
@@ -57,72 +122,30 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
}
|
||||
|
||||
public boolean startRecording() {
|
||||
AudioFormat format = new AudioFormat(
|
||||
Options.getInteger("audio.recording.samplerate"),
|
||||
16,
|
||||
Options.getInteger("audio.recording.channels"),
|
||||
true,
|
||||
false
|
||||
);
|
||||
|
||||
Mixer.Info mixer = Options.getRecordingMixer();
|
||||
|
||||
line = null;
|
||||
|
||||
try {
|
||||
line = AudioSystem.getTargetDataLine(format, mixer);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (line == null) {
|
||||
JOptionPane.showMessageDialog(AudiobookRecorder.window, "Sample format not supported", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
if (AudiobookRecorder.window.microphone == null) {
|
||||
JOptionPane.showMessageDialog(AudiobookRecorder.window, "Microphone not started. Start the microphone first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
inputStream = new AudioInputStream(line);
|
||||
|
||||
try {
|
||||
line.open();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
recordingThread = new RecordingThread(getTempFile(), getFile(), Options.getAudioFormat());
|
||||
|
||||
line.start();
|
||||
Thread rc = new Thread(recordingThread);
|
||||
rc.setDaemon(true);
|
||||
rc.start();
|
||||
|
||||
File audioFile = getFile();
|
||||
|
||||
recordingThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
AudioSystem.write(inputStream, AudioFileFormat.Type.WAVE, audioFile);
|
||||
} catch (Exception e) {
|
||||
inputStream = null;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
recordingThread.setDaemon(true);
|
||||
|
||||
recordingThread.start();
|
||||
|
||||
recording = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void stopRecording() {
|
||||
recordingThread.stopRecording();
|
||||
while (recordingThread.isRunning()) {
|
||||
try {
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
line.stop();
|
||||
line.close();
|
||||
line = null;
|
||||
Thread.sleep(10);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
recording = false;
|
||||
}
|
||||
|
||||
storedAudioData = null;
|
||||
|
||||
if (!id.equals("room-noise")) {
|
||||
@@ -277,6 +300,14 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
return new File(b, id + ".wav");
|
||||
}
|
||||
|
||||
public File getTempFile() {
|
||||
File b = new File(AudiobookRecorder.window.getBookFolder(), "files");
|
||||
if (!b.exists()) {
|
||||
b.mkdirs();
|
||||
}
|
||||
return new File(b, id + ".wax");
|
||||
}
|
||||
|
||||
public void editText() {
|
||||
String t = JOptionPane.showInputDialog(null, "Edit Text", text);
|
||||
|
||||
@@ -420,12 +451,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
EqualizerInputStream eq = new EqualizerInputStream(s, 31);
|
||||
AudioFormat format = eq.getFormat();
|
||||
IIRControls controls = eq.getControls();
|
||||
for (int i = 0; i < 31; i++) {
|
||||
controls.setBandDbValue(i, 0, Options.getFloat("audio.eq." + i));
|
||||
if (format.getChannels() == 2) {
|
||||
controls.setBandDbValue(i, 1, Options.getFloat("audio.eq." + i));
|
||||
}
|
||||
}
|
||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
||||
|
||||
int frameSize = format.getFrameSize();
|
||||
|
||||
@@ -459,12 +485,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
AudioFormat format = eq.getFormat();
|
||||
|
||||
IIRControls controls = eq.getControls();
|
||||
for (int i = 0; i < 31; i++) {
|
||||
controls.setBandDbValue(i, 0, Options.getFloat("audio.eq." + i));
|
||||
if (format.getChannels() == 2) {
|
||||
controls.setBandDbValue(i, 1, Options.getFloat("audio.eq." + i));
|
||||
}
|
||||
}
|
||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
||||
|
||||
int frameSize = format.getFrameSize();
|
||||
|
||||
@@ -504,12 +525,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
|
||||
|
||||
AudioFormat format = eq.getFormat();
|
||||
IIRControls controls = eq.getControls();
|
||||
for (int i = 0; i < 31; i++) {
|
||||
controls.setBandDbValue(i, 0, Options.getFloat("audio.eq." + i));
|
||||
if (format.getChannels() == 2) {
|
||||
controls.setBandDbValue(i, 1, Options.getFloat("audio.eq." + i));
|
||||
}
|
||||
}
|
||||
AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels());
|
||||
|
||||
int frameSize = format.getFrameSize();
|
||||
int length = crossEndOffset - crossStartOffset;
|
||||
|
||||
Reference in New Issue
Block a user