当前位置:  编程技术>移动开发
本页文章导读:
    ▪wave混音的兑现(1)        wave混音的实现(1) 先看关于wav文件的头信息下面是封装好的一个辅助类。用于生成头部信息。package example.audiotest; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * * @author cninjazh.........
    ▪ stringbuffer 跟stringbuilder的区别        stringbuffer 和stringbuilder的区别 虽然都知道String和它们的区别,但是我还有很多朋友说不清 stringbuffer 和stringbuilder的区别,很惭愧,我以前也说不清楚,今天发给大家共同学习        java.........
    ▪ wave混音的兑现(2)       wave混音的实现(2) 关于混音算法,参考的是http://jacky-zhang.iteye.com/blog/766053,下面是具体的实现逻辑package example.audio; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io..........

[1]wave混音的兑现(1)
    来源: 互联网  发布时间: 2014-02-18
wave混音的实现(1)
先看关于wav文件的头信息

下面是封装好的一个辅助类。用于生成头部信息。
package example.audiotest;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
 * 
 * @author cninjazh
 * WavHeader辅助类。用于生成头部信息。
 * WAV标准,头部应该是44字节
 */
public class WaveHeader {
	public final char fileID[] = { 'R', 'I', 'F', 'F' };
	public int fileLength;
	public char wavTag[] = { 'W', 'A', 'V', 'E' };
	public char fmtHdrID[] = { 'f', 'm', 't', ' ' };
	public int fmtHdrLeth;
	public short formatTag;
	public short channels;
	public int samplesPerSec;
	public int avgBytesPerSec;
	public short blockAlign;
	public short bitsPerSample;
	public char dataHdrID[] = { 'd', 'a', 't', 'a' };
	public int dataHdrLeth;
	/*
	 * pre-define wave header for 256kbps, 16bit, 16kHz, 1(mono), pcm
	 * 填入参数,比特率等等。这里用的是16位单声道 16000Hz
	 * fileLength = 内容的大小(dataSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
	 * avgBytesPerSec = 8bit/16bit、11kHz/16kHz的WAV流进行传输(最大流量为16*16=256kbps=32KB/s)
	 */
	public WaveHeader(int dataSize) {
		fileLength = dataSize + (44 - 8);
		fmtHdrLeth = 16;
		bitsPerSample = 16;
		channels = 1;
		formatTag = 0x0001;
		samplesPerSec = 16000;
		blockAlign = (short) (channels * bitsPerSample / 8);
		avgBytesPerSec = blockAlign * samplesPerSec;
		dataHdrLeth = dataSize;
	}
	
	public WaveHeader(int dataSize, short bitsPerSample, int samplesPerSec) {
		fileLength = dataSize + (44 - 8);
		fmtHdrLeth = 16;
		this.bitsPerSample = bitsPerSample;
		channels = 1;
		formatTag = 0x0001;
		this.samplesPerSec = samplesPerSec;
		blockAlign = (short) (channels * bitsPerSample / 8);
		avgBytesPerSec = blockAlign * samplesPerSec;
		dataHdrLeth = dataSize;
	}
	
	public byte[] getHeader() throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		/*
		 * ①RIFF WAVE Chunk
  			==================================
 			 | |所占字节数| 具体内容 |
  			==================================
 			 | ID | 4 Bytes | 'RIFF' |
 			----------------------------------
 			 | Size | 4 Bytes | |
  			----------------------------------
 			 | Type | 4 Bytes | 'WAVE' |
 			----------------------------------
		 */
		WriteChar(bos, fileID);//以RIFF作为标识
		WriteInt(bos, fileLength);//size,该size的大小是整个WAVE文件大小减去8个字节
		WriteChar(bos, wavTag);//Type字段,为"WAVE"表示是Wav文件
		/*
		 * ②Format Chunk
  			====================================================================
  			| | 字节数 | 具体内容 |
  			====================================================================
 			| ID | 4 Bytes | 'fmt ' |
  			--------------------------------
  			| Size | 4 Bytes | 数值为16或18,18则最后又附加信息 |
 			 -------------------------------- ----
 		 	| FormatTag | 2 Bytes | 编码方式,一般为0x0001 | |
  			-------------------------------- |
  			| Channels | 2 Bytes | 声道数目,1--单声道;2--双声道 | |
  			-------------------------------- |
  			| SamplesPerSec | 4 Bytes | 采样频率 | |
  			-------------------------------- |
  			| AvgBytesPerSec| 4 Bytes | 每秒所需字节数 | |===> WAVE_FORMAT
  			-------------------------------- |
  			| BlockAlign | 2 Bytes | 数据块对齐单位(每个采样需要的字节数) | |
  			-------------------------------- |
  			| BitsPerSample | 2 Bytes | 每个采样需要的bit数 | |
  			-------------------------------- |
  			| | 2 Bytes | 附加信息(可选,通过Size来判断有无) | |
  			-------------------------------- ----
		 */
		WriteChar(bos, fmtHdrID);//以"fmt "作为标识
		WriteInt(bos, fmtHdrLeth);//一般长度为16个字节,如果是18个字节则有附加信息,写在最后两个字节上
		WriteShort(bos, formatTag);
		WriteShort(bos, channels);
		WriteInt(bos, samplesPerSec);
		WriteInt(bos, avgBytesPerSec);
		WriteShort(bos, blockAlign);
		WriteShort(bos, bitsPerSample);
		
		WriteChar(bos, dataHdrID);
		WriteInt(bos, dataHdrLeth);
		bos.flush();
		byte[] r = bos.toByteArray();
		bos.close();
		return r;
	}

	private void WriteShort(ByteArrayOutputStream bos, int s)
			throws IOException {
		byte[] mybyte = new byte[2];
		mybyte[1] = (byte) ((s << 16) >> 24);
		mybyte[0] = (byte) ((s << 24) >> 24);
		bos.write(mybyte);
	}

	private void WriteInt(ByteArrayOutputStream bos, int n) throws IOException {
		byte[] buf = new byte[4];
		buf[3] = (byte) (n >> 24);
		buf[2] = (byte) ((n << 8) >> 24);
		buf[1] = (byte) ((n << 16) >> 24);
		buf[0] = (byte) ((n << 24) >> 24);
		bos.write(buf);
	}

	private void WriteChar(ByteArrayOutputStream bos, char[] id) {
		for (int i = 0; i < id.length; i++) {
			char c = id[i];
			bos.write(c);
		}
	}
}


    
[2] stringbuffer 跟stringbuilder的区别
    来源: 互联网  发布时间: 2014-02-18
stringbuffer 和stringbuilder的区别
虽然都知道String和它们的区别,但是我还有很多朋友说不清 stringbuffer 和stringbuilder的区别,很惭愧,我以前也说不清楚,今天发给大家共同学习
        java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

        StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

        例如,如果 z 引用一个当前内容是"start"的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含"startle",而 z.insert(4, "le") 将更改字符串缓冲区,使之包含"starlet"。

        通常,如果 sb 引用 StringBuilder 的一个实例,则 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。

        只要发生有关源序列(如在源序列中追加或插入)的操作,该类就只在执行此操作的字符串缓冲区上而不是在源上实现同步。

        每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即 StringBuilder。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

        java.lang.StringBuilder一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

        在 StringBuilder 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串生成器中。append 方法始终将这些字符添加到生成器的末端;而 insert 方法则在指定的点添加字符。

        例如,如果 z 引用一个当前内容为"start"的字符串生成器对象,则该方法调用 z.append("le") 将使字符串生成器包含"startle",而 z.insert(4, "le") 将更改字符串生成器,使之包含"starlet"。

        通常,如果 sb 引用 StringBuilder 的实例,则 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。 每个字符串生成器都有一定的容量。只要字符串生成器所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区。如果内部缓冲区溢出,则此容量自动增大。

将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。

    
[3] wave混音的兑现(2)
    来源: 互联网  发布时间: 2014-02-18
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;
	}

}

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3