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