view src/AudioListener.java @ 0:5c6db5d47717 default tip

first commit
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Tue, 09 Dec 2008 15:04:03 +0900
parents
children
line wrap: on
line source


import javax.sound.sampled.*;
import java.lang.Runnable;
import java.lang.Math;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;

public class AudioListener implements Runnable {
	private int frameLength;
	private Plotter plotter;
	private Plotter sprPlotter;
	private AudioFormat format;
	private boolean runnable=true;
	private Thread thread;
	private FloatFFT_1D fft;
	private double[] window;

	public AudioListener(AudioFormat af, Plotter plotter, Plotter sprPlotter, int fps, boolean windowOn) {
		assert af.getSampleRate()%fps==0;
		this.frameLength = (int)af.getSampleRate()/fps;
		this.plotter = plotter;
		this.sprPlotter = sprPlotter;
		this.format = af;
		this.fft = new FloatFFT_1D(frameLength);
		this.window = new double[frameLength];
		for (int i=0; i<frameLength; i++) {
			if (windowOn)
				window[i] = Math.exp( -Math.pow((((double)i-frameLength/2.0)/(frameLength/2.0)*5),2) /4.0);
			else
				window[i] = 1;
			//window[i] = ( -Math.pow((((double)i-frameLength/2.0)/(frameLength/2.0)*5),2) /4.0);
		}
	}

	public void start() {
		thread = new Thread(this);
		thread.start();
	}

	public void run() {
		int count=0;
		TargetDataLine line;
		//format = formatControls.getFormat();

		/* こいつが3つものthreadを生成している?  */
		DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
		if (!AudioSystem.isLineSupported(info)) {
			System.out.println("Line matching " + info + " not supported.");
			return;
		}

		// get and open the source data line for playback.
		try {
			line = (TargetDataLine) AudioSystem.getLine(info);
			System.out.println("You can access the line");
			line.open(format, frameLength*5);
		} catch (Exception ex) { 
			System.err.println("Unable to open the line: " + ex);
			return;
		}

		/* main loop.  */
		line.start();
		byte[] data = new byte[frameLength];
		byte[] spectrum = new byte[frameLength/2];
		while (runnable) {
			int numByte;
			numByte = line.read(data, 0, data.length);
			if (numByte==-1) {
				System.err.println("error");
				break;
			}

			computeSpectrum(data, spectrum);
			plotter.setData(data);
			plotter.repaint();
			sprPlotter.setData(spectrum);
			sprPlotter.repaint();
			count++;
		}

		line.stop();
		line.flush();
		line.close();
		System.out.println("count: "+count);

	}

	public void stop() {
		runnable=false;
		try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("thread end");
	}

	public void computeSpectrum(byte[] input, byte[] output) {
		float[] data = new float[2*frameLength];

		/*  windowing */
		/*
		 *  w(t) = exp(-x^2/o^2)
		 *  w(t) = exp( -(x-5)^2 / 2^2 )   0<x<10
		 */

		for (int i=0; i<frameLength; i++) {
			data[2*i] = (float)input[i] * (float)window[i];
			/* windowing */
			data[2*i+1] = 0;
		}

		/* Fast Fourier Transform  */
		fft.complexForward(data);

		for (int i=0; i<frameLength/2; i++) {
			//double tmp = java.lang.Math.hypot(data[2*i],data[2*i+1]);
			double tmp = data[2*i]*data[2*i]+data[2*i+1]*data[2*i+1];
			//output[i] = (byte)java.lang.Math.log10(tmp);
			output[i] = (byte)(tmp/(float)frameLength);
		}
	}

}