我想要实现语音边录边放功能,其中用到speex编解码,但是播放的是噪音,我觉得是speex编解码时的音频数据参数出问题,参考网上跟官方的代码都不统一,求大神搭救
package com.embedsky.audiorecord;
import com.trunkbow.speextest.Speex;
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.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
Button btnRecord, btnStop, btnExit;
SeekBar skbVolume;//调节音量
boolean isRecording = false;//是否录放的标记
static final int frequency = 44100;
static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
int recBufSize,playBufSize;
AudioRecord audioRecord;
AudioTrack audioTrack;
private Speex speex;
private int frameSize;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("AudioRecord");
recBufSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
playBufSize=AudioTrack.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
// ---------------语音录制和播放--------------------------
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, recBufSize*10);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
channelConfiguration, audioEncoding,
playBufSize*10, AudioTrack.MODE_STREAM);
//---------------控件---------------------------
btnRecord = (Button) this.findViewById(R.id.btnRecord);
btnRecord.setOnClickListener(new ClickEvent());
btnStop = (Button) this.findViewById(R.id.btnStop);
btnStop.setOnClickListener(new ClickEvent());
btnExit = (Button) this.findViewById(R.id.btnExit);
btnExit.setOnClickListener(new ClickEvent());
skbVolume=(SeekBar)this.findViewById(R.id.skbVolume);
skbVolume.setMax(100);//音量调节的极限
skbVolume.setProgress(70);//设置seekbar的位置值
audioTrack.setStereoVolume(0.8f, 0.8f);//设置当前音量大小
skbVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
float vol=(float)(seekBar.getProgress())/(float)(seekBar.getMax());
audioTrack.setStereoVolume(vol, vol);//设置音量
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
});
//speex编解码
speex = new Speex();
speex.init();
frameSize = speex.getFrameSize();
}
@Override
protected void onDestroy() {
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());
}
class ClickEvent implements View.OnClickListener {
@Override
public void onClick(View v) {
if (v == btnRecord) {
isRecording = true;
new RecordPlayThread().start();// 开一条线程边录边放
} else if (v == btnStop) {
isRecording = false;
} else if (v == btnExit) {
isRecording = false;
MainActivity.this.finish();
}
}
}
class RecordPlayThread extends Thread {
public void run() {
try {
audioRecord.startRecording();//开始录制
audioTrack.play();//开始播放
while (isRecording) {
int totleByte = 0;
short[] bufferRead = new short[160];
byte[] processedData = new byte[1024];
short[] rawdata = new short[1024];
/**
* 声音采集
* pcm数据通过speex编码
*/
int bufferReadResult = audioRecord.read(bufferRead, 0,160);
synchronized (audioRecord) {
System.arraycopy(bufferRead, 0, rawdata, 0, bufferReadResult);
totleByte = speex.encode(rawdata, 0, processedData, bufferReadResult);// 编码后的总字节长度
if (totleByte != 0) {
Log.i("SPEEX", "编码成功 字节数组长度 = " + totleByte
+ " , short[] 长度 = " + bufferReadResult);
} else {
System.out.println("speex编码失败!");
}
}
/**
* 解码
*/
short[] rcvProcessedData = new short[160];
byte[] rawData= new byte[256];
System.arraycopy(processedData, 0, rawData, 0, bufferReadResult);
int desize;
synchronized (audioTrack) {
desize = speex.decode(processedData, rcvProcessedData, 160);
}
if (desize > 0) {
audioTrack.write(rcvProcessedData, 0, desize);
System.out.println("speex解码成功!");
}
}
audioTrack.stop();
audioRecord.stop();
} catch (Throwable t) {
System.out.println(t.getMessage());
}
}
};
}