5 changed files with 288 additions and 5 deletions
Binary file not shown.
@ -0,0 +1,183 @@ |
|||||
|
package qianmu.container.util; |
||||
|
|
||||
|
import android.media.AudioFormat; |
||||
|
import android.media.AudioManager; |
||||
|
import android.media.AudioTrack; |
||||
|
import android.os.Bundle; |
||||
|
import android.os.Handler; |
||||
|
import android.os.Looper; |
||||
|
import android.os.Message; |
||||
|
import android.util.Log; |
||||
|
|
||||
|
import androidx.annotation.NonNull; |
||||
|
|
||||
|
import com.iflytek.sparkchain.core.tts.OnlineTTS; |
||||
|
import com.iflytek.sparkchain.core.tts.TTS; |
||||
|
import com.iflytek.sparkchain.core.tts.TTSCallbacks; |
||||
|
|
||||
|
|
||||
|
import org.greenrobot.eventbus.EventBus; |
||||
|
|
||||
|
import qianmu.container.app.Constant; |
||||
|
import qianmu.container.entity.MessageEvent; |
||||
|
|
||||
|
/** |
||||
|
* 科大讯飞语音 |
||||
|
*/ |
||||
|
public class KDXFUtil { |
||||
|
private static String TAG = "TTS: "; |
||||
|
// 语音合成对象
|
||||
|
private OnlineTTS mOnlineTTS; |
||||
|
private int sampleRate = 16000; |
||||
|
|
||||
|
TTSCallbacks mTTSCallback = new TTSCallbacks() { |
||||
|
|
||||
|
@Override |
||||
|
public void onResult(TTS.TTSResult result, Object o) { |
||||
|
//解析获取的交互结果,示例展示所有结果获取,开发者可根据自身需要,选择获取。
|
||||
|
byte[] audio = result.getData();//音频数据
|
||||
|
int status = result.getStatus();//数据状态
|
||||
|
|
||||
|
Bundle bundle = new Bundle(); |
||||
|
bundle.putByteArray("audio", audio); |
||||
|
Message msg = mAudioPlayHandler.obtainMessage(); |
||||
|
msg.what = AUDIOPLAYER_WRITE; |
||||
|
msg.obj = bundle; |
||||
|
mAudioPlayHandler.sendMessage(msg); |
||||
|
if(status == 2){ |
||||
|
//音频合成回调结束状态,注意,此状态不是播报完成状态
|
||||
|
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_END); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onError(TTS.TTSError ttsError, Object o) { |
||||
|
int errCode = ttsError.getCode();//错误码
|
||||
|
String errMsg = ttsError.getErrMsg();//错误信息
|
||||
|
LoggerUtil.d(TAG, "onError:errCode:" + errCode+ ",errMsg:" + errMsg); |
||||
|
//如果此时已经播报,则停止播报
|
||||
|
EventBus.getDefault().post(new MessageEvent(Constant.VOID_STOP)); |
||||
|
stopTTs(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
public void initTts(){ |
||||
|
mAudioPlayThread.start(); |
||||
|
// 初始化合成对象 发音人
|
||||
|
mOnlineTTS = new OnlineTTS("x4_xiaoyan"); //xiaoyan
|
||||
|
} |
||||
|
|
||||
|
//开始听写
|
||||
|
public void startTTs(String texts){ |
||||
|
if (null == mOnlineTTS) { |
||||
|
LoggerUtil.d(TAG, "未初始化"); |
||||
|
initTts(); |
||||
|
} |
||||
|
if(audioTrack == null){ |
||||
|
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_INIT); |
||||
|
}else{ |
||||
|
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_START); |
||||
|
} |
||||
|
setParam(); |
||||
|
// 合成并播放
|
||||
|
int ret = mOnlineTTS.aRun(texts); |
||||
|
if(ret!=0){ |
||||
|
LoggerUtil.d(TAG, "语音合成失败" ); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//停止听写
|
||||
|
public void stopTTs(){ |
||||
|
LoggerUtil.d(TAG, "手动暂停播放"); |
||||
|
if (null == mOnlineTTS) { |
||||
|
LoggerUtil.d(TAG, "未初始化"); |
||||
|
return; |
||||
|
} |
||||
|
mAudioPlayHandler.removeCallbacksAndMessages(null); |
||||
|
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_END); |
||||
|
mOnlineTTS.stop(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 参数设置 |
||||
|
* |
||||
|
* @return |
||||
|
*/ |
||||
|
private void setParam() { |
||||
|
mOnlineTTS.aue("raw"); |
||||
|
mOnlineTTS.auf("audio/L16;rate="+sampleRate); // 8K 或 16K
|
||||
|
mOnlineTTS.speed(60);//语速:0对应默认语速的1/2,100对应默认语速的2倍。最⼩值:0, 最⼤值:100
|
||||
|
mOnlineTTS.pitch(50);//语调:0对应默认语速的1/2,100对应默认语速的2倍。最⼩值:0, 最⼤值:100
|
||||
|
mOnlineTTS.volume(80);//音量:0是静音,1对应默认音量1/2,100对应默认音量的2倍。最⼩值:0, 最⼤值:100
|
||||
|
mOnlineTTS.bgs(0); //合成音频的背景音 0:无背景音(默认值) 1:有背景音
|
||||
|
mOnlineTTS.tte("UTF8"); |
||||
|
mOnlineTTS.registerCallbacks(mTTSCallback); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 播放器,用于播报合成的音频。 |
||||
|
* 注意:当前Demo中的播放器仅实现了播放PCM格式的音频,如果客户合成的是其他格式的音频,需自行实现播放功能。 |
||||
|
*/ |
||||
|
private static final int AUDIOPLAYER_INIT = 0x0000; |
||||
|
private static final int AUDIOPLAYER_START = 0x0001; |
||||
|
private static final int AUDIOPLAYER_WRITE = 0x0002; |
||||
|
private static final int AUDIOPLAYER_END = 0x0003; |
||||
|
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_OUT_MONO; // 单声道输出
|
||||
|
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; // PCM 16位编码
|
||||
|
private AudioTrack audioTrack; |
||||
|
private Handler mAudioPlayHandler; |
||||
|
private boolean isPlaying = false; |
||||
|
int count = 0; |
||||
|
private Thread mAudioPlayThread = new Thread(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
Looper.prepare(); |
||||
|
mAudioPlayHandler = new Handler(Looper.myLooper()){ |
||||
|
@Override |
||||
|
public void handleMessage(@NonNull Message msg) { |
||||
|
super.handleMessage(msg); |
||||
|
switch(msg.what){ |
||||
|
case AUDIOPLAYER_INIT: |
||||
|
Log.d(TAG,"audioInit"); |
||||
|
int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, CHANNEL_CONFIG, AUDIO_FORMAT); |
||||
|
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize, AudioTrack.MODE_STREAM); |
||||
|
mAudioPlayHandler.sendEmptyMessage(AUDIOPLAYER_START); |
||||
|
break; |
||||
|
case AUDIOPLAYER_START: |
||||
|
Log.d(TAG,"audioStart"); |
||||
|
if(audioTrack!=null) { |
||||
|
isPlaying = true; |
||||
|
audioTrack.play(); |
||||
|
} |
||||
|
break; |
||||
|
case AUDIOPLAYER_WRITE: |
||||
|
count ++; |
||||
|
if(count%5 == 0){ |
||||
|
Log.d(TAG,"audioWrite"); |
||||
|
count = 0; |
||||
|
} |
||||
|
Bundle bundle = (Bundle) msg.obj; |
||||
|
byte[] audioData = bundle.getByteArray("audio"); |
||||
|
if(audioTrack!=null&&audioData.length>0){ |
||||
|
audioTrack.write(audioData,0,audioData.length); |
||||
|
} |
||||
|
break; |
||||
|
case AUDIOPLAYER_END: |
||||
|
Log.d(TAG,"audioEnd"); |
||||
|
EventBus.getDefault().post(new MessageEvent(Constant.VOID_STOP)); |
||||
|
if(audioTrack!=null) { |
||||
|
audioTrack.stop(); |
||||
|
audioTrack.release(); |
||||
|
audioTrack = null; |
||||
|
isPlaying = false; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
Looper.loop(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue