Added zero crossing detection #7

This commit is contained in:
2018-09-16 15:34:49 +01:00
parent 43d80c00d9
commit 1c056c9e7b
4 changed files with 116 additions and 11 deletions

View File

@@ -257,6 +257,7 @@ public class AudiobookRecorder extends JFrame {
selectedSentence.autoTrimSampleFFT();
sampleWaveform.setData(selectedSentence.getAudioData());
sampleWaveform.setMarkers(selectedSentence.getStartOffset(), selectedSentence.getEndOffset());
sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing());
startOffset.setValue(selectedSentence.getStartOffset());
endOffset.setValue(selectedSentence.getEndOffset());
postSentenceGap.setValue(selectedSentence.getPostGap());
@@ -272,6 +273,7 @@ public class AudiobookRecorder extends JFrame {
selectedSentence.autoTrimSamplePeak();
sampleWaveform.setData(selectedSentence.getAudioData());
sampleWaveform.setMarkers(selectedSentence.getStartOffset(), selectedSentence.getEndOffset());
sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing());
startOffset.setValue(selectedSentence.getStartOffset());
endOffset.setValue(selectedSentence.getEndOffset());
postSentenceGap.setValue(selectedSentence.getPostGap());
@@ -292,6 +294,8 @@ public class AudiobookRecorder extends JFrame {
if (selectedSentence != null) {
selectedSentence.setStartOffset((Integer)ob.getValue());
sampleWaveform.setLeftMarker((Integer)ob.getValue());
selectedSentence.updateStartCrossing();
sampleWaveform.setLeftAltMarker(selectedSentence.getStartCrossing());
}
}
});
@@ -302,6 +306,8 @@ public class AudiobookRecorder extends JFrame {
if (selectedSentence != null) {
selectedSentence.setEndOffset((Integer)ob.getValue());
sampleWaveform.setRightMarker((Integer)ob.getValue());
selectedSentence.updateEndCrossing();
sampleWaveform.setRightAltMarker(selectedSentence.getEndCrossing());
}
}
});
@@ -1170,6 +1176,8 @@ public class AudiobookRecorder extends JFrame {
selectedSentence = s;
sampleWaveform.setData(s.getAudioData());
sampleWaveform.setMarkers(s.getStartOffset(), s.getEndOffset());
s.updateCrossings();
sampleWaveform.setAltMarkers(s.getStartCrossing(), s.getEndCrossing());
startOffset.setValue(s.getStartOffset());
endOffset.setValue(s.getEndOffset());
postSentenceGap.setValue(s.getPostGap());
@@ -1532,7 +1540,6 @@ public class AudiobookRecorder extends JFrame {
File mp3File = new File(export, name + "-untagged.mp3");
File taggedFile = new File(export, name + ".mp3");
System.err.println(attributes);
encoder.encode(wavFile, mp3File, attributes);
Mp3File id3 = new Mp3File(mp3File);

View File

@@ -14,12 +14,10 @@ public class CacheManager {
cache.add(ob);
} else {
ob.clearCache();
System.err.println("Purged " + ob);
}
}
cache.add(c);
System.err.println("Cached " + c);
}
public static void setCacheSize(int c) {

View File

@@ -20,6 +20,8 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
int postGap;
int startOffset = 0;
int endOffset = 0;
int crossStartOffset = -1;
int crossEndOffset = -1;
int sampleSize = -1;
@@ -132,6 +134,8 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
}
public void autoTrimSampleFFT() {
crossStartOffset = -1;
crossEndOffset = -1;
int[] samples = getAudioData();
if (samples == null) return;
@@ -205,10 +209,13 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
if (endOffset <= startOffset) endOffset = startOffset + 4096;
if (endOffset < 0) endOffset = 0;
if (endOffset >= samples.length) endOffset = samples.length;
updateCrossings();
}
public void autoTrimSamplePeak() {
crossStartOffset = -1;
crossEndOffset = -1;
int[] samples = getAudioData();
if (samples == null) return;
int noiseFloor = AudiobookRecorder.window.getNoiseFloor();
@@ -247,6 +254,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
if (startOffset < 0) startOffset = 0;
if (endOffset >= samples.length) endOffset = samples.length-1;
updateCrossings();
}
public String getId() {
@@ -349,12 +357,40 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
return null;
}
public int getStartCrossing() {
return crossStartOffset;
}
public int getStartOffset() {
return startOffset;
}
public void updateCrossings() {
updateStartCrossing();
updateEndCrossing();
}
public void updateStartCrossing() {
if (crossStartOffset == -1) {
crossStartOffset = findNearestZeroCrossing(startOffset, 4096);
}
}
public void updateEndCrossing() {
if (crossEndOffset == -1) {
crossEndOffset = findNearestZeroCrossing(endOffset, 4096);
}
}
public void setStartOffset(int o) {
startOffset = o;
if (startOffset != o) {
startOffset = o;
crossStartOffset = -1;
}
}
public int getEndCrossing() {
return crossEndOffset;
}
public int getEndOffset() {
@@ -362,7 +398,10 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
}
public void setEndOffset(int o) {
endOffset = o;
if (endOffset != o) {
endOffset = o;
crossEndOffset = -1;
}
}
public int getSampleSize() {
@@ -411,7 +450,9 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
long len = s.getFrameLength();
int frameSize = format.getFrameSize();
int pos = startOffset * frameSize;
updateCrossings();
int pos = crossStartOffset * frameSize;
SourceDataLine play = AudioSystem.getSourceDataLine(format, Options.getPlaybackMixer());
play.open(format);
@@ -422,7 +463,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
s.skip(pos);
while (pos < endOffset * frameSize) {
while (pos < crossEndOffset * frameSize) {
int nr = s.read(buffer);
pos += nr;
@@ -438,13 +479,14 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public byte[] getRawAudioData() {
File f = getFile();
try {
updateCrossings();
AudioInputStream s = AudioSystem.getAudioInputStream(f);
AudioFormat format = s.getFormat();
int frameSize = format.getFrameSize();
int length = endOffset - startOffset;
int length = crossEndOffset - crossStartOffset;
byte[] data = new byte[length * frameSize];
s.skip(startOffset * frameSize);
s.skip(crossStartOffset * frameSize);
s.read(data);
@@ -497,8 +539,6 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
}
System.err.println("Decimated from " + length + " to " + newLen);
ByteArrayInputStream bas = new ByteArrayInputStream(decimated);
recognizer.startRecognition(bas);
SpeechResult result;
@@ -546,4 +586,40 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable {
public boolean lockedInCache() {
return id.equals("room-noise");
}
public int findNearestZeroCrossing(int pos, int range) {
int[] data = getAudioData();
if (pos < 0) pos = 0;
if (pos >= data.length) pos = data.length-1;
int backwards = pos;
int forwards = pos;
int backwardsPrev = data[backwards];
int forwardsPrev = data[forwards];
while (backwards > 0 || forwards < data.length-2) {
if (forwards < data.length-2) forwards++;
if (backwards > 0) backwards--;
if (backwardsPrev >= 0 && data[backwards] < 0) { // Found one!
return backwards;
}
if (forwardsPrev < 0 && data[forwards] >= 0) {
return forwards;
}
range--;
if (range == 0) {
return pos;
}
backwardsPrev = data[backwards];
forwardsPrev = data[forwards];
}
return pos;
}
}

View File

@@ -12,6 +12,9 @@ public class Waveform extends JPanel {
int leftMarker = 0;
int rightMarker = 0;
int leftAltMarker = 0;
int rightAltMarker = 0;
public Waveform() {
super();
}
@@ -87,15 +90,36 @@ public class Waveform extends JPanel {
g.setColor(new Color(255, 0, 0));
g.drawLine(leftMarker/step, 0, leftMarker/step, h);
g.drawLine(rightMarker/step, 0, rightMarker/step, h);
g.setColor(new Color(255, 255, 0));
g.drawLine(leftAltMarker/step, 0, leftAltMarker/step, h);
g.drawLine(rightAltMarker/step, 0, rightAltMarker/step, h);
}
}
public void setAltMarkers(int l, int r) {
leftAltMarker = l;
rightAltMarker = r;
repaint();
}
public void setMarkers(int l, int r) {
leftMarker = l;
rightMarker = r;
repaint();
}
public void setLeftAltMarker(int l) {
leftAltMarker = l;
repaint();
}
public void setRightAltMarker(int r) {
rightAltMarker = r;
repaint();
}
public void setLeftMarker(int l) {
leftMarker = l;
repaint();