From fab11f5755ee5d65735f02471d49d8d3169110c1 Mon Sep 17 00:00:00 2001 From: Matt Jenkins Date: Wed, 26 Sep 2018 16:38:34 +0100 Subject: [PATCH] Beginnings of multi-bit support --- .../jeq/core/EqualizerInputStream.java | 39 ++++++++++++ .../audiobookrecorder/AudiobookRecorder.java | 8 +-- .../co/majenko/audiobookrecorder/Options.java | 36 +++++------ .../majenko/audiobookrecorder/Sentence.java | 59 +++++++++++-------- 4 files changed, 92 insertions(+), 50 deletions(-) diff --git a/src/davaguine/jeq/core/EqualizerInputStream.java b/src/davaguine/jeq/core/EqualizerInputStream.java index f1b9d74..2519607 100644 --- a/src/davaguine/jeq/core/EqualizerInputStream.java +++ b/src/davaguine/jeq/core/EqualizerInputStream.java @@ -89,6 +89,7 @@ public class EqualizerInputStream extends InputStream { case 8: case 16: case 24: + case 32: break; default: return false; @@ -175,6 +176,23 @@ public class EqualizerInputStream extends InputStream { } break; } + case 32: { + l = length / 4; + if (l > 0) { + if (bigendian) + for (int i = 0; i < l; i++) { + temp = ((a1 = inbuf)[inpos++] & 0xff) | ((a1[inpos++] & 0xff) << 8) | ((a1[inpos++] & 0xff) << 16) | ((a1[inpos++] & 0xff) << 24); + workbuf[i] = temp; //signed && temp > 8388607 ? temp - 16777216 : temp; + } + else + for (int i = 0; i < l; i++) { + temp = (((a1 = inbuf)[inpos++] & 0xff) << 24) | ((a1[inpos++] & 0xff) << 16) | ((a1[inpos++] & 0xff) << 8) | (a1[inpos++] & 0xff); + workbuf[i] = temp; //signed && temp > 8388607 ? temp - 16777216 : temp; + } + inlen -= inpos; + } + break; + } } return l; } @@ -252,6 +270,27 @@ public class EqualizerInputStream extends InputStream { } break; } + case 32: { + if (bigendian) { + for (int i = 0; i < length; i++) { + d = workbuf[i]; + b[p++] = (byte) (d & 0xff); + b[p++] = (byte) ((d & 0xff00) >> 8); + b[p++] = (byte) ((d & 0xff0000) >> 16); + b[p++] = (byte) ((d & 0xff000000) >> 24); + } + } else { + for (int i = 0; i < length; i++) { + d = wrap24Bit(workbuf[i]); + b[p++] = (byte) ((d & 0xff000000) >> 24); + b[p++] = (byte) ((d & 0xff0000) >> 16); + b[p++] = (byte) ((d & 0xff00) >> 8); + b[p++] = (byte) (d & 0xff); + } + } + break; + } + } return p - off; } diff --git a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java index e5dec77..aa4d77d 100644 --- a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java +++ b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java @@ -1679,13 +1679,7 @@ public class AudiobookRecorder extends JFrame { } public boolean enableMicrophone() { - AudioFormat format = new AudioFormat( - Options.getInteger("audio.recording.samplerate"), - 16, - Options.getInteger("audio.recording.channels"), - true, - false - ); + AudioFormat format = Options.getAudioFormat(); Mixer.Info mixer = Options.getRecordingMixer(); diff --git a/src/uk/co/majenko/audiobookrecorder/Options.java b/src/uk/co/majenko/audiobookrecorder/Options.java index 787d8d0..2ffdf42 100644 --- a/src/uk/co/majenko/audiobookrecorder/Options.java +++ b/src/uk/co/majenko/audiobookrecorder/Options.java @@ -19,6 +19,7 @@ public class Options extends JDialog { JComboBox playbackList; JComboBox channelList; JComboBox rateList; + JComboBox bitDepth; JTextField storageFolder; JSpinner preChapterGap; JSpinner postChapterGap; @@ -245,6 +246,7 @@ public class Options extends JDialog { mixerList = addDropdown(optionsPanel, "Recording device:", getRecordingMixerList(), get("audio.recording.device")); channelList = addDropdown(optionsPanel, "Channels:", getChannelCountList(), get("audio.recording.channels")); rateList = addDropdown(optionsPanel, "Sample rate:", getSampleRateList(), get("audio.recording.samplerate")); + bitDepth = addDropdown(optionsPanel, "Sample resolution:", getResolutionList(), get("audio.recording.resolution")); addSeparator(optionsPanel); @@ -420,9 +422,10 @@ public class Options extends JDialog { } static KVPair[] getSampleRateList() { - KVPair[] l = new KVPair[2]; + KVPair[] l = new KVPair[3]; l[0] = new KVPair("44100", "44100"); l[1] = new KVPair("48000", "48000"); + l[2] = new KVPair("96000", "96000"); return l; } @@ -440,6 +443,7 @@ public class Options extends JDialog { } defaultPrefs.put("audio.recording.channels", "2"); defaultPrefs.put("audio.recording.samplerate", "44100"); + defaultPrefs.put("audio.recording.resolution", "16"); if (playbackMixers.length > 0) { defaultPrefs.put("audio.playback.device", playbackMixers[0].key); } else { @@ -584,6 +588,7 @@ public class Options extends JDialog { set("audio.recording.device", ((KVPair)mixerList.getSelectedItem()).key); set("audio.recording.channels", ((KVPair)channelList.getSelectedItem()).key); set("audio.recording.samplerate", ((KVPair)rateList.getSelectedItem()).key); + set("audio.recording.resolution", ((KVPair)bitDepth.getSelectedItem()).key); set("audio.playback.device", ((KVPair)playbackList.getSelectedItem()).key); set("path.storage", storageFolder.getText()); set("path.ffmpeg", ffmpegLocation.getText()); @@ -606,25 +611,10 @@ public class Options extends JDialog { } public static AudioFormat getAudioFormat() { - String sampleRate = get("audio.recording.samplerate"); - String channels = get("audio.recording.channels"); - - float sr = 48000f; - int chans = 2; - - try { - sr = Float.parseFloat(sampleRate); - } catch (Exception e) { - sr = 48000f; - } - - try { - chans = Integer.parseInt(channels); - } catch (Exception e) { - chans = 2; - } - - AudioFormat af = new AudioFormat(sr, 16, chans, true, false); + AudioFormat af = new AudioFormat( + getInteger("audio.recording.samplerate"), + getInteger("audio.recording.resolution"), + getInteger("audio.recording.channels"), true, false); return af; } @@ -656,4 +646,10 @@ public class Options extends JDialog { pairs[3] = new KVPair("320000", "320kbps"); return pairs; } + + public static KVPair[] getResolutionList() { + KVPair[] pairs = new KVPair[1]; + pairs[0] = new KVPair("16", "16 Bit"); + return pairs; + } } diff --git a/src/uk/co/majenko/audiobookrecorder/Sentence.java b/src/uk/co/majenko/audiobookrecorder/Sentence.java index 0e9f0cf..de9a363 100644 --- a/src/uk/co/majenko/audiobookrecorder/Sentence.java +++ b/src/uk/co/majenko/audiobookrecorder/Sentence.java @@ -347,6 +347,32 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { } } + public int[] getAudioDataS16LE(AudioInputStream s, AudioFormat format) throws IOException { + long len = s.getFrameLength(); + int frameSize = format.getFrameSize(); + int chans = format.getChannels(); + int bytes = frameSize / chans; + + byte[] frame = new byte[frameSize]; + int[] samples = new int[(int)len]; + + for (long fno = 0; fno < len; fno++) { + + s.read(frame); + int sample = 0; + if (chans == 2) { // Stereo + int left = (frame[1] << 8) | frame[0]; + int right = (frame[3] << 8) | frame[2]; + sample = (left + right) / 2; + } else { + sample = (frame[1] << 8) | frame[0]; + } + samples[(int)fno] = sample; + } + + return samples; + } + public int[] getAudioData() { if (storedAudioData != null) { return storedAudioData; @@ -356,28 +382,15 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { AudioInputStream s = AudioSystem.getAudioInputStream(f); AudioFormat format = s.getFormat(); - long len = s.getFrameLength(); - int frameSize = format.getFrameSize(); - int chans = format.getChannels(); - int bytes = frameSize / chans; + int[] samples = null; - byte[] frame = new byte[frameSize]; - int[] samples = new int[(int)len]; - - if (bytes != 2) return null; - - for (long fno = 0; fno < len; fno++) { - s.read(frame); - int sample = 0; - if (chans == 2) { // Stereo - int left = (frame[1] << 8) | frame[0]; - int right = (frame[3] << 8) | frame[2]; - sample = (left + right) / 2; - } else { - sample = (frame[1] << 8) | frame[0]; - } - samples[(int)fno] = sample; + switch (format.getSampleSizeInBits()) { + case 16: + samples = getAudioDataS16LE(s, format); + break; } + + s.close(); sampleSize = samples.length; storedAudioData = samples; @@ -484,8 +497,8 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { AudioFormat format = eq.getFormat(); - IIRControls controls = eq.getControls(); - AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels()); +// IIRControls controls = eq.getControls(); +// AudiobookRecorder.window.book.equaliser.apply(controls, format.getChannels()); int frameSize = format.getFrameSize(); @@ -498,7 +511,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { play.start(); - byte[] buffer = new byte[1024]; + byte[] buffer = new byte[50000]; eq.skip(pos);