当前位置: 代码迷 >> Android >> 2011.08.12(四)——— android AudioTrack 不能播放awr
  详细解决方案

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

热度:76   发布时间:2016-05-01 18:45:30.0
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来传输 所以还是需要解码的


  相关解决方案