Speex语音压缩和消除回声

发布于:2021-07-21 05:12:20



/**
* 录音类
*/
public class AudioRecordUtil {

private AudioRecord audioRecord;
private final static int AUDIO_SOURCE= MediaRecorder.AudioSource.MIC;//录取源
private final static int SAMPLE_RATE=8000;//采样率
private final static int CHANNEL_CONFIG= AudioFormat.CHANNEL_IN_MONO;//声道配置,和日常左右声道的意思一样
private final static int AUDIO_FORMAT=AudioFormat.ENCODING_PCM_16BIT;//音频量化所采用的方案
private int minBufferSize;//最小的缓存长度
private boolean isRecord=false;//用于标志循环中是否录音
private int audioFrame;
private Speex speex;
private OnAudioStreamCallback onAudioStreamCallback;

public void setOnAudioStreamCallback(OnAudioStreamCallback onAudioStreamCallback) {
this.onAudioStreamCallback = onAudioStreamCallback;
}

public AudioRecordUtil(){

minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,CHANNEL_CONFIG,AUDIO_FORMAT);//获取最小的缓存长度
// audioRecord = new AudioRecord(AUDIO_SOURCE, SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize);//新建AudioRecord对象
audioRecord= EchoCancel.createAudioRecorder(SAMPLE_RATE,CHANNEL_CONFIG,AUDIO_FORMAT,minBufferSize);
speex = new Speex();
speex.init();
audioFrame=speex.getFrameSize();
startRecord();
}

public synchronized void startRecord(){

if(!isRecord){
isRecord=true;
audioRecord.startRecording();//开始录音
new Thread(recordRunnable).start();//启动录音线程
}
}

public synchronized void stopRecord(){
if(isRecord){
isRecord=false;
audioRecord.stop();//停止录音
}
}

Runnable recordRunnable = new Runnable() {
@Override
public void run() {
while (isRecord){
/******************录音(start)*************************/
short[] audioData = new short[audioFrame];//新建数组用于保存录音数据;
int readSize=audioRecord.read(audioData, 0, audioFrame);
/******************录音(end)*************************/



/*************音频编码压缩(start)*******************/
byte encodeData[] = new byte[audioFrame];
readSize = speex.echoCancellationEncode(audioData,encodeData);//进行回声消除和压缩
/*************音频编码压缩(end)*******************/

if(onAudioStreamCallback!=null){
onAudioStreamCallback.onAudioStream(encodeData,readSize);
}
}
}
};

public interface OnAudioStreamCallback{
void onAudioStream(byte audioData[],int len);
}


}


?


?


/**
* 播放类
*/
public class AudioTrackUtil {

private AudioTrack audioTrack;
private final static int STREAM_TYPE= AudioManager.STREAM_MUSIC;//播放方式
private final static int SAMPLE_RATE=8000;//采样率
private final static int CHANNEL_CONFIG= AudioFormat.CHANNEL_OUT_MONO;//声道配置,和日常左右声道的意思一样
private final static int AUDIO_FORMAT=AudioFormat.ENCODING_PCM_16BIT;//音频量化所采用的方案
private final static int MODE=AudioTrack.MODE_STREAM;//播放模式
private int minBufferSize;//缓存音频的最小尺寸
private boolean isPlay=false;
private Queue audioDataQueue=new LinkedList<>();
private Speex speex;
private int audioFrame;


public AudioTrackUtil(Context context){
minBufferSize=AudioTrack.getMinBufferSize(SAMPLE_RATE,CHANNEL_CONFIG,AUDIO_FORMAT);
// audioTrack = new AudioTrack(STREAM_TYPE,SAMPLE_RATE,CHANNEL_CONFIG,AUDIO_FORMAT,minBufferSize,MODE);
audioTrack = EchoCancel.createAudioTrack(SAMPLE_RATE,CHANNEL_CONFIG,AUDIO_FORMAT,minBufferSize);
if (audioTrack!=null) {
EchoCancel.setplayertospeaker(context);
}
speex = new Speex();
speex.init();
audioFrame = speex.getFrameSize();
startPlay();
}

public void startPlay(){
if(!isPlay){
isPlay=true;
audioTrack.play();
new Thread(playRunnable).start();
}
}

public void stopPlay(){
if(isPlay){
isPlay = false;
audioTrack.stop();
}
}

public void write( byte[] audioData, int offsetInBytes, int sizeInBytes){
AudioData data = new AudioData();
data.setData(audioData);
data.setLen(sizeInBytes);
audioDataQueue.offer(data);
}

Runnable playRunnable=new Runnable() {
@Override
public void run() {
while (isPlay){
if(audioDataQueue!=null&&audioDataQueue.size()>0){
/**************读取数据(start)*********************/
AudioData data =audioDataQueue.poll();
if (data==null)
{
continue;
}
/**************读取数据(end)*********************/

/*************解码数据(start)**********************/
short[] decodeData=new short[audioFrame];
int size=speex.decode(data.getData(),decodeData,data.getLen());//数据进行解码
/*************解码数据(end)**********************/

speex.capture(decodeData);//采集回声,用于回声消除
audioTrack.write(decodeData,0,decodeData.length);

}
}
}
};
}


?

Demo下载链接:https://download.csdn.net/download/hengfeng430/12222581


?

相关推荐

最新更新

猜你喜欢