/** Undo the last operation */ public void performUndo() { if (!canUndo()) return; Object lastOperation = undoOperations.get(undoOperations.size() - 1); if (lastOperation instanceof Integer) { Integer last = (Integer) lastOperation; int action = last.intValue(); switch (action) { case EditAction.PASTE: case EditAction.TRIM: redoElements.add(cutList.getLastElement()); cutList.removeLastElement(); case EditAction.CUT: case EditAction.DELETE: redoElements.add(cutList.getLastElement()); cutList.removeLastElement(); break; default: break; } } else if (lastOperation instanceof CutListElement) { cutList.removeLastElement(); redoElements.add(lastOperation); } redoOperations.add(lastOperation); undoOperations.remove(lastOperation); }
/** Redo the last undone operation */ public void performRedo() { if (!canRedo()) return; Object lastOperation = redoOperations.get(redoOperations.size() - 1); if (lastOperation instanceof Integer) { Integer last = (Integer) redoOperations.get(redoOperations.size() - 1); int action = last.intValue(); CutListElement el; switch (action) { case EditAction.PASTE: case EditAction.TRIM: el = (CutListElement) redoElements.get(redoElements.size() - 1); redoElements.remove(el); cutList.addElement(el); case EditAction.CUT: case EditAction.DELETE: el = (CutListElement) redoElements.get(redoElements.size() - 1); redoElements.remove(el); cutList.addElement(el); break; default: break; } } else if (lastOperation instanceof CutListElement) { cutList.addElement((CutListElement) lastOperation); redoElements.remove(lastOperation); } undoOperations.add(lastOperation); redoOperations.remove(lastOperation); }
/** * Set the source file for this WaveTab * * @param f The source file to set * @param waveForm The WaveForm corresponding to the file */ protected void setInput(File f, AudioFileWaveForm waveForm) { tabItem.setText(f.getName()); source = f; cutList.removeModificationListener(this); cutList = new CutList(new AudioFileSource(f, waveForm)); cutList.addModificationListener(this); waveDisplay.redraw(); }
/** Trim this WaveTab´s data to the current selection */ public void performTrim() { Selection sel = waveDisplay.getSelection(); int pos = sel.getLeft(); cutList.addElement(new DeleteElement(0, sel.getLeft())); cutList.addElement( new DeleteElement( sel.getRight() - sel.getLeft(), cutList.getLength() - sel.getRight() + sel.getLeft())); waveDisplay.setSelection(new Selection(0, cutList.getLength())); waveDisplay.setPosition(0); }
/** Delete the current selection */ public void performDelete() { Selection sel = waveDisplay.getSelection(); int pos = sel.getLeft(); cutList.addElement(new DeleteElement(sel.getLeft(), sel.getRight() - sel.getLeft())); waveDisplay.setSelection(new Selection(0)); waveDisplay.setPosition(pos); }
/** Create a clone of the current CutList to be used as clipboard source */ private void prepareClipboard() { Selection sel = waveDisplay.getSelection(); int left = sel.getLeft(); int right = sel.getRight(); CutListSource cl = cutList.duplicate(); if (left == 0 && right == cl.getLength()) copySource = cl; else copySource = new SubSource(cl, left, right - left); }
/** Insert the clipboard content of the editor at the current position */ public void performPaste() throws DifferentChannelException { WaveTab sourceTab = editor.getCopySource(); if (sourceTab == null) return; if (sourceTab.getChannels() != getChannels()) { throw new DifferentChannelException(); } CutListSource source = sourceTab.getCopySource(); int pos = waveDisplay.getSelection().getLeft(); performDelete(); cutList.addElement(new InsertElement(source, pos)); }
/** * @see * com.groovemanager.sampled.waveform.WaveFormProvider#getWaveForm(com.groovemanager.sampled.waveform.AbstractWaveFormDisplay, * int, int, int) */ public WaveForm getWaveForm(AbstractWaveFormDisplay display, int start, int length, int width) { if (display == waveDisplay) { // Can we use the last WaveForm? if (lastWaveForm != null && lastWaveForm.canProvide( (int) Math.round((start - lastWaveFormPos) / lastWaveForm.getZoomFactor()), (int) Math.round(length / lastWaveForm.getZoomFactor()), width)) lastWaveForm = lastWaveForm.subWaveForm( (int) Math.round((start - lastWaveFormPos) / lastWaveForm.getZoomFactor()), (int) Math.round(length / lastWaveForm.getZoomFactor()), width); else lastWaveForm = cutList.getWaveForm(start, length, width); lastWaveFormPos = start; return lastWaveForm; } else { // Can we use the last WaveForm? if (lastZoomWaveForm != null && lastZoomWaveForm.canProvide( (int) Math.round((start - lastZoomWaveFormPos) / lastZoomWaveForm.getZoomFactor()), (int) Math.round(length / lastZoomWaveForm.getZoomFactor()), width)) lastZoomWaveForm = lastZoomWaveForm.subWaveForm( (int) Math.round((start - lastZoomWaveFormPos) / lastZoomWaveForm.getZoomFactor()), (int) Math.round(length / lastZoomWaveForm.getZoomFactor()), width); else lastZoomWaveForm = cutList.getWaveForm(start, length, width); lastZoomWaveFormPos = start; return lastZoomWaveForm; } }
/** * Get the AudioInputStream for the current selection * * @see com.groovemanager.sampled.AudioPlayerProvider#getAudioInputStream() */ public AudioInputStream getAudioInputStream() throws NotReadyException { Selection sel = waveDisplay.getSelection(); lastStart = sel.getLeft(); if (lastStart >= cutList.getLength()) lastStart = 0; int right = sel.getRight(); if (right > cutList.getLength()) right = cutList.getLength(); if (lastStart == right) return cutList.getAudioInputStream(lastStart, cutList.getLength() - right); else return cutList.getAudioInputStream(lastStart, right - lastStart); }
/** @see com.groovemanager.sampled.AudioPlayerProvider#stopRec() */ public void stopRec() { modified = true; canRec = false; recording = false; try { out.close(); File tempPeak = File.createTempFile("gmtmp_", ".gmpk"); ((DynamicPeakWaveForm) afWF.getPeakWaveForm()).close(source.lastModified()); try { AudioFileWaveForm aw = new AudioFileWaveForm(source, afWF.getPeakWaveForm(), 32 * 1024, 25); fileFormat = AudioSystem.getAudioFileFormat(source); cutList.setSource(new AudioFileSource(source, aw)); waveDisplay.showAll(); } catch (UnsupportedAudioFileException e1) { e1.printStackTrace(); editor.errorMessage(e1.getMessage()); } this.editor.player.setProvider(this); } catch (IOException e) { e.printStackTrace(); editor.errorMessage(e.getMessage()); } editor.zoomWaveDisplay.setSource(this); }
/** * Apply the given effect to this WaveTab´s audio data * * @param effect The effect to apply */ public void applyEffect(Effect effect) { Selection sel = waveDisplay.getSelection(); if (sel.getLeft() == sel.getRight()) waveDisplay.setSelection(new Selection(0, getTotalLength())); Thread thread = null; try { AudioInputStream stream = getAudioInputStream(); int sourceChannels = stream.getFormat().getChannels(); stream = AudioManager.getStereoInputStream(stream); final FXUnit unit = new FXUnit(effect); if (effect.needsAnalysis()) { Analyzer a = new Analyzer(unit, stream); ProgressMonitor monitor = new ProgressMonitor(getShell(), a, "Analyzing...", "Analyzing audio data"); monitor.start(); stream = AudioManager.getStereoInputStream(getAudioInputStream()); } final SourceDataLine sourceLine = unit.getEffectSourceLine(); sourceLine.open(); sourceLine.start(); final TargetDataLine targetLine = unit.getEffectTargetLine(); targetLine.open(); targetLine.start(); if (!stream.getFormat().equals(sourceLine.getFormat())) { if (AudioSystem.isConversionSupported(sourceLine.getFormat(), stream.getFormat())) stream = AudioSystem.getAudioInputStream(sourceLine.getFormat(), stream); else { editor.errorMessage( "Unable to apply effect:\nFormat conversion from " + stream.getFormat() + " to " + sourceLine.getFormat() + " not supported."); return; } } final AudioInputStream inStream = stream; thread = new Thread() { public void run() { int numBytesRead = 0; byte[] buffer = new byte[sourceLine.getBufferSize()]; while (numBytesRead != -1 && !getItem().isDisposed()) { try { numBytesRead = inStream.read(buffer, 0, buffer.length); } catch (IOException e1) { e1.printStackTrace(); numBytesRead = -1; } if (numBytesRead > 0) { sourceLine.write(buffer, 0, numBytesRead); } try { Thread.sleep(0, 1); } catch (InterruptedException e) { } } } }; thread.start(); AudioInputStream in = new AudioInputStream(targetLine); if (sourceChannels == 1) in = AudioManager.getMonoInputStream(in); File tempFile = File.createTempFile("gmtmp_", ".wav"); AudioFormat tempFormat = new AudioFormat( fileFormat.getFormat().getSampleRate(), 16, fileFormat.getFormat().getChannels(), true, false); AudioFileOutputStream out = AudioManager.getDefault() .getAudioFileOutputStream( tempFile, tempFormat, AudioFileFormat.Type.WAVE, null, null, null); if (!in.getFormat().equals(out.getFormat())) in = AudioSystem.getAudioInputStream(out.getFormat(), in); SaveFileThread saver = new SaveFileThread( in, out, (int) inStream.getFrameLength(), in.getFormat().getFrameSize(), true); ProgressMonitor monitor = new ProgressMonitor( getShell(), saver, "Apply Effect", "Applying " + effect.getName() + " to Selection"); monitor.start(); File tempPeak = File.createTempFile("gmtmp_", ".gmpk"); CreatePeakFileThread peak = new CreatePeakFileThread(AudioSystem.getAudioInputStream(tempFile), tempPeak); monitor = new ProgressMonitor( getShell(), peak, "Creating peak file", "Creating peak file for applied effect."); monitor.start(); PeakWaveForm pwf = new PeakWaveForm(tempPeak); AudioFileWaveForm awf = new AudioFileWaveForm(tempFile, pwf, 32 * 1024, 25); CutListSource newSource = new AudioFileSource(tempFile, awf); sel = waveDisplay.getSelection(); int left = sel.getLeft(); int right = sel.getRight(); ReplaceElement el = new ReplaceElement( effect.getName(), newSource, left, right - left, fileFormat.getFormat()); cutList.addElement(el); undoOperations.add(el); redoOperations.clear(); thread.stop(); } catch (NotReadyException e) { e.printStackTrace(); editor.errorMessage(e.getMessage()); if (thread != null) thread.stop(); } catch (NotFinishedException e) { e.printStackTrace(); editor.errorMessage(e.getMessage()); if (thread != null) thread.stop(); } catch (LineUnavailableException e) { e.printStackTrace(); editor.errorMessage(e.getMessage()); if (thread != null) thread.stop(); } catch (IOException e) { e.printStackTrace(); editor.errorMessage(e.getMessage()); if (thread != null) thread.stop(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); editor.errorMessage(e.getMessage()); if (thread != null) thread.stop(); } }
/** @see com.groovemanager.sampled.waveform.WaveFormProvider#getTotalLength() */ public int getTotalLength() { return cutList.getLength(); }
/** @see com.groovemanager.sampled.AudioPlayerProvider#canProvide() */ public boolean canProvide() { return cutList.isReady(); }
/** * Get the whole AudioInputStream from this WaveTab´s audio data independent of its selection * * @return The AudioInputStream for all of this WaveTab´s audio data * @throws NotReadyException If no audio data can be provided at the moment */ public AudioInputStream getWholeAudioInputStream() throws NotReadyException { return cutList.getAudioInputStream(0, cutList.getLength()); }
/** * Create a new WaveTab * * @param editor The SampleEditor to which the WaveTab belongs * @param parent The TabFolder to be used as parent for the TabItem that will be created * @param style The style to be used for the TabItem * @param waveStyle The style to be used for the WaveFormDisplay * @param f The source file * @param wf The WaveForm corresponding to the file * @param format The AudioFormat to be used for recording or <code>null</code>, if not recording * @param rec true, if recording should be possible for this WaveTab, false otherwise * @throws UnsupportedAudioFileException If the AudioFileFormat of the given file can not be * detected (only in case of not recording) * @throws IOException If an I/O error occured */ WaveTab( SimpleSampleEditor editor, TabFolder parent, int style, int waveStyle, File f, AudioFileWaveForm wf, AudioFormat format, boolean rec) throws UnsupportedAudioFileException, IOException { this.editor = editor; afWF = wf; channels = wf.getChannels(); afSource = new AudioFileSource(f, afWF); cutList = new CutList(afSource); cutList.addModificationListener(this); waveDisplay = new WaveFormDisplay(parent, waveStyle, false); waveDisplay.setChannelBackgroundColor(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK)); waveDisplay.addWaveDisplayListener(editor); waveDisplay.setSource(this); waveDisplay.setEditMarkers(true); waveDisplay.getComposite().addKeyListener(createKeyListener()); waveDisplay.getComposite().addKeyListener(editor.keyListener); waveDisplay.addSelectableListener( new SelectableListener() { public void selectionPermanentChanged(Selectable s, Selection sel) {} public void selectionChanged(Selectable s, Selection sel) { WaveTab.this.editor.zoomSel.setEnabled(!sel.isEmpty()); } public void positionChanged(Selectable s, int pos) {} public void positionWillChange(Selectable s) {} public void positionWontChange(Selectable s) {} }); source = f; tabItem = new TabItem(parent, style); tabItem.setText(f.getName()); tabItem.setControl(waveDisplay.getComposite()); tabItem.setData(WaveTab.this); tabItem.addDisposeListener( new DisposeListener() { public void widgetDisposed(DisposeEvent e) { if (WaveTab.this.editor.player.getProvider() == WaveTab.this) WaveTab.this.editor.player.removeProvider(); } }); recording = rec; if (rec) { this.format = format; isNew = true; canRec = true; } else { fileFormat = AudioManager.getDefault().getAudioFileFormat(f, null, new String[] {"slices", "RLND"}); format = fileFormat.getFormat(); isNew = false; canRec = false; // For compatibility to 1.4... Map properties = AudioManager.getProperties(fileFormat); if (properties != null) { Object sl = properties.get("slices"); if (sl != null && sl instanceof int[][]) { int[][] slices = (int[][]) sl; for (int i = 0; i < slices.length; i++) { waveDisplay.addMarker(slices[i][0], ""); } } } } }