diff --git a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java index d794c23..36014c3 100644 --- a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java +++ b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java @@ -67,24 +67,12 @@ public class AudiobookRecorder extends JFrame { JPanel sampleControl; Waveform sampleWaveform; - JSpinner startOffset; - JSpinner endOffset; JSpinner postSentenceGap; JCheckBox locked; JButton reprocessAudioFFT; JButton reprocessAudioPeak; - JButton startSlowDown; - JButton startSlowUp; - JButton startFastDown; - JButton startFastUp; - - JButton endSlowDown; - JButton endSlowUp; - JButton endFastDown; - JButton endFastUp; - Thread playingThread = null; Random rng = new Random(); @@ -287,6 +275,32 @@ public class AudiobookRecorder extends JFrame { sampleControl.setLayout(new BorderLayout()); sampleControl.setPreferredSize(new Dimension(400, 150)); sampleWaveform = new Waveform(); + + sampleWaveform.addMarkerDragListener(new MarkerDragListener() { + public void leftMarkerMoved(MarkerDragEvent e) { + if (selectedSentence != null) { + if (!selectedSentence.isLocked()) { + selectedSentence.setStartOffset(e.getPosition()); + selectedSentence.updateCrossings(); + sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing()); + } else { + sampleWaveform.setLeftMarker(selectedSentence.getStartOffset()); + } + } + } + + public void rightMarkerMoved(MarkerDragEvent e) { + if (selectedSentence != null) { + if (!selectedSentence.isLocked()) { + selectedSentence.setEndOffset(e.getPosition()); + selectedSentence.updateCrossings(); + sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing()); + } else { + sampleWaveform.setRightMarker(selectedSentence.getEndOffset()); + } + } + } + }); sampleControl.add(sampleWaveform, BorderLayout.CENTER); @@ -299,8 +313,6 @@ public class AudiobookRecorder extends JFrame { sampleWaveform.setData(selectedSentence.getAudioData()); sampleWaveform.setMarkers(selectedSentence.getStartOffset(), selectedSentence.getEndOffset()); sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing()); - startOffset.setValue(selectedSentence.getStartOffset()); - endOffset.setValue(selectedSentence.getEndOffset()); postSentenceGap.setValue(selectedSentence.getPostGap()); } } @@ -315,44 +327,14 @@ public class AudiobookRecorder extends JFrame { sampleWaveform.setData(selectedSentence.getAudioData()); sampleWaveform.setMarkers(selectedSentence.getStartOffset(), selectedSentence.getEndOffset()); sampleWaveform.setAltMarkers(selectedSentence.getStartCrossing(), selectedSentence.getEndCrossing()); - startOffset.setValue(selectedSentence.getStartOffset()); - endOffset.setValue(selectedSentence.getEndOffset()); postSentenceGap.setValue(selectedSentence.getPostGap()); } } }); - startOffset = new JSpinner(new SteppedNumericSpinnerModel(0, 0, 1, 0)); - startOffset.setPreferredSize(new Dimension(100, 20)); - endOffset = new JSpinner(new SteppedNumericSpinnerModel(0, 0, 1, 0)); - endOffset.setPreferredSize(new Dimension(100, 20)); postSentenceGap = new JSpinner(new SteppedNumericSpinnerModel(0, 5000, 100, 0)); postSentenceGap.setPreferredSize(new Dimension(75, 20)); - startOffset.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent e) { - JSpinner ob = (JSpinner)e.getSource(); - if (selectedSentence != null) { - selectedSentence.setStartOffset((Integer)ob.getValue()); - sampleWaveform.setLeftMarker((Integer)ob.getValue()); - selectedSentence.updateStartCrossing(); - sampleWaveform.setLeftAltMarker(selectedSentence.getStartCrossing()); - } - } - }); - - endOffset.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent e) { - JSpinner ob = (JSpinner)e.getSource(); - if (selectedSentence != null) { - selectedSentence.setEndOffset((Integer)ob.getValue()); - sampleWaveform.setRightMarker((Integer)ob.getValue()); - selectedSentence.updateEndCrossing(); - sampleWaveform.setRightAltMarker(selectedSentence.getEndCrossing()); - } - } - }); - postSentenceGap.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { JSpinner ob = (JSpinner)e.getSource(); @@ -364,7 +346,6 @@ public class AudiobookRecorder extends JFrame { JPanel controlsTop = new JPanel(); - JPanel controlsBottom = new JPanel(); JToolBar controlsLeft = new JToolBar(JToolBar.VERTICAL); JToolBar controlsRight = new JToolBar(JToolBar.VERTICAL); @@ -374,119 +355,6 @@ public class AudiobookRecorder extends JFrame { controlsLeft.add(reprocessAudioFFT); controlsLeft.add(reprocessAudioPeak); - controlsBottom.add(new JLabel("Start Offset:")); - - startFastDown = new JButton("<<"); - startFastDown.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)startOffset.getModel(); - int f = (Integer)startOffset.getValue(); - int max = m.getMaximum(); - f -= (max / 10); - if (f < 0) f = 0; - startOffset.setValue(f); - } - }); - controlsBottom.add(startFastDown); - - startSlowDown = new JButton("<"); - startSlowDown.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)startOffset.getModel(); - int f = (Integer)startOffset.getValue(); - int max = m.getMaximum(); - f -= (max / 100); - if (f < 0) f = 0; - startOffset.setValue(f); - } - }); - controlsBottom.add(startSlowDown); - - controlsBottom.add(startOffset); - - startSlowUp = new JButton(">"); - startSlowUp.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)startOffset.getModel(); - int f = (Integer)startOffset.getValue(); - int max = m.getMaximum(); - f += (max / 100); - if (f > max) f = max; - startOffset.setValue(f); - } - }); - controlsBottom.add(startSlowUp); - - startFastUp = new JButton(">>"); - startFastUp.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)startOffset.getModel(); - int f = (Integer)startOffset.getValue(); - int max = m.getMaximum(); - f += (max / 10); - if (f > max) f = max; - startOffset.setValue(f); - } - }); - controlsBottom.add(startFastUp); - - - controlsBottom.add(new JLabel("End Offset:")); - - endFastDown = new JButton("<<"); - endFastDown.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)endOffset.getModel(); - int f = (Integer)endOffset.getValue(); - int max = m.getMaximum(); - f -= (max / 10); - if (f < 0) f = 0; - endOffset.setValue(f); - } - }); - controlsBottom.add(endFastDown); - - endSlowDown = new JButton("<"); - endSlowDown.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)endOffset.getModel(); - int f = (Integer)endOffset.getValue(); - int max = m.getMaximum(); - f -= (max / 100); - if (f < 0) f = 0; - endOffset.setValue(f); - } - }); - controlsBottom.add(endSlowDown); - - controlsBottom.add(endOffset); - - endSlowUp = new JButton(">"); - endSlowUp.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)endOffset.getModel(); - int f = (Integer)endOffset.getValue(); - int max = m.getMaximum(); - f += (max / 100); - if (f > max) f = max; - endOffset.setValue(f); - } - }); - controlsBottom.add(endSlowUp); - - endFastUp = new JButton(">>"); - endFastUp.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - SteppedNumericSpinnerModel m = (SteppedNumericSpinnerModel)endOffset.getModel(); - int f = (Integer)endOffset.getValue(); - int max = m.getMaximum(); - f += (max / 10); - if (f > max) f = max; - endOffset.setValue(f); - } - }); - controlsBottom.add(endFastUp); - locked = new JCheckBox("Sentence locked"); locked.addActionListener(new ActionListener() { @@ -512,7 +380,6 @@ public class AudiobookRecorder extends JFrame { controlsTop.add(new JLabel("ms")); sampleControl.add(controlsTop, BorderLayout.NORTH); - sampleControl.add(controlsBottom, BorderLayout.SOUTH); sampleControl.add(controlsLeft, BorderLayout.WEST); sampleControl.add(controlsRight, BorderLayout.EAST); @@ -1350,32 +1217,13 @@ public class AudiobookRecorder extends JFrame { sampleWaveform.setMarkers(s.getStartOffset(), s.getEndOffset()); s.updateCrossings(); sampleWaveform.setAltMarkers(s.getStartCrossing(), s.getEndCrossing()); - startOffset.setValue(s.getStartOffset()); - endOffset.setValue(s.getEndOffset()); postSentenceGap.setValue(s.getPostGap()); locked.setSelected(s.isLocked()); postSentenceGap.setEnabled(!s.isLocked()); - startOffset.setEnabled(!s.isLocked()); - endOffset.setEnabled(!s.isLocked()); reprocessAudioFFT.setEnabled(!s.isLocked()); reprocessAudioPeak.setEnabled(!s.isLocked()); - startSlowDown.setEnabled(!s.isLocked()); - startSlowUp.setEnabled(!s.isLocked()); - startFastDown.setEnabled(!s.isLocked()); - startFastUp.setEnabled(!s.isLocked()); - - endSlowDown.setEnabled(!s.isLocked()); - endSlowUp.setEnabled(!s.isLocked()); - endFastDown.setEnabled(!s.isLocked()); - endFastUp.setEnabled(!s.isLocked()); - - int samples = s.getSampleSize(); - - ((SteppedNumericSpinnerModel)startOffset.getModel()).setMaximum(samples); - ((SteppedNumericSpinnerModel)endOffset.getModel()).setMaximum(samples); - if (playing == null) { toolBar.enableSentence(); toolBar.disableStop(); @@ -1387,8 +1235,6 @@ public class AudiobookRecorder extends JFrame { selectedSentence = null; toolBar.disableSentence(); sampleWaveform.clearData(); - startOffset.setValue(0); - endOffset.setValue(0); toolBar.disableStop(); postSentenceGap.setValue(0); locked.setSelected(false); diff --git a/src/uk/co/majenko/audiobookrecorder/MarkerDragEvent.java b/src/uk/co/majenko/audiobookrecorder/MarkerDragEvent.java new file mode 100644 index 0000000..5dd2995 --- /dev/null +++ b/src/uk/co/majenko/audiobookrecorder/MarkerDragEvent.java @@ -0,0 +1,22 @@ +package uk.co.majenko.audiobookrecorder; + +import java.awt.event.*; + +public class MarkerDragEvent { + + Object src; + int position; + + public MarkerDragEvent(Object s, int pos) { + src = s; + position = pos; + } + + public Object getSource() { + return src; + } + + public int getPosition() { + return position; + } +} diff --git a/src/uk/co/majenko/audiobookrecorder/MarkerDragListener.java b/src/uk/co/majenko/audiobookrecorder/MarkerDragListener.java new file mode 100644 index 0000000..94faae5 --- /dev/null +++ b/src/uk/co/majenko/audiobookrecorder/MarkerDragListener.java @@ -0,0 +1,7 @@ +package uk.co.majenko.audiobookrecorder; + +public abstract interface MarkerDragListener { + abstract public void leftMarkerMoved(MarkerDragEvent event); + abstract public void rightMarkerMoved(MarkerDragEvent event); +} + diff --git a/src/uk/co/majenko/audiobookrecorder/Waveform.java b/src/uk/co/majenko/audiobookrecorder/Waveform.java index 32735ea..01a2c41 100644 --- a/src/uk/co/majenko/audiobookrecorder/Waveform.java +++ b/src/uk/co/majenko/audiobookrecorder/Waveform.java @@ -2,22 +2,40 @@ package uk.co.majenko.audiobookrecorder; import javax.swing.*; import java.awt.*; +import java.awt.event.*; import java.util.*; import java.io.*; import javax.sound.sampled.*; -public class Waveform extends JPanel { +public class Waveform extends JPanel implements MouseListener, MouseMotionListener { int[] samples = null; int leftMarker = 0; int rightMarker = 0; + int leftMarkerSaved = 0; + int rightMarkerSaved = 0; int leftAltMarker = 0; int rightAltMarker = 0; + int dragging = 0; + + int step = 1; + + ArrayList markerDragListeners; + public Waveform() { super(); + addMouseListener(this); + addMouseMotionListener(this); + markerDragListeners = new ArrayList(); + } + + public void addMarkerDragListener(MarkerDragListener l) { + if (markerDragListeners.indexOf(l) == -1) { + markerDragListeners.add(l); + } } public void paintComponent(Graphics g) { @@ -48,7 +66,7 @@ public class Waveform extends JPanel { if (samples != null) { int num = samples.length; - int step = num / w; + step = num / w; if (step == 0) return; for (int n = 0; n < w; n++) { @@ -88,14 +106,18 @@ public class Waveform extends JPanel { g.drawLine(n, h/2 + (int)lave, n, h/2 - (int)have); } + g.setColor(new Color(255, 0, 0, 32)); + g.fillRect(0, 0, leftAltMarker/step, h); + g.fillRect(rightAltMarker/step, 0, w , h); + g.setColor(new Color(255, 0, 0)); + g.drawLine(leftAltMarker/step, 0, leftAltMarker/step, h); + g.drawLine(rightAltMarker/step, 0, rightAltMarker/step, h); + + g.setColor(new Color(255, 255, 0)); g.drawLine(leftMarker/step, 0, leftMarker/step, h); g.drawLine(rightMarker/step, 0, rightMarker/step, h); - g.setColor(new Color(255, 255, 0)); - - g.drawLine(leftAltMarker/step, 0, leftAltMarker/step, h); - g.drawLine(rightAltMarker/step, 0, rightAltMarker/step, h); } } @@ -141,4 +163,84 @@ public class Waveform extends JPanel { repaint(); } + public void mouseExited(MouseEvent e) { + if (dragging != 0) { + leftMarker = leftMarkerSaved; + rightMarker = rightMarkerSaved; + repaint(); + } + dragging = 0; + } + + public void mouseEntered(MouseEvent e) { + } + + public void mousePressed(MouseEvent e) { + int x = e.getX(); + if ((x >= (leftMarker/step) - 2) && (x <= (leftMarker/step) + 2)) { + leftMarkerSaved = leftMarker; + rightMarkerSaved = rightMarker; + dragging = 1; + return; + } + if ((x >= (rightMarker/step) - 2) && (x <= (rightMarker/step) + 2)) { + rightMarkerSaved = rightMarker; + leftMarkerSaved = leftMarker; + dragging = 2; + return; + } + } + + public void mouseReleased(MouseEvent e) { + if (dragging == 1) { + MarkerDragEvent evt = new MarkerDragEvent(this, leftMarker); + for (MarkerDragListener l : markerDragListeners) { + l.leftMarkerMoved(evt); + } + } else if (dragging == 2) { + MarkerDragEvent evt = new MarkerDragEvent(this, rightMarker); + for (MarkerDragListener l : markerDragListeners) { + l.rightMarkerMoved(evt); + } + } + dragging = 0; + } + + public void mouseClicked(MouseEvent e) { + } + + public void mouseMoved(MouseEvent e) { + int x = e.getX(); + if ((x >= (leftMarker/step) - 2) && (x <= (leftMarker/step) + 2)) { + setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); + return; + } + if ((x >= (rightMarker/step) - 2) && (x <= (rightMarker/step) + 2)) { + setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); + return; + } + + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + + } + + public void mouseDragged(MouseEvent e) { + if (dragging == 0) return; + int x = e.getX(); + + if (dragging == 1) { + leftMarker = x * step; + if (leftMarker > rightMarker) { + leftMarker = rightMarker; + } + } else if (dragging == 2) { + rightMarker = x * step; + if (rightMarker < leftMarker) { + rightMarker = leftMarker; + } + } + + repaint(); + + } }