From bdbf4c604d9f97a143cdd8fd93995d0342c63f75 Mon Sep 17 00:00:00 2001 From: Matt Jenkins Date: Wed, 29 Jan 2020 02:01:05 +0000 Subject: [PATCH] Invert sample storage arrays --- src/uk/co/majenko/audiobookrecorder/AGC.java | 10 +- .../majenko/audiobookrecorder/Amplifier.java | 6 +- .../audiobookrecorder/AudiobookRecorder.java | 238 ++++++++++++++-- .../co/majenko/audiobookrecorder/Biquad.java | 18 +- .../majenko/audiobookrecorder/Clipping.java | 10 +- .../audiobookrecorder/CommandLine.java | 192 +++++++++++++ .../co/majenko/audiobookrecorder/Debug.java | 41 +++ .../majenko/audiobookrecorder/DelayLine.java | 60 ++-- .../audiobookrecorder/DelayLineStore.java | 10 +- src/uk/co/majenko/audiobookrecorder/LFO.java | 10 +- src/uk/co/majenko/audiobookrecorder/Pan.java | 6 +- .../majenko/audiobookrecorder/Sentence.java | 264 +++++++++++++----- .../majenko/audiobookrecorder/Waveform.java | 16 +- 13 files changed, 706 insertions(+), 175 deletions(-) create mode 100644 src/uk/co/majenko/audiobookrecorder/CommandLine.java diff --git a/src/uk/co/majenko/audiobookrecorder/AGC.java b/src/uk/co/majenko/audiobookrecorder/AGC.java index e125ae7..c4ca48c 100644 --- a/src/uk/co/majenko/audiobookrecorder/AGC.java +++ b/src/uk/co/majenko/audiobookrecorder/AGC.java @@ -27,9 +27,9 @@ public class AGC implements Effect { public void process(double[][] samples) { gain = 1d; - for (int i = 0; i < samples.length; i++) { - double absSampleLeft = Math.abs(samples[i][Sentence.LEFT]) * gain; - double absSampleRight = Math.abs(samples[i][Sentence.RIGHT]) * gain; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + double absSampleLeft = Math.abs(samples[Sentence.LEFT][i]) * gain; + double absSampleRight = Math.abs(samples[Sentence.RIGHT][i]) * gain; double factor = 0.0d; @@ -49,8 +49,8 @@ public class AGC implements Effect { if (gain > limit) gain = limit; if (gain < 0) gain = 0; - samples[i][Sentence.LEFT] *= gain; - samples[i][Sentence.RIGHT] *= gain; + samples[Sentence.LEFT][i] *= gain; + samples[Sentence.RIGHT][i] *= gain; } } diff --git a/src/uk/co/majenko/audiobookrecorder/Amplifier.java b/src/uk/co/majenko/audiobookrecorder/Amplifier.java index ad3a157..52079f9 100644 --- a/src/uk/co/majenko/audiobookrecorder/Amplifier.java +++ b/src/uk/co/majenko/audiobookrecorder/Amplifier.java @@ -20,9 +20,9 @@ public class Amplifier implements Effect { } public void process(double[][] samples) { - for (int i = 0; i < samples.length; i++) { - samples[i][Sentence.LEFT] *= gain; - samples[i][Sentence.RIGHT] *= gain; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + samples[Sentence.LEFT][i] *= gain; + samples[Sentence.RIGHT][i] *= gain; } } diff --git a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java index 0369271..86348eb 100644 --- a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java +++ b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java @@ -55,6 +55,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public final static int STOPPING = 2; public int state = IDLE; + public static CommandLine CLI = new CommandLine(); + MainToolBar toolBar; JMenuBar menuBar; @@ -151,6 +153,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public static AudiobookRecorder window; void initSphinx() { + Debug.trace(); sphinxConfig = new Configuration(); sphinxConfig.setAcousticModelPath(AudiobookRecorder.SPHINX_MODEL); @@ -165,6 +168,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } void buildToolbar(Container ob) { + Debug.trace(); toolBar = new MainToolBar(this); toolBar.addSeparator(); toolBar.add(Box.createHorizontalGlue()); @@ -172,6 +176,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } void buildMenu(Container ob) { + Debug.trace(); menuBar = new JMenuBar(); fileMenu = new JMenu("File"); @@ -179,6 +184,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { fileNewBook = new JMenuItem("New Book..."); fileNewBook.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); saveBookStructure(); createNewBook(); } @@ -186,6 +192,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { fileOpenBook = new JMenuItem("Open Book..."); fileOpenBook.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); saveBookStructure(); openBook(); } @@ -193,6 +200,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { fileSave = new JMenuItem("Save Book"); fileSave.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); saveBookStructure(); } }); @@ -200,6 +208,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { fileOpenArchive = new JMenuItem("Open Archive..."); fileOpenArchive.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); openArchive(); } }); @@ -207,6 +216,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { fileExit = new JMenuItem("Exit"); fileExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); saveBookStructure(); System.exit(0); } @@ -228,6 +238,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookNewChapter = new JMenuItem("New Chapter"); bookNewChapter.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); addChapter(); } }); @@ -235,6 +246,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookExportAudio = new JMenuItem("Export Audio"); bookExportAudio.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); exportAudio(); } }); @@ -242,6 +254,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookPurgeBackups = new JMenuItem("Purge Backups"); bookPurgeBackups.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); book.purgeBackups(); } }); @@ -256,6 +269,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookVisitTitle = new JMenuItem("Title"); bookVisitTitle.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); Utils.browse("https://www.acx.com/titleview/" + book.getACX()); } }); @@ -264,6 +278,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookVisitAudition = new JMenuItem("Audition"); bookVisitAudition.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); Utils.browse("https://www.acx.com/titleview/" + book.getACX() + "?bucket=AUDITION_READY"); } }); @@ -272,6 +287,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookVisitProduce = new JMenuItem("Produce"); bookVisitProduce.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); Utils.browse("https://www.acx.com/titleview/" + book.getACX() + "?bucket=PRODUCE"); } }); @@ -284,6 +300,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { toolsMerge = new JMenuItem("Merge Book..."); toolsMerge.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); saveBookStructure(); mergeBook(); } @@ -292,6 +309,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { toolsArchive = new JMenuItem("Archive Book"); toolsArchive.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); saveBookStructure(); archiveBook(); } @@ -300,6 +318,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { toolsCoverArt = new JMenuItem("Import Cover Art..."); toolsCoverArt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); loadCoverArt(); } }); @@ -307,6 +326,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { toolsManuscript = new JMenuItem("Import Manuscript..."); toolsManuscript.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); loadManuscript(); } }); @@ -314,6 +334,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { toolsOptions = new JMenuItem("Options"); toolsOptions.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); new Options(AudiobookRecorder.this); } }); @@ -333,6 +354,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { helpAbout.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JOptionPane.showMessageDialog(AudiobookRecorder.this, new AboutPanel(), "About AudiobookRecorder", JOptionPane.PLAIN_MESSAGE); } }); @@ -346,10 +368,19 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { setLocationRelativeTo(null); } - public AudiobookRecorder() { + public AudiobookRecorder(String[] args) { + Debug.trace(); window = this; + CLI.addParameter("debug", "", Boolean.class, "Enable debug output"); + CLI.addParameter("trace", "", Boolean.class, "Enable function tracing"); + + String[] argv = CLI.process(args); + + Debug.debugEnabled = CLI.isSet("debug"); + Debug.traceEnabled = CLI.isSet("trace"); + try { String clsname = "com.jtattoo.plaf.hifi.HiFiLookAndFeel"; @@ -381,6 +412,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { + Debug.trace(); saveBookStructure(); System.exit(0); } @@ -402,12 +434,14 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { sampleScroll.setMaximum(1000); sampleScroll.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { + Debug.trace(); sampleWaveform.setOffset(sampleScroll.getValue()); } }); sampleWaveform.addMarkerDragListener(new MarkerDragListener() { public void leftMarkerMoved(MarkerDragEvent e) { + Debug.trace(); if (selectedSentence != null) { if (!selectedSentence.isLocked()) { selectedSentence.setStartOffset(e.getPosition()); @@ -420,6 +454,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void rightMarkerMoved(MarkerDragEvent e) { + Debug.trace(); if (selectedSentence != null) { if (!selectedSentence.isLocked()) { selectedSentence.setEndOffset(e.getPosition()); @@ -436,6 +471,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { reprocessAudioFFT = new JButtonSpacePlay(Icons.fft, "Autotrim Audio (FFT)", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (selectedSentence != null) { selectedSentence.autoTrimSampleFFT(); sampleWaveform.setData(selectedSentence.getDoubleAudioData(effectsEnabled)); @@ -449,6 +485,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { reprocessAudioPeak = new JButtonSpacePlay(Icons.peak, "Autotrim Audio (Peak)", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (selectedSentence != null) { selectedSentence.autoTrimSamplePeak(); sampleWaveform.setData(selectedSentence.getDoubleAudioData(effectsEnabled)); @@ -462,6 +499,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { normalizeAudio = new JButtonSpacePlay(Icons.normalize, "Normalize audio", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (selectedSentence != null) { selectedSentence.normalize(); sampleWaveform.setData(selectedSentence.getDoubleAudioData(effectsEnabled)); @@ -471,18 +509,21 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { selectSplitMode = new JToggleButtonSpacePlay(Icons.split, "Toggle split mode", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); toggleSplitMode(); } }); selectCutMode = new JToggleButtonSpacePlay(Icons.cut, "Toggle cut mode", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); toggleCutMode(); } }); doCutSplit = new JButtonSpacePlay(Icons.docut, "Perform cut or split", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); executeCutOrSplit(); } }); @@ -492,6 +533,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { postSentenceGap.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { + Debug.trace(); JSpinner ob = (JSpinner)e.getSource(); if (selectedSentence != null) { selectedSentence.setPostGap((Integer)ob.getValue()); @@ -504,6 +546,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { gainPercent.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { + Debug.trace(); JSpinner ob = (JSpinner)e.getSource(); if (selectedSentence != null) { selectedSentence.setGain((Integer)ob.getValue() / 100d); @@ -536,6 +579,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { locked.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JCheckBox c = (JCheckBox)e.getSource(); if (c.isSelected()) { if (selectedSentence != null) { @@ -566,6 +610,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { attention.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JCheckBox c = (JCheckBox)e.getSource(); if (c.isSelected()) { if (selectedSentence != null) { @@ -596,6 +641,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JButtonSpacePlay zoomIn = new JButtonSpacePlay(Icons.zoomIn, "Zoom In", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); sampleWaveform.increaseZoom(); } }); @@ -603,6 +649,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JButtonSpacePlay zoomOut = new JButtonSpacePlay(Icons.zoomOut, "Zoom Out", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); sampleWaveform.decreaseZoom(); } }); @@ -618,6 +665,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { effectChain.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); + Debug.d(e); if (selectedSentence != null) { int i = effectChain.getSelectedIndex(); KVPair p = effectChain.getItemAt(i); @@ -650,6 +699,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { centralPanel.getActionMap().put("startRecord", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (!getLock()) return; if (getFocusOwner() == bookNotesArea) { freeLock(); return; } if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } @@ -668,6 +718,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { }); centralPanel.getActionMap().put("startRecordShort", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (!getLock()) return; if (getFocusOwner() == bookNotesArea) { freeLock(); return; } if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } @@ -686,6 +737,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { }); centralPanel.getActionMap().put("startRecordNewPara", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (!getLock()) return; if (getFocusOwner() == bookNotesArea) { freeLock(); return; } if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } @@ -704,6 +756,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { }); centralPanel.getActionMap().put("startRecordNewSection", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (!getLock()) return; if (getFocusOwner() == bookNotesArea) { freeLock(); return; } if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } @@ -722,6 +775,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { }); centralPanel.getActionMap().put("startRerecord", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (!getLock()) return; if (getFocusOwner() == bookNotesArea) { freeLock(); return; } if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } @@ -740,6 +794,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { }); centralPanel.getActionMap().put("stopRecord", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (getFocusOwner() == bookNotesArea) { return; } if (getFocusOwner() == chapterNotesArea) { return; } if (getFocusOwner() == sentenceNotesArea) { return; } @@ -751,6 +806,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { }); centralPanel.getActionMap().put("deleteLast", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (getFocusOwner() == bookNotesArea) { return; } if (getFocusOwner() == chapterNotesArea) { return; } if (getFocusOwner() == sentenceNotesArea) { return; } @@ -761,6 +817,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { centralPanel.getActionMap().put("startStopPlayback", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (getFocusOwner() == bookNotesArea) { return; } if (getFocusOwner() == chapterNotesArea) { return; } if (getFocusOwner() == sentenceNotesArea) { return; } @@ -775,6 +832,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { centralPanel.getActionMap().put("startPlaybackFrom", new AbstractAction() { public void actionPerformed(ActionEvent e) { + Debug.trace(); if (getFocusOwner() == bookNotesArea) { return; } if (getFocusOwner() == chapterNotesArea) { return; } if (getFocusOwner() == sentenceNotesArea) { return; } @@ -815,10 +873,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { mainSplit.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent ev) { + Debug.trace(); if (ev.getPropertyName().equals("dividerLocation")) { if ((bookTreeModel != null) && (book != null)) { SwingUtilities.invokeLater(new Runnable() { public void run() { + Debug.trace(); bookTreeModel.reload(book); } }); @@ -841,6 +901,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { SwingUtilities.invokeLater(new Runnable() { public void run() { + Debug.trace(); mainSplit.setDividerLocation(0.8d); } }); @@ -876,6 +937,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } void bindKeys(JComponent component) { + Debug.trace(); component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F"), "startRecordShort"); component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released F"), "stopRecord"); @@ -898,6 +960,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } void unbindKeys(JComponent component) { + Debug.trace(); component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F"), "ignore"); component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released F"), "ignore"); @@ -920,6 +983,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public static void main(String args[]) { + Debug.trace(); try { config.load(AudiobookRecorder.class.getResourceAsStream("config.txt")); } catch (Exception e) { @@ -927,10 +991,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } - new AudiobookRecorder(); + new AudiobookRecorder(args); } public void createNewBook() { + Debug.trace(); BookInfoPanel info = new BookInfoPanel("", "", "", "", ""); int r = JOptionPane.showConfirmDialog(this, info, "New Book", JOptionPane.OK_CANCEL_OPTION); if (r != JOptionPane.OK_OPTION) return; @@ -990,20 +1055,24 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public JMenuObject(String p) { super(p); + Debug.trace(); ob = null; } public JMenuObject(String p, Object o, ActionListener l) { super(p); + Debug.trace(); ob = o; addActionListener(l); } public void setObject(Object o) { + Debug.trace(); ob = o; } public Object getObject() { + Debug.trace(); return ob; } } @@ -1014,30 +1083,36 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public JMenuObject2(String p) { super(p); + Debug.trace(); ob1 = null; ob2 = null; } public JMenuObject2(String p, Object o1, Object o2, ActionListener l) { super(p); + Debug.trace(); ob1 = o1; ob2 = o2; addActionListener(l); } public void setObject1(Object o) { + Debug.trace(); ob1 = o; } public void setObject2(Object o) { + Debug.trace(); ob2 = o; } public Object getObject1() { + Debug.trace(); return ob1; } public Object getObject2() { + Debug.trace(); return ob2; } } @@ -1046,9 +1121,11 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { Chapter chapter; public BatchConversionThread(Chapter c) { + Debug.trace(); chapter = c; } public void run() { + Debug.trace(); try { Configuration sphinxConfig = new Configuration(); @@ -1080,6 +1157,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { @SuppressWarnings("unchecked") void treePopup(MouseEvent e) { + Debug.trace(); int selRow = bookTree.getRowForLocation(e.getX(), e.getY()); TreePath selPath = bookTree.getPathForLocation(e.getX(), e.getY()); if (selRow != -1) { @@ -1095,6 +1173,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject rec = new JMenuObject("Recognise text from audio", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Sentence s = (Sentence)o.getObject(); if (!s.isLocked()) { @@ -1112,6 +1191,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { Chapter chp = (Chapter)c.nextElement(); JMenuObject2 m = new JMenuObject2(chp.getName(), s, chp, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject2 ob = (JMenuObject2)e.getSource(); Sentence sentence = (Sentence)ob.getObject1(); Chapter target = (Chapter)ob.getObject2(); @@ -1125,6 +1205,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject moveUp = new JMenuObject("Move Up", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Sentence sent = (Sentence)o.getObject(); Chapter chap = (Chapter)sent.getParent(); @@ -1137,6 +1218,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject moveDown = new JMenuObject("Move Down", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Sentence sent = (Sentence)o.getObject(); Chapter chap = (Chapter)sent.getParent(); @@ -1166,6 +1248,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject2 gapTypeSentence = new JMenuObject2(sentenceText, s, "sentence", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject2 o = (JMenuObject2)e.getSource(); Sentence sent = (Sentence)o.getObject1(); String type = (String)o.getObject2(); @@ -1178,6 +1261,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject2 gapTypeContinuation = new JMenuObject2(continuationText, s, "continuation", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject2 o = (JMenuObject2)e.getSource(); Sentence sent = (Sentence)o.getObject1(); String type = (String)o.getObject2(); @@ -1190,6 +1274,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject2 gapTypeParagraph = new JMenuObject2(paragraphText, s, "paragraph", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject2 o = (JMenuObject2)e.getSource(); Sentence sent = (Sentence)o.getObject1(); String type = (String)o.getObject2(); @@ -1202,6 +1287,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject2 gapTypeSection = new JMenuObject2(sectionText, s, "section", new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject2 o = (JMenuObject2)e.getSource(); Sentence sent = (Sentence)o.getObject1(); String type = (String)o.getObject2(); @@ -1216,6 +1302,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject ins = new JMenuObject("Insert phrase above", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Sentence s = (Sentence)o.getObject(); Chapter c = (Chapter)s.getParent(); @@ -1228,6 +1315,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject del = new JMenuObject("Delete phrase", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Sentence s = (Sentence)o.getObject(); if (!s.isLocked()) { @@ -1239,6 +1327,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject dup = new JMenuObject("Duplicate phrase", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); try { JMenuObject o = (JMenuObject)e.getSource(); Sentence s = (Sentence)o.getObject(); @@ -1255,6 +1344,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject edit = new JMenuObject("Open in external editor", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); try { JMenuObject o = (JMenuObject)e.getSource(); Sentence s = (Sentence)o.getObject(); @@ -1273,6 +1363,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { if (name.equals("")) break; JMenuObject ob = new JMenuObject(name, s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Sentence s = (Sentence)o.getObject(); s.runExternalProcessor(Utils.s2i(o.getActionCommand())); @@ -1284,6 +1375,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject undo = new JMenuObject("Undo", s, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Sentence s = (Sentence)o.getObject(); s.undo(); @@ -1316,6 +1408,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject undo = new JMenuObject("Undo all", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter c = (Chapter)o.getObject(); for (Enumeration s = c.children(); s.hasMoreElements();) { @@ -1327,6 +1420,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject peaknew = new JMenuObject("Auto-trim new (Peak)", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); @@ -1341,6 +1435,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject fftnew = new JMenuObject("Auto-trim new (FFT)", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); @@ -1355,6 +1450,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject peak = new JMenuObject("Auto-trim all (Peak)", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); @@ -1369,6 +1465,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject fft = new JMenuObject("Auto-trim all (FFT)", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); @@ -1383,6 +1480,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject resetChapterGaps = new JMenuObject("Reset post gaps", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter c = (Chapter)o.getObject(); c.resetPostGaps(); @@ -1391,6 +1489,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject moveUp = new JMenuObject("Move Up", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); int pos = bookTreeModel.getIndexOfChild(book, chap); @@ -1412,6 +1511,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject moveDown = new JMenuObject("Move Down", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); int pos = bookTreeModel.getIndexOfChild(book, chap); @@ -1440,6 +1540,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } JMenuObject2 m = new JMenuObject2(chp.getName(), c, chp, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject2 ob = (JMenuObject2)e.getSource(); Chapter source = (Chapter)ob.getObject1(); Chapter target = (Chapter)ob.getObject2(); @@ -1457,6 +1558,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject lockAll = new JMenuObject("Lock all phrases", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter c = (Chapter)o.getObject(); for (Enumeration s = c.children(); s.hasMoreElements();) { @@ -1469,6 +1571,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject unlockAll = new JMenuObject("Unlock all phrases", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter c = (Chapter)o.getObject(); for (Enumeration s = c.children(); s.hasMoreElements();) { @@ -1481,6 +1584,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject exportChapter = new JMenuObject("Export chapter", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); @@ -1495,6 +1599,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject deleteChapter = new JMenuObject("Delete chapter", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter c = (Chapter)o.getObject(); int rv = JOptionPane.showConfirmDialog(AudiobookRecorder.this, "Are you sure you want to delete this chapter?", "Are you sure?", JOptionPane.OK_CANCEL_OPTION); @@ -1512,6 +1617,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject convertAll = new JMenuObject("Detect all text", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter c = (Chapter)o.getObject(); BatchConversionThread r = new BatchConversionThread(c); @@ -1522,6 +1628,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject normalizeAll = new JMenuObject("Normalize chapter", c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter chap = (Chapter)o.getObject(); @@ -1543,6 +1650,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { if (name.equals("")) break; JMenuObject ob = new JMenuObject(name, c, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JMenuObject o = (JMenuObject)e.getSource(); Chapter c = (Chapter)o.getObject(); for (Enumeration s = c.children(); s.hasMoreElements();) { @@ -1588,6 +1696,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuItem editData = new JMenuItem("Edit Data..."); editData.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); JTabbedPane tabs = new JTabbedPane(); BookInfoPanel info = new BookInfoPanel( book.getName(), @@ -1655,6 +1764,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { JMenuObject resetBookGaps = new JMenuObject("Reset all post gaps", book, new ActionListener() { public void actionPerformed(ActionEvent e) { + Debug.trace(); for (Enumeration ch = book.children(); ch.hasMoreElements();) { Chapter chap = (Chapter)ch.nextElement(); chap.resetPostGaps(); @@ -1671,6 +1781,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void startReRecording() { + Debug.trace(); if (recording != null) return; if (book == null) return; @@ -1708,6 +1819,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void startRecordingShort() { + Debug.trace(); if (recording != null) return; if (book == null) return; @@ -1759,6 +1871,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public void startRecordingNewParagraph() { + Debug.trace(); if (recording != null) return; if (book == null) return; @@ -1809,6 +1922,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void startRecordingNewSection() { + Debug.trace(); if (recording != null) return; if (book == null) return; @@ -1859,6 +1973,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void startRecording() { + Debug.trace(); if (recording != null) return; if (book == null) return; @@ -1909,6 +2024,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void stopRecording() { + Debug.trace(); if (recording == null) return; recording.stopRecording(); @@ -1924,6 +2040,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void deleteLastRecording() { + Debug.trace(); if (recording != null) return; if (book == null) return; @@ -1967,6 +2084,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void addChapter() { + Debug.trace(); Chapter c = book.addChapter(); Chapter lc = book.getLastChapter(); int i = bookTreeModel.getIndexOfChild(book, lc); @@ -1976,6 +2094,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { @SuppressWarnings("unchecked") public void saveBookStructure() { + Debug.trace(); if (book == null) return; File bookRoot = new File(Options.get("path.storage"), book.getName()); @@ -2002,6 +2121,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void loadXMLBookStructure(File inputFile) { + Debug.trace(); try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); @@ -2034,6 +2154,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookTree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { + Debug.trace(); + DefaultMutableTreeNode n = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); if (n instanceof BookTreeNode) { @@ -2083,12 +2205,14 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookTree.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { + Debug.trace(); if (e.isPopupTrigger()) { treePopup(e); } } public void mouseReleased(MouseEvent e) { + Debug.trace(); if (e.isPopupTrigger()) { treePopup(e); } @@ -2125,6 +2249,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void loadBookStructure(File f) { + Debug.trace(); try { Properties prefs = new Properties(); FileInputStream fis = new FileInputStream(f); @@ -2155,6 +2280,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { /* Retained for legacy use...! */ public void buildBook(Properties prefs) { + Debug.trace(); book = new Book(prefs, prefs.getProperty("book.name")); @@ -2207,6 +2333,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookTree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { + Debug.trace(); DefaultMutableTreeNode n = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); if (n instanceof BookTreeNode) { BookTreeNode btn = (BookTreeNode)n; @@ -2255,12 +2382,14 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookTree.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { + Debug.trace(); if (e.isPopupTrigger()) { treePopup(e); } } public void mouseReleased(MouseEvent e) { + Debug.trace(); if (e.isPopupTrigger()) { treePopup(e); } @@ -2373,6 +2502,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void openBook() { + Debug.trace(); OpenBookPanel info = new OpenBookPanel(); int r = JOptionPane.showConfirmDialog(this, info, "Open Book", JOptionPane.OK_CANCEL_OPTION); @@ -2409,6 +2539,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public File getBookFolder() { + Debug.trace(); File bf = new File(Options.get("path.storage"), book.getName()); if (!bf.exists()) { bf.mkdirs(); @@ -2417,44 +2548,26 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public double getNoiseFloor() { + Debug.trace(); if (roomNoise == null) return 0; return roomNoise.getPeak(); -/* double[][] samples = roomNoise.getDoubleAudioData(); - if (samples == null) { - return 0; - } - double ms = 0; - for (int i = 0; i < samples.length; i++) { - if (Math.abs((samples[i][Sentence.LEFT] + samples[i][Sentence.RIGHT]) / 2d) > ms) { - ms = Math.abs((samples[i][Sentence.LEFT] + samples[i][Sentence.RIGHT]) / 2d); - } - } - - ms *= 10d; - ms /= 7d; - return ms;*/ } public int getNoiseFloorDB() { + Debug.trace(); if (roomNoise == null) return 0; return roomNoise.getPeakDB(); -/* - double r = getNoiseFloor(); - if (r == 0) return 0; - double l10 = Math.log10(r); - double db = 20d * l10; - - return (int)db; -*/ } public void recordRoomNoise() { + Debug.trace(); if (roomNoise.startRecording()) { centralPanel.setFlash(true); java.util.Timer ticker = new java.util.Timer(true); ticker.schedule(new TimerTask() { public void run() { + Debug.trace(); roomNoise.stopRecording(); centralPanel.setFlash(false); statusLabel.setText("Noise floor: " + getNoiseFloorDB() + "dB"); @@ -2465,6 +2578,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public void playSelectedSentence() { + Debug.trace(); if (selectedSentence == null) return; if (playing != null) return; if (getNoiseFloor() == 0) { @@ -2475,6 +2589,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { playingThread = new Thread(new Runnable() { public void run() { + Debug.trace(); Sentence s = playing; byte[] data; @@ -2514,7 +2629,6 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { play.close(); } play = null; - e.printStackTrace(); } } }); @@ -2529,12 +2643,14 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public NormalizeThread(Chapter c, ProgressDialog e) { super(); + Debug.trace(); dialog = e; chapter = c; } @SuppressWarnings("unchecked") public void run() { + Debug.trace(); int numKids = chapter.getChildCount(); int kidCount = 0; @@ -2568,6 +2684,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public AutoTrimThread(Chapter c, ProgressDialog e, int t, int sc) { super(); + Debug.trace(); dialog = e; chapter = c; type = t; @@ -2576,6 +2693,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { @SuppressWarnings("unchecked") public void run() { + Debug.trace(); int numKids = chapter.getChildCount(); int kidCount = 0; @@ -2608,12 +2726,14 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public ExportThread(Chapter c, ProgressDialog e) { super(); + Debug.trace(); exportDialog = e; chapter = c; } @SuppressWarnings("unchecked") public void run() { + Debug.trace(); try { chapter.exportChapter(exportDialog); @@ -2627,6 +2747,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { @SuppressWarnings("unchecked") public void exportAudio() { + Debug.trace(); for (Enumeration o = book.children(); o.hasMoreElements();) { @@ -2644,6 +2765,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public void playToSelectedSentence() { + Debug.trace(); if (selectedSentence == null) return; if (playing != null) return; if (getNoiseFloor() == 0) { @@ -2654,6 +2776,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { playingThread = new Thread(new Runnable() { public void run() { + Debug.trace(); Sentence s = playing; byte[] data; @@ -2722,6 +2845,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void playFromSelectedSentence() { + Debug.trace(); if (selectedSentence == null) return; if (playing != null) return; if (getNoiseFloor() == 0) { @@ -2732,6 +2856,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { playingThread = new Thread(new Runnable() { public void run() { + Debug.trace(); Sentence s = playing; byte[] data; @@ -2766,6 +2891,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { if (next != null) { Thread t = new Thread(new Runnable() { public void run() { + Debug.trace(); Sentence ns = (Sentence)next; ns.getProcessedAudioData(effectsEnabled); // Cache it } @@ -2822,6 +2948,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { public byte[] getRoomNoise(int ms) { + Debug.trace(); if (roomNoise == null) return null; @@ -2848,6 +2975,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void stopPlaying() { + Debug.trace(); if (play != null) { play.close(); play = null; @@ -2856,10 +2984,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void alertNoRoomNoise() { + Debug.trace(); JOptionPane.showMessageDialog(this, "You must record room noise\nbefore recording or playback", "Error", JOptionPane.ERROR_MESSAGE); } public boolean enableMicrophone() { + Debug.trace(); AudioFormat format = Options.getAudioFormat(); Mixer.Info mixer = Options.getRecordingMixer(); @@ -2894,6 +3024,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void disableMicrophone() { + Debug.trace(); try { microphoneStream.close(); microphone.stop(); @@ -2906,6 +3037,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void execScript(String s) { + Debug.trace(); if (s == null) return; String[] lines = s.split("\n"); @@ -2923,6 +3055,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void mergeBook() { + Debug.trace(); OpenBookPanel info = new OpenBookPanel(); int r = JOptionPane.showConfirmDialog(this, info, "Merge Book", JOptionPane.OK_CANCEL_OPTION); if (r == JOptionPane.OK_OPTION) { @@ -2984,6 +3117,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void mergeChapter(Properties prefs, String chid) { + Debug.trace(); Chapter c = book.addChapter(); c.setName("Merged-" + prefs.getProperty("chapter." + chid + ".name")); c.setPostGap(Utils.s2i(prefs.getProperty("chapter." + chid + ".post-gap"))); @@ -3051,10 +3185,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { ProgressDialog pd; public ArchiveBookThread(ProgressDialog p) { + Debug.trace(); pd = p; } public void run() { + Debug.trace(); try { String name = AudiobookRecorder.this.book.getName(); File storageDir = new File(Options.get("path.storage")); @@ -3154,6 +3290,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void archiveBook() { + Debug.trace(); int r = JOptionPane.showConfirmDialog(this, "This will stash the current book away\nin the archives folder in a compressed\nform. The existing book files will be deleted\nand the book closed.\n\nAre you sure you want to do this?", "Archive Book", JOptionPane.OK_CANCEL_OPTION); if (r == JOptionPane.OK_OPTION) { @@ -3172,6 +3309,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void openArchive() { + Debug.trace(); JFileChooser jc = new JFileChooser(new File(Options.get("path.archive"))); FileNameExtensionFilter filter = new FileNameExtensionFilter("Audiobook Archives", "abz"); jc.addChoosableFileFilter(filter); @@ -3195,6 +3333,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { ZipInputStream zis = new ZipInputStream(new FileInputStream(f)) { public void close() throws IOException { + Debug.trace(); return; } }; @@ -3274,6 +3413,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void loadCoverArt() { + Debug.trace(); if (book == null) return; JFileChooser jc = new JFileChooser(); @@ -3321,7 +3461,10 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void updateWaveform() { + Debug.trace(); if (selectedSentence != null) { + if ((sampleWaveform.getId() != null) && (sampleWaveform.getId().equals(selectedSentence.getId()))) return; + sampleWaveform.setId(selectedSentence.getId()); if (rawAudio.isSelected()) { sampleWaveform.setData(selectedSentence.getRawAudioData()); } else { @@ -3331,6 +3474,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void loadEffects() { + Debug.trace(); effects = new TreeMap(); loadEffectsFromFolder(new File(Options.get("path.storage"), "System")); if (book != null) { @@ -3340,6 +3484,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void loadEffectsFromFolder(File dir) { + Debug.trace(); if (dir == null) return; if (!dir.exists()) return; File[] files = dir.listFiles(); @@ -3355,6 +3500,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public EffectGroup loadEffect(File xml) { + Debug.trace(); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); @@ -3372,6 +3518,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public EffectGroup loadEffectGroup(Element root) { + Debug.trace(); EffectGroup group = new EffectGroup(root.getAttribute("name")); NodeList kids = root.getChildNodes(); for (int i = 0; i < kids.getLength(); i++) { @@ -3430,6 +3577,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public Biquad loadBiquad(Element root) { + Debug.trace(); String type = root.getAttribute("type").toLowerCase(); Biquad bq = new Biquad(); @@ -3459,6 +3607,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public DelayLine loadDelayLine(Element root) { + Debug.trace(); DelayLine line = new DelayLine(); NodeList list = root.getChildNodes(); @@ -3539,26 +3688,31 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public Amplifier loadAmplifier(Element root) { + Debug.trace(); Amplifier a = new Amplifier(Utils.s2d(root.getAttribute("gain"))); return a; } public Chain loadChain(Element root) { + Debug.trace(); Chain c = new Chain(root.getAttribute("src")); return c; } public Pan loadPan(Element root) { + Debug.trace(); Pan p = new Pan(Utils.s2d(root.getAttribute("pan"))); return p; } public Clipping loadClipping(Element root) { + Debug.trace(); Clipping c = new Clipping(Utils.s2d(root.getAttribute("clip"))); return c; } public LFO loadLFO(Element root) { + Debug.trace(); double f = Utils.s2d(root.getAttribute("frequency")); double d = Utils.s2d(root.getAttribute("depth")); double p = Utils.s2d(root.getAttribute("phase")); @@ -3599,6 +3753,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public AGC loadAGC(Element root) { + Debug.trace(); double ceiling = Utils.s2d(root.getAttribute("ceiling")); double limit = Utils.s2d(root.getAttribute("limit")); double attack = Utils.s2d(root.getAttribute("attack")); @@ -3614,6 +3769,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void updateEffectChains() { + Debug.trace(); int sel = effectChain.getSelectedIndex(); KVPair ent = effectChain.getItemAt(sel); while (effectChain.getItemCount() > 0) { @@ -3635,6 +3791,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void setEffectChain(String key) { + Debug.trace(); for (int i = 0; i < effectChain.getItemCount(); i++) { KVPair p = effectChain.getItemAt(i); if (p.getKey().equals(key)) { @@ -3654,10 +3811,12 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public String getDefaultEffectsChain() { + Debug.trace(); return book.getDefaultEffect(); } public synchronized boolean getLock() { + Debug.trace(); if (state == RECORDING) return false; int counts = 0; @@ -3677,14 +3836,17 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void freeLock() { + Debug.trace(); state = IDLE; } public void stopLock() { + Debug.trace(); state = STOPPING; } public void toggleSplitMode() { + Debug.trace(); selectCutMode.setSelected(false); if (selectedSentence != null) { sampleWaveform.setDisplaySplit(selectSplitMode.isSelected()); @@ -3694,6 +3856,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void toggleCutMode() { + Debug.trace(); selectSplitMode.setSelected(false); if (selectedSentence != null) { sampleWaveform.setDisplayCut(selectCutMode.isSelected()); @@ -3703,12 +3866,13 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void doCut(int start, int end) { + Debug.trace(); try { double[][] samples = selectedSentence.getRawAudioData(); - double[][] croppedSamples = new double[samples.length - (end - start)][2]; + double[][] croppedSamples = new double[2][samples[Sentence.LEFT].length - (end - start)]; int a = 0; - for (int i = 0; i < samples.length; i++) { + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { if ((i < start) || (i > end)) { croppedSamples[a++] = samples[i]; } @@ -3722,6 +3886,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void doSplit(int at) { + Debug.trace(); try { if (selectedSentence == null) { System.err.println("Selected sentence is NULL in split. That CANNOT happen!"); @@ -3733,13 +3898,13 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { bookTreeModel.insertNodeInto(newSentence, c, idx); double[][] samples = selectedSentence.getRawAudioData(); - double[][] startSamples = new double[at][2]; - double[][] endSamples = new double[samples.length - at][2]; + double[][] startSamples = new double[2][at]; + double[][] endSamples = new double[2][samples[Sentence.LEFT].length - at]; int a = 0; int b = 0; - for (int i = 0; i < samples.length; i++) { + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { if (i < at) { startSamples[a++] = samples[i]; } else { @@ -3761,6 +3926,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void executeCutOrSplit() { + Debug.trace(); int start = sampleWaveform.getCutStart(); int end = sampleWaveform.getCutEnd(); if (selectCutMode.isSelected()) { @@ -3775,35 +3941,43 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void setEffectsEnabled(boolean b) { + Debug.trace(); effectsEnabled = b; System.err.println("Effects Enabled: " + b); } public void setBookNotes(String text) { + Debug.trace(); bookNotesArea.setText(text); } public void setChapterNotes(String text) { + Debug.trace(); chapterNotesArea.setText(text); } public void setSentenceNotes(String text) { + Debug.trace(); sentenceNotesArea.setText(text); } public String getBookNotes() { + Debug.trace(); return bookNotesArea.getText(); } public String getChapterNotes() { + Debug.trace(); return chapterNotesArea.getText(); } public String getSentenceNotes() { + Debug.trace(); return sentenceNotesArea.getText(); } public void openManuscript() { + Debug.trace(); if (book == null) return; File ms = book.getManuscript(); if (ms == null) return; @@ -3815,6 +3989,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void loadManuscript() { + Debug.trace(); if (book == null) return; JFileChooser jc = new JFileChooser(); @@ -3835,6 +4010,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { //* DocumentListener public void changedUpdate(DocumentEvent e) { + Debug.trace(); javax.swing.text.Document doc = e.getDocument(); if (doc == chapterNotesArea.getDocument()) { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); @@ -3857,6 +4033,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void removeUpdate(DocumentEvent e) { + Debug.trace(); javax.swing.text.Document doc = e.getDocument(); if (doc == chapterNotesArea.getDocument()) { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); @@ -3879,6 +4056,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener { } public void insertUpdate(DocumentEvent e) { + Debug.trace(); javax.swing.text.Document doc = e.getDocument(); if (doc == chapterNotesArea.getDocument()) { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); diff --git a/src/uk/co/majenko/audiobookrecorder/Biquad.java b/src/uk/co/majenko/audiobookrecorder/Biquad.java index 3f4cc8e..f6af8a9 100644 --- a/src/uk/co/majenko/audiobookrecorder/Biquad.java +++ b/src/uk/co/majenko/audiobookrecorder/Biquad.java @@ -94,19 +94,19 @@ public class Biquad implements Effect { lz2 = 0d; rz1 = 0d; rz2 = 0d; - for (double[] in : samples) { - double lout = in[Sentence.LEFT] * a0 + lz1; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + double lout = samples[Sentence.LEFT][i] * a0 + lz1; - lz1 = in[Sentence.LEFT] * a1 + lz2 - b1 * lout; - lz2 = in[Sentence.LEFT] * a2 - b2 * lout; + lz1 = samples[Sentence.LEFT][i] * a1 + lz2 - b1 * lout; + lz2 = samples[Sentence.LEFT][i] * a2 - b2 * lout; - double rout = in[Sentence.RIGHT] * a0 + rz1; + double rout = samples[Sentence.RIGHT][i] * a0 + rz1; - rz1 = in[Sentence.RIGHT] * a1 + rz2 - b1 * rout; - rz2 = in[Sentence.RIGHT] * a2 - b2 * rout; + rz1 = samples[Sentence.RIGHT][i] * a1 + rz2 - b1 * rout; + rz2 = samples[Sentence.RIGHT][i] * a2 - b2 * rout; - in[Sentence.LEFT] = lout; - in[Sentence.RIGHT] = rout; + samples[Sentence.LEFT][i] = lout; + samples[Sentence.RIGHT][i] = rout; } } diff --git a/src/uk/co/majenko/audiobookrecorder/Clipping.java b/src/uk/co/majenko/audiobookrecorder/Clipping.java index fda3d98..3a6d843 100644 --- a/src/uk/co/majenko/audiobookrecorder/Clipping.java +++ b/src/uk/co/majenko/audiobookrecorder/Clipping.java @@ -20,11 +20,11 @@ public class Clipping implements Effect { } public void process(double[][] samples) { - for (double[] sample : samples) { - if (sample[Sentence.LEFT] > clip) sample[Sentence.LEFT] = clip; - if (sample[Sentence.LEFT] < -clip) sample[Sentence.LEFT] = -clip; - if (sample[Sentence.RIGHT] > clip) sample[Sentence.RIGHT] = clip; - if (sample[Sentence.RIGHT] < -clip) sample[Sentence.RIGHT] = -clip; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + if (samples[Sentence.LEFT][i] > clip) samples[Sentence.LEFT][i] = clip; + if (samples[Sentence.LEFT][i] < -clip) samples[Sentence.LEFT][i] = -clip; + if (samples[Sentence.RIGHT][i] > clip) samples[Sentence.RIGHT][i] = clip; + if (samples[Sentence.RIGHT][i] < -clip) samples[Sentence.RIGHT][i] = -clip; } } diff --git a/src/uk/co/majenko/audiobookrecorder/CommandLine.java b/src/uk/co/majenko/audiobookrecorder/CommandLine.java new file mode 100644 index 0000000..b545a7c --- /dev/null +++ b/src/uk/co/majenko/audiobookrecorder/CommandLine.java @@ -0,0 +1,192 @@ +package uk.co.majenko.audiobookrecorder; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashMap; + +public class CommandLine { + HashMap> parameterTypes = new HashMap>(); + HashMap parameterComments = new HashMap(); + HashMap parameterValues = new HashMap(); + HashMap parameterNames = new HashMap(); + ArrayList extraValues = new ArrayList(); + + public CommandLine() { + } + + public void addParameter(String key, String name, Class type, String comment) { + parameterNames.put(key, name); + parameterTypes.put(key, type); + parameterComments.put(key, comment); + } + + public String[] process(String[] args) { + parameterValues = new HashMap(); + extraValues = new ArrayList(); + + for (String arg : args) { + if (arg.startsWith("--")) { + arg = arg.substring(2); + String value = ""; + int equals = arg.indexOf("="); + if (equals > -1) { + value = arg.substring(equals + 1); + arg = arg.substring(0, equals); + } + + Class aclass = parameterTypes.get(arg); + if (aclass == null) { + help(); + System.exit(0); + } + if (aclass == Boolean.class) { + Boolean b = true; + parameterValues.put(arg, b); + continue; + } + if (value.equals("")) { + help(); + System.exit(0); + } + if (aclass == Integer.class) { + Integer i = 0; + try { + i = Integer.parseInt(value); + } catch (Exception ignored) { + } + parameterValues.put(arg, i); + continue; + } + if (aclass == Float.class) { + Float f = 0F; + try { + f = Float.parseFloat(value); + } catch (Exception ignored) { + } + parameterValues.put(arg, f); + continue; + } + if (aclass == Double.class) { + Double d = 0D; + try { + d = Double.parseDouble(value); + } catch (Exception ignored) { + } + parameterValues.put(arg, d); + continue; + } + if (aclass == String.class) { + parameterValues.put(arg, value); + continue; + } + } else { + extraValues.add(arg); + } + } + + return extraValues.toArray(new String[0]); + } + + public void help() { + System.out.println("Available command line arguments:"); + int maxlen = 0; + + String[] arglist = parameterTypes.keySet().toArray(new String[0]); + Arrays.sort(arglist); + + for (String s : arglist) { + int thislen = s.length(); + if (parameterTypes.get(s) != Boolean.class) { + thislen++; + thislen += parameterNames.get(s).length(); + } + if (thislen > maxlen) { + maxlen = thislen; + } + } + for (String s : arglist) { + StringBuilder sb = new StringBuilder(); + System.out.print(" --"); + sb.append(s); + if (parameterTypes.get(s) != Boolean.class) { + sb.append("="); + sb.append(parameterNames.get(s)); + } + while (sb.length() < maxlen) { + sb.append(" "); + } + System.out.print(sb.toString()); + System.out.print(" "); + System.out.println(parameterComments.get(s)); + } + } + + public boolean isSet(String key) { + Object value = parameterValues.get(key); + if (value == null) { + return false; + } + return true; + } + + public String getString(String key) { + Class type = parameterTypes.get(key); + if (type == null) { + return null; + } + if (type != String.class) { + return null; + } + String value = (String)parameterValues.get(key); + return value; + } + + public int getInteger(String key) { + Class type = parameterTypes.get(key); + if (type == null) { + return 0; + } + if (type != Integer.class) { + return 0; + } + Integer value = (Integer)parameterValues.get(key); + if (value == null) { + return 0; + } + return (int)value; + } + + public float getFloat(String key) { + Class type = parameterTypes.get(key); + if (type == null) { + return 0f; + } + if (type != Float.class) { + return 0f; + } + Float value = (Float)parameterValues.get(key); + if (value == null) { + return 0f; + } + return (float)value; + } + + public double getDouble(String key) { + Class type = parameterTypes.get(key); + if (type == null) { + return 0d; + } + if (type != Double.class) { + return 0d; + } + Double value = (Double)parameterValues.get(key); + if (value == null) { + return 0d; + } + return (double)value; + } + + public void set(String key, String value) { + parameterValues.put(key, value); + } +} diff --git a/src/uk/co/majenko/audiobookrecorder/Debug.java b/src/uk/co/majenko/audiobookrecorder/Debug.java index 3134850..2efe3f1 100644 --- a/src/uk/co/majenko/audiobookrecorder/Debug.java +++ b/src/uk/co/majenko/audiobookrecorder/Debug.java @@ -1,12 +1,53 @@ package uk.co.majenko.audiobookrecorder; +import java.util.Date; +import java.text.SimpleDateFormat; + public class Debug { static long timestamp; + static public boolean debugEnabled = false; + static public boolean traceEnabled = false; static void debug(String msg) { + if (!debugEnabled) return; long now = System.currentTimeMillis(); long diff = now - timestamp; timestamp = now; System.err.println(String.format("%8d - %s", diff, msg)); } + + static void d(Object... args) { + if (!debugEnabled) return; + + Thread t = Thread.currentThread(); + StackTraceElement[] st = t.getStackTrace(); + StackTraceElement caller = st[2]; + + String tag = "[" + getCurrentLocalDateTimeStamp() + "] " + caller.getFileName() + " " + caller.getLineNumber() + " (" + caller.getMethodName() + "):"; + + System.err.print(tag); + + for (Object o : args) { + System.err.print(" "); + System.err.print(o); + } + System.err.println(); + } + + static void trace() { + if (!traceEnabled) return; + Thread t = Thread.currentThread(); + StackTraceElement[] st = t.getStackTrace(); + StackTraceElement caller = st[3]; + StackTraceElement callee = st[2]; + + String tag = "[" + getCurrentLocalDateTimeStamp() + "] " + t.getName() + " - " + caller.getFileName() + ":" + caller.getLineNumber() + " " + caller.getMethodName() + "(...) -> " + callee.getFileName() + ":" + callee.getLineNumber() + " " + callee.getMethodName() + "(...)"; + + System.err.println(tag); + } + + public static String getCurrentLocalDateTimeStamp() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()); + } + } diff --git a/src/uk/co/majenko/audiobookrecorder/DelayLine.java b/src/uk/co/majenko/audiobookrecorder/DelayLine.java index a4dc2e3..62beda9 100644 --- a/src/uk/co/majenko/audiobookrecorder/DelayLine.java +++ b/src/uk/co/majenko/audiobookrecorder/DelayLine.java @@ -17,60 +17,50 @@ public class DelayLine implements Effect { } public void process(double[][] samples) { - double[][] savedSamples = new double[samples.length][2]; - for (int i = 0; i < samples.length; i++) { - savedSamples[i][Sentence.LEFT] = samples[i][Sentence.LEFT]; - savedSamples[i][Sentence.RIGHT] = samples[i][Sentence.RIGHT]; + double[][] savedSamples = new double[2][samples[Sentence.LEFT].length]; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + savedSamples[Sentence.LEFT][i] = samples[Sentence.LEFT][i]; + savedSamples[Sentence.RIGHT][i] = samples[Sentence.RIGHT][i]; } if (wetOnly) { - for (int i = 0; i < samples.length; i++) { - samples[i][Sentence.LEFT] = 0d; - samples[i][Sentence.RIGHT] = 0d; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + samples[Sentence.LEFT][i] = 0d; + samples[Sentence.RIGHT][i] = 0d; } } - double[][] subSamples = new double[samples.length][2]; - for (int i = 0; i < samples.length; i++) { - subSamples[i][Sentence.LEFT] = savedSamples[i][Sentence.LEFT]; - subSamples[i][Sentence.RIGHT] = savedSamples[i][Sentence.RIGHT]; + double[][] subSamples = new double[2][samples[Sentence.LEFT].length]; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + subSamples[Sentence.LEFT][i] = savedSamples[Sentence.LEFT][i]; + subSamples[Sentence.RIGHT][i] = savedSamples[Sentence.RIGHT][i]; } for (DelayLineStore d : delayLines) { - for (int i = 0; i < samples.length; i++) { - subSamples[i][Sentence.LEFT] = savedSamples[i][Sentence.LEFT]; - subSamples[i][Sentence.RIGHT] = savedSamples[i][Sentence.RIGHT]; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + subSamples[Sentence.LEFT][i] = savedSamples[Sentence.LEFT][i]; + subSamples[Sentence.RIGHT][i] = savedSamples[Sentence.RIGHT][i]; } d.process(subSamples); - for (int i = 0; i < subSamples.length; i++) { + for (int i = 0; i < subSamples[Sentence.LEFT].length; i++) { int off = i + d.getSamples(); - if ((off < samples.length) && (off > 0)) { - - double[] ns = mix(samples[off], subSamples[i]); - samples[off][Sentence.LEFT] = ns[Sentence.LEFT]; - samples[off][Sentence.RIGHT] = ns[Sentence.RIGHT]; + if ((off < samples[Sentence.LEFT].length) && (off > 0)) { + samples[Sentence.LEFT][off] = mix(samples[Sentence.LEFT][off], subSamples[Sentence.LEFT][i]); + samples[Sentence.RIGHT][off] = mix(samples[Sentence.RIGHT][off], subSamples[Sentence.RIGHT][i]); } } } } - double[] mix(double[] a, double[] b) { - double[] out = new double[2]; + double mix(double a, double b) { + double out; - if ((a[Sentence.LEFT] < 0) && (b[Sentence.LEFT] < 0)) { - out[Sentence.LEFT] = (a[Sentence.LEFT] + b[Sentence.LEFT]) - (a[Sentence.LEFT] * b[Sentence.LEFT]); - } else if ((a[Sentence.LEFT] > 0) && (b[Sentence.LEFT] > 0)) { - out[Sentence.LEFT] = (a[Sentence.LEFT] + b[Sentence.LEFT]) - (a[Sentence.LEFT] * b[Sentence.LEFT]); + if ((a < 0) && (b < 0)) { + out = (a + b) - (a * b); + } else if ((a > 0) && (b > 0)) { + out = (a + b) - (a * b); } else { - out[Sentence.LEFT] = a[Sentence.LEFT] + b[Sentence.LEFT]; - } - - if ((a[Sentence.RIGHT] < 0) && (b[Sentence.RIGHT] < 0)) { - out[Sentence.RIGHT] = (a[Sentence.RIGHT] + b[Sentence.RIGHT]) - (a[Sentence.RIGHT] * b[Sentence.RIGHT]); - } else if ((a[Sentence.RIGHT] > 0) && (b[Sentence.RIGHT] > 0)) { - out[Sentence.RIGHT] = (a[Sentence.RIGHT] + b[Sentence.RIGHT]) - (a[Sentence.RIGHT] * b[Sentence.RIGHT]); - } else { - out[Sentence.RIGHT] = a[Sentence.RIGHT] + b[Sentence.RIGHT]; + out = a + b; } return out; diff --git a/src/uk/co/majenko/audiobookrecorder/DelayLineStore.java b/src/uk/co/majenko/audiobookrecorder/DelayLineStore.java index 1a69545..09b6d83 100644 --- a/src/uk/co/majenko/audiobookrecorder/DelayLineStore.java +++ b/src/uk/co/majenko/audiobookrecorder/DelayLineStore.java @@ -29,16 +29,16 @@ public class DelayLineStore { e.process(samples); } - for (double[] sample : samples) { - sample[Sentence.LEFT] *= gain; - sample[Sentence.RIGHT] *= gain; + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { + samples[Sentence.LEFT][i] *= gain; + samples[Sentence.RIGHT][i] *= gain; if (pan < 0) { double p = 1 + pan; - sample[Sentence.RIGHT] *= p; + samples[Sentence.RIGHT][i] *= p; } else { double p = 1 - pan; - sample[Sentence.LEFT] *= p; + samples[Sentence.LEFT][i] *= p; } } } diff --git a/src/uk/co/majenko/audiobookrecorder/LFO.java b/src/uk/co/majenko/audiobookrecorder/LFO.java index e10c107..b6ccc8e 100644 --- a/src/uk/co/majenko/audiobookrecorder/LFO.java +++ b/src/uk/co/majenko/audiobookrecorder/LFO.java @@ -48,7 +48,7 @@ public class LFO implements Effect { } public void process(double[][] samples) { - for (double[] sample : samples) { + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { double v = 0; switch (waveform) { case SINE: v = Math.sin(phase); break; @@ -68,12 +68,12 @@ public class LFO implements Effect { // Apply it to the sample switch (mode) { case REPLACE: - sample[Sentence.LEFT] = (sample[Sentence.LEFT] * v); - sample[Sentence.RIGHT] = (sample[Sentence.RIGHT] * v); + samples[Sentence.LEFT][i] = (samples[Sentence.LEFT][i] * v); + samples[Sentence.RIGHT][i] = (samples[Sentence.RIGHT][i] * v); break; case ADD: - sample[Sentence.LEFT] += (sample[Sentence.LEFT] * v); - sample[Sentence.RIGHT] += (sample[Sentence.RIGHT] * v); + samples[Sentence.LEFT][i] += (samples[Sentence.LEFT][i] * v); + samples[Sentence.RIGHT][i] += (samples[Sentence.RIGHT][i] * v); break; } } diff --git a/src/uk/co/majenko/audiobookrecorder/Pan.java b/src/uk/co/majenko/audiobookrecorder/Pan.java index 7c6de41..2a81c65 100644 --- a/src/uk/co/majenko/audiobookrecorder/Pan.java +++ b/src/uk/co/majenko/audiobookrecorder/Pan.java @@ -20,13 +20,13 @@ public class Pan implements Effect { } public void process(double[][] samples) { - for (double[] sample : samples) { + for (int i = 0; i < samples[Sentence.LEFT].length; i++) { if (pan < 0) { double p = 1 + pan; - sample[Sentence.RIGHT] *= p; + samples[Sentence.RIGHT][i] *= p; } else { double p = 1 - pan; - sample[Sentence.LEFT] *= p; + samples[Sentence.LEFT][i] *= p; } } } diff --git a/src/uk/co/majenko/audiobookrecorder/Sentence.java b/src/uk/co/majenko/audiobookrecorder/Sentence.java index b31757d..ed1de38 100644 --- a/src/uk/co/majenko/audiobookrecorder/Sentence.java +++ b/src/uk/co/majenko/audiobookrecorder/Sentence.java @@ -91,6 +91,7 @@ public class Sentence extends BookTreeNode implements Cacheable { boolean effectEthereal = false; public void setSampleSize(int s) { + Debug.trace(); sampleSize = s; } @@ -106,6 +107,7 @@ public class Sentence extends BookTreeNode implements Cacheable { AudioFormat format; public RecordingThread(File tf, File wf, AudioFormat af, Sentence s) { + Debug.trace(); tempFile = tf; wavFile = wf; format = af; @@ -113,6 +115,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void run() { + Debug.trace(); try { running = true; recording = true; @@ -154,16 +157,19 @@ public class Sentence extends BookTreeNode implements Cacheable { } public boolean isRunning() { + Debug.trace(); return running; } public void stopRecording() { + Debug.trace(); recording = false; } } public Sentence() { super(""); + Debug.trace(); id = UUID.randomUUID().toString(); text = id; setUserObject(text); @@ -172,6 +178,7 @@ public class Sentence extends BookTreeNode implements Cacheable { public Sentence(String i, String t) { super(""); + Debug.trace(); id = i; text = t; setUserObject(text); @@ -180,6 +187,7 @@ public class Sentence extends BookTreeNode implements Cacheable { public Sentence(Element root) { super(""); + Debug.trace(); id = root.getAttribute("id"); text = Book.getTextNode(root, "text"); notes = Book.getTextNode(root, "notes"); @@ -191,7 +199,7 @@ public class Sentence extends BookTreeNode implements Cacheable { crossEndOffset = Utils.s2i(Book.getTextNode(root, "end-offset", "-1")); setLocked(Utils.s2b(Book.getTextNode(root, "locked"))); setAttentionFlag(Utils.s2b(Book.getTextNode(root, "attention"))); - setGain(Utils.s2d(Book.getTextNode(root, "gain"))); + gain = Utils.s2d(Book.getTextNode(root, "gain")); setEffectChain(Book.getTextNode(root, "effect")); setPostGapType(Book.getTextNode(root, "gaptype")); sampleSize = Utils.s2i(Book.getTextNode(root, "samples")); @@ -200,7 +208,6 @@ public class Sentence extends BookTreeNode implements Cacheable { peak = Utils.s2d(Book.getTextNode(root, "peak", "-1.000")); if ((crossStartOffset == -1) || (crossEndOffset == -1)) { - System.err.println("Updating " + id); updateCrossings(true); } @@ -208,6 +215,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public boolean startRecording() { + Debug.trace(); if (AudiobookRecorder.window.microphone == null) { JOptionPane.showMessageDialog(AudiobookRecorder.window, "Microphone not started. Start the microphone first.", "Error", JOptionPane.ERROR_MESSAGE); return false; @@ -225,6 +233,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void stopRecording() { + Debug.trace(); recordingThread.stopRecording(); while (recordingThread.isRunning()) { try { @@ -246,10 +255,12 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void autoTrimSample() { + Debug.trace(); autoTrimSample(false); } public void autoTrimSample(boolean useRaw) { + Debug.trace(); String tm = Options.get("audio.recording.trim"); if (tm.equals("peak")) { autoTrimSamplePeak(useRaw); @@ -261,17 +272,19 @@ public class Sentence extends BookTreeNode implements Cacheable { endOffset = sampleSize - 1; crossEndOffset = sampleSize - 1; processed = false; - peak = -1d; +// peak = -1d; } } public static final int FFTBuckets = 1024; public void autoTrimSampleFFT() { + Debug.trace(); autoTrimSampleFFT(false); } public void autoTrimSampleFFT(boolean useRaw) { + Debug.trace(); crossStartOffset = -1; crossEndOffset = -1; double[][] samples; @@ -286,18 +299,18 @@ public class Sentence extends BookTreeNode implements Cacheable { int fftSize = Options.getInteger("audio.recording.trim.blocksize"); - int blocks = samples.length / fftSize + 1; + int blocks = samples[LEFT].length / fftSize + 1; int[] intens = new int[blocks]; int block = 0; - for (int i = 0; i < samples.length; i+= fftSize) { + for (int i = 0; i < samples[LEFT].length; i+= fftSize) { double[] real = new double[fftSize]; double[] imag = new double[fftSize]; for (int j = 0; j < fftSize; j++) { - if (i + j < samples.length) { - real[j] = (samples[i+j][LEFT] + samples[i+j][RIGHT]) / 2d; + if (i + j < samples[LEFT].length) { + real[j] = (samples[LEFT][i+j] + samples[RIGHT][i+j]) / 2d; imag[j] = 0; } else { real[j] = 0; @@ -340,7 +353,7 @@ public class Sentence extends BookTreeNode implements Cacheable { startOffset = start * fftSize; if (startOffset < 0) startOffset = 0; - if (startOffset >= samples.length) startOffset = samples.length; + if (startOffset >= samples[LEFT].length) startOffset = samples[LEFT].length; int end = blocks - 1; // And last block with > 1 intensity and add one. @@ -359,7 +372,7 @@ public class Sentence extends BookTreeNode implements Cacheable { if (endOffset <= startOffset) endOffset = startOffset + fftSize; if (endOffset < 0) endOffset = 0; - if (endOffset >= samples.length) endOffset = samples.length; + if (endOffset >= samples[LEFT].length) endOffset = samples[LEFT].length; updateCrossings(useRaw); intens = null; samples = null; @@ -368,10 +381,12 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void autoTrimSamplePeak() { + Debug.trace(); autoTrimSamplePeak(false); } public void autoTrimSamplePeak(boolean useRaw) { + Debug.trace(); crossStartOffset = -1; crossEndOffset = -1; double[][] samples; @@ -385,27 +400,27 @@ public class Sentence extends BookTreeNode implements Cacheable { noiseFloor *= 1.1; // Find start - for (int i = 0; i < samples.length; i++) { + for (int i = 0; i < samples[LEFT].length; i++) { startOffset = i; - if (Math.abs((samples[i][LEFT] + samples[i][RIGHT])/2d) > noiseFloor) { + if (Math.abs((samples[LEFT][i] + samples[RIGHT][i])/2d) > noiseFloor) { startOffset --; if (startOffset < 0) startOffset = 0; break; } } - if (startOffset >= samples.length-1) { // Failed! Silence? + if (startOffset >= samples[LEFT].length-1) { // Failed! Silence? startOffset = 0; } int fftSize = Options.getInteger("audio.recording.trim.blocksize"); startOffset -= fftSize; - for (int i = samples.length-1; i >= 0; i--) { + for (int i = samples[LEFT].length-1; i >= 0; i--) { endOffset = i; - if (Math.abs((samples[i][LEFT] + samples[i][RIGHT])/2d) > noiseFloor) { + if (Math.abs((samples[LEFT][i] + samples[RIGHT][i])/2d) > noiseFloor) { endOffset ++; - if (endOffset >= samples.length-1) endOffset = samples.length-1; + if (endOffset >= samples[LEFT].length-1) endOffset = samples[LEFT].length-1; break; } } @@ -414,31 +429,35 @@ public class Sentence extends BookTreeNode implements Cacheable { if (endOffset <= startOffset) endOffset = startOffset + fftSize; if (endOffset <= 0) { - endOffset = samples.length-1; + endOffset = samples[LEFT].length-1; } if (startOffset < 0) startOffset = 0; - if (endOffset >= samples.length) endOffset = samples.length-1; + if (endOffset >= samples[LEFT].length) endOffset = samples[LEFT].length-1; updateCrossings(useRaw); processed = true; reloadTree(); } public String getId() { + Debug.trace(); return id; } public void setText(String t) { + Debug.trace(); overrideText = null; text = t; reloadTree(); } public String getText() { + Debug.trace(); return text; } public File getFile() { + Debug.trace(); File b = new File(AudiobookRecorder.window.getBookFolder(), "files"); if (!b.exists()) { b.mkdirs(); @@ -447,6 +466,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public File getTempFile() { + Debug.trace(); File b = new File(AudiobookRecorder.window.getBookFolder(), "files"); if (!b.exists()) { b.mkdirs(); @@ -455,6 +475,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void editText() { + Debug.trace(); String t = JOptionPane.showInputDialog(null, "Edit Text", text); if (t != null) { @@ -464,6 +485,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public String toString() { + Debug.trace(); return text; /* if (effectChain == null) return text; @@ -475,10 +497,12 @@ public class Sentence extends BookTreeNode implements Cacheable { } public boolean isRecording() { + Debug.trace(); return recording; } public void setUserObject(Object o) { + Debug.trace(); if (o instanceof String) { String so = (String)o; text = so; @@ -487,14 +511,17 @@ public class Sentence extends BookTreeNode implements Cacheable { } public int getPostGap() { + Debug.trace(); return postGap; } public void setPostGap(int g) { + Debug.trace(); postGap = g; } public void deleteFiles() { + Debug.trace(); File audioFile = getFile(); if (audioFile.exists()) { audioFile.delete(); @@ -502,18 +529,22 @@ public class Sentence extends BookTreeNode implements Cacheable { } public int getStartCrossing() { + Debug.trace(); return crossStartOffset; } public int getStartOffset() { + Debug.trace(); return startOffset; } public void updateCrossings() { + Debug.trace(); updateCrossings(false); } public void updateCrossings(boolean useRaw) { + Debug.trace(); updateStartCrossing(useRaw); updateEndCrossing(useRaw); runtime = -1d; @@ -521,26 +552,31 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void updateStartCrossing() { + Debug.trace(); updateStartCrossing(false); } public void updateStartCrossing(boolean useRaw) { + Debug.trace(); if (crossStartOffset == -1) { crossStartOffset = findNearestZeroCrossing(useRaw, startOffset, 4096); } } public void updateEndCrossing() { + Debug.trace(); updateEndCrossing(false); } public void updateEndCrossing(boolean useRaw) { + Debug.trace(); if (crossEndOffset == -1) { crossEndOffset = findNearestZeroCrossing(useRaw, endOffset, 4096); } } public void setStartOffset(int o) { + Debug.trace(); if (startOffset != o) { startOffset = o; crossStartOffset = -1; @@ -549,14 +585,17 @@ public class Sentence extends BookTreeNode implements Cacheable { } public int getEndCrossing() { + Debug.trace(); return crossEndOffset; } public int getEndOffset() { + Debug.trace(); return endOffset; } public void setEndOffset(int o) { + Debug.trace(); if (endOffset != o) { endOffset = o; crossEndOffset = -1; @@ -565,14 +604,17 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void setStartCrossing(int o) { + Debug.trace(); crossStartOffset = o; } public void setEndCrossing(int o) { + Debug.trace(); crossEndOffset = o; } public int getSampleSize() { + Debug.trace(); if (sampleSize == -1) { loadFile(); } @@ -580,6 +622,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public AudioFormat getAudioFormat() { + Debug.trace(); if (storedFormat != null) return storedFormat; File f = getFile(); @@ -595,6 +638,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void doRecognition(StreamSpeechRecognizer recognizer) { + Debug.trace(); try { setText("[recognising...]"); reloadTree(); @@ -619,8 +663,10 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void recognise() { + Debug.trace(); Thread t = new Thread(new Runnable() { public void run() { + Debug.trace(); try { Configuration sphinxConfig = new Configuration(); @@ -648,38 +694,46 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void setLocked(boolean l) { + Debug.trace(); if (locked == l) return; locked = l; reloadTree(); } public boolean isLocked() { + Debug.trace(); return locked; } public void setInSample(boolean s) { + Debug.trace(); inSample = s; } public boolean isInSample() { + Debug.trace(); return inSample; } public void clearCache() { + Debug.trace(); audioData = null; processedAudio = null; storedFormat = null; } public boolean lockedInCache() { + Debug.trace(); return id.equals("room-noise"); } public int findNearestZeroCrossing(int pos, int range) { + Debug.trace(); return findNearestZeroCrossing(false, pos, range); } public int findNearestZeroCrossing(boolean useRaw, int pos, int range) { + Debug.trace(); double[][] data = null; if (useRaw) { data = getRawAudioData(); @@ -687,27 +741,27 @@ public class Sentence extends BookTreeNode implements Cacheable { data = getProcessedAudioData(); } if (data == null) return 0; - if (data.length == 0) return 0; + if (data[LEFT].length == 0) return 0; if (pos < 0) pos = 0; - if (pos >= data.length) pos = data.length-1; + if (pos >= data[LEFT].length) pos = data[LEFT].length-1; int backwards = pos; int forwards = pos; - double backwardsPrev = (data[backwards][LEFT] + data[backwards][RIGHT]) / 2d; - double forwardsPrev = (data[forwards][LEFT] + data[forwards][RIGHT]) / 2d; + double backwardsPrev = (data[LEFT][backwards] + data[RIGHT][backwards]) / 2d; + double forwardsPrev = (data[LEFT][forwards] + data[RIGHT][forwards]) / 2d; - while (backwards > 0 || forwards < data.length-2) { + while (backwards > 0 || forwards < data[LEFT].length-2) { - if (forwards < data.length-2) forwards++; + if (forwards < data[LEFT].length-2) forwards++; if (backwards > 0) backwards--; - if (backwardsPrev >= 0 && ((data[backwards][LEFT] + data[backwards][RIGHT]) / 2d) < 0) { // Found one! + if (backwardsPrev >= 0 && ((data[LEFT][backwards] + data[RIGHT][backwards]) / 2d) < 0) { // Found one! return backwards; } - if (forwardsPrev < 0 && ((data[forwards][LEFT] + data[forwards][RIGHT]) / 2d) >= 0) { + if (forwardsPrev < 0 && ((data[LEFT][forwards] + data[RIGHT][forwards]) / 2d) >= 0) { return forwards; } @@ -716,14 +770,15 @@ public class Sentence extends BookTreeNode implements Cacheable { return pos; } - backwardsPrev = (data[backwards][LEFT] + data[backwards][RIGHT]) / 2d; - forwardsPrev = (data[forwards][LEFT] + data[forwards][RIGHT]) / 2d; + backwardsPrev = (data[LEFT][backwards] + data[RIGHT][backwards]) / 2d; + forwardsPrev = (data[LEFT][forwards] + data[RIGHT][forwards]) / 2d; } return pos; } /* Get the length of the sample in seconds */ public double getLength() { + Debug.trace(); if (runtime > 0.01d) return runtime; File f = getFile(); if (!f.exists()) { // Not recorded yet! @@ -737,6 +792,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public Sentence cloneSentence() throws IOException { + Debug.trace(); Sentence sentence = new Sentence(); sentence.setPostGap(getPostGap()); if (!id.equals(text)) { @@ -756,24 +812,29 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void setAttentionFlag(boolean f) { + Debug.trace(); if (attention == f) return; attention = f; reloadTree(); } public boolean getAttentionFlag() { + Debug.trace(); return attention; } public double getPeakValue() { + Debug.trace(); return getPeakValue(false, true); } public double getPeakValue(boolean useRaw) { + Debug.trace(); return getPeakValue(useRaw, true); } public double getPeakValue(boolean useRaw, boolean applyGain) { + Debug.trace(); double oldGain = gain; gain = 1.0d; double[][] samples = null; @@ -787,15 +848,16 @@ public class Sentence extends BookTreeNode implements Cacheable { return 0; } double ms = 0; - for (int i = 0; i < samples.length; i++) { - if (Math.abs((samples[i][LEFT] + samples[i][RIGHT]) / 2d) > ms) { - ms = Math.abs((samples[i][LEFT] + samples[i][RIGHT]) / 2d); + for (int i = 0; i < samples[LEFT].length; i++) { + if (Math.abs((samples[LEFT][i] + samples[RIGHT][i]) / 2d) > ms) { + ms = Math.abs((samples[LEFT][i] + samples[RIGHT][i]) / 2d); } } return ms; } public int getHeadroom() { + Debug.trace(); double r = getPeakValue(); if (r == 0) return 0; double l10 = Math.log10(r); @@ -805,6 +867,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void setGain(double g) { + Debug.trace(); if (g <= 0.0001d) g = 1.0d; if (g == gain) return; @@ -819,26 +882,35 @@ public class Sentence extends BookTreeNode implements Cacheable { } public double getGain() { + Debug.trace(); return gain; } public double normalize(double low, double high) { + Debug.trace(); if (locked) return gain; double max = getPeakValue(true, false); double d = 0.708 / max; if (d > 1d) d = 1d; if (d < low) d = low; if (d > high) d = high; + peak = -1; setGain(d); + getPeak(); + reloadTree(); return d; } public double normalize() { + Debug.trace(); if (locked) return gain; double max = getPeakValue(true, false); double d = 0.708 / max; if (d > 1d) d = 1d; setGain(d); + peak = -1; + getPeak(); + reloadTree(); return d; } @@ -849,6 +921,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void run() { + Debug.trace(); String command = Options.get("editor.external"); if (command == null) return; if (command.equals("")) return; @@ -877,12 +950,14 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void openInExternalEditor() { + Debug.trace(); ExternalEditor ed = new ExternalEditor(this); Thread t = new Thread(ed); t.start(); } public void backup() throws IOException { + Debug.trace(); File whereto = getFile().getParentFile(); String name = getFile().getName(); @@ -911,11 +986,13 @@ public class Sentence extends BookTreeNode implements Cacheable { int number; public ExternalProcessor(Sentence s, int num) { + Debug.trace(); sentence = s; number = num; } public void run() { + Debug.trace(); String command = Options.get("editor.processor." + number + ".command"); if (command == null) return; if (command.equals("")) return; @@ -967,6 +1044,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void runExternalProcessor(int num) { + Debug.trace(); if (isLocked()) return; ExternalProcessor ed = new ExternalProcessor(this, num); Thread t = new Thread(ed); @@ -974,6 +1052,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void undo() { + Debug.trace(); File whereto = getFile().getParentFile(); String name = getFile().getName(); @@ -1009,12 +1088,13 @@ public class Sentence extends BookTreeNode implements Cacheable { } public double[][] getDoubleDataS16LE(AudioInputStream s, AudioFormat format) throws IOException { + Debug.trace(); long len = s.getFrameLength(); int frameSize = format.getFrameSize(); int chans = format.getChannels(); byte[] frame = new byte[frameSize]; - double[][] samples = new double[(int)len][2]; + double[][] samples = new double[2][(int)len]; for (long fno = 0; fno < len; fno++) { @@ -1028,15 +1108,15 @@ public class Sentence extends BookTreeNode implements Cacheable { int right = (rh << 8) | rl; if ((left & 0x8000) == 0x8000) left |= 0xFFFF0000; if ((right & 0x8000) == 0x8000) right |= 0xFFFF0000; - samples[(int)fno][LEFT] = (double)left / 32767d; - samples[(int)fno][RIGHT] = (double)right / 32767d; + samples[LEFT][(int)fno] = (double)left / 32767d; + samples[RIGHT][(int)fno] = (double)right / 32767d; } else { int l = frame[0] >= 0 ? frame[0] : 256 + frame[0]; int h = frame[1] >= 0 ? frame[1] : 256 + frame[1]; int mono = (h << 8) | l; if ((mono & 0x8000) == 0x8000) mono |= 0xFFFF0000; - samples[(int)fno][LEFT] = (double)mono / 32767d; - samples[(int)fno][RIGHT] = (double)mono / 32767d; + samples[LEFT][(int)fno] = (double)mono / 32767d; + samples[RIGHT][(int)fno] = (double)mono / 32767d; } } @@ -1044,9 +1124,10 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void writeDoubleDataS16LE(double[][] samples, AudioFormat format) throws IOException { + Debug.trace(); int chans = format.getChannels(); - int frames = samples.length; + int frames = samples[LEFT].length; byte[] buffer; @@ -1055,8 +1136,8 @@ public class Sentence extends BookTreeNode implements Cacheable { buffer = new byte[buflen]; for (int i = 0; i < frames; i++) { - double left = samples[i][LEFT]; - double right = samples[i][RIGHT]; + double left = samples[LEFT][i]; + double right = samples[RIGHT][i]; int off = i * 4; left *= 32767d; right *= 32767d; @@ -1078,8 +1159,8 @@ public class Sentence extends BookTreeNode implements Cacheable { buffer = new byte[buflen]; for (int i = 0; i < frames; i++) { - double left = samples[i][LEFT]; - double right = samples[i][RIGHT]; + double left = samples[LEFT][i]; + double right = samples[RIGHT][i]; double mono = (left + right) / 2d; int off = i * 2; mono *= 32767d; @@ -1104,9 +1185,10 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void writeDoubleDataS24LE(double[][] samples, AudioFormat format) throws IOException { + Debug.trace(); int chans = format.getChannels(); - int frames = samples.length; + int frames = samples[LEFT].length; byte[] buffer; @@ -1115,8 +1197,8 @@ public class Sentence extends BookTreeNode implements Cacheable { buffer = new byte[buflen]; for (int i = 0; i < frames; i++) { - double left = samples[i][LEFT]; - double right = samples[i][RIGHT]; + double left = samples[LEFT][i]; + double right = samples[RIGHT][i]; int off = i * 6; left *= 8388607d; right *= 8388607d; @@ -1140,8 +1222,8 @@ public class Sentence extends BookTreeNode implements Cacheable { buffer = new byte[buflen]; for (int i = 0; i < frames; i++) { - double left = samples[i][LEFT]; - double right = samples[i][RIGHT]; + double left = samples[LEFT][i]; + double right = samples[RIGHT][i]; double mono = (left + right) / 2d; int off = i * 3; mono *= 8388607d; @@ -1167,6 +1249,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void writeAudioData(double[][] samples) throws IOException { + Debug.trace(); AudioFormat format = getAudioFormat(); switch (format.getSampleSizeInBits()) { @@ -1182,18 +1265,21 @@ public class Sentence extends BookTreeNode implements Cacheable { } public double[][] getDoubleDataS24LE(AudioInputStream s, AudioFormat format) throws IOException { + Debug.trace(); long len = s.getFrameLength(); int frameSize = format.getFrameSize(); int chans = format.getChannels(); byte[] frame = new byte[frameSize]; - double[][] samples = new double[(int)len][2]; + double[][] samples = new double[2][(int)len]; - for (long fno = 0; fno < len; fno++) { + int pos = 0; - s.read(frame); - int sample = 0; - if (chans == 2) { // Stereo + Debug.d("Starting processing"); + if (chans == 2) { // Stereo + for (long fno = 0; fno < len; fno++) { + s.read(frame); + int sample = 0; int ll = frame[0] >= 0 ? frame[0] : 256 + frame[0]; int lm = frame[1] >= 0 ? frame[1] : 256 + frame[1]; int lh = frame[2] >= 0 ? frame[2] : 256 + frame[2]; @@ -1204,23 +1290,28 @@ public class Sentence extends BookTreeNode implements Cacheable { int right = (rh << 16) | (rm << 8) | rl; if ((left & 0x800000) == 0x800000) left |= 0xFF000000; if ((right & 0x800000) == 0x800000) right |= 0xFF000000; - samples[(int)fno][LEFT] = (double)left / 8388607d; - samples[(int)fno][RIGHT] = (double)right / 8388607d; - } else { + samples[LEFT][(int)fno] = (double)left / 8388607d; + samples[RIGHT][(int)fno] = (double)right / 8388607d; + } + } else { + for (long fno = 0; fno < len; fno++) { + s.read(frame); int l = frame[0] >= 0 ? frame[0] : 256 + frame[0]; int m = frame[1] >= 0 ? frame[1] : 256 + frame[1]; int h = frame[2] >= 0 ? frame[2] : 256 + frame[2]; int mono = (h << 16) | (m << 8) | l; if ((mono & 0x800000) == 0x800000) mono |= 0xFF000000; - samples[(int)fno][LEFT] = (double)mono / 8388607d; - samples[(int)fno][RIGHT] = (double)mono / 8388607d; + samples[LEFT][(int)fno] = (double)mono / 8388607d; + samples[RIGHT][(int)fno] = (double)mono / 8388607d; } } + Debug.d("Finished processing"); return samples; } public void loadFile() { + Debug.trace(); if (audioData != null) { return; } @@ -1246,8 +1337,9 @@ public class Sentence extends BookTreeNode implements Cacheable { } s.close(); - sampleSize = samples.length; + sampleSize = samples[LEFT].length; audioData = samples; + getPeak(); CacheManager.addToCache(this); } catch (Exception e) { e.printStackTrace(); @@ -1255,29 +1347,33 @@ public class Sentence extends BookTreeNode implements Cacheable { } synchronized public double[][] getRawAudioData() { + Debug.trace(); loadFile(); return audioData; } synchronized public double[][] getProcessedAudioData() { + Debug.trace(); return getProcessedAudioData(true, true); } synchronized public double[][] getProcessedAudioData(boolean effectsEnabled) { + Debug.trace(); return getProcessedAudioData(effectsEnabled, true); } synchronized public double[][] getProcessedAudioData(boolean effectsEnabled, boolean applyGain) { + Debug.trace(); loadFile(); if (processedAudio != null) { return processedAudio; } if (audioData == null) return null; - processedAudio = new double[audioData.length][2]; - for (int i = 0; i < audioData.length; i++) { - processedAudio[i][LEFT] = audioData[i][LEFT]; - processedAudio[i][RIGHT] = audioData[i][RIGHT]; + processedAudio = new double[2][audioData[LEFT].length]; + for (int i = 0; i < audioData[LEFT].length; i++) { + processedAudio[LEFT][i] = audioData[LEFT][i]; + processedAudio[RIGHT][i] = audioData[RIGHT][i]; } // Add processing in here. @@ -1305,9 +1401,9 @@ public class Sentence extends BookTreeNode implements Cacheable { if (applyGain) { // Add final master gain stage - for (int i = 0; i < processedAudio.length; i++) { - processedAudio[i][LEFT] *= gain; - processedAudio[i][RIGHT] *= gain; + for (int i = 0; i < processedAudio[LEFT].length; i++) { + processedAudio[LEFT][i] *= gain; + processedAudio[RIGHT][i] *= gain; } } @@ -1315,49 +1411,55 @@ public class Sentence extends BookTreeNode implements Cacheable { } public double[][] getDoubleAudioData() { + Debug.trace(); return getDoubleAudioData(true); } public double[][] getDoubleAudioData(boolean effectsEnabled) { + Debug.trace(); return getProcessedAudioData(effectsEnabled); } public double[][] getCroppedAudioData() { + Debug.trace(); return getCroppedAudioData(true); } public double[][] getCroppedAudioData(boolean effectsEnabled) { + Debug.trace(); double[][] inSamples = getDoubleAudioData(effectsEnabled); if (inSamples == null) return null; updateCrossings(); int length = crossEndOffset - crossStartOffset; - double[][] samples = new double[length][2]; + double[][] samples = new double[2][length]; for (int i = 0; i < length; i++) { - samples[i][LEFT] = inSamples[crossStartOffset + i][LEFT]; - samples[i][RIGHT] = inSamples[crossStartOffset + i][RIGHT]; + samples[LEFT][i] = inSamples[LEFT][crossStartOffset + i]; + samples[RIGHT][i] = inSamples[RIGHT][crossStartOffset + i]; } return samples; } public byte[] getPCMData() { + Debug.trace(); return getPCMData(true); } public byte[] getPCMData(boolean effectsEnabled) { + Debug.trace(); double[][] croppedData = getCroppedAudioData(effectsEnabled); if (croppedData == null) return null; - int length = croppedData.length; + int length = croppedData[LEFT].length; byte[] pcmData = new byte[length * 4]; for (int i = 0; i < length; i++) { - double sd = croppedData[i][LEFT] * 32767d; + double sd = croppedData[LEFT][i] * 32767d; int si = (int)sd; if (si > 32767) si = 32767; if (si < -32767) si = -32767; pcmData[i * 4] = (byte)(si & 0xFF); pcmData[(i * 4) + 1] = (byte)((si & 0xFF00) >> 8); - sd = croppedData[i][RIGHT] * 32767d; + sd = croppedData[RIGHT][i] * 32767d; si = (int)sd; if (si > 32767) si = 32767; if (si < -32767) si = -32767; @@ -1368,6 +1470,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void setEffectChain(String key) { + Debug.trace(); if ((effectChain != null) && (effectChain.equals(key))) { return; } @@ -1379,15 +1482,18 @@ public class Sentence extends BookTreeNode implements Cacheable { } public String getEffectChain() { + Debug.trace(); if (effectChain == null) return "none"; return effectChain; } public String getPostGapType() { + Debug.trace(); return postGapType; } public void setPostGapType(String t) { + Debug.trace(); if (t == null || t.equals("none")) { if (getPostGap() == Options.getInteger("catenation.short-sentence")) { t = "continuation"; @@ -1406,6 +1512,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void resetPostGap() { + Debug.trace(); if (postGapType == null) { postGapType = "sentence"; } @@ -1422,10 +1529,12 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void debug(String txt) { + Debug.trace(); Debug.debug(String.format("%s: %s", id, txt)); } public TreeMap getSentenceData() { + Debug.trace(); TreeMap out = new TreeMap(); @@ -1445,6 +1554,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public void purgeBackups() { + Debug.trace(); File whereto = getFile().getParentFile(); String name = getFile().getName(); @@ -1458,6 +1568,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public Element getSentenceXML(Document doc) { + Debug.trace(); Element sentenceNode = doc.createElement("sentence"); sentenceNode.setAttribute("id", getId()); sentenceNode.appendChild(Book.makeTextNode(doc, "text", getText())); @@ -1480,33 +1591,40 @@ public class Sentence extends BookTreeNode implements Cacheable { } public boolean isProcessed() { + Debug.trace(); return processed; } public void setProcessed(boolean p) { + Debug.trace(); processed = p; reloadTree(); } public void setNotes(String n) { + Debug.trace(); notes = n; } public String getNotes() { + Debug.trace(); return notes; } public void onSelect() { + Debug.trace(); AudiobookRecorder.window.setSentenceNotes(notes); } void reloadTree() { + Debug.trace(); if (id.equals("room-noise")) return; if (getParent() == null) return; AudiobookRecorder.window.bookTreeModel.reload(this); } public double getPeak() { + Debug.trace(); if (peak > -1) return peak; double[][] samples = getDoubleAudioData(); if (samples == null) { @@ -1514,9 +1632,10 @@ public class Sentence extends BookTreeNode implements Cacheable { return 0; } double ms = 0; - for (int i = 0; i < samples.length; i++) { - if (Math.abs((samples[i][Sentence.LEFT] + samples[i][Sentence.RIGHT]) / 2d) > ms) { - ms = Math.abs((samples[i][Sentence.LEFT] + samples[i][Sentence.RIGHT]) / 2d); + for (int i = 0; i < samples[LEFT].length; i++) { + double n = Math.abs((samples[LEFT][i] + samples[RIGHT][i]) / 2d); + if (n > ms) { + ms = n; } } @@ -1527,6 +1646,7 @@ public class Sentence extends BookTreeNode implements Cacheable { } public int getPeakDB() { + Debug.trace(); double r = getPeak(); if (r == 0) return 0; double l10 = Math.log10(r); diff --git a/src/uk/co/majenko/audiobookrecorder/Waveform.java b/src/uk/co/majenko/audiobookrecorder/Waveform.java index 79ee36d..8a7ae08 100644 --- a/src/uk/co/majenko/audiobookrecorder/Waveform.java +++ b/src/uk/co/majenko/audiobookrecorder/Waveform.java @@ -34,6 +34,8 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen int offsetFactor = 0; int offset = 0; + String loadedId = null; + ArrayList markerDragListeners; public Waveform() { @@ -79,7 +81,7 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen if (samples != null) { - int num = samples.length; + int num = samples[Sentence.LEFT].length; step = num / zoomFactor / w; if (step == 0) return; @@ -97,8 +99,8 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen double lmax = 0; for (int o = 0; o < step; o++) { - if (offset + (n * step) + o >= samples.length) break; - double sample = (samples[offset + (n * step) + o][Sentence.LEFT] + samples[offset + (n * step) + o][Sentence.RIGHT]) / 2d; + if (offset + (n * step) + o >= samples[Sentence.LEFT].length) break; + double sample = (samples[Sentence.LEFT][offset + (n * step) + o] + samples[Sentence.RIGHT][offset + (n * step) + o]) / 2d; if (sample >= 0) { have += sample; hcnt++; @@ -387,4 +389,12 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen public int getCutEnd() { return cutExit; } + + public void setId(String id) { + loadedId = id; + } + + public String getId() { + return loadedId; + } }