From 955227e9e309fbe1db1ece2804ce1c0f90c9d932 Mon Sep 17 00:00:00 2001 From: Matt Jenkins Date: Wed, 26 Sep 2018 14:26:44 +0100 Subject: [PATCH] Complete overhaul of recording to allow better recording from microphones that require a warmup and self-calibration period --- .../majenko/audiobookrecorder/icons/mic.png | Bin 0 -> 588 bytes .../audiobookrecorder/AudiobookRecorder.java | 87 ++++++++++- .../majenko/audiobookrecorder/Equaliser.java | 15 +- .../co/majenko/audiobookrecorder/Icons.java | 2 +- .../audiobookrecorder/MainToolBar.java | 18 +++ .../co/majenko/audiobookrecorder/Options.java | 17 +- .../majenko/audiobookrecorder/Sentence.java | 145 +++++++++++------- 7 files changed, 223 insertions(+), 61 deletions(-) create mode 100644 resources/uk/co/majenko/audiobookrecorder/icons/mic.png diff --git a/resources/uk/co/majenko/audiobookrecorder/icons/mic.png b/resources/uk/co/majenko/audiobookrecorder/icons/mic.png new file mode 100644 index 0000000000000000000000000000000000000000..86586baac121492b6ae1986381a4bc22d4209d1b GIT binary patch literal 588 zcmV-S0<-;zP)V&oPYAU0f0ZI zqM{;`GM;jYa*uL>GJ(?KPw)K=HOuAlr?FTJqehLwqD6}^efo6pJP(CJ@rLdjMZ@fm zDDSGPt1)fbG;G|s@w*HjJec7x=$Txx@Jx+HgMR(`VabvuKf&x;JRS!n)ogM~*k-^8r!aXuG zGa-}7pi-$23_2ZF)J4yW@AEC_-$ zu;1^0WOq0qAGi;6Oby6M2U~46tX#S31Dr@Cq=Biy9-7T&Ruv!M+S*#l;0FeS;s3xI ztrp42$?$r;sHv%u48E^WDnI defaultPrefs; static Preferences prefs = null; @@ -282,10 +284,19 @@ public class Options extends JDialog { equaliser.setChannel(i, Options.getFloat("audio.eq." + i)); } - tabs.add("EQ", equaliser); + tabs.add("Default EQ", equaliser); + + 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); @@ -482,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); } @@ -587,6 +600,8 @@ public class Options extends JDialog { set("audio.eq." + i, equaliser.getChannel(i)); } + set("scripts.startup", startupScript.getText()); + savePreferences(); } diff --git a/src/uk/co/majenko/audiobookrecorder/Sentence.java b/src/uk/co/majenko/audiobookrecorder/Sentence.java index b836a17..0e9f0cf 100644 --- a/src/uk/co/majenko/audiobookrecorder/Sentence.java +++ b/src/uk/co/majenko/audiobookrecorder/Sentence.java @@ -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() { - try { - inputStream.close(); - inputStream = null; - line.stop(); - line.close(); - line = null; - } catch (Exception e) { - e.printStackTrace(); + recordingThread.stopRecording(); + while (recordingThread.isRunning()) { + try { + Thread.sleep(10); + } catch (Exception e) { + } } - 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);