Compare commits

...

8 Commits

7 changed files with 166 additions and 33 deletions

View File

@@ -1 +1 @@
version=0.1.8 version=0.1.9

View File

@@ -31,23 +31,23 @@ public class AGC implements Effect {
double absSampleLeft = Math.abs(samples[i][Sentence.LEFT]) * gain; double absSampleLeft = Math.abs(samples[i][Sentence.LEFT]) * gain;
double absSampleRight = Math.abs(samples[i][Sentence.RIGHT]) * gain; double absSampleRight = Math.abs(samples[i][Sentence.RIGHT]) * gain;
double factor = 0.0d;
if (absSampleLeft > ceiling) { if (absSampleLeft > ceiling) {
gain -= attack; factor = -attack;
if (gain < 0) gain = 0;
} }
if (absSampleRight > ceiling) { if (absSampleRight > ceiling) {
gain -= attack; factor = -attack;
if (gain < 0) gain = 0;
} }
if ((absSampleLeft < ceiling) && (absSampleRight < ceiling)) { if ((absSampleLeft < ceiling) && (absSampleRight < ceiling)) {
gain += decay; factor = decay;
if (gain > limit) {
gain = limit;
}
} }
gain += factor;
if (gain > limit) gain = limit;
samples[i][Sentence.LEFT] *= gain; samples[i][Sentence.LEFT] *= gain;
samples[i][Sentence.RIGHT] *= gain; samples[i][Sentence.RIGHT] *= gain;
} }

View File

@@ -24,6 +24,7 @@ import edu.cmu.sphinx.api.*;
import edu.cmu.sphinx.decoder.adaptation.*; import edu.cmu.sphinx.decoder.adaptation.*;
import edu.cmu.sphinx.result.*; import edu.cmu.sphinx.result.*;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import java.util.concurrent.*;
public class AudiobookRecorder extends JFrame { public class AudiobookRecorder extends JFrame {
@@ -38,6 +39,11 @@ public class AudiobookRecorder extends JFrame {
String defaultEffectChain = "none"; String defaultEffectChain = "none";
public final static int IDLE = 0;
public final static int RECORDING = 1;
public final static int STOPPING = 2;
public int state = IDLE;
MainToolBar toolBar; MainToolBar toolBar;
JMenuBar menuBar; JMenuBar menuBar;
@@ -548,6 +554,7 @@ public class AudiobookRecorder extends JFrame {
int i = effectChain.getSelectedIndex(); int i = effectChain.getSelectedIndex();
KVPair<String, String> p = effectChain.getItemAt(i); KVPair<String, String> p = effectChain.getItemAt(i);
if (p == null) return; if (p == null) return;
CacheManager.removeFromCache(selectedSentence);
selectedSentence.setEffectChain(p.getKey()); selectedSentence.setEffectChain(p.getKey());
updateWaveform(); updateWaveform();
} }
@@ -591,8 +598,13 @@ public class AudiobookRecorder extends JFrame {
centralPanel.getActionMap().put("startRecord", new AbstractAction() { centralPanel.getActionMap().put("startRecord", new AbstractAction() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (bookTree.isEditing()) return; if (!getLock()) return;
if (bookTree.isEditing()) {
freeLock();
return;
}
if (getNoiseFloor() == 0) { if (getNoiseFloor() == 0) {
freeLock();
alertNoRoomNoise(); alertNoRoomNoise();
return; return;
} }
@@ -601,8 +613,13 @@ public class AudiobookRecorder extends JFrame {
}); });
centralPanel.getActionMap().put("startRecordShort", new AbstractAction() { centralPanel.getActionMap().put("startRecordShort", new AbstractAction() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (bookTree.isEditing()) return; if (!getLock()) return;
if (bookTree.isEditing()) {
freeLock();
return;
}
if (getNoiseFloor() == 0) { if (getNoiseFloor() == 0) {
freeLock();
alertNoRoomNoise(); alertNoRoomNoise();
return; return;
} }
@@ -611,9 +628,14 @@ public class AudiobookRecorder extends JFrame {
}); });
centralPanel.getActionMap().put("startRecordNewPara", new AbstractAction() { centralPanel.getActionMap().put("startRecordNewPara", new AbstractAction() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (bookTree.isEditing()) return; if (!getLock()) return;
if (bookTree.isEditing()) {
freeLock();
return;
}
if (getNoiseFloor() == 0) { if (getNoiseFloor() == 0) {
alertNoRoomNoise(); alertNoRoomNoise();
freeLock();
return; return;
} }
startRecordingNewParagraph(); startRecordingNewParagraph();
@@ -621,8 +643,13 @@ public class AudiobookRecorder extends JFrame {
}); });
centralPanel.getActionMap().put("startRecordNewSection", new AbstractAction() { centralPanel.getActionMap().put("startRecordNewSection", new AbstractAction() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (bookTree.isEditing()) return; if (!getLock()) return;
if (bookTree.isEditing()) {
freeLock();
return;
}
if (getNoiseFloor() == 0) { if (getNoiseFloor() == 0) {
freeLock();
alertNoRoomNoise(); alertNoRoomNoise();
return; return;
} }
@@ -631,8 +658,13 @@ public class AudiobookRecorder extends JFrame {
}); });
centralPanel.getActionMap().put("startRerecord", new AbstractAction() { centralPanel.getActionMap().put("startRerecord", new AbstractAction() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (bookTree.isEditing()) return; if (!getLock()) return;
if (bookTree.isEditing()) {
freeLock();
return;
}
if (getNoiseFloor() == 0) { if (getNoiseFloor() == 0) {
freeLock();
alertNoRoomNoise(); alertNoRoomNoise();
return; return;
} }
@@ -642,7 +674,9 @@ public class AudiobookRecorder extends JFrame {
centralPanel.getActionMap().put("stopRecord", new AbstractAction() { centralPanel.getActionMap().put("stopRecord", new AbstractAction() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (bookTree.isEditing()) return; if (bookTree.isEditing()) return;
stopLock();
stopRecording(); stopRecording();
freeLock();
} }
}); });
centralPanel.getActionMap().put("deleteLast", new AbstractAction() { centralPanel.getActionMap().put("deleteLast", new AbstractAction() {
@@ -2668,6 +2702,7 @@ public class AudiobookRecorder extends JFrame {
public void loadEffectsFromFolder(File dir) { public void loadEffectsFromFolder(File dir) {
if (dir == null) return; if (dir == null) return;
if (!dir.exists()) return;
File[] files = dir.listFiles(); File[] files = dir.listFiles();
for (File f : files) { for (File f : files) {
if (f.getName().endsWith(".eff")) { if (f.getName().endsWith(".eff")) {
@@ -2949,4 +2984,32 @@ public class AudiobookRecorder extends JFrame {
public String getDefaultEffectsChain() { public String getDefaultEffectsChain() {
return defaultEffectChain; return defaultEffectChain;
} }
public synchronized boolean getLock() {
if (state == RECORDING) return false;
int counts = 0;
while (state == STOPPING) {
try {
Thread.sleep(100);
} catch (Exception ex) {
ex.printStackTrace();
}
counts++;
if (counts > 100) return false;
}
state = RECORDING;
return true;
}
public void freeLock() {
state = IDLE;
}
public void stopLock() {
state = STOPPING;
}
} }

View File

@@ -18,9 +18,16 @@ public class CacheManager {
} }
cache.add(c); cache.add(c);
System.gc();
} }
public static void setCacheSize(int c) { public static void setCacheSize(int c) {
cacheSize = c; cacheSize = c;
} }
public static void removeFromCache(Cacheable c) {
cache.remove(c);
c.clearCache();
}
} }

View File

@@ -331,7 +331,7 @@ public class Options extends JDialog {
addSeparator(optionsPanel); addSeparator(optionsPanel);
cacheSize = addSpinner(optionsPanel, "Cache size:", 0, 5000, 1, getInteger("cache.size"), ""); cacheSize = addSpinner(optionsPanel, "Cache size:", 2, 100, 1, getInteger("cache.size"), "");
addSeparator(optionsPanel); addSeparator(optionsPanel);
tabs.add("Options", new JScrollPane(optionsPanel)); tabs.add("Options", new JScrollPane(optionsPanel));

View File

@@ -68,7 +68,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
double[][] audioData = null; double[][] audioData = null;
// double[][] processedAudio = null; double[][] processedAudio = null;
RecordingThread recordingThread; RecordingThread recordingThread;
@@ -94,7 +94,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
try { try {
running = true; running = true;
recording = true; recording = true;
byte[] buf = new byte[AudiobookRecorder.window.microphone.getBufferSize()]; byte[] buf = new byte[1024]; //AudiobookRecorder.window.microphone.getBufferSize()];
FileOutputStream fos = new FileOutputStream(tempFile); FileOutputStream fos = new FileOutputStream(tempFile);
int len = 0; int len = 0;
AudiobookRecorder.window.microphone.flush(); AudiobookRecorder.window.microphone.flush();
@@ -160,6 +160,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
return false; return false;
} }
CacheManager.removeFromCache(this);
recordingThread = new RecordingThread(getTempFile(), getFile(), Options.getAudioFormat()); recordingThread = new RecordingThread(getTempFile(), getFile(), Options.getAudioFormat());
@@ -180,10 +181,10 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} }
} }
CacheManager.removeFromCache(this);
audioData = null; audioData = null;
// processedAudio = null; processedAudio = 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");
@@ -196,6 +197,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
recognise(); recognise();
} }
} }
} }
public static final int FFTBuckets = 1024; public static final int FFTBuckets = 1024;
@@ -213,7 +215,11 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} else { } else {
samples = getProcessedAudioData(); samples = getProcessedAudioData();
} }
if (samples == null) return; if (samples == null) {
System.err.println("Error: loading data failed!");
return;
}
int blocks = samples.length / 4096 + 1; int blocks = samples.length / 4096 + 1;
@@ -252,6 +258,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
block++; block++;
} }
int limit = Options.getInteger("audio.recording.trim.fft"); int limit = Options.getInteger("audio.recording.trim.fft");
// Find first block with > 1 intensity and subtract one. // Find first block with > 1 intensity and subtract one.
@@ -288,7 +295,10 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
if (endOffset <= startOffset) endOffset = startOffset + 4096; if (endOffset <= startOffset) endOffset = startOffset + 4096;
if (endOffset < 0) endOffset = 0; if (endOffset < 0) endOffset = 0;
if (endOffset >= samples.length) endOffset = samples.length; if (endOffset >= samples.length) endOffset = samples.length;
updateCrossings(); updateCrossings(useRaw);
intens = null;
samples = null;
System.gc();
} }
@@ -343,7 +353,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
if (startOffset < 0) startOffset = 0; if (startOffset < 0) startOffset = 0;
if (endOffset >= samples.length) endOffset = samples.length-1; if (endOffset >= samples.length) endOffset = samples.length-1;
updateCrossings(); updateCrossings(useRaw);
} }
public String getId() { public String getId() {
@@ -427,19 +437,31 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} }
public void updateCrossings() { public void updateCrossings() {
updateStartCrossing(); updateCrossings(false);
updateEndCrossing(); }
public void updateCrossings(boolean useRaw) {
updateStartCrossing(useRaw);
updateEndCrossing(useRaw);
} }
public void updateStartCrossing() { public void updateStartCrossing() {
updateStartCrossing(false);
}
public void updateStartCrossing(boolean useRaw) {
if (crossStartOffset == -1) { if (crossStartOffset == -1) {
crossStartOffset = findNearestZeroCrossing(startOffset, 4096); crossStartOffset = findNearestZeroCrossing(useRaw, startOffset, 4096);
} }
} }
public void updateEndCrossing() { public void updateEndCrossing() {
updateEndCrossing(false);
}
public void updateEndCrossing(boolean useRaw) {
if (crossEndOffset == -1) { if (crossEndOffset == -1) {
crossEndOffset = findNearestZeroCrossing(endOffset, 4096); crossEndOffset = findNearestZeroCrossing(useRaw, endOffset, 4096);
} }
} }
@@ -558,7 +580,9 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public void clearCache() { public void clearCache() {
audioData = null; audioData = null;
// processedAudio = null; processedAudio = null;
storedFormat = null;
storedLength = -1;
} }
public boolean lockedInCache() { public boolean lockedInCache() {
@@ -566,7 +590,16 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} }
public int findNearestZeroCrossing(int pos, int range) { public int findNearestZeroCrossing(int pos, int range) {
double[][] data = getProcessedAudioData(); return findNearestZeroCrossing(false, pos, range);
}
public int findNearestZeroCrossing(boolean useRaw, int pos, int range) {
double[][] data = null;
if (useRaw) {
data = getRawAudioData();
} else {
data = getProcessedAudioData();
}
if (data == null) return 0; if (data == null) return 0;
if (data.length == 0) return 0; if (data.length == 0) return 0;
@@ -640,9 +673,18 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} }
public double getPeakValue() { public double getPeakValue() {
return getPeakValue(false);
}
public double getPeakValue(boolean useRaw) {
double oldGain = gain; double oldGain = gain;
gain = 1.0d; gain = 1.0d;
double[][] samples = getProcessedAudioData(); double[][] samples = null;
if (useRaw) {
samples = getRawAudioData();
} else {
samples = getProcessedAudioData();
}
gain = oldGain; gain = oldGain;
if (samples == null) { if (samples == null) {
return 0; return 0;
@@ -930,10 +972,16 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
} }
public void loadFile() { public void loadFile() {
if (audioData != null) return; if (audioData != null) {
return;
}
File f = getFile(); File f = getFile();
try { try {
if (!f.exists()) {
System.err.println("TODO: Race condition: wav file doesn't exist yet");
return;
}
AudioInputStream s = AudioSystem.getAudioInputStream(f); AudioInputStream s = AudioSystem.getAudioInputStream(f);
AudioFormat format = getAudioFormat(); AudioFormat format = getAudioFormat();
@@ -953,6 +1001,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
audioData = samples; audioData = samples;
CacheManager.addToCache(this); CacheManager.addToCache(this);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
} }
} }
@@ -963,10 +1012,10 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
synchronized public double[][] getProcessedAudioData() { synchronized public double[][] getProcessedAudioData() {
loadFile(); loadFile();
// if (processedAudio != null) return processedAudio; if (processedAudio != null) return processedAudio;
if (audioData == null) return null; if (audioData == null) return null;
double[][] processedAudio = new double[audioData.length][2]; processedAudio = new double[audioData.length][2];
for (int i = 0; i < audioData.length; i++) { for (int i = 0; i < audioData.length; i++) {
processedAudio[i][LEFT] = audioData[i][LEFT]; processedAudio[i][LEFT] = audioData[i][LEFT];
processedAudio[i][RIGHT] = audioData[i][RIGHT]; processedAudio[i][RIGHT] = audioData[i][RIGHT];
@@ -998,6 +1047,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
processedAudio[i][LEFT] *= gain; processedAudio[i][LEFT] *= gain;
processedAudio[i][RIGHT] *= gain; processedAudio[i][RIGHT] *= gain;
} }
return processedAudio; return processedAudio;
} }

View File

@@ -63,4 +63,17 @@ public class Utils {
} }
} }
} }
static long millis = System.currentTimeMillis();
public static void report(String tag) {
long t = System.currentTimeMillis();
long d = t - millis;
millis = t;
System.err.println(String.format("%10d - %10s : %8d | %8d | %8d", d, tag,
Runtime.getRuntime().totalMemory(),
Runtime.getRuntime().maxMemory(),
Runtime.getRuntime().freeMemory()
));
}
} }