wave混音的实现(2)

关于混音算法,参考的是 http://jacky-zhang.iteye.com/blog/766053,下面是具体的实现逻辑
package example.audio;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class Mixing2 extends MIDlet implements CommandListener{
	private Command play1 = new Command("Play one", Command.OK, 0);
	private Command play2 = new Command("Play two", Command.OK, 1);
	private Command play3 = new Command("Play three", Command.OK, 6);
	private Command stop1 = new Command("Stop one", Command.CANCEL, 2);
	private Command stop2 = new Command("stop two", Command.CANCEL, 3);
	private Command stop3 = new Command("stop three", Command.CANCEL, 7);
	private Command playMix = new Command("play mix", Command.OK, 4);
	private Command stopRecord = new Command("stop record", Command.OK, 5);
	private Player player1;
	private Player player2;
	private Player player3;
	private Player player4;
	private String[] urls = {"/128kbps/intwap-5.wav","/128kbps/intwap-6.wav","/128kbps/intwap-7.wav"};
	private Form form = new Form("Test mixing");
	private byte[][] data = new byte[3][];
	private int[][] times = new int[3][];
	private long startTime = 0;
	private long size;
	private int idx1 = 0;
	private int idx2 = 0;
	private int idx3 = 0;
	private static final int FIRST = 1;
	private static final int SECOND = 2;
	private static final int THIRD = 3;
	private boolean start = false;
	
	public Mixing2() {}

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {	}

	protected void pauseApp() {	}

	protected void startApp() throws MIDletStateChangeException {
		form.addCommand(play1);
		form.addCommand(stop1);
		form.addCommand(play2);
		form.addCommand(stop2);
		form.addCommand(play3);
		form.addCommand(stop3);
		form.addCommand(playMix);
		form.addCommand(stopRecord);
		form.setCommandListener(this);
		Display.getDisplay(this).setCurrent(form);
	}
	
	public void commandAction(Command arg0, Displayable arg1) {
		if (arg0 == play1) {
			form.append("play one");
			if(startTime == 0) startTime = System.currentTimeMillis();
			new Thread(){
				public void run() {
					try {
						stopPlayer1();
						(player1 = initPlayer(FIRST)).start();
					} catch (MediaException e) {
						e.printStackTrace();
					}					
				}
			}.start();
			System.out.println("player1.start.time: "+System.currentTimeMillis());
		}
		else if (arg0 == stop1) {
			stopPlayer1();
		}
		else if (arg0 == play2) {
			form.append("play two");
			if(startTime == 0) startTime = System.currentTimeMillis();
			new Thread(){
				public void run() {
					try {
						stopPlayer2();
						(player2 = initPlayer(SECOND)).start();
					} catch (MediaException e) {
						e.printStackTrace();
					}					
				}
			}.start();
		}
		else if (arg0 == stop2) {
			stopPlayer2();
		}
		else if (arg0 == play3) {
			form.append("play three");
			if(startTime == 0) startTime = System.currentTimeMillis();
			new Thread(){
				public void run() {
					try {
						stopPlayer3();
						(player3 = initPlayer(THIRD)).start();
					} catch (MediaException e) {
						e.printStackTrace();
					}					
				}
			}.start();
		}
		else if (arg0 == stop3) {
			stopPlayer3();
		}
		else if (arg0 == playMix) {
			new Thread(){
				public void run() {
					try {
						ByteArrayOutputStream bos = new ByteArrayOutputStream();
						byte[] data = mixing();
						System.out.println("combine.................data "+data.length);
						try {
							bos.write(new WaveHeader(data.length, (short)16, 8000).getHeader());
							bos.write(data);
						} catch (IOException e) {
							e.printStackTrace();
						}
						System.out.println("ready....stop....player........ ");
						stopPlayer4();
						System.out.println("ready....mix....player........ ");
						player4 = Manager.createPlayer(new ByteArrayInputStream(bos.toByteArray()), "audio/x-wav");
						player4.prefetch();
						player4.realize();
						player4.start();
					} catch (IOException e) {
						e.printStackTrace();
					} catch (MediaException e) {
						e.printStackTrace();
					}
					System.out.println("playing.........mix.......data ");
					for(int i=0;i<times.length;i++){
						times[i] = null;
					}
					startTime = 0;
					idx1 = idx2 = idx3 = 0;
				};
			}.start();
		}
		else if (arg0 == stopRecord) {
			stopPlayer1();
			stopPlayer2();
			stopPlayer3();
			System.gc();
		}
	}
	
	private void saveToDisk(){
//		FileConnection file = (FileConnection)Connector.open("file://localhost/" + );
	}
	
	private byte[] mixing(){
		size = (System.currentTimeMillis() - startTime) * 16;
		long start = System.currentTimeMillis();
		byte[] mixData = new byte[(int) size];
		byte[][] mixPices = new byte[times.length][];
		System.out.println("111111111111: "+size);
		for(int i=0; i< times.length;i++){
			if(times[i]==null) continue;
			mixPices[i] = new byte[(int) size];
			int length = data[i].length-44;
			for(int j =0; j<times[i].length;j++){
				if(times[i][j]==0)break;
				System.out.println("player"+i+".time: "+times[i][j]);
				if((j+1)%2==0)System.out.println((times[i][j]-times[i][j-1]));
				if((j+1)%2==0) {
					int max = times[i][j]-times[i][j-1];
					for (int k = 44; k < max; k++){
						if(k >= length) break;
						mixPices[i][(int) times[i][j-1]+k-44] = data[i][k];
					}
				}
			}
		}
		System.out.println("999999999999: "+(System.currentTimeMillis() - start));
		double f = 1.0f;
		int MAX = 127, MIN = -127;
		double STEPSIZE;
		for(int m=0;m<mixData.length;m++){
			mixData[m] = 0;
			double temp = 0;
			for(int n =0;n<mixPices.length;n++){
				if(mixPices[n]==null) continue;
				temp += mixPices[n][m];
			}
			if(temp==0) continue;
			temp = temp * f;
			if(temp>MAX){
				double f0 = 127.0f/temp;
				f = f0;
				temp = MAX;
			}
			else if(temp < MIN){
				double f0 = -127.0f/temp;
				f = f0;
				temp = (byte) MIN;
			}
			if(f<1) {
				STEPSIZE = ((1.0f-f)/16);
				f += STEPSIZE;
			}
			mixData[m] = (byte) temp;
		}
		for(int n =0;n<mixPices.length;n++){
			mixPices[n] = null;
		}
		mixPices = null;
		System.out.println("mix cost time: "+(System.currentTimeMillis()-start));
		return mixData;
	}
	
	private Player initPlayer(int p){
		byte[] temp = null;
		PlayerListener plistener = null;
		if( p == FIRST) {
			if (data[0]==null) {
				data[0] = getWaveData(urls[0]);
			}
			temp = data[0];
			plistener = p1;
		}
		else if(p==SECOND) {
			if(data[1]==null){
				data[1] = getWaveData(urls[1]);
			}
			temp = data[1];
			plistener = p2;
		}
		else if(p==THIRD) {
			if(data[2]==null){
				data[2] = getWaveData(urls[2]);
			}
			temp = data[2];
			plistener = p3;
		}
		Player player = null;
		try {
			InputStream is = new ByteArrayInputStream(temp);
			player = Manager.createPlayer(is, "audio/x-wav");
			player.prefetch();
			player.realize();
			player.addPlayerListener(plistener);
//			player.setLoopCount(-1);
		} catch (MediaException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
		return player;
	}
	
	private void stopPlayer1(){
		if(player1!=null && player1.getState() != Player.CLOSED){
			form.append("stop one");
			try {
				player1.stop();
				player1.close();
				player1 = null;
//				System.gc();
			} catch (MediaException e) {
				e.printStackTrace();
			}			
		}
	}
	
	private void stopPlayer2(){
		if(player2!=null && player2.getState() != Player.CLOSED){
			form.append("stop two");
			try {
				player2.stop();
				player2.close();
				player2 = null;
//				System.gc();
			} catch (MediaException e) {
				e.printStackTrace();
			}			
		}
	}
	
	private void stopPlayer3(){
		if(player3!=null && player3.getState() != Player.CLOSED){
			form.append("stop three");
			try {
				player3.stop();
				player3.close();
				player3 = null;
//				System.gc();
			} catch (MediaException e) {
				e.printStackTrace();
			}			
		}
	}
	private void stopPlayer4(){
		if(player4!=null && player4.getState() != Player.CLOSED){
			form.append("stop mix");
			try {
				player4.stop();
				player4.close();
				player4 = null;
//				System.gc();
			} catch (MediaException e) {
				e.printStackTrace();
			}			
		}
	}
	
	PlayerListener p1 = new PlayerListener(){

		public void playerUpdate(Player arg0, String arg1, Object arg2) {
			if(arg1.equals(PlayerListener.END_OF_MEDIA)){
				System.out.println("end of media");
//				System.out.println(System.currentTimeMillis());
				times[0][idx1] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx1++;
				System.out.println("  player1.cost.time: "+arg0.getMediaTime());
			}
			else if(arg1.equals(PlayerListener.STOPPED)){
				System.out.println("stopped");
				times[0][idx1] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx1++;
//				System.out.println(System.currentTimeMillis());
			}
			else if(arg1.equals(PlayerListener.STARTED)){
				System.out.println("started");
				if(times[0] == null) times[0] = new int[100];
				times[0][idx1] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx1++;
				System.out.println(System.currentTimeMillis());
			}
		}
		
	};
	
	PlayerListener p2 = new PlayerListener(){

		public void playerUpdate(Player arg0, String arg1, Object arg2) {
			if(arg1.equals(PlayerListener.STARTED)){
				System.out.println("started");
				if(times[1] == null) times[1] = new int[100];
				times[1][idx2] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx2++;
//				System.out.println(System.currentTimeMillis());
			}
			else if(arg1.equals(PlayerListener.STOPPED)){
				System.out.println("stopped");
				times[1][idx2] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx2++;
//				System.out.println(System.currentTimeMillis());
			}
			else if(arg1.equals(PlayerListener.END_OF_MEDIA)){
				System.out.println(player2.getState());
				times[1][idx2] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx2++;
			}
		}
		
	};

	PlayerListener p3 = new PlayerListener(){

		public void playerUpdate(Player arg0, String arg1, Object arg2) {
			if(arg1.equals(PlayerListener.STARTED)){
				System.out.println("started");
				if(times[2] == null) times[2] = new int[100];
				times[2][idx3] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx3++;
//				System.out.println(System.currentTimeMillis());
			}
			else if(arg1.equals(PlayerListener.STOPPED)){
				System.out.println("stopped");
				times[2][idx3] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx3++;
//				System.out.println(System.currentTimeMillis());
			}
			else if(arg1.equals(PlayerListener.END_OF_MEDIA)){
				System.out.println(player3.getState());
				times[2][idx3] = (int) ((System.currentTimeMillis() - startTime) * 16);
				idx3++;
			}
		}
		
	};
	private byte[] getWaveData(String url){
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		InputStream is = getClass().getResourceAsStream(url);
//		int m = 0;
		byte[] d = new byte[2048];
		while(true){
			try {
				int t = is.read(d);
//				m = is.read();
				if(t==-1) break;
				bos.write(d);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		byte[] data = bos.toByteArray();
		System.out.println(data.length);
		try {
			is.close();
			bos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}

}

你可能感兴趣的:(thread,算法,Blog,F#,J#)