From 671f2b92709f9eb334711cd8ada12183efa50ecb Mon Sep 17 00:00:00 2001 From: Matt Jenkins Date: Sat, 7 Sep 2019 21:24:46 +0100 Subject: [PATCH] Added adjustable FFT block size --- .../audiobookrecorder/MainToolBar.java | 1 + .../co/majenko/audiobookrecorder/Options.java | 17 ++++++++++ .../majenko/audiobookrecorder/Sentence.java | 32 ++++++++++--------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/uk/co/majenko/audiobookrecorder/MainToolBar.java b/src/uk/co/majenko/audiobookrecorder/MainToolBar.java index 0653c05..803e6de 100644 --- a/src/uk/co/majenko/audiobookrecorder/MainToolBar.java +++ b/src/uk/co/majenko/audiobookrecorder/MainToolBar.java @@ -165,6 +165,7 @@ public class MainToolBar extends JToolBar { "1.50x", "1.75x" }); + playbackSpeed.setFocusable(false); playbackSpeed.setSelectedIndex(1); add(playbackSpeed); diff --git a/src/uk/co/majenko/audiobookrecorder/Options.java b/src/uk/co/majenko/audiobookrecorder/Options.java index e8b6daa..0f6c4fc 100644 --- a/src/uk/co/majenko/audiobookrecorder/Options.java +++ b/src/uk/co/majenko/audiobookrecorder/Options.java @@ -24,6 +24,7 @@ public class Options extends JDialog { JComboBox rateList; JComboBox bitDepth; JComboBox trimMethod; + JComboBox fftBlockSize; JTextField storageFolder; JTextField archiveFolder; JSpinner preChapterGap; @@ -297,6 +298,7 @@ public class Options extends JDialog { bitDepth = addDropdown(optionsPanel, "Sample resolution:", getResolutionList(), get("audio.recording.resolution")); trimMethod = addDropdown(optionsPanel, "Auto-trim method:", getTrimMethods(), get("audio.recording.trim")); fftThreshold = addSpinner(optionsPanel, "FFT threshold:", 0, 100, 1, getInteger("audio.recording.trim.fft"), ""); + fftBlockSize = addDropdown(optionsPanel, "FFT Block size:", getFFTBlockSizes(), get("audio.recording.trim.blocksize")); addSeparator(optionsPanel); @@ -565,6 +567,7 @@ public class Options extends JDialog { } else { defaultPrefs.put("audio.playback.device", ""); } + defaultPrefs.put("audio.recording.trim.blocksize", "4096"); defaultPrefs.put("catenation.pre-chapter", "1000"); defaultPrefs.put("catenation.post-chapter", "1500"); @@ -708,6 +711,7 @@ public class Options extends JDialog { set("editor.external", externalEditor.getText()); set("cache.size", cacheSize.getValue()); set("audio.recording.trim.fft", fftThreshold.getValue()); + set("audio.recording.trim.blocksize", ((KVPair)fftBlockSize.getSelectedItem()).key); set("effects.ethereal.offset", etherealOffset.getValue()); set("effects.ethereal.iterations", etherealIterations.getValue()); @@ -782,6 +786,19 @@ public class Options extends JDialog { return pairs; } + public static KVPair[] getFFTBlockSizes() { + KVPair[] pairs = new KVPair[8]; + pairs[0] = new KVPair("1024", "1024"); + pairs[1] = new KVPair("2048", "2048"); + pairs[2] = new KVPair("4096", "4096"); + pairs[3] = new KVPair("8192", "8192"); + pairs[4] = new KVPair("16384", "16384"); + pairs[5] = new KVPair("32768", "32768"); + pairs[6] = new KVPair("65536", "65537"); + pairs[7] = new KVPair("131072", "131072"); + return pairs; + } + public static void createEffectChains() { effectChains = new ArrayList(); diff --git a/src/uk/co/majenko/audiobookrecorder/Sentence.java b/src/uk/co/majenko/audiobookrecorder/Sentence.java index 62f8abb..90d5954 100644 --- a/src/uk/co/majenko/audiobookrecorder/Sentence.java +++ b/src/uk/co/majenko/audiobookrecorder/Sentence.java @@ -31,7 +31,7 @@ import java.util.Timer; public class Sentence extends DefaultMutableTreeNode implements Cacheable { - + String text; String id; int postGap; @@ -225,17 +225,18 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { return; } + int fftSize = Options.getInteger("audio.recording.trim.blocksize"); - int blocks = samples.length / 4096 + 1; + int blocks = samples.length / fftSize + 1; int[] intens = new int[blocks]; int block = 0; - for (int i = 0; i < samples.length; i+= 4096) { - double[] real = new double[4096]; - double[] imag = new double[4096]; + for (int i = 0; i < samples.length; i+= fftSize) { + double[] real = new double[fftSize]; + double[] imag = new double[fftSize]; - for (int j = 0; j < 4096; j++) { + for (int j = 0; j < fftSize; j++) { if (i + j < samples.length) { real[j] = (samples[i+j][LEFT] + samples[i+j][RIGHT]) / 2d; imag[j] = 0; @@ -247,14 +248,14 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { double[] buckets = FFT.fft(real, imag, true); double av = 0; - for (int j = 1; j < 2048; j++) { + for (int j = 1; j < fftSize/2; j++) { av += Math.abs(buckets[j]); } - av /= 2047d; + av /= (fftSize / 2); intens[block] = 0; - for (int j = 2; j < 4096; j += 2) { + for (int j = 2; j < fftSize; j += 2) { double d = Math.abs(av - buckets[j]); if (d > 0.05) { intens[block]++; @@ -278,7 +279,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { start = 0; } - startOffset = start * 4096; + startOffset = start * fftSize; if (startOffset < 0) startOffset = 0; if (startOffset >= samples.length) startOffset = samples.length; @@ -295,9 +296,9 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { end = blocks - 1; } - endOffset = end * 4096; + endOffset = (end+1) * fftSize; - if (endOffset <= startOffset) endOffset = startOffset + 4096; + if (endOffset <= startOffset) endOffset = startOffset + fftSize; if (endOffset < 0) endOffset = 0; if (endOffset >= samples.length) endOffset = samples.length; updateCrossings(useRaw); @@ -337,7 +338,8 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { startOffset = 0; } - startOffset -= 4096; + int fftSize = Options.getInteger("audio.recording.trim.blocksize"); + startOffset -= fftSize; for (int i = samples.length-1; i >= 0; i--) { endOffset = i; @@ -348,9 +350,9 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { } } - endOffset += 4096; + endOffset += fftSize; - if (endOffset <= startOffset) endOffset = startOffset + 4096; + if (endOffset <= startOffset) endOffset = startOffset + fftSize; if (endOffset <= 0) { endOffset = samples.length-1; }