All Downloads are FREE. Search and download functionalities are using the official Maven repository.

examples.be.tarsos.dsp.example.Flanger Maven / Gradle / Ivy

The newest version!
/*
*      _______                       _____   _____ _____  
*     |__   __|                     |  __ \ / ____|  __ \ 
*        | | __ _ _ __ ___  ___  ___| |  | | (___ | |__) |
*        | |/ _` | '__/ __|/ _ \/ __| |  | |\___ \|  ___/ 
*        | | (_| | |  \__ \ (_) \__ \ |__| |____) | |     
*        |_|\__,_|_|  |___/\___/|___/_____/|_____/|_|     
*                                                         
* -------------------------------------------------------------
*
* TarsosDSP is developed by Joren Six at IPEM, University Ghent
*  
* -------------------------------------------------------------
*
*  Info: http://0110.be/tag/TarsosDSP
*  Github: https://github.com/JorenSix/TarsosDSP
*  Releases: http://0110.be/releases/TarsosDSP/
*  
*  TarsosDSP includes modified source code by various authors,
*  for credits and info, see README.
* 
*/


package be.tarsos.dsp.example;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import be.tarsos.dsp.AudioDispatcher;
import be.tarsos.dsp.GainProcessor;
import be.tarsos.dsp.MultichannelToMono;
import be.tarsos.dsp.effects.FlangerEffect;
import be.tarsos.dsp.io.TarsosDSPAudioInputStream;
import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
import be.tarsos.dsp.io.jvm.AudioPlayer;
import be.tarsos.dsp.io.jvm.JVMAudioInputStream;
import be.tarsos.dsp.io.jvm.WaveformWriter;

public class Flanger extends JFrame {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -5020248948695915733L;
	private AudioDispatcher dispatcher;
	private FlangerEffect flangerEffect;
	private GainProcessor inputGain;
	
	private int defaultInputGain = 100;//%
	private int defaultLength = 20;//ms
	private int defaultImpact = 50;//%
	private int defaultFrequency = 3;//Hz
	
	
	public Flanger() {
		this.setLayout(new BorderLayout());
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		this.addWindowListener( new WindowAdapter() {
              @Override
              public void windowClosing(WindowEvent we) {
                  if(dispatcher != null){
                	  dispatcher.stop();
                  }
                  System.exit(0);
              }
          } );
		this.setTitle("Flanger Effect Example");
		
		JPanel inputPanel = buildInputPanel();		
		
		final JSlider flangerLengthSlider = new JSlider(1, 100);
		flangerLengthSlider.setValue(defaultLength);
		flangerLengthSlider.setPaintLabels(true);
		flangerLengthSlider.addChangeListener(new ChangeListener(){
			@Override
			public void stateChanged(ChangeEvent arg0) {
				if (flangerEffect != null) {
					double flangerLength = flangerLengthSlider.getValue() / 1000.0;
					flangerEffect.setFlangerLength(flangerLength);
				}
				defaultLength = flangerLengthSlider.getValue();
			}
		});
		
		final JSlider impact = new JSlider(0,100);
		impact.setValue(defaultImpact);
		impact.setPaintLabels(true);
		impact.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent arg0) {
				if (flangerEffect != null) {
					double depth = impact.getValue() / 100.0;
					flangerEffect.setWet(depth);
				}
				defaultImpact = impact.getValue();
			}
		});
		
		final JSlider lfoFrequency = new JSlider(0,100);
		lfoFrequency.setValue(defaultFrequency);
		lfoFrequency.setPaintLabels(true);
		lfoFrequency.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent arg0) {
				if (flangerEffect != null) {
					double frequency = lfoFrequency.getValue() / 10.0;
					flangerEffect.setLFOFrequency(frequency);		
				}
				defaultFrequency = lfoFrequency.getValue();		
			}
		});
		
		
		
		JPanel params = new JPanel(new GridLayout(0,1));
		params.setBorder(new TitledBorder("2. Set the algorithm parameters"));
		
		JLabel label = new JLabel("Impact (%)");
		label.setToolTipText("The impact factor in % (100 is no change).");
		params.add(label);
		params.add(impact);
		
		label = new JLabel("Flanger length (in ms)");
		label.setToolTipText("The flanger buffer lengt in ms.");
		params.add(label);
		params.add(flangerLengthSlider);	
		
		label = new JLabel("Flanger LFO Frequency (in Hz x 10)");
		label.setToolTipText("The flanger LFO Frequency lengt in dHz.");
		params.add(label);
		params.add(lfoFrequency);
		
		final JSlider gainSlider = new JSlider(0,200);
		gainSlider.setValue(defaultInputGain);
		gainSlider.setPaintLabels(true);
		gainSlider.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent arg0) {
				if (inputGain != null) {
					double gainValue = gainSlider.getValue() / 100.0;
					inputGain.setGain(gainValue);
				}
				defaultInputGain = gainSlider.getValue();
			}
		});
		
		JPanel gainPanel = new JPanel(new BorderLayout());
		label = new JLabel("Gain (in %)");
		label.setToolTipText("Volume in % (100 is no change).");
		gainPanel.add(label,BorderLayout.NORTH);
		gainPanel.add(gainSlider,BorderLayout.CENTER);
		gainPanel.setBorder(new TitledBorder("3. Optionally change the input volume"));
		
		add(inputPanel,BorderLayout.NORTH);
		add(params,BorderLayout.CENTER);
		add(gainPanel,BorderLayout.SOUTH);
	}
	


	private JPanel buildInputPanel() {
		JPanel fileChooserPanel = new JPanel(new BorderLayout());
		fileChooserPanel.setBorder(new TitledBorder("1... Or choose your audio (wav mono)"));
		
		final JFileChooser fileChooser = new JFileChooser();
		
		JButton chooseFileButton = new JButton("Choose a file...");
		chooseFileButton.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int returnVal = fileChooser.showOpenDialog(Flanger.this);
	            if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fileChooser.getSelectedFile();
	                startFile(file,null);
	            } else {
	                //canceled
	            }
			}			
		});
		fileChooserPanel.add(chooseFileButton);
		fileChooser.setLayout(new BoxLayout(fileChooser, BoxLayout.PAGE_AXIS));
		

		JPanel inputSubPanel = new JPanel(new BorderLayout());
		JPanel inputPanel = new InputPanel();
		inputPanel.addPropertyChangeListener("mixer",
				new PropertyChangeListener() {
					@Override
					public void propertyChange(PropertyChangeEvent arg0) {
						startFile(null,(Mixer) arg0.getNewValue());
					}
				});
		inputSubPanel.add(inputPanel,BorderLayout.NORTH);
		inputSubPanel.add(fileChooserPanel,BorderLayout.SOUTH);
		return inputSubPanel;
	}
	
	private void startFile(File inputFile, Mixer mixer) {
		if (dispatcher != null) {
			dispatcher.stop();
		}
		AudioFormat format;
		int bufferSize = 1024;
		int overlap = 0;
		double sampleRate = 44100;
		try {
			if(inputFile != null){
				format = AudioSystem.getAudioFileFormat(inputFile).getFormat();
				sampleRate = format.getSampleRate();
			}else{
				format = new AudioFormat((float) sampleRate, 16, 1, true,true);
			}
			
			inputGain = new GainProcessor(defaultInputGain/100.0);
			AudioPlayer audioPlayer = new AudioPlayer(format);	
			
			 if(inputFile == null){
				 DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, format);
				TargetDataLine line;
				line = (TargetDataLine) mixer.getLine(dataLineInfo);
				line.open(format, bufferSize);
				line.start();
				final AudioInputStream stream = new AudioInputStream(line);
				final TarsosDSPAudioInputStream audioStream = new JVMAudioInputStream(stream);
				dispatcher = new AudioDispatcher(audioStream, bufferSize,overlap); 
			 }else{
					if(format.getChannels() != 1){
						dispatcher = AudioDispatcherFactory.fromFile(inputFile,bufferSize * format.getChannels(),overlap * format.getChannels());
						dispatcher.addAudioProcessor(new MultichannelToMono(format.getChannels(),true));
					}else{
						dispatcher = AudioDispatcherFactory.fromFile(inputFile,bufferSize,overlap);
					}
			 }
			 
			flangerEffect = new FlangerEffect(defaultLength/1000.0,defaultImpact/100.0,sampleRate,defaultFrequency/10.0);
				
			dispatcher.addAudioProcessor(flangerEffect);
			dispatcher.addAudioProcessor(inputGain);
			dispatcher.addAudioProcessor(new WaveformWriter(format, "flanger.wav"));
			dispatcher.addAudioProcessor(audioPlayer);

			Thread t = new Thread(dispatcher);
			t.start();
		} catch (UnsupportedAudioFileException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (LineUnavailableException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

	public static void main(String... strings) throws InterruptedException,
			InvocationTargetException {
		SwingUtilities.invokeAndWait(new Runnable() {
			@Override
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
				} catch (Exception e) {
					//ignore failure to set default look en feel;
				}
				JFrame frame = new Flanger();
				frame.pack();
				frame.setVisible(true);
			}
		});
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy