`

2011.08.12(4)——— android AudioTrack 不能播放awr

阅读更多
2011.08.12(4)——— android AudioTrack 不能播放awr
http://blog.sina.com.cn/s/blog_7cb539590100qkcr.html
http://blog.csdn.net/chenjie19891104/article/details/6333553
http://blog.csdn.net/hellogv/article/details/6026455

我用AudioTrack播放MP3 awr都是不成功的 只会传出一堆的噪声,但是播放wav是没有问题的,因为wav就相当于原生态的pcm

这时候 我有两个选择

1、从3gp网站上下载awr解码算法 用jni调用 把awr解码成pcm
2、可以用AudioRecord来录制pcm 并用AudioTrack来播放

我用的时后者
package com.lp;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{
	
	private TextView stateView;
	
	private Button btnStart,btnStop,btnPlay,btnFinish;
	
	private RecordTask recorder;
	private PlayTask player;
	
	private File audioFile;
	
	private boolean isRecording=true, isPlaying=false; 
	
	private int frequence = 44100; 
	private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
	private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
	
	
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_pcm);
		
		stateView = (TextView)this.findViewById(R.id.view_state);
		stateView.setText("准备开始");
		btnStart = (Button)this.findViewById(R.id.btn_start);
		btnStop = (Button)this.findViewById(R.id.btn_stop);
		btnPlay = (Button)this.findViewById(R.id.btn_play);
		btnFinish = (Button)this.findViewById(R.id.btn_finish);
		btnFinish.setText("停止播放");
		btnPlay.setEnabled(false);
		btnFinish.setEnabled(false);
		btnStart.setOnClickListener(this);
		btnStop.setOnClickListener(this);
		btnPlay.setOnClickListener(this);
		btnFinish.setOnClickListener(this);
		
//		File fpath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/11");
//		fpath.mkdirs();
		try {
			//audioFile = File.createTempFile("test", ".pcm", fpath);
			audioFile = new File("/mnt/sdcard/1.pcm");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
	
	
	public void onClick(View v){
		int id = v.getId();
		switch(id){
		case R.id.btn_start:
			
			recorder = new RecordTask();
			recorder.execute();
			
			break;
		case R.id.btn_stop:
			this.isRecording = false;
			System.out.println(isRecording);
			break;
		case R.id.btn_play:
			
			player = new PlayTask();
			player.execute();
			break;
		case R.id.btn_finish:
			this.isPlaying = false;
			break;
			
		}
	}
	
	class RecordTask extends AsyncTask<Void, Integer, Void>{
		@Override
		protected Void doInBackground(Void... arg0) {
			//isRecording = true;
			try {
				//开通输出流到指定的文件
				DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(audioFile)));
				//FileOutputStream fos = new FileOutputStream(audioFile);
				//根据定义好的几个配置,来获取合适的缓冲大小
				int bufferSize = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding);
				//实例化AudioRecord
				AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, frequence, channelConfig, audioEncoding, bufferSize);
				//定义缓冲
				short[] buffer = new short[bufferSize];
				//byte[] buffer = new byte[bufferSize];
				
				//开始录制
				record.startRecording();
				
				int r = 0; //存储录制进度
				//定义循环,根据isRecording的值来判断是否继续录制
				while(isRecording){
					//从bufferSize中读取字节,返回读取的short个数
					//这里老是出现buffer overflow,不知道是什么原因,试了好几个值,都没用,TODO:待解决
					int bufferReadResult = record.read(buffer, 0, buffer.length);
					//循环将buffer中的音频数据写入到OutputStream中
					for(int i=0; i<bufferReadResult; i++){
						dos.writeShort(buffer[i]);
					}
					
//					byte[] tmpBuf = new byte[bufferReadResult];  
//                    System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult); 
//                    fos.write(tmpBuf, 0, bufferReadResult);
//                    fos.flush();
					publishProgress(new Integer(r)); //向UI线程报告当前进度
					r++; //自增进度值
				}
				//录制结束
				record.stop();
				System.out.println("The File length::"+audioFile.length());
				dos.close();
				//fos.close();
			} catch (Exception e) {
				// TODO: handle exception
			}
			return null;
		}
		
		//当在上面方法中调用publishProgress时,该方法触发,该方法在UI线程中被执行
		protected void onProgressUpdate(Integer...progress){
			stateView.setText(progress[0].toString());
		}
		
		protected void onPostExecute(Void result){
			btnStop.setEnabled(false);
			btnStart.setEnabled(true);
			btnPlay.setEnabled(true);
			btnFinish.setEnabled(false);
		}
		
		protected void onPreExecute(){
			//stateView.setText("正在录制");
			btnStart.setEnabled(false);
			btnPlay.setEnabled(false);
			btnFinish.setEnabled(false);
			btnStop.setEnabled(true);		
		}
		
	}
	
	class PlayTask extends AsyncTask<Void, Integer, Void>{
		@Override
		protected Void doInBackground(Void... arg0) {
			isPlaying = true;
			int bufferSize = AudioTrack.getMinBufferSize(frequence, channelConfig, audioEncoding);
			short[] buffer = new short[bufferSize/4];
			//byte[] buffer = new byte[bufferSize];
			try {
				//定义输入流,将音频写入到AudioTrack类中,实现播放
				DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(audioFile)));
				//FileInputStream fis = new FileInputStream(audioFile);
				//实例AudioTrack
				AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, frequence, channelConfig, audioEncoding, bufferSize, AudioTrack.MODE_STREAM);
				//开始播放
				track.play();
				//由于AudioTrack播放的是流,所以,我们需要一边播放一边读取
				while(isPlaying && dis.available()>0){
					int i = 0;
					while(dis.available()>0 && i<buffer.length){
						buffer[i] = dis.readShort();
						i++;
					}
					//然后将数据写入到AudioTrack中
					track.write(buffer, 0, buffer.length);
					
				}
				
				//播放结束
				track.stop();
				dis.close();
			} catch (Exception e) {
				// TODO: handle exception
			}
			return null;
		}
		
		protected void onPostExecute(Void result){
			btnPlay.setEnabled(true);
			btnFinish.setEnabled(false);
			btnStart.setEnabled(true);
			btnStop.setEnabled(false);
		}
		
		protected void onPreExecute(){	
			
			//stateView.setText("正在播放");
			btnStart.setEnabled(false);
			btnStop.setEnabled(false);
			btnPlay.setEnabled(false);
			btnFinish.setEnabled(true);			
		}
		
	}
}


对了 别忘了权限
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 	<uses-permission android:name="android.permission.RECORD_AUDIO" />



注意:其实这种方法也是不可取的 因为保存的PCM原始音频 没有压缩 所以非常大,一般还是用awr来传输 所以还是需要解码的


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics